## @e22m4u/js-repository-mongodb-adapter

MongoDB адаптер для
[@e22m4u/js-repository](https://www.npmjs.com/package/@e22m4u/js-repository).

- [Установка](#установка)
- [Описание](#описание)
- [Источник данных](#источник-данных)
- [Ограничения](#ограничения)
- [Преобразование операторов](#преобразование-операторов)
- [Тесты](#тесты)
- [Лицензия](#лицензия)

## Установка

```bash
npm install @e22m4u/js-repository-mongodb-adapter
```

## Описание

Адаптер предоставляет возможность использовать MongoDB в качестве хранилища
данных для `@e22m4u/js-repository`. Он автоматически преобразует названия
моделей в названия коллекций, а также выполняет преобразование стандартных
операторов фильтрации в нативные запросы MongoDB.

#### ObjectId

Взаимодействие с репозиторием происходит с использованием строкового
представления идентификаторов. Адаптер самостоятельно преобразует строки
в `ObjectId` перед отправкой запросов в базу данных и выполняет обратное
преобразование при получении результатов. Это позволяет работать
с идентификаторами как с обычными строками без необходимости импортировать
`ObjectId` из драйвера MongoDB.

## Источник данных

Источник данных для MongoDB адаптера определяется с помощью метода
`defineDatasource` экземпляра `DatabaseSchema`.

**Параметры**

| название | значение по умолчанию | описание               |
|----------|-----------------------|------------------------|
| protocol | `'mongodb'`           | протокол подключения   |
| host     | `'127.0.0.1'`         | имя хоста или IP адрес |
| port     | `27017`               | порт                   |
| database | `'database'`          | название базы данных   |
| username | `undefined`           | имя пользователя       |
| password | `undefined`           | пароль                 |

Кроме перечисленных выше, адаптер поддерживает все стандартные параметры
`MongoClientOptions` из официального драйвера MongoDB для NodeJS. Эти
параметры можно передавать напрямую в определении источника данных.

**Пример**

```js
import {DatabaseSchema} from '@e22m4u/js-repository';

const dbs = new DatabaseSchema();

// объявление источника
dbs.defineDatasource({
  name: 'myMongo',     // название источника
  adapter: 'mongodb',  // имя адаптера
  // параметры
  host: '127.0.0.1',
  port: 27017,
  database: 'myDatabase',
});

// объявление модели
dbs.defineModel({
  name: 'user',          // название модели
  datasource: 'myMongo', // используемый источник
  properties: {          // поля модели
    name: 'string',
    surname: 'string',
  },
});

// получение репозитория и создание документа
const userRep = dbs.getRepository('user');
const user = await userRep.create({name: 'John', surname: 'Doe'});

console.log(user);
// {
//   id: '64f3454e5e0893c13f9bf47e', // id является строкой
//   name: 'John',
//   surname: 'Doe',
// }
```

## Ограничения

- **Первичный ключ.**  
  Свойство, выступающее в роли первичного ключа, должно иметь
  название `id` или `_id`. Использование других названий для
  первичного ключа не поддерживается.

- **Автогенерация идентификатора.**  
  Автоматическая генерация `ObjectId` при создании нового документа
  работает только для свойств с типом `string` или `any`. Для других
  типов данных значение первичного ключа необходимо указывать вручную.

## Преобразование операторов

Адаптер преобразует стандартные операторы фильтрации в нативные операторы
запросов MongoDB.

| оператор | MongoDB                        |
|----------|--------------------------------|
| `and`    | `$and`                         |
| `or`     | `$or`                          |
| `nor`    | `$nor`                         |
| `eq`     | `$eq`                          |
| `neq`    | `$ne`                          |
| `gt`     | `$gt`                          |
| `lt`     | `$lt`                          |
| `gte`    | `$gte`                         |
| `lte`    | `$lte`                         |
| `inq`    | `$in`                          |
| `nin`    | `$nin`                         |
| `between`| `{$gte: ..., $lte: ...}`       |
| `exists` | `$exists`                      |
| `like`   | `$regex`                       |
| `nlike`  | `$not` с `$regex`              |
| `ilike`  | `$regex` с флагом `i`          |
| `nilike` | `$not` с `$regex` и флагом `i` |
| `regexp` | `$regex`                       |

## Тесты

Запуск контейнера `mongo:latest` скриптом `setup.sh`

```bash
./setup.sh
```

Выполнение тестов

```bash
npm run test
```

## Лицензия

MIT