@nocobase/database 0.7.0-alpha.80 → 0.7.0-alpha.83
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/database.d.ts +7 -1
- package/lib/database.js +55 -17
- package/lib/index.d.ts +1 -0
- package/lib/index.js +14 -0
- package/lib/migration.d.ts +33 -0
- package/lib/migration.js +76 -0
- package/lib/mock-database.d.ts +1 -0
- package/lib/mock-database.js +2 -1
- package/package.json +5 -4
- package/src/__tests__/migrator.test.ts +52 -0
- package/src/database.ts +52 -18
- package/src/index.ts +1 -0
- package/src/migration.ts +75 -0
- package/src/mock-database.ts +1 -0
package/lib/database.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ import { AsyncEmitter } from '@nocobase/utils';
|
|
|
3
3
|
import merge from 'deepmerge';
|
|
4
4
|
import { EventEmitter } from 'events';
|
|
5
5
|
import { ModelCtor, Options, QueryInterfaceDropAllTablesOptions, QueryOptions, Sequelize, SyncOptions } from 'sequelize';
|
|
6
|
+
import { Umzug } from 'umzug';
|
|
6
7
|
import { Collection, CollectionOptions, RepositoryType } from './collection';
|
|
7
8
|
import { ImportFileExtension } from './collection-importer';
|
|
8
9
|
import * as FieldTypes from './fields';
|
|
9
10
|
import { Field, FieldContext, RelationField } from './fields';
|
|
11
|
+
import { Migrations } from './migration';
|
|
10
12
|
import { Model } from './model';
|
|
11
13
|
import { ModelHook } from './model-hook';
|
|
12
14
|
import { RelationRepository } from './relation-repository/relation-repository';
|
|
@@ -22,8 +24,9 @@ interface MapOf<T> {
|
|
|
22
24
|
}
|
|
23
25
|
export interface IDatabaseOptions extends Options {
|
|
24
26
|
tablePrefix?: string;
|
|
27
|
+
migrator?: any;
|
|
25
28
|
}
|
|
26
|
-
export declare type DatabaseOptions = IDatabaseOptions
|
|
29
|
+
export declare type DatabaseOptions = IDatabaseOptions;
|
|
27
30
|
interface RegisterOperatorsContext {
|
|
28
31
|
db?: Database;
|
|
29
32
|
path?: string;
|
|
@@ -36,6 +39,8 @@ export interface CleanOptions extends QueryInterfaceDropAllTablesOptions {
|
|
|
36
39
|
declare type OperatorFunc = (value: any, ctx?: RegisterOperatorsContext) => any;
|
|
37
40
|
export declare class Database extends EventEmitter implements AsyncEmitter {
|
|
38
41
|
sequelize: Sequelize;
|
|
42
|
+
migrator: Umzug;
|
|
43
|
+
migrations: Migrations;
|
|
39
44
|
fieldTypes: Map<any, any>;
|
|
40
45
|
options: IDatabaseOptions;
|
|
41
46
|
models: Map<string, ModelCtor<Model<any, any>>>;
|
|
@@ -50,6 +55,7 @@ export declare class Database extends EventEmitter implements AsyncEmitter {
|
|
|
50
55
|
mergeOptions?: any;
|
|
51
56
|
}[]>;
|
|
52
57
|
constructor(options: DatabaseOptions);
|
|
58
|
+
addMigration(item: any): void;
|
|
53
59
|
/**
|
|
54
60
|
* Add collection to database
|
|
55
61
|
* @param options
|
package/lib/database.js
CHANGED
|
@@ -57,12 +57,24 @@ function _sequelize() {
|
|
|
57
57
|
return data;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
function _umzug() {
|
|
61
|
+
const data = require("umzug");
|
|
62
|
+
|
|
63
|
+
_umzug = function _umzug() {
|
|
64
|
+
return data;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return data;
|
|
68
|
+
}
|
|
69
|
+
|
|
60
70
|
var _collection = require("./collection");
|
|
61
71
|
|
|
62
72
|
var _collectionImporter = require("./collection-importer");
|
|
63
73
|
|
|
64
74
|
var FieldTypes = _interopRequireWildcard(require("./fields"));
|
|
65
75
|
|
|
76
|
+
var _migration = require("./migration");
|
|
77
|
+
|
|
66
78
|
var _modelHook = require("./model-hook");
|
|
67
79
|
|
|
68
80
|
var _operators = _interopRequireDefault(require("./operators"));
|
|
@@ -108,6 +120,8 @@ class Database extends _events().EventEmitter {
|
|
|
108
120
|
constructor(options) {
|
|
109
121
|
super();
|
|
110
122
|
this.sequelize = void 0;
|
|
123
|
+
this.migrator = void 0;
|
|
124
|
+
this.migrations = void 0;
|
|
111
125
|
this.fieldTypes = new Map();
|
|
112
126
|
this.options = void 0;
|
|
113
127
|
this.models = new Map();
|
|
@@ -119,28 +133,29 @@ class Database extends _events().EventEmitter {
|
|
|
119
133
|
this.modelHook = void 0;
|
|
120
134
|
this.delayCollectionExtend = new Map();
|
|
121
135
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
force: false
|
|
131
|
-
}
|
|
132
|
-
}, options);
|
|
136
|
+
const opts = _objectSpread({
|
|
137
|
+
sync: {
|
|
138
|
+
alter: {
|
|
139
|
+
drop: false
|
|
140
|
+
},
|
|
141
|
+
force: false
|
|
142
|
+
}
|
|
143
|
+
}, options);
|
|
133
144
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
145
|
+
if (options.storage && options.storage !== ':memory:') {
|
|
146
|
+
if (!(0, _path().isAbsolute)(options.storage)) {
|
|
147
|
+
opts.storage = (0, _path().resolve)(process.cwd(), options.storage);
|
|
138
148
|
}
|
|
149
|
+
}
|
|
139
150
|
|
|
140
|
-
|
|
141
|
-
|
|
151
|
+
if (options.dialect === 'sqlite') {
|
|
152
|
+
delete opts.timezone;
|
|
153
|
+
} else if (!opts.timezone) {
|
|
154
|
+
opts.timezone = '+00:00';
|
|
142
155
|
}
|
|
143
156
|
|
|
157
|
+
this.sequelize = new (_sequelize().Sequelize)(opts);
|
|
158
|
+
this.options = opts;
|
|
144
159
|
this.collections = new Map();
|
|
145
160
|
this.modelHook = new _modelHook.ModelHook(this);
|
|
146
161
|
this.on('afterDefineCollection', collection => {
|
|
@@ -170,6 +185,29 @@ class Database extends _events().EventEmitter {
|
|
|
170
185
|
}
|
|
171
186
|
|
|
172
187
|
this.initOperators();
|
|
188
|
+
const migratorOptions = this.options.migrator || {};
|
|
189
|
+
|
|
190
|
+
const context = _objectSpread({
|
|
191
|
+
db: this,
|
|
192
|
+
sequelize: this.sequelize,
|
|
193
|
+
queryInterface: this.sequelize.getQueryInterface()
|
|
194
|
+
}, migratorOptions.context);
|
|
195
|
+
|
|
196
|
+
this.migrations = new _migration.Migrations(context);
|
|
197
|
+
this.migrator = new (_umzug().Umzug)({
|
|
198
|
+
logger: migratorOptions.logger || console,
|
|
199
|
+
migrations: this.migrations.callback(),
|
|
200
|
+
context,
|
|
201
|
+
storage: new (_umzug().SequelizeStorage)(_objectSpread(_objectSpread({
|
|
202
|
+
modelName: `${this.options.tablePrefix || ''}migrations`
|
|
203
|
+
}, migratorOptions.storage), {}, {
|
|
204
|
+
sequelize: this.sequelize
|
|
205
|
+
}))
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
addMigration(item) {
|
|
210
|
+
return this.migrations.add(item);
|
|
173
211
|
}
|
|
174
212
|
/**
|
|
175
213
|
* Add collection to database
|
package/lib/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './database';
|
|
|
4
4
|
export { Database as default } from './database';
|
|
5
5
|
export * from './fields';
|
|
6
6
|
export * from './magic-attribute-model';
|
|
7
|
+
export * from './migration';
|
|
7
8
|
export * from './mock-database';
|
|
8
9
|
export * from './model';
|
|
9
10
|
export * from './relation-repository/belongs-to-many-repository';
|
package/lib/index.js
CHANGED
|
@@ -85,6 +85,20 @@ Object.keys(_magicAttributeModel).forEach(function (key) {
|
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
var _migration = require("./migration");
|
|
89
|
+
|
|
90
|
+
Object.keys(_migration).forEach(function (key) {
|
|
91
|
+
if (key === "default" || key === "__esModule") return;
|
|
92
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
93
|
+
if (key in exports && exports[key] === _migration[key]) return;
|
|
94
|
+
Object.defineProperty(exports, key, {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get: function get() {
|
|
97
|
+
return _migration[key];
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
88
102
|
var _mockDatabase = require("./mock-database");
|
|
89
103
|
|
|
90
104
|
Object.keys(_mockDatabase).forEach(function (key) {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { QueryInterface, Sequelize } from 'sequelize';
|
|
2
|
+
import Database from './database';
|
|
3
|
+
export interface MigrationContext {
|
|
4
|
+
db: Database;
|
|
5
|
+
queryInterface: QueryInterface;
|
|
6
|
+
sequelize: Sequelize;
|
|
7
|
+
}
|
|
8
|
+
export declare class Migration {
|
|
9
|
+
name: string;
|
|
10
|
+
context: {
|
|
11
|
+
db: Database;
|
|
12
|
+
};
|
|
13
|
+
constructor(context: MigrationContext);
|
|
14
|
+
get db(): Database;
|
|
15
|
+
get sequelize(): Sequelize;
|
|
16
|
+
get queryInterface(): QueryInterface;
|
|
17
|
+
up(): Promise<void>;
|
|
18
|
+
down(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface MigrationItem {
|
|
21
|
+
name: string;
|
|
22
|
+
migration?: typeof Migration;
|
|
23
|
+
up?: any;
|
|
24
|
+
down?: any;
|
|
25
|
+
}
|
|
26
|
+
export declare class Migrations {
|
|
27
|
+
items: any[];
|
|
28
|
+
context: any;
|
|
29
|
+
constructor(context: any);
|
|
30
|
+
clear(): void;
|
|
31
|
+
add(item: MigrationItem): void;
|
|
32
|
+
callback(): (ctx: any) => any[];
|
|
33
|
+
}
|
package/lib/migration.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Migrations = exports.Migration = void 0;
|
|
7
|
+
|
|
8
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
9
|
+
|
|
10
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
11
|
+
|
|
12
|
+
class Migration {
|
|
13
|
+
constructor(context) {
|
|
14
|
+
this.name = void 0;
|
|
15
|
+
this.context = void 0;
|
|
16
|
+
this.context = context;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get db() {
|
|
20
|
+
return this.context.db;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get sequelize() {
|
|
24
|
+
return this.context.db.sequelize;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get queryInterface() {
|
|
28
|
+
return this.context.db.sequelize.getQueryInterface();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
up() {// todo
|
|
32
|
+
|
|
33
|
+
return _asyncToGenerator(function* () {})();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
down() {// todo
|
|
37
|
+
|
|
38
|
+
return _asyncToGenerator(function* () {})();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
exports.Migration = Migration;
|
|
44
|
+
|
|
45
|
+
class Migrations {
|
|
46
|
+
constructor(context) {
|
|
47
|
+
this.items = [];
|
|
48
|
+
this.context = void 0;
|
|
49
|
+
this.context = context;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
clear() {
|
|
53
|
+
this.items = [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
add(item) {
|
|
57
|
+
const Migration = item.migration;
|
|
58
|
+
|
|
59
|
+
if (Migration) {
|
|
60
|
+
const migration = new Migration(this.context);
|
|
61
|
+
migration.name = item.name;
|
|
62
|
+
this.items.push(migration);
|
|
63
|
+
} else {
|
|
64
|
+
this.items.push(item);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
callback() {
|
|
69
|
+
return ctx => {
|
|
70
|
+
return this.items;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
exports.Migrations = Migrations;
|
package/lib/mock-database.d.ts
CHANGED
package/lib/mock-database.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/database",
|
|
3
|
-
"version": "0.7.0-alpha.
|
|
3
|
+
"version": "0.7.0-alpha.83",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -12,17 +12,18 @@
|
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@nocobase/utils": "0.7.0-alpha.
|
|
15
|
+
"@nocobase/utils": "0.7.0-alpha.83",
|
|
16
16
|
"async-mutex": "^0.3.2",
|
|
17
17
|
"deepmerge": "^4.2.2",
|
|
18
18
|
"flat": "^5.0.2",
|
|
19
19
|
"glob": "^7.1.6",
|
|
20
|
-
"sequelize": "^6.9.0"
|
|
20
|
+
"sequelize": "^6.9.0",
|
|
21
|
+
"umzug": "^3.1.1"
|
|
21
22
|
},
|
|
22
23
|
"repository": {
|
|
23
24
|
"type": "git",
|
|
24
25
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
25
26
|
"directory": "packages/database"
|
|
26
27
|
},
|
|
27
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "838f4f18dcd9ed4fe2ae2660a4918e2a5bd3a869"
|
|
28
29
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Database, Migration, mockDatabase } from '@nocobase/database';
|
|
2
|
+
|
|
3
|
+
const names = (migrations: Array<{ name: string }>) => migrations.map(m => m.name);
|
|
4
|
+
|
|
5
|
+
describe('migrator', () => {
|
|
6
|
+
let db: Database;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
|
|
10
|
+
db = mockDatabase({
|
|
11
|
+
tablePrefix: 'test_',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
await db.clean({ drop: true });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
await db.close();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('up and down', async () => {
|
|
22
|
+
const spy = jest.fn();
|
|
23
|
+
db.addMigration({
|
|
24
|
+
name: 'migration1',
|
|
25
|
+
migration: class extends Migration {
|
|
26
|
+
async up() {
|
|
27
|
+
spy('migration1-up');
|
|
28
|
+
}
|
|
29
|
+
async down() {
|
|
30
|
+
spy('migration1-down');
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
db.addMigration({
|
|
35
|
+
name: 'migration2',
|
|
36
|
+
migration: class extends Migration {
|
|
37
|
+
async up() {
|
|
38
|
+
spy('migration2-up');
|
|
39
|
+
}
|
|
40
|
+
async down() {
|
|
41
|
+
spy('migration2-down');
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
await db.migrator.up();
|
|
46
|
+
expect(names(await db.migrator.executed())).toEqual(['migration1', 'migration2']);
|
|
47
|
+
await db.migrator.down();
|
|
48
|
+
expect(names(await db.migrator.executed())).toEqual(['migration1']);
|
|
49
|
+
expect(spy).toHaveBeenCalledTimes(3);
|
|
50
|
+
expect(spy).toHaveBeenNthCalledWith(1, 'migration1-up');
|
|
51
|
+
});
|
|
52
|
+
});
|
package/src/database.ts
CHANGED
|
@@ -13,10 +13,12 @@ import {
|
|
|
13
13
|
SyncOptions,
|
|
14
14
|
Utils
|
|
15
15
|
} from 'sequelize';
|
|
16
|
+
import { SequelizeStorage, Umzug } from 'umzug';
|
|
16
17
|
import { Collection, CollectionOptions, RepositoryType } from './collection';
|
|
17
18
|
import { ImporterReader, ImportFileExtension } from './collection-importer';
|
|
18
19
|
import * as FieldTypes from './fields';
|
|
19
20
|
import { Field, FieldContext, RelationField } from './fields';
|
|
21
|
+
import { Migrations } from './migration';
|
|
20
22
|
import { Model } from './model';
|
|
21
23
|
import { ModelHook } from './model-hook';
|
|
22
24
|
import extendOperators from './operators';
|
|
@@ -36,9 +38,10 @@ interface MapOf<T> {
|
|
|
36
38
|
|
|
37
39
|
export interface IDatabaseOptions extends Options {
|
|
38
40
|
tablePrefix?: string;
|
|
41
|
+
migrator?: any;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
export type DatabaseOptions = IDatabaseOptions
|
|
44
|
+
export type DatabaseOptions = IDatabaseOptions;
|
|
42
45
|
|
|
43
46
|
interface RegisterOperatorsContext {
|
|
44
47
|
db?: Database;
|
|
@@ -55,6 +58,8 @@ type OperatorFunc = (value: any, ctx?: RegisterOperatorsContext) => any;
|
|
|
55
58
|
|
|
56
59
|
export class Database extends EventEmitter implements AsyncEmitter {
|
|
57
60
|
sequelize: Sequelize;
|
|
61
|
+
migrator: Umzug;
|
|
62
|
+
migrations: Migrations;
|
|
58
63
|
fieldTypes = new Map();
|
|
59
64
|
options: IDatabaseOptions;
|
|
60
65
|
models = new Map<string, ModelCtor<Model>>();
|
|
@@ -71,27 +76,30 @@ export class Database extends EventEmitter implements AsyncEmitter {
|
|
|
71
76
|
constructor(options: DatabaseOptions) {
|
|
72
77
|
super();
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
sync: {
|
|
79
|
-
alter: {
|
|
80
|
-
drop: false,
|
|
81
|
-
},
|
|
82
|
-
force: false,
|
|
79
|
+
const opts = {
|
|
80
|
+
sync: {
|
|
81
|
+
alter: {
|
|
82
|
+
drop: false,
|
|
83
83
|
},
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
force: false,
|
|
85
|
+
},
|
|
86
|
+
...options,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
if (options.storage && options.storage !== ':memory:') {
|
|
90
|
+
if (!isAbsolute(options.storage)) {
|
|
91
|
+
opts.storage = resolve(process.cwd(), options.storage);
|
|
90
92
|
}
|
|
91
|
-
this.sequelize = new Sequelize(opts);
|
|
92
|
-
this.options = opts;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
if (options.dialect === 'sqlite') {
|
|
96
|
+
delete opts.timezone;
|
|
97
|
+
} else if (!opts.timezone) {
|
|
98
|
+
opts.timezone = '+00:00';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.sequelize = new Sequelize(opts);
|
|
102
|
+
this.options = opts;
|
|
95
103
|
this.collections = new Map();
|
|
96
104
|
this.modelHook = new ModelHook(this);
|
|
97
105
|
|
|
@@ -116,6 +124,32 @@ export class Database extends EventEmitter implements AsyncEmitter {
|
|
|
116
124
|
}
|
|
117
125
|
|
|
118
126
|
this.initOperators();
|
|
127
|
+
|
|
128
|
+
const migratorOptions: any = this.options.migrator || {};
|
|
129
|
+
|
|
130
|
+
const context = {
|
|
131
|
+
db: this,
|
|
132
|
+
sequelize: this.sequelize,
|
|
133
|
+
queryInterface: this.sequelize.getQueryInterface(),
|
|
134
|
+
...migratorOptions.context,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
this.migrations = new Migrations(context);
|
|
138
|
+
|
|
139
|
+
this.migrator = new Umzug({
|
|
140
|
+
logger: migratorOptions.logger || console,
|
|
141
|
+
migrations: this.migrations.callback(),
|
|
142
|
+
context,
|
|
143
|
+
storage: new SequelizeStorage({
|
|
144
|
+
modelName: `${this.options.tablePrefix||''}migrations`,
|
|
145
|
+
...migratorOptions.storage,
|
|
146
|
+
sequelize: this.sequelize,
|
|
147
|
+
}),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
addMigration(item) {
|
|
152
|
+
return this.migrations.add(item);
|
|
119
153
|
}
|
|
120
154
|
|
|
121
155
|
/**
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './database';
|
|
|
4
4
|
export { Database as default } from './database';
|
|
5
5
|
export * from './fields';
|
|
6
6
|
export * from './magic-attribute-model';
|
|
7
|
+
export * from './migration';
|
|
7
8
|
export * from './mock-database';
|
|
8
9
|
export * from './model';
|
|
9
10
|
export * from './relation-repository/belongs-to-many-repository';
|
package/src/migration.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { QueryInterface, Sequelize } from 'sequelize';
|
|
2
|
+
import Database from './database';
|
|
3
|
+
|
|
4
|
+
export interface MigrationContext {
|
|
5
|
+
db: Database;
|
|
6
|
+
queryInterface: QueryInterface;
|
|
7
|
+
sequelize: Sequelize;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class Migration {
|
|
11
|
+
public name: string;
|
|
12
|
+
|
|
13
|
+
public context: { db: Database };
|
|
14
|
+
|
|
15
|
+
constructor(context: MigrationContext) {
|
|
16
|
+
this.context = context;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get db() {
|
|
20
|
+
return this.context.db;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get sequelize() {
|
|
24
|
+
return this.context.db.sequelize;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get queryInterface() {
|
|
28
|
+
return this.context.db.sequelize.getQueryInterface();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async up() {
|
|
32
|
+
// todo
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async down() {
|
|
36
|
+
// todo
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface MigrationItem {
|
|
41
|
+
name: string;
|
|
42
|
+
migration?: typeof Migration;
|
|
43
|
+
up?: any;
|
|
44
|
+
down?: any;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class Migrations {
|
|
48
|
+
items = [];
|
|
49
|
+
context: any;
|
|
50
|
+
|
|
51
|
+
constructor(context: any) {
|
|
52
|
+
this.context = context;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
clear() {
|
|
56
|
+
this.items = [];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
add(item: MigrationItem) {
|
|
60
|
+
const Migration = item.migration;
|
|
61
|
+
if (Migration) {
|
|
62
|
+
const migration = new Migration(this.context);
|
|
63
|
+
migration.name = item.name;
|
|
64
|
+
this.items.push(migration);
|
|
65
|
+
} else {
|
|
66
|
+
this.items.push(item);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
callback() {
|
|
71
|
+
return (ctx) => {
|
|
72
|
+
return this.items;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|