tachybase_todo/docs/reference/database.md
2021-11-09 15:08:24 +08:00

372 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
toc: menu
---
# Database
## `db.sequelize`
Sequelize 实例
##### Definition
```ts
class Database {
public sequelize: Sequelize;
}
```
##### Examples
直接调用 sequelize api
```ts
db.sequelize.close();
```
## `db.constructor()`
##### Definition
```ts
class Database {
constructor (options: DatabaseOptions) => void;
}
type DatabaseOptions = Sequelize.Options | Sequelize;
```
##### Examples
配置 options 与 Sequelize.Options 一致,如:
```ts
const db = new Database({
dialect: 'sqlite',
storage: 'path/to/database.sqlite'
});
```
也可以直接传 sequelize 实例
```ts
const sequelize = new Sequelize('sqlite::memory:');
const db = new Database(sequelize);
```
注意new Sequelize() 会有针对参数的 try catch 处理Database 如果要捕获异常,也需要在 new 的时候 try catch
```ts
try {
const db = new Database({
dialect: 'sqlite',
storage: 'path/to/database.sqlite'
});
} catch(error) {
}
```
## `db.collection()`
配置数据表、字段和索引等,更多字段配置查看 [Field Types](field-types)
##### Definition
```ts
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
```ts
const Post = db.collection({
name: 'posts',
fields: [
{ type: 'string', name: 'name' },
],
});
```
自定义 model 见 [db.registerModels()](#dbregistermodels)
自定义 repository 见 [db.registerRepositories()](#dbregisterrepositories)
## `db.sync()`
将所有定义的 Collections 同步给数据库。
##### Definition
```ts
class Database {
sync(options?: Sequelize.SyncOptions): Promise<Database>;
}
```
##### Examples
```ts
await db.sync();
await db.sync({force: true});
```
## `db.close()`
断开数据库连接
##### Definition
```ts
class Database {
close(): Promise<void>;
}
```
##### Examples
```ts
await db.close();
```
## `db.registerFieldTypes()`
自定义字段存储类型,更多字段类型查看 [Field Types](field-types)
##### Definition
```ts
class Database {
registerFieldTypes(types: RegisterFieldTypes): void;
}
interface RegisterFieldTypes {
[key: string]: Field;
}
```
##### Examples
```ts
class CustomField extends Field {
get dataType() {
return DataTypes.STRING;
}
}
db.registerFieldTypes({ custom: CustomField });
db.collection({
name: 'tests',
fields: [
{ type: 'custom', name: 'customName' },
],
});
```
## `db.import()`
##### Definition
```ts
class Database {
import(options: ImportOptions): Map<string, Collection>;
}
interface ImportOptions {
// 配置所在文件夹
directory: string;
// 配置后置
// @default ['js', 'ts', 'json']
extensions?: string[];
}
```
##### Examples
导入某文件夹下的所有 Collection 配置
```ts
db.import({
directory: '/path/to/collections',
extensions: ['js', 'ts', 'json'],
});
```
## `db.on()`
##### Definition
##### Examples
## `db.emitAsync()`
异步事件触发
##### Definition
##### Examples
## `db.emit()`
同步事件触发
##### Definition
##### Examples
## `db.registerModels()`
自定义 Model
##### Definition
```ts
class Database {
registerModels(models: RegisterModels): void;
}
interface RegisterModels {
[key: string]: Sequelize.Model;
}
```
##### Examples
```ts
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.registerRepositories()`
自定义 Repository
##### Examples
```ts
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.registerOperators()`
自定义筛选条件
##### Definition
```ts
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可以直接转换
```ts
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 比较复杂
```ts
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'],
},
});
```