tachybase_todo/docs/reference/database.md
2021-11-25 11:20:05 +08:00

6.8 KiB
Raw Blame History

toc
menu

Database

db.sequelize

Sequelize 实例

Definition
class Database {
  public sequelize: Sequelize;
}
Examples

直接调用 sequelize api

db.sequelize.close();

db.close()

断开数据库连接

Definition
class Database {
  close(): Promise<void>;
}
Examples
await db.close();

db.collection()

配置数据表、字段和索引等,更多字段配置查看 Field Types

Definition
class Database {
  collection(options: CollectionOptions) : Collection;
}

interface CollectionOptions {
  name: string;
  title?: string;
  // 自定义 model
  model?: string;
  // 自定义 repository
  repository?: string;
  // 字段配置
  fields?: FieldOptions;
}

// TODO需要提供完善的 types用于配置时提示
type FieldOptions;
Examples

配置 fields

const Post = db.collection({
  name: 'posts',
  fields: [
    { type: 'string', name: 'name' },
  ],
});

自定义 model 见 db.registerModels()

自定义 repository 见 db.registerRepositories()

db.constructor()

Definition
class Database {
  constructor (options: DatabaseOptions) => void;
}

type DatabaseOptions = Sequelize.Options | Sequelize;
Examples

配置 options 与 Sequelize.Options 一致,如:

const db = new Database({
  dialect: 'sqlite',
  storage: 'path/to/database.sqlite'
});

也可以直接传 sequelize 实例

const sequelize = new Sequelize('sqlite::memory:');
const db = new Database(sequelize);

注意new Sequelize() 会有针对参数的 try catch 处理Database 如果要捕获异常,也需要在 new 的时候 try catch

try {
  const db = new Database({
    dialect: 'sqlite',
    storage: 'path/to/database.sqlite'
  });
} catch(error) {

}

db.emit()

同步事件触发

Definition
Examples

db.emitAsync()

异步事件触发

Definition
Examples

db.getCollection() 待完善

Definition
class Database {
  getCollection(name: string): Collection;
}
Examples
const collection = db.getCollection('tests');

db.hasCollection() 待完善

Definition
class Database {
  hasCollection(name: string): boolean;
}
Examples
if (db.hasCollection('tests')) {

}

db.import() 待完善

Definition
class Database {
  import(options: ImportOptions): Map<string, Collection>;
}

interface ImportOptions {
  // 配置所在文件夹
  directory: string;
  // 配置后置
  // @default ['js', 'ts', 'json']
  extensions?: string[];
}
Examples

导入某文件夹下的所有 Collection 配置

db.import({
  directory: '/path/to/collections',
  extensions: ['js', 'ts', 'json'],
});

db.on() 待完善

Definition

collection 的事件(都是同步的)

  • beforeDefineCollection
  • afterDefineCollection
  • beforeUpdateCollection
  • afterUpdateCollection
  • beforeRemoveCollection
  • afterRemoveCollection

model 的事件(异步的)

  • <modelName>.<hookType>
Examples

全局事件

db.on('beforeDefineCollection', (options: CollectionOptions) => {

});

db.on('afterDefineCollection', (collection: Collection) => {

});

db.on('afterCreate', async (model, options) => {

});

特定 model 事件

db.on('posts.afterCreate', async (model, options) => {

});

db.registerFieldTypes()

自定义字段存储类型,更多字段类型查看 Field Types

Definition
class Database {
  registerFieldTypes(types: RegisterFieldTypes): void;
}

interface RegisterFieldTypes {
  [key: string]: Field;
}
Examples
class CustomField extends Field {
  get dataType() {
    return DataTypes.STRING;
  }
}

db.registerFieldTypes({ custom: CustomField });

db.collection({
  name: 'tests',
  fields: [
    { type: 'custom', name: 'customName' },
  ],
});

db.registerModels() 待完善

自定义 Model

Definition
class Database {
  registerModels(models: RegisterModels): void;
}

interface RegisterModels {
  [key: string]: Sequelize.Model;
}
Examples
class CustomModel extends Model {
  customMethod() {
    console.log('custom method');
  }
}

db.registerModels({
  CustomModel,
});

const Test = db.collection({
  name: 'tests',
  model: 'CustomModel',
});

const test = Test.model<CustomModel>.create();
test.customMethod();

db.registerOperators() 待完善

自定义筛选条件

Definition
class Database {
  registerOperators(operators: RegisterOperators): any;
}

interface RegisterOperators {
  [key: string]: (value: any, ctx?: RegisterOperatorsContext) => any;
}

interface RegisterOperatorsContext {
  db?: Database;
  path?: string;
  field?: Field;
}
Examples

大部分自定义 Operator可以直接转换

db.registerOperators({
  includes: (value, ctx) => {
    const dialect = ctx.db.sequelize.getDialect();
    return {
      [dialect === 'postgres' ? Op.iLike : Op.like]: `%${value}%`,
    }
  },
});

repository.find({
  filter: {
    'attr.$includes': 'abc',
  },
});

但是也有少量 Operator 比较复杂

db.registerOperators({
  anyOf: (value: any[], ctx) => {
    if (!values) {
      return Sequelize.literal('');
    }
    values = Array.isArray(values) ? values : [values];
    if (values.length === 0) {
      return Sequelize.literal('');
    }
    const { path } = ctx;
    const column = path
      .split('.')
      .map((name) => `"${name}"`)
      .join('.');
    const sql = values
      .map((value) => `(${column})::jsonb @> '${JSON.stringify(value)}'`)
      .join(' OR ');
    return Sequelize.literal(sql);
  },
});

repository.find({
  filter: {
    'attr.$anyOf': ['val1', 'val2'],
  },
});

db.registerRepositories() 待完善

自定义 Repository

Examples
class CustomRepository extends Repository {
  customMethod() {
    console.log('custom method');
  }
}

db.registerModels({
  CustomRepository,
});

const Test = db.collection({
  name: 'tests',
  repository: 'CustomRepository',
});

Test.repository<CustomRepository>.customMethod();

db.removeCollection() 待完善

移除 collection

Definition
class Database {
  removeCollection(name: string): Collection;
}
Examples
db.removeCollection('tests');

db.sync()

将所有定义的 Collections 同步给数据库。

Definition
class Database {
  sync(options?: Sequelize.SyncOptions): Promise<Database>;
}
Examples
await db.sync();
await db.sync({force: true});