Описание логики и класса js, реализующие систему оперативного хранения данных в структуре, похожей на реляционную базу данных. Основные возможности: перекрёстные ссылки на таблицы, поиск и фильтрация записей, хранение данных в local storage. Поддерживает массовое внесение и удаление записей. В текущей версии запросы выполняются синхронно. Не рекомендуется хранение более 1 000 000 записей в таблице, чтобы исключить длительные фризы интерфейса.
- Неудобный интерфейс и скудные возможности IndexedDB
- Образовательные потребности.
Основной объект базы данных содержит обзательные специальные ключи: __data __tables и геттер about
Ключ __data содержит объект, который описывает базу данных: имя, версия краткое описание. version — числовое поле, допустимо дробное и отрицательное значения, два других — текстовые.
__data: {
name: "goodsBase",
version: 1,
description: "База данных продуктов, клиентов и покупок"
}
Ключ __tables — объект, ключи которого — имена таблиц.
Таблица — объект, содержащий специальный ключ __captions, являющийся обязательным, в объекте по этому ключу описывается каждое поле таблицы: его тип и доп. информация, нужная для работы с полем. Таблица также содержит обязательный ключ __rows с массивом объектов — данные таблицы. Если таблица пуста, rows содержит пустой массив.
customers: {
__captions: {
id: {
type: "auto",
format: "integer",
unique: true,
next: 1
},
name: {
type: "text"
}
},
__rows: [
{id: 0, name: "Петров Сергей Иванович"}
]
}
Поле с автоинкрементом по добавлению записи. Обязательные поля:
- format (в текущей версии всегда равен "integer")
- next: integer следующее значение для поля.
- unique: true
Все описания полей заполняются автоматически. Нумерация всегда начинается с нуля, это не настраивается.
Ссылка на запись или поле записи в другой таблице.
Обязательные поля
- table: tablename имя таблицы для ссылки
- to: colname имя столбца по которому ищем совпадения
- data: (:all | colname | [colname1, colname2] ) (вся запись целиком | значение одного поля записи | набор полей, которые будут добавлены в возвращаемый объект)
- multiply: true | false (в поле ожидается массив значений для сверки с целевой таблицей. | в поле ожидается один ключ, будет возвращено значение)
Если link указывает на поле с атрибутом unique: false, программа будет возвращать по ссылке массив всех записей. Не может содержать unique
Квазиссылка. Копирует фактическое значение по адресу из to, не следует по ссылкам.
Обязательные поля
- table: tablename имя таблицы для ссылки
- to: colname
- data: colname
- format: скопирует формат поля по ссылке, если есть, иначе текст.
Не может содержать unique
Текстовое поле. обязательные поля: нет. Автоматически устанавливается
format: string
Возможные поля:
- unique: true | false.
Текстовое поле c html-тегами. обязательные поля: нет. Автоматически устанавливается
format: string
Дата в формате js Date или текст, который спарсится без ошибок. Возможные поля:
- format: {} описание формата в нотации js Date
- language: string язык, согласно формату date.toLocaleString. Указание одного из этих полей, требует обязательного наличия второго поля. В value объекта спарсенной таблицы пишется результат toLocaleDateString со значениями полей language и format в качестве аргументов.
Пока не проверяется на unique.
Число. Может быть целым или с указанной точностью.
Обязательные поля:
- format: integer | float | precision (целое | с плавающей запятой | с указанной точностью) Если формат не указан, устанавливается в integer.
Для формата precision обязательно требуется поле
- precision: integer. Указывается число знаков после запятой.
Возможные поля:
- unique: true | false.
Булево значение. Обязательные поля отсутствуют
- format: boolean устанавливается автоматически. не может содержать unique.
Поле, вычисляемое на основании других полей строки при запросе. Не реализовано.
Примем, что basе — экземпляр класса GCBase.
При создании экземпляра, конструктору можно передать объект с ключами, характерными для заголовка БД или строку.
В первом случае будет создана пустая БД с использованием переданной информации. Во втором случае, если строка длиннее 30 символов, предполагается, что получена стрингифицированная БД. Строка парсится с помощью JSON.parse и использованием вспомогательных функций {insert names here later} для приведения содержимого ключей к нужному формату и проверки валидности.
//Case #1 example
let base = new GCBase( {name: "customersBase", version: 1, description: "База данных продуктов, клиентов и покупок"});
//Case #2 example
let base = new GCBase(
`{
__data: {name: "goodsBase", version: 1, description: "База данных продуктов, клиентов и покупок"},
customers: {
__captions: {
id: {
type: "auto",
format: "integer",
unique: true,
next: 1
},
name: {
type: "text"
}
},
rows: [
{id: 0, name: "Петров Сергей Иванович"}
]
}
}` );
Если строка, переданная конструктору короче или равна 30 символам, предполагается, что это имя БД для загрузки из LS. Если БД с таким именем отсутствует в LS, будет брошено исключение "GCBase error loading database from Local storage: no database".
Создание БД методами экземпляра GCBase не предусмотрено.
GCBase.exists("myBase"); // true | false
GCBase.checkDB(myBase); // true / false
checkDBData: проверяет валидность заголовк базы данных в формате объекта на соответствие структуре __data
GCBase.checkDBDate(myBase); // true / false
base.setVersion(2);
Аргумент должен быть валидным числом и превосходить текущий номер версии БД или быть равным ему.
Геттер, возвращает копию объекта base.__data
Метод addTable принимает объект, описывающий столбцы (поля) таблицы, с указанием обязательных элементов описания, значение которых не выставляется автоматически (см. "Keys formats description").
base.addTable("customers", {
id: {
type: "auto"
},
FIO: {
type: "text"
}
);
Если передан параметр true, обработает и кэшированные (с отформатированными значениями, загруженными link'ами) таблицы иначе, только source
base.stringify([withCache])
Возвращает стрингифицированный результат, ничего не меняет.
base.stringifyCache()
recache — пересчет ссылок, дат и т.д. для каждой таблицы. Требуется после изменения таблицы, на которую ссылается текущая. Производится вручную (для экономии ресурсов)
(-) Метод принимает имя таблицы для удаления.
base.dropTable("customers")
Если на таблицу есть ссылки из других таблиц, будет брошено исключение "GCBase drop table error: the table has links from the another tables. Remove links first.".
Если указать false, не будет сохранять кэш таблиц.
(-) base.save([withCache = true]);
Текущая БД удаляется без сохранения, все данные загружаются из LS. При отсутствии БД с соответствующим именем в LS, бросает исключение.
base.reload();
base.hasTable("tablename");
Позволяет: переименовывать таблицу, читать информацию о столбцах, получать содержимое таблицы или конкретную запись, получать сгруппированные записи и т.д. В параметре row содержится спарсенная таблица. В спарсенной таблице для link, date, создается объект вида {source: исходное значение поля, value: обработанное значение}
// Получаем все записи из таблицы customers, для которых fn вернет true (строго)
base.table("customers").rows
Фильтрацию, сортировку строк предлагается осуществлять методами Array. При этом, деструктивные методы в обкекте устранены, предлагается удалять строки методами БД.
Более подробно см. в разделе "Queries"
Все запросы, работающие с существующими таблицами, начинаются с метода table, которому передается имя таблицы. У возвращаемого методом объекта есть свойства:
- rows — Array обработанных (получены ссылки, спарсена дата). Экземпляр массива модифицирован (деструктивные методы приравнены к undefined). Добавлены свои методы. Default methods: rows.delete, rows.splice, rows.shift, rows.push, rows.unshift, rows.pop are undefined.
- captions — объект заголовков БД (копия оригинальных заголовков)
Методы
-
rows.add(object: table row | Array of table rows)
-
recache — пересчет ссылок, дат и т.д. Требуется после изменения таблицы, на которую ссылается текущая. Производится вручную (для экономии ресурсов)
-
(-)rows.delete (fn) удаление строк по функции
-
(-) rename(string: new name) rename table
-
(-) removeColumn( colname, [filterfn | value strict equal] ) will remove the whole column if don't recieve the second parameter.
-
(-) addColumn(colname, object: description of the format for __captions
-
(-) change(filterfn, changefn) prohibit to change link and qlink columns
Database management
- base.about геттер, возвращает копию объекта base.__data
- Чейнинг: все методы экземпляра должны возвращать осмысленные объекты.
- Группировка: например, суммирование. По группирующему запросу должен возвращаться объект. Или оставить на пользователя.
- При добавлении таблицы отслеживать циклические ссылки.