@nocobase/database 0.9.1-alpha.2 → 0.9.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/collection-group-manager.d.ts +13 -0
- package/lib/collection-group-manager.js +91 -0
- package/lib/collection-importer.js +0 -24
- package/lib/collection.d.ts +24 -3
- package/lib/collection.js +176 -236
- package/lib/database-utils/index.js +3 -15
- package/lib/database.d.ts +3 -0
- package/lib/database.js +160 -298
- package/lib/decorators/must-have-filter-decorator.js +0 -7
- package/lib/decorators/transaction-decorator.js +5 -18
- package/lib/errors/identifier-error.js +0 -3
- package/lib/features/ReferencesMap.js +1 -14
- package/lib/features/referential-integrity-check.js +7 -21
- package/lib/field-repository/array-field-repository.js +5 -45
- package/lib/fields/array-field.js +0 -13
- package/lib/fields/belongs-to-field.js +24 -50
- package/lib/fields/belongs-to-many-field.js +23 -47
- package/lib/fields/boolean-field.js +0 -7
- package/lib/fields/context-field.js +2 -23
- package/lib/fields/date-field.d.ts +4 -0
- package/lib/fields/date-field.js +15 -7
- package/lib/fields/field.js +32 -85
- package/lib/fields/has-many-field.js +16 -49
- package/lib/fields/has-one-field.js +18 -52
- package/lib/fields/index.js +0 -44
- package/lib/fields/json-field.js +0 -12
- package/lib/fields/number-field.js +0 -23
- package/lib/fields/password-field.js +8 -35
- package/lib/fields/radio-field.js +0 -18
- package/lib/fields/relation-field.js +4 -16
- package/lib/fields/set-field.js +0 -8
- package/lib/fields/sort-field.js +84 -73
- package/lib/fields/string-field.js +0 -7
- package/lib/fields/text-field.js +0 -7
- package/lib/fields/time-field.js +0 -7
- package/lib/fields/uid-field.js +4 -22
- package/lib/fields/uuid-field.js +3 -12
- package/lib/fields/virtual-field.js +0 -7
- package/lib/filter-match.js +7 -22
- package/lib/filter-parser.js +37 -101
- package/lib/index.d.ts +3 -0
- package/lib/index.js +36 -42
- package/lib/inherited-collection.js +15 -62
- package/lib/inherited-map.js +7 -48
- package/lib/listeners/adjacency-list.d.ts +3 -0
- package/lib/listeners/adjacency-list.js +91 -0
- package/lib/listeners/index.d.ts +2 -0
- package/lib/listeners/index.js +12 -0
- package/lib/magic-attribute-model.js +58 -114
- package/lib/migration.js +7 -28
- package/lib/mock-database.d.ts +4 -4
- package/lib/mock-database.js +15 -18
- package/lib/model-hook.js +4 -35
- package/lib/model.js +12 -54
- package/lib/operators/array.js +2 -32
- package/lib/operators/association.js +0 -6
- package/lib/operators/boolean.js +0 -6
- package/lib/operators/child-collection.d.ts +2 -0
- package/lib/operators/child-collection.js +32 -0
- package/lib/operators/date.js +123 -60
- package/lib/operators/empty.js +3 -32
- package/lib/operators/eq.d.ts +2 -0
- package/lib/operators/eq.js +26 -0
- package/lib/operators/index.js +4 -7
- package/lib/operators/ne.js +5 -5
- package/lib/operators/notIn.js +0 -5
- package/lib/operators/string.js +0 -11
- package/lib/operators/utils.js +0 -6
- package/lib/options-parser.d.ts +1 -1
- package/lib/options-parser.js +47 -107
- package/lib/playground.js +0 -4
- package/lib/query-interface/mysql-query-interface.d.ts +11 -0
- package/lib/query-interface/mysql-query-interface.js +59 -10
- package/lib/query-interface/postgres-query-interface.d.ts +8 -0
- package/lib/query-interface/postgres-query-interface.js +70 -12
- package/lib/query-interface/query-interface-builder.js +0 -5
- package/lib/query-interface/query-interface.d.ts +12 -0
- package/lib/query-interface/query-interface.js +33 -3
- package/lib/query-interface/sqlite-query-interface.d.ts +11 -0
- package/lib/query-interface/sqlite-query-interface.js +61 -10
- package/lib/relation-repository/belongs-to-many-repository.js +21 -78
- package/lib/relation-repository/belongs-to-repository.js +0 -3
- package/lib/relation-repository/hasmany-repository.js +8 -44
- package/lib/relation-repository/hasone-repository.js +0 -3
- package/lib/relation-repository/multiple-relation-repository.js +14 -68
- package/lib/relation-repository/relation-repository.js +5 -42
- package/lib/relation-repository/single-relation-repository.js +5 -43
- package/lib/repository.d.ts +1 -0
- package/lib/repository.js +36 -182
- package/lib/sql-parser/index.js +10527 -0
- package/lib/sql-parser/sql.pegjs +1297 -0
- package/lib/sync-runner.js +19 -54
- package/lib/update-associations.js +58 -157
- package/lib/update-guard.js +10 -49
- package/lib/utils.js +6 -54
- package/lib/value-parsers/array-value-parser.js +3 -21
- package/lib/value-parsers/base-value-parser.js +0 -13
- package/lib/value-parsers/boolean-value-parser.js +4 -10
- package/lib/value-parsers/date-value-parser.js +0 -23
- package/lib/value-parsers/index.js +0 -10
- package/lib/value-parsers/json-value-parser.js +0 -7
- package/lib/value-parsers/number-value-parser.js +0 -9
- package/lib/value-parsers/string-value-parser.js +3 -20
- package/lib/value-parsers/to-many-value-parser.js +1 -42
- package/lib/value-parsers/to-one-value-parser.js +0 -14
- package/lib/view/field-type-map.d.ts +47 -0
- package/lib/view/field-type-map.js +56 -0
- package/lib/view/view-inference.d.ts +31 -0
- package/lib/view/view-inference.js +92 -0
- package/lib/view-collection.d.ts +6 -0
- package/lib/view-collection.js +24 -0
- package/package.json +4 -4
- package/src/__tests__/collection.test.ts +44 -0
- package/src/__tests__/fields/date.test.ts +75 -0
- package/src/__tests__/fields/sort-field.test.ts +100 -0
- package/src/__tests__/filter.test.ts +3 -3
- package/src/__tests__/group.test.ts +50 -0
- package/src/__tests__/inhertits/collection-inherits.test.ts +114 -0
- package/src/__tests__/operator/date-operator.test.ts +244 -98
- package/src/__tests__/operator/eq.test.ts +76 -0
- package/src/__tests__/operator/ne.test.ts +19 -1
- package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +82 -0
- package/src/__tests__/repository/find.test.ts +33 -0
- package/src/__tests__/repository.test.ts +88 -0
- package/src/__tests__/sql-parser.test.ts +13 -0
- package/src/__tests__/tree.test.ts +217 -0
- package/src/__tests__/view/list-view.test.ts +34 -0
- package/src/__tests__/view/view-collection.test.ts +199 -0
- package/src/__tests__/view/view-inference.test.ts +145 -0
- package/src/__tests__/view/view-repository.test.ts +67 -0
- package/src/collection-group-manager.ts +94 -0
- package/src/collection.ts +108 -14
- package/src/database-utils/index.ts +1 -0
- package/src/database.ts +79 -12
- package/src/features/ReferencesMap.ts +3 -2
- package/src/fields/belongs-to-many-field.ts +15 -2
- package/src/fields/date-field.ts +18 -0
- package/src/fields/field.ts +16 -8
- package/src/fields/json-field.ts +1 -0
- package/src/fields/sort-field.ts +90 -29
- package/src/filter-parser.ts +1 -0
- package/src/index.ts +3 -1
- package/src/listeners/adjacency-list.ts +60 -0
- package/src/listeners/index.ts +7 -0
- package/src/mock-database.ts +14 -2
- package/src/model.ts +4 -0
- package/src/operators/child-collection.ts +24 -0
- package/src/operators/date.ts +108 -24
- package/src/operators/eq.ts +14 -0
- package/src/operators/index.ts +2 -0
- package/src/operators/ne.ts +12 -7
- package/src/options-parser.ts +25 -11
- package/src/query-interface/mysql-query-interface.ts +53 -1
- package/src/query-interface/postgres-query-interface.ts +84 -3
- package/src/query-interface/query-interface.ts +31 -0
- package/src/query-interface/sqlite-query-interface.ts +62 -1
- package/src/relation-repository/belongs-to-many-repository.ts +20 -1
- package/src/relation-repository/hasmany-repository.ts +5 -3
- package/src/relation-repository/multiple-relation-repository.ts +9 -1
- package/src/repository.ts +6 -13
- package/src/sql-parser/index.js +10698 -0
- package/src/sql-parser/readme.md +2 -0
- package/src/sql-parser/sql.pegjs +1297 -0
- package/src/sync-runner.ts +13 -15
- package/src/update-associations.ts +26 -22
- package/src/view/field-type-map.ts +56 -0
- package/src/view/view-inference.ts +106 -0
- package/src/view-collection.ts +21 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import QueryInterface from './query-interface';
|
|
2
2
|
import { Collection } from '../collection';
|
|
3
3
|
import { Transactionable } from 'sequelize';
|
|
4
|
+
import sqlParser from '../sql-parser';
|
|
4
5
|
|
|
5
6
|
export default class MysqlQueryInterface extends QueryInterface {
|
|
6
7
|
constructor(db) {
|
|
@@ -12,9 +13,60 @@ export default class MysqlQueryInterface extends QueryInterface {
|
|
|
12
13
|
|
|
13
14
|
const tableName = collection.model.tableName;
|
|
14
15
|
const databaseName = this.db.options.database;
|
|
15
|
-
const sql = `SELECT TABLE_NAME
|
|
16
|
+
const sql = `SELECT TABLE_NAME
|
|
17
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
18
|
+
WHERE TABLE_SCHEMA = '${databaseName}'
|
|
19
|
+
AND TABLE_NAME = '${tableName}'`;
|
|
16
20
|
|
|
17
21
|
const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
|
|
18
22
|
return results.length > 0;
|
|
19
23
|
}
|
|
24
|
+
|
|
25
|
+
async listViews() {
|
|
26
|
+
const sql = `SELECT TABLE_NAME as name, VIEW_DEFINITION as definition
|
|
27
|
+
FROM information_schema.views
|
|
28
|
+
WHERE TABLE_SCHEMA = DATABASE()
|
|
29
|
+
ORDER BY TABLE_NAME;`;
|
|
30
|
+
|
|
31
|
+
return await this.db.sequelize.query(sql, { type: 'SELECT' });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
|
|
35
|
+
[view_column_name: string]: {
|
|
36
|
+
column_name: string;
|
|
37
|
+
table_name: string;
|
|
38
|
+
table_schema?: string;
|
|
39
|
+
};
|
|
40
|
+
}> {
|
|
41
|
+
try {
|
|
42
|
+
const viewDefinition = await this.db.sequelize.query(`SHOW CREATE VIEW ${options.viewName}`, { type: 'SELECT' });
|
|
43
|
+
const createView = viewDefinition[0]['Create View'];
|
|
44
|
+
const regex = /(?<=AS\s)([\s\S]*)/i;
|
|
45
|
+
const match = createView.match(regex);
|
|
46
|
+
const sql = match[0];
|
|
47
|
+
|
|
48
|
+
const { ast } = sqlParser.parse(sql);
|
|
49
|
+
|
|
50
|
+
const columns = ast.columns;
|
|
51
|
+
|
|
52
|
+
const results = [];
|
|
53
|
+
for (const column of columns) {
|
|
54
|
+
if (column.expr.type === 'column_ref') {
|
|
55
|
+
results.push([
|
|
56
|
+
column.as || column.expr.column,
|
|
57
|
+
{
|
|
58
|
+
column_name: column.expr.column,
|
|
59
|
+
table_name: column.expr.table,
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return Object.fromEntries(results);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
this.db.logger.warn(e);
|
|
68
|
+
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
20
72
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import QueryInterface from './query-interface';
|
|
2
2
|
import { Collection } from '../collection';
|
|
3
|
+
import sqlParser from '../sql-parser';
|
|
3
4
|
|
|
4
5
|
export default class PostgresQueryInterface extends QueryInterface {
|
|
5
6
|
constructor(db) {
|
|
@@ -12,11 +13,91 @@ export default class PostgresQueryInterface extends QueryInterface {
|
|
|
12
13
|
const tableName = collection.model.tableName;
|
|
13
14
|
const schema = collection.collectionSchema() || 'public';
|
|
14
15
|
|
|
15
|
-
const sql = `SELECT EXISTS(SELECT 1
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const sql = `SELECT EXISTS(SELECT 1
|
|
17
|
+
FROM information_schema.tables
|
|
18
|
+
WHERE table_schema = '${schema}'
|
|
19
|
+
AND table_name = '${tableName}')`;
|
|
18
20
|
|
|
19
21
|
const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
|
|
20
22
|
return results[0]['exists'];
|
|
21
23
|
}
|
|
24
|
+
|
|
25
|
+
async listViews() {
|
|
26
|
+
const sql = `
|
|
27
|
+
SELECT viewname as name, definition, schemaname as schema
|
|
28
|
+
FROM pg_views
|
|
29
|
+
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
|
|
30
|
+
ORDER BY viewname;
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
return await this.db.sequelize.query(sql, { type: 'SELECT' });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async viewColumnUsage(options): Promise<{
|
|
37
|
+
[view_column_name: string]: {
|
|
38
|
+
column_name: string;
|
|
39
|
+
table_name: string;
|
|
40
|
+
table_schema?: string;
|
|
41
|
+
};
|
|
42
|
+
}> {
|
|
43
|
+
const { viewName, schema = 'public' } = options;
|
|
44
|
+
const sql = `
|
|
45
|
+
SELECT *
|
|
46
|
+
FROM information_schema.view_column_usage
|
|
47
|
+
WHERE view_schema = '${schema}'
|
|
48
|
+
AND view_name = '${viewName}';
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
const columnUsages = (await this.db.sequelize.query(sql, { type: 'SELECT' })) as Array<{
|
|
52
|
+
column_name: string;
|
|
53
|
+
table_name: string;
|
|
54
|
+
table_schema: string;
|
|
55
|
+
}>;
|
|
56
|
+
|
|
57
|
+
const viewDefQuery = await this.db.sequelize.query(
|
|
58
|
+
`
|
|
59
|
+
select pg_get_viewdef(format('%I.%I', '${schema}', '${viewName}')::regclass, true) as definition
|
|
60
|
+
`,
|
|
61
|
+
{ type: 'SELECT' },
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const def = viewDefQuery[0]['definition'];
|
|
65
|
+
try {
|
|
66
|
+
const { ast } = sqlParser.parse(def);
|
|
67
|
+
const columns = ast[0].columns;
|
|
68
|
+
|
|
69
|
+
const usages = columns
|
|
70
|
+
.map((column) => {
|
|
71
|
+
const fieldAlias = column.as || column.expr.column;
|
|
72
|
+
const columnUsage = columnUsages.find((columnUsage) => {
|
|
73
|
+
let columnExprTable = column.expr.table;
|
|
74
|
+
|
|
75
|
+
// handle column alias
|
|
76
|
+
const from = ast[0].from;
|
|
77
|
+
const findAs = from.find((from) => from.as === columnExprTable);
|
|
78
|
+
|
|
79
|
+
if (findAs) {
|
|
80
|
+
columnExprTable = findAs.table;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return columnUsage.column_name === column.expr.column && columnUsage.table_name === columnExprTable;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return [
|
|
87
|
+
fieldAlias,
|
|
88
|
+
columnUsage
|
|
89
|
+
? {
|
|
90
|
+
...columnUsage,
|
|
91
|
+
}
|
|
92
|
+
: null,
|
|
93
|
+
];
|
|
94
|
+
})
|
|
95
|
+
.filter(([, columnUsage]) => columnUsage !== null);
|
|
96
|
+
|
|
97
|
+
return Object.fromEntries(usages);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
this.db.logger.warn(e);
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
22
103
|
}
|
|
@@ -4,9 +4,40 @@ import { QueryInterface as SequelizeQueryInterface, Transactionable } from 'sequ
|
|
|
4
4
|
|
|
5
5
|
export default abstract class QueryInterface {
|
|
6
6
|
sequelizeQueryInterface: SequelizeQueryInterface;
|
|
7
|
+
|
|
7
8
|
protected constructor(public db: Database) {
|
|
8
9
|
this.sequelizeQueryInterface = db.sequelize.getQueryInterface();
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
abstract collectionTableExists(collection: Collection, options?: Transactionable): Promise<boolean>;
|
|
13
|
+
|
|
14
|
+
abstract listViews();
|
|
15
|
+
|
|
16
|
+
abstract viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
|
|
17
|
+
[view_column_name: string]: {
|
|
18
|
+
column_name: string;
|
|
19
|
+
table_name: string;
|
|
20
|
+
table_schema?: string;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
async dropAll(options) {
|
|
25
|
+
if (options.drop !== true) return;
|
|
26
|
+
|
|
27
|
+
const views = await this.listViews();
|
|
28
|
+
|
|
29
|
+
for (const view of views) {
|
|
30
|
+
let removeSql;
|
|
31
|
+
|
|
32
|
+
if (view.schema) {
|
|
33
|
+
removeSql = `DROP VIEW IF EXISTS "${view.schema}"."${view.name}"`;
|
|
34
|
+
} else {
|
|
35
|
+
removeSql = `DROP VIEW IF EXISTS ${view.name}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
await this.db.sequelize.query(removeSql, { transaction: options.transaction });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await this.db.sequelize.getQueryInterface().dropAllTables(options);
|
|
42
|
+
}
|
|
12
43
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import QueryInterface from './query-interface';
|
|
2
2
|
import { Collection } from '../collection';
|
|
3
|
+
import sqlParser from '../sql-parser';
|
|
3
4
|
|
|
4
5
|
export default class SqliteQueryInterface extends QueryInterface {
|
|
5
6
|
constructor(db) {
|
|
@@ -11,8 +12,68 @@ export default class SqliteQueryInterface extends QueryInterface {
|
|
|
11
12
|
|
|
12
13
|
const tableName = collection.model.tableName;
|
|
13
14
|
|
|
14
|
-
const sql = `SELECT name
|
|
15
|
+
const sql = `SELECT name
|
|
16
|
+
FROM sqlite_master
|
|
17
|
+
WHERE type = 'table'
|
|
18
|
+
AND name = '${tableName}';`;
|
|
15
19
|
const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
|
|
16
20
|
return results.length > 0;
|
|
17
21
|
}
|
|
22
|
+
|
|
23
|
+
async listViews() {
|
|
24
|
+
const sql = `
|
|
25
|
+
SELECT name , sql as definition
|
|
26
|
+
FROM sqlite_master
|
|
27
|
+
WHERE type = 'view'
|
|
28
|
+
ORDER BY name;
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
return await this.db.sequelize.query(sql, {
|
|
32
|
+
type: 'SELECT',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
|
|
37
|
+
[view_column_name: string]: {
|
|
38
|
+
column_name: string;
|
|
39
|
+
table_name: string;
|
|
40
|
+
table_schema?: string;
|
|
41
|
+
};
|
|
42
|
+
}> {
|
|
43
|
+
try {
|
|
44
|
+
const viewDefinition = await this.db.sequelize.query(
|
|
45
|
+
`SELECT sql FROM sqlite_master WHERE name = '${options.viewName}' AND type = 'view'`,
|
|
46
|
+
{
|
|
47
|
+
type: 'SELECT',
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const createView = viewDefinition[0]['sql'];
|
|
52
|
+
const regex = /(?<=AS\s)([\s\S]*)/i;
|
|
53
|
+
const match = createView.match(regex);
|
|
54
|
+
const sql = match[0];
|
|
55
|
+
|
|
56
|
+
const { ast } = sqlParser.parse(sql);
|
|
57
|
+
|
|
58
|
+
const columns = ast.columns;
|
|
59
|
+
|
|
60
|
+
const results = [];
|
|
61
|
+
for (const column of columns) {
|
|
62
|
+
if (column.expr.type === 'column_ref') {
|
|
63
|
+
results.push([
|
|
64
|
+
column.as || column.expr.column,
|
|
65
|
+
{
|
|
66
|
+
column_name: column.expr.column,
|
|
67
|
+
table_name: column.expr.table,
|
|
68
|
+
},
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return Object.fromEntries(results);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
this.db.logger.warn(e);
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
18
79
|
}
|
|
@@ -11,20 +11,29 @@ type CreateBelongsToManyOptions = CreateOptions;
|
|
|
11
11
|
|
|
12
12
|
interface IBelongsToManyRepository<M extends Model> {
|
|
13
13
|
find(options?: FindOptions): Promise<M[]>;
|
|
14
|
+
|
|
14
15
|
findAndCount(options?: FindAndCountOptions): Promise<[M[], number]>;
|
|
16
|
+
|
|
15
17
|
findOne(options?: FindOneOptions): Promise<M>;
|
|
18
|
+
|
|
16
19
|
// 新增并关联,存在中间表数据
|
|
17
20
|
create(options?: CreateOptions): Promise<M>;
|
|
21
|
+
|
|
18
22
|
// 更新,存在中间表数据
|
|
19
23
|
update(options?: UpdateOptions): Promise<M>;
|
|
24
|
+
|
|
20
25
|
// 删除
|
|
21
26
|
destroy(options?: number | string | number[] | string[] | DestroyOptions): Promise<Boolean>;
|
|
27
|
+
|
|
22
28
|
// 建立关联
|
|
23
29
|
set(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
|
|
30
|
+
|
|
24
31
|
// 附加关联,存在中间表数据
|
|
25
32
|
add(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
|
|
33
|
+
|
|
26
34
|
// 移除关联
|
|
27
35
|
remove(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
|
|
36
|
+
|
|
28
37
|
toggle(options: TargetKey | { pk?: TargetKey; transaction?: Transaction }): Promise<void>;
|
|
29
38
|
}
|
|
30
39
|
|
|
@@ -157,7 +166,17 @@ export class BelongsToManyRepository extends MultipleRelationRepository implemen
|
|
|
157
166
|
return carry;
|
|
158
167
|
}, {});
|
|
159
168
|
|
|
160
|
-
|
|
169
|
+
const targetKeys = Object.keys(setObj);
|
|
170
|
+
const association = this.association;
|
|
171
|
+
|
|
172
|
+
const targetObjects = await this.targetModel.findAll({
|
|
173
|
+
where: {
|
|
174
|
+
[association['targetKey']]: targetKeys,
|
|
175
|
+
},
|
|
176
|
+
transaction,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
await sourceModel[this.accessors()[call]](targetObjects, {
|
|
161
180
|
transaction,
|
|
162
181
|
});
|
|
163
182
|
|
|
@@ -43,12 +43,14 @@ export class HasManyRepository extends MultipleRelationRepository implements IHa
|
|
|
43
43
|
addFilter[this.associationField.targetKey] = options.filterByTk;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
...omit(options, ['filterByTk']),
|
|
46
|
+
const findOptions = {
|
|
47
|
+
...omit(options, ['filterByTk', 'where', 'values', 'attributes']),
|
|
48
48
|
filter: {
|
|
49
49
|
$and: [options.filter || {}, addFilter],
|
|
50
50
|
},
|
|
51
|
-
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return await targetRepository.find(findOptions);
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
@transaction((args, transaction) => {
|
|
@@ -80,10 +80,18 @@ export abstract class MultipleRelationRepository extends RelationRepository {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
const data = await sourceModel[getAccessor]({
|
|
84
84
|
...findOptions,
|
|
85
85
|
transaction,
|
|
86
86
|
});
|
|
87
|
+
|
|
88
|
+
await this.collection.db.emitAsync('afterRepositoryFind', {
|
|
89
|
+
findOptions: options,
|
|
90
|
+
dataCollection: this.collection,
|
|
91
|
+
data,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return data;
|
|
87
95
|
}
|
|
88
96
|
|
|
89
97
|
async findAndCount(options?: FindAndCountOptions): Promise<[any[], number]> {
|
package/src/repository.ts
CHANGED
|
@@ -106,6 +106,7 @@ export interface CommonFindOptions extends Transactionable {
|
|
|
106
106
|
except?: Except;
|
|
107
107
|
sort?: Sort;
|
|
108
108
|
context?: any;
|
|
109
|
+
tree?: boolean;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
export type FindOneOptions = Omit<FindOptions, 'limit'>;
|
|
@@ -336,19 +337,11 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|
|
336
337
|
});
|
|
337
338
|
}
|
|
338
339
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
options.raw
|
|
346
|
-
? (row['__collection'] = rowCollectionName)
|
|
347
|
-
: row.set('__collection', rowCollectionName, {
|
|
348
|
-
raw: true,
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
}
|
|
340
|
+
await this.collection.db.emitAsync('afterRepositoryFind', {
|
|
341
|
+
findOptions: options,
|
|
342
|
+
dataCollection: this.collection,
|
|
343
|
+
data: rows,
|
|
344
|
+
});
|
|
352
345
|
|
|
353
346
|
return rows;
|
|
354
347
|
}
|