umbot
Version:
Мультиплатформенный фреймворк для создания голосовых навыков и чат-ботов с единой бизнес-логикой. Встроенная поддержка ВКонтакте, Telegram, Viber, MAX, Яндекс Алисы, Маруси и Сбера SmartApp. Архитектура на адаптерах позволяет подключать любые другие платф
337 lines (336 loc) • 10.6 kB
TypeScript
/**
* Модуль базовой модели для работы с данными
*
* Предоставляет абстрактный класс для:
* - Взаимодействия с базой данных
* - Валидации данных
* - Управления состоянием модели
* - Выполнения CRUD операций
*/
import { IDataValue, IModelRes, IModelRules, TQueryCb } from '../interface';
import { IQueryData, IQuery, TKey } from './QueryData';
import { AppContext, IDbResult } from '../../core';
export interface IModelState {
[key: string]: unknown;
}
/**
* Интерфейс для описания результата выполнения операции с поиском 1 значения
*/
export interface ISelectOneModelRes extends Omit<IModelRes, 'data'> {
/**
* Результат выполнения операции.
* Присутствует только при status = true.
* Может содержать любые данные в зависимости от операции
*/
data?: IDataValue;
}
/**
* Абстрактный класс для создания моделей данных
* Предоставляет базовую функциональность для работы с данными в базе данных
*
* @example
* ```ts
* class UserModel extends Model<UserState> {
* // Определение правил валидации
* rules(): IModelRules[] {
* return [
* { name: ['username'], type: 'string', max: 50 },
* { name: ['age'], type: 'integer' }
* ];
* }
*
* // Определение меток атрибутов
* attributeLabels(): UserState {
* return {
* id: 'ID',
* username: 'Имя пользователя',
* age: 'Возраст'
* };
* }
*
* // Определение имени таблицы
* tableName(): string {
* return 'users';
* }
* }
*
* // Использование модели
* const user = new UserModel();
* user.state.username = 'John';
* user.state.age = 25;
* await user.save();
* ```
*
* @template TState - Тип состояния модели
* @class Model
*/
export declare abstract class Model<TState extends IModelState> {
#private;
/**
* Объект для хранения параметров запроса.
* Содержит условия поиска и данные для обновления
*/
queryData: IQuery;
/**
* Начальный индекс для итерации по данным.
* Используется при инициализации модели из массива
*/
startIndex: number;
/**
* Состояние модели.
* Содержит текущие значения всех атрибутов
*
* @example
* ```ts
* // Установка значений
* this.state.username = 'John';
* this.state.age = 25;
*
* // Получение значений
* console.log(this.state.username);
* ```
*/
state: Partial<TState>;
/**
* Контекст приложения.
*/
protected _appContext: AppContext;
/**
* Определяет правила валидации для полей модели
* Должен быть реализован в дочерних классах
*
* @example
* ```ts
* rules(): IModelRules[] {
* return [
* { name: ['username'], type: 'string', max: 50 },
* { name: ['age'], type: 'integer' }
* ];
* }
* ```
*
* @returns Массив правил валидации
* @virtual
*/
abstract rules(): IModelRules[];
/**
* Определяет метки атрибутов модели
* Должен быть реализован в дочерних классах
*
* @example
* ```ts
* attributeLabels(): UserState {
* return {
* id: 'ID',
* username: 'Имя пользователя',
* age: 'Возраст'
* };
* }
* ```
*
* @returns Объект с метками атрибутов
* @virtual
*/
abstract attributeLabels(): TState;
/**
* Определяет имя таблицы в базе данных
* Должен быть реализован в дочерних классах
*
* @example
* ```ts
* tableName(): string {
* return 'users';
* }
* ```
*
* @returns Имя таблицы
* @virtual
*/
abstract tableName(): string;
/**
* Создает новый экземпляр модели.
* Инициализирует контроллер базы данных и состояние модели
*
* @example
* ```ts
* const user = new UserModel();
* ```
*/
protected constructor(appContext: AppContext);
/**
* Проверяет состояние подключения к базе данных
*
* @example
* ```ts
* const isConnected = await model.isConnected();
* if (isConnected) {
* // Выполнение операций с базой данных
* }
* ```
*
* @returns Promise<boolean> - true если подключение активно
*/
isConnected(): Promise<boolean> | boolean;
/**
* Экранирует специальные символы в строке
*
* @example
* ```ts
* const safe = model.escapeString("O'Connor");
* ```
*
* @param text - Текст для экранирования
* @returns Экранированная строка
*/
escapeString(text: string | number): string;
/**
* Выполняет валидацию данных модели
* Может быть переопределен в дочерних классах
*
* @example
* ```ts
* validate(): void {
* if (!this.state.username) {
* throw new Error('Username is required');
* }
* }
* ```
*/
validate(): void;
/**
* Определяет имя первичного ключа таблицы.
* Ищет поле с меткой 'id' или 'ID'
*
* @returns Имя первичного ключа или null
*/
protected getId(): TKey;
/**
* Инициализирует модель данными
*
* @example
* ```ts
* model.init({
* id: 1,
* username: 'John',
* age: 25
* });
* ```
*
* @param data - Данные для инициализации
*/
init(data: IDbResult[] | IDbResult | null): void;
/**
* Выполняет поиск записи по первичному ключу
*
* @example
* ```ts
* const result = await model.selectOne();
* if (result.status) {
* model.init(result.data);
* }
* ```
*
* @returns Promise с результатом запроса
*/
selectOne(): Promise<ISelectOneModelRes>;
/**
* Сохраняет данные модели в базу данных
* Если запись существует - обновляет, иначе создает новую
*
* @example
* ```ts
* model.state.name = 'John';
* await model.save(); // Обновление существующей записи
* await model.save(true); // Создание новой записи
* ```
*
* @param isNew - Флаг создания новой записи
* @returns Promise с результатом операции
*/
save(isNew?: boolean): Promise<boolean>;
/**
* Обновляет существующую запись в базе данных
*
* @example
* ```ts
* model.state.name = 'John';
* await model.update();
* ```
*
* @returns Promise с результатом операции
*/
update(): Promise<boolean>;
/**
* Добавляет новую запись в базу данных
*
* @example
* ```ts
* model.state.name = 'John';
* await model.add();
* ```
*
* @returns Promise с результатом операции
*/
add(): Promise<boolean>;
/**
* Удаляет запись из базы данных
*
* @example
* ```ts
* await model.remove();
* ```
*
* @returns Promise<boolean> - true если удаление успешно
*/
remove(): Promise<boolean>;
/**
* Выполняет произвольный запрос к базе данных
*
* @param where - Условия запроса
* @param isOne - Флаг выборки одной записи
* @returns Promise с результатом запроса
*/
where(where?: string | IQueryData, isOne?: boolean): Promise<IModelRes>;
/**
* Выполняет запрос с выборкой одной записи
*
* @example
* ```ts
* const found = await model.whereOne({ id: 1 });
* if (found) {
* console.log('Record found');
* }
* ```
*
* @param where - Условия запроса
* @returns Promise<boolean> - true если запись найдена
*/
whereOne(where?: string | IQueryData): Promise<boolean>;
/**
* Выполняет произвольный запрос к базе данных
*
* @example
* ```ts
* const result = await model.query(async (client, db) => {
* const collection = db.collection('users');
* return await collection.aggregate([
* { $match: { age: { $gt: 18 } } },
* { $group: { _id: '$city', count: { $sum: 1 } } }
* ]).toArray();
* });
* ```
*
* @param callback - Функция обратного вызова для выполнения запроса
* @returns Результат выполнения запроса
*/
query(callback: TQueryCb): unknown;
/**
* Закрывает соединение с базой данных
*
* @example
* ```ts
* model.destroy();
* ```
*/
destroy(): void | Promise<void>;
}