Реализация репозитория для работы с базами данных
|
|
2 years ago | |
|---|---|---|
| .husky | 2 years ago | |
| src | 2 years ago | |
| .c8rc | 2 years ago | |
| .commitlintrc | 2 years ago | |
| .editorconfig | 2 years ago | |
| .eslintignore | 2 years ago | |
| .eslintrc.cjs | 2 years ago | |
| .gitignore | 2 years ago | |
| .mocharc.cjs | 2 years ago | |
| .prettierrc | 2 years ago | |
| LICENSE | 2 years ago | |
| README.md | 2 years ago | |
| mocha.setup.js | 2 years ago | |
| package.json | 2 years ago |
Абстракция для работы с базами данных для Node.js
| адаптер | описание |
|---|---|
| memory | виртуальная база в памяти процесса (для разработки и тестирования) |
| mongodb | MongoDB - система управления NoSQL базами данных (требует установки) |
npm install @e22m4u/node-repository
Опционально устанавливаем адаптер, например mongodb
npm install @e22m4u/node-repository-mongodb-adapter
Создаем экземпляр класса Schema
import {Schema} from '@e22m4u/node-repository';
const schema = new Schema();
Создаем источник данных myMemory
schema.defineDatasource({
name: 'myMemory', // название источника
adapter: 'memory', // выбранный адаптер
});
Создаем модель user
schema.defineModel({
name: 'user', // название модели
adapter: 'myMemory', // выбранный источник
properties: { // поля модели
name: 'string',
age: 'number',
},
});
Получаем репозиторий модели user
const userRep = schema.getRepository('user');
Добавляем новую запись методом create
const fedor = await userRep.create({
name: 'Fedor',
age: 24,
});
console.log(fedor);
// {
// id: 1,
// name: 'Fedor',
// age: 24,
// }
Изменяем данные методом patchById
const result = await userRep.patchById(
fedor.id,
{age: 30},
);
console.log(result);
// {
// id: 1,
// name: 'Fedor',
// age: 30,
// }
Удаляем по идентификатору методом deleteById
await userRep.deleteById(fedor.id); // true
Выполняет операции чтения и записи определенной коллекции.
Методы:
create(data, filter = undefined)replaceById(id, data, filter = undefined)replaceOrCreate(data, filter = undefined)patchById(id, data, filter = undefined)find(filter = undefined)findOne(filter = undefined)findById(id, filter = undefined)delete(where = undefined)deleteById(id)exists(id)count(where = undefined)Получение репозитория модели:
import {Schema} from '@e22m4u/node-repository';
const schema = new Schema();
// создаем источник
schema.defineDatasource({name: 'myDatasource', adapter: 'memory'});
// создаем модель
schema.defineModel({name: 'myModel', datasource: 'myDatasource'});
// получаем репозиторий по названию модели
const repositorty = schema.getRepository('myModel');
Переопределение конструктора:
import {Schema} from '@e22m4u/node-repository';
import {Repository} from '@e22m4u/node-repository';
import {RepositoryRegistry} from '@e22m4u/node-repository';
class MyRepository extends Repository {
/*...*/
}
const schema = new Schema();
schema.get(RepositoryRegistry).setRepositoryCtor(MyRepository);
// теперь schema.getRepository(modelName) будет возвращать
// экземпляр класса MyRepository
Большинство методов репозитория принимают объект filter
для фильтрации возвращаемого ответа. Описание параметров объекта:
where (условия выборки данных из
базы)
примеры:
where: {foo: 'bar'} поиск по значению поля
foo
where: {foo: {eq: 'bar'}} оператор равенства
eq
where: {foo: {neq: 'bar'}} оператор неравенства
neq
where: {foo: {gt: 5}} оператор "больше"
gt
where: {foo: {lt: 10}} оператор "меньше"
lt
where: {foo: {gte: 5}} оператор "больше или равно"
gte
where: {foo: {lte: 10}} оператор "меньше или равно"
lte
where: {foo: {inq: ['bar', 'baz']}} равенство одного из
значений inq
where: {foo: {nin: ['bar', 'baz']}} исключение значений
массива nin
where: {foo: {between: [5, 10]}} оператор диапазона
between
where: {foo: {exists: true}} оператор наличия значения
exists
where: {foo: {like: 'bar'}} оператор поиска подстроки
like
where: {foo: {ilike: 'BaR'}} регистронезависимая версия
ilike
where: {foo: {nlike: 'bar'}} оператор исключения подстроки
nlike
where: {foo: {nilike: 'BaR'}} регистронезависимая версия
nilike
where: {foo: {regexp: 'ba.+'}} оператор регулярного
выражения regexp
where: {foo: {regexp: 'ba.+', flags: 'i'}} флаги
регулярного выражения
order (упорядочить записи по
полю)
примеры:
order: 'foo' порядок по полю foo
order: 'foo ASC' явное указание порядка
order: 'foo DESC' инвертировать порядок
order: ['foo', 'bar ASC', 'baz DESC'] по нескольким
полям
limit (не более N записей)
примеры:
limit: 0 не ограничивать
limit: 14 не более 14-и
skip (пропуск первых N записей)
примеры:
skip: 0 выборка без пропуска
skip: 10 пропустить 10 объектов выборки
include (включение связанных данных в
результат)
примеры:
include: 'foo' включение связи foo
include: ['foo', 'bar'] включение foo и
bar
include: {foo: 'bar'} включение вложенной связи
foo
Определяет настройки и способ подключения к базе.
Параметры:
name: string название нового источникаadapter: string выбранный адаптер базы данныхПример:
schema.defineDatasource({
name: 'myDatasource',
adapter: 'memory',
});
Адаптер может иметь параметры, которые передаются при определении источника.
Пример:
schema.defineDatasource({
name: 'myDatasource',
adapter: 'mongodb',
// параметры адаптера:
host: '127.0.0.1',
port: 27017,
});
Описывает набор полей и связей к другим моделям.
Параметры:
name: string название новой моделиdatasource: string выбранный источник данныхproperties: object определения полей моделиrelations: object определения связей моделиПример:
schema.defineModel({
name: 'myModel',
datasource: 'myDatasource',
properties: {...}, // см. ниже
relations: {...}, // см. ниже
});
Параметр properties описывает набор полей и их
настройки.
Типы:
stringnumberbooleanarrayobjectanyПример:
schema.defineModel({
// ...
properties: {
prop1: 'string',
prop2: 'number',
prop3: 'boolean',
prop4: 'array',
prop5: 'object',
prop6: 'any',
},
});
Расширенные параметры:
type: string тип хранимого значенияitemType: string тип элемента массива (для
type: 'array')model: string модель объекта (для
type: 'object')primaryKey: boolean объявить поле первичным ключомcolumnName: string переопределение названия
колонкиcolumnType: string тип колонки (определяется
адаптером)required: boolean объявить поле обязательнымdefault: any значение по умолчанию для
undefinedПример:
schema.defineModel({
// ...
properties: {
prop1: {
type: 'string',
primaryKey: true,
},
prop2: {
type: 'boolean',
required: true,
},
prop3: {
type: 'number',
default: 100,
},
prop3: {
type: 'string',
// фабричное значение
default: () => new Date().toISOString(),
},
prop4: {
type: 'array',
itemType: 'string',
},
prop5: {
type: 'object',
model: 'objectModel',
},
},
});
Параметр relations описывает набор связей к другим
моделям.
Понятия:
Типы:
belongsTo - ссылка на целевую модель находится в
источникеhasOne - ссылка на источник находится в целевой модели
(one-to-one)hasMany - ссылка на источник находится в целевой модели
(one-to-many)referencesMany - массив ссылок на целевую модель
находится в источникеПараметры:
type: string тип связиmodel: string целевая модельforeignKey: string поле для идентификатора целиpolymorphic: boolean|string объявить связь
полиморфной*discriminator: string поле для названия целевой модели
(для polymorphic: true)i. Полиморфный режим belongsTo позволяет динамически
определять цель связи, где имя целевой модели хранится в отдельном поле,
рядом с foreignKey
Связь заказа к покупателю через поле customerId
schema.defineModel({
// ...
relations: {
// ...
customer: {
type: 'belongsTo',
model: 'customer',
foreignKey: 'customerId', // опционально
},
},
});
Полиморфная версия
schema.defineModel({
// ...
relations: {
// ...
customer: {
type: 'belongsTo',
polymorphic: true,
foreignKey: 'customerId', // опционально
discriminator: 'customerType', // опционально
},
},
});
Связь покупателя к заказу, как обратная сторона
belongsTo
schema.defineModel({
// ...
relations: {
// ...
order: {
type: 'hasOne',
model: 'order',
foreignKey: 'customerId', // опционально
},
},
});
Обратная сторона полиморфной версии belongsTo
schema.defineModel({
// ...
relations: {
// ...
order: {
type: 'hasOne',
model: 'order',
polymorphic: 'customer', // имя связи целевой модели
},
},
});
Явное указание foreignKey и
discriminator
schema.defineModel({
// ...
relations: {
// ...
order: {
type: 'hasOne',
model: 'order',
polymorphic: true, // true вместо имени модели
foreignKey: 'customerId', // поле целевой модели
discriminator: 'customerType', // поле целевой модели
},
},
});
Связь покупателя к заказам, как обратная сторона
belongsTo
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'hasMany',
model: 'order',
foreignKey: 'customerId', // опционально
},
},
});
Обратная сторона полиморфной версии belongsTo
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'hasMany',
model: 'order',
polymorphic: 'customer', // имя связи целевой модели
},
},
});
Явное указание foreignKey и
discriminator
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'hasMany',
model: 'order',
polymorphic: true, // true вместо имени модели
foreignKey: 'customerId', // поле целевой модели
discriminator: 'customerType', // поле целевой модели
},
},
});
Связь покупателя к заказам через поле orderIds
schema.defineModel({
// ...
relations: {
// ...
orders: {
type: 'referencesMany',
model: 'order',
foreignKey: 'orderIds', // опционально
},
},
});
npm run test
MIT