@proteinjs/db-driver-knex 1.0.14 → 1.0.16
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/.eslintrc.js +20 -0
- package/.prettierignore +4 -0
- package/.prettierrc +8 -0
- package/CHANGELOG.md +16 -20
- package/README.md +1 -1
- package/dist/src/KnexColumnTypeFactory.d.ts.map +1 -1
- package/dist/src/KnexColumnTypeFactory.js +18 -9
- package/dist/src/KnexColumnTypeFactory.js.map +1 -1
- package/dist/src/KnexConfig.d.ts.map +1 -1
- package/dist/src/KnexDriver.d.ts.map +1 -1
- package/dist/src/KnexDriver.js +7 -4
- package/dist/src/KnexDriver.js.map +1 -1
- package/dist/src/KnexSchemaOperations.d.ts.map +1 -1
- package/dist/src/KnexSchemaOperations.js +26 -11
- package/dist/src/KnexSchemaOperations.js.map +1 -1
- package/dist/src/getColumnFactory.d.ts.map +1 -1
- package/dist/src/getColumnFactory.js +27 -12
- package/dist/src/getColumnFactory.js.map +1 -1
- package/dist/test/Crud.test.js.map +1 -1
- package/dist/test/TableManager.test.js.map +1 -1
- package/generated/index.ts +5 -8
- package/index.ts +1 -1
- package/jest.config.js +8 -17
- package/package.json +50 -45
- package/src/KnexColumnTypeFactory.ts +24 -12
- package/src/KnexConfig.ts +5 -5
- package/src/KnexDriver.ts +69 -66
- package/src/KnexSchemaOperations.ts +114 -91
- package/src/getColumnFactory.ts +67 -49
- package/test/Crud.test.ts +11 -16
- package/test/TableManager.test.ts +11 -17
- package/tsconfig.json +18 -22
package/jest.config.js
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"ts",
|
|
11
|
-
"tsx",
|
|
12
|
-
"js",
|
|
13
|
-
"jsx",
|
|
14
|
-
"json",
|
|
15
|
-
"node"
|
|
16
|
-
],
|
|
17
|
-
"testEnvironment": "node"
|
|
18
|
-
}
|
|
2
|
+
roots: ['<rootDir>/test'],
|
|
3
|
+
transform: {
|
|
4
|
+
'^.+\\.tsx?$': 'ts-jest',
|
|
5
|
+
},
|
|
6
|
+
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
|
|
7
|
+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
|
8
|
+
testEnvironment: 'node',
|
|
9
|
+
};
|
package/package.json
CHANGED
|
@@ -1,47 +1,52 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
2
|
+
"name": "@proteinjs/db-driver-knex",
|
|
3
|
+
"version": "1.0.16",
|
|
4
|
+
"description": "Db driver for Knex",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/proteinjs/db.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/proteinjs/db/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/proteinjs/db#readme",
|
|
16
|
+
"author": "Brent Bahry",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"clean": "rm -rf dist/ node_modules/ generated/",
|
|
20
|
+
"build": "reflection-build && tsc",
|
|
21
|
+
"watch": "reflection-watch",
|
|
22
|
+
"test": "jest"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@proteinjs/db": "^1.0.17",
|
|
26
|
+
"@proteinjs/db-query": "^1.0.10",
|
|
27
|
+
"@proteinjs/reflection": "1.1.1",
|
|
28
|
+
"@proteinjs/util": "1.1.0",
|
|
29
|
+
"knex": "0.21.5",
|
|
30
|
+
"moment": "2.27.0",
|
|
31
|
+
"mysql": "2.18.1",
|
|
32
|
+
"uuid": "8.3.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@proteinjs/reflection-build": "1.0.16",
|
|
36
|
+
"@types/jest": "29.5.5",
|
|
37
|
+
"@types/knex": "0.16.1",
|
|
38
|
+
"@types/node": "14.0.27",
|
|
39
|
+
"@types/uuid": "8.3.0",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "7.8.0",
|
|
41
|
+
"@typescript-eslint/parser": "7.8.0",
|
|
42
|
+
"eslint": "8.57.0",
|
|
43
|
+
"eslint-config-prettier": "9.1.0",
|
|
44
|
+
"eslint-plugin-prettier": "5.1.3",
|
|
45
|
+
"jest": "29.7.0",
|
|
46
|
+
"ts-jest": "29.1.1",
|
|
47
|
+
"typescript": "5.2.2"
|
|
48
|
+
},
|
|
49
|
+
"main": "./dist/generated/index.js",
|
|
50
|
+
"types": "./dist/generated/index.d.ts",
|
|
51
|
+
"gitHead": "e168c40fd3f7c538d5d5ddcedb0bb4f5550ca81f"
|
|
47
52
|
}
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
import { isInstanceOf } from '@proteinjs/util';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BinaryColumn,
|
|
4
|
+
BooleanColumn,
|
|
5
|
+
Column,
|
|
6
|
+
DateColumn,
|
|
7
|
+
DateTimeColumn,
|
|
8
|
+
DecimalColumn,
|
|
9
|
+
FloatColumn,
|
|
10
|
+
IntegerColumn,
|
|
11
|
+
StringColumn,
|
|
12
|
+
UuidColumn,
|
|
13
|
+
} from '@proteinjs/db';
|
|
3
14
|
|
|
4
15
|
// note: this might be specific to maria db
|
|
5
16
|
export class KnexColumnTypeFactory {
|
|
6
17
|
getType(column: Column<any, any>): string {
|
|
7
|
-
if (isInstanceOf(column, IntegerColumn))
|
|
18
|
+
if (isInstanceOf(column, IntegerColumn)) {
|
|
8
19
|
return (column as IntegerColumn).large ? 'bigint' : 'int';
|
|
9
|
-
else if (isInstanceOf(column, UuidColumn))
|
|
20
|
+
} else if (isInstanceOf(column, UuidColumn)) {
|
|
10
21
|
return 'char';
|
|
11
|
-
else if (isInstanceOf(column, StringColumn))
|
|
22
|
+
} else if (isInstanceOf(column, StringColumn)) {
|
|
12
23
|
return (column as StringColumn).maxLength === 'MAX' ? 'longtext' : 'varchar';
|
|
13
|
-
else if (isInstanceOf(column, FloatColumn))
|
|
24
|
+
} else if (isInstanceOf(column, FloatColumn)) {
|
|
14
25
|
return 'float';
|
|
15
|
-
else if (isInstanceOf(column, DecimalColumn))
|
|
26
|
+
} else if (isInstanceOf(column, DecimalColumn)) {
|
|
16
27
|
return 'decimal';
|
|
17
|
-
else if (isInstanceOf(column, BooleanColumn))
|
|
28
|
+
} else if (isInstanceOf(column, BooleanColumn)) {
|
|
18
29
|
return 'tinyint';
|
|
19
|
-
else if (isInstanceOf(column, DateColumn))
|
|
30
|
+
} else if (isInstanceOf(column, DateColumn)) {
|
|
20
31
|
return 'date';
|
|
21
|
-
else if (isInstanceOf(column, DateTimeColumn))
|
|
32
|
+
} else if (isInstanceOf(column, DateTimeColumn)) {
|
|
22
33
|
return 'datetime';
|
|
23
|
-
else if (isInstanceOf(column, BinaryColumn))
|
|
34
|
+
} else if (isInstanceOf(column, BinaryColumn)) {
|
|
24
35
|
return (column as BinaryColumn).maxLength === 'MAX' ? 'longblob' : 'blob';
|
|
25
|
-
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
throw new Error(`Invalid column type: ${column.constructor.name}, must extend a base column`);
|
|
27
39
|
}
|
|
28
|
-
}
|
|
40
|
+
}
|
package/src/KnexConfig.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type KnexConfig = {
|
|
2
|
-
host: string
|
|
3
|
-
user: string
|
|
4
|
-
password: string
|
|
5
|
-
dbName: string
|
|
6
|
-
}
|
|
2
|
+
host: string;
|
|
3
|
+
user: string;
|
|
4
|
+
password: string;
|
|
5
|
+
dbName: string;
|
|
6
|
+
};
|
package/src/KnexDriver.ts
CHANGED
|
@@ -7,84 +7,87 @@ import { KnexSchemaOperations } from './KnexSchemaOperations';
|
|
|
7
7
|
import { KnexColumnTypeFactory } from './KnexColumnTypeFactory';
|
|
8
8
|
|
|
9
9
|
export class KnexDriver implements DbDriver {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
private static KNEX: knex;
|
|
11
|
+
private logger = new Logger(this.constructor.name);
|
|
12
|
+
private config: KnexConfig;
|
|
13
|
+
private knexConfig: any;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
constructor(config: KnexConfig) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.knexConfig = {
|
|
18
|
+
client: 'mysql',
|
|
19
|
+
connection: {
|
|
20
|
+
host: this.config.host,
|
|
21
|
+
user: this.config.user,
|
|
22
|
+
password: this.config.password,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
getKnex(): knex {
|
|
28
|
+
if (!KnexDriver.KNEX) {
|
|
29
|
+
KnexDriver.KNEX = knex(this.knexConfig);
|
|
30
|
+
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
return KnexDriver.KNEX;
|
|
33
|
+
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
getDbName() {
|
|
36
|
+
return this.config.dbName as string;
|
|
37
|
+
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
async createDbIfNotExists(): Promise<void> {
|
|
40
|
+
if (await this.dbExists(this.getDbName())) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
await this.getKnex().raw(`CREATE DATABASE ${this.getDbName()};`);
|
|
45
|
+
}
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
private async dbExists(databaseName: string): Promise<boolean> {
|
|
48
|
+
const result: any = await this.getKnex().raw('SHOW DATABASES;');
|
|
49
|
+
for (const existingDatabase of result[0]) {
|
|
50
|
+
if (existingDatabase['Database'] == databaseName) {
|
|
49
51
|
return true;
|
|
50
|
-
|
|
52
|
+
}
|
|
53
|
+
}
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
async start() {
|
|
59
|
+
await this.setMaxAllowedPacketSize();
|
|
60
|
+
}
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
async stop() {
|
|
63
|
+
await this.getKnex().destroy();
|
|
64
|
+
}
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
private async setMaxAllowedPacketSize(): Promise<void> {
|
|
67
|
+
await this.getKnex().raw('SET GLOBAL max_allowed_packet=1073741824;');
|
|
68
|
+
await this.getKnex().destroy();
|
|
69
|
+
KnexDriver.KNEX = knex(this.knexConfig);
|
|
70
|
+
this.logger.info('Set global max_allowed_packet size to 1gb');
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
getTableManager(): TableManager {
|
|
74
|
+
const columnTypeFactory = new KnexColumnTypeFactory();
|
|
75
|
+
const schemaOperations = new KnexSchemaOperations(this);
|
|
76
|
+
return new TableManager(this, columnTypeFactory, schemaOperations);
|
|
77
|
+
}
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
async runQuery(generateStatement: (config: DbDriverStatementConfig) => Statement): Promise<SerializedRecord[]> {
|
|
80
|
+
const { sql, params } = generateStatement({ useParams: true, prefixTablesWithDb: true });
|
|
81
|
+
try {
|
|
82
|
+
return (await this.getKnex().raw(sql, params as any))[0]; // returns 2 arrays, first is records, second is metadata per record
|
|
83
|
+
} catch (error: any) {
|
|
84
|
+
this.logger.error(`Failed when executing query: ${sql}`);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
89
|
+
async runDml(generateStatement: (config: DbDriverStatementConfig) => Statement): Promise<number> {
|
|
90
|
+
const { affectedRows } = (await this.runQuery(generateStatement)) as any;
|
|
91
|
+
return affectedRows;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -7,9 +7,7 @@ import { getColumnFactory } from './getColumnFactory';
|
|
|
7
7
|
export class KnexSchemaOperations implements SchemaOperations {
|
|
8
8
|
private logger = new Logger(this.constructor.name);
|
|
9
9
|
|
|
10
|
-
constructor(
|
|
11
|
-
private knexDriver: KnexDriver
|
|
12
|
-
){}
|
|
10
|
+
constructor(private knexDriver: KnexDriver) {}
|
|
13
11
|
|
|
14
12
|
async createTable(table: Table<any>) {
|
|
15
13
|
let resolve: any;
|
|
@@ -18,113 +16,138 @@ export class KnexSchemaOperations implements SchemaOperations {
|
|
|
18
16
|
resolve = rs;
|
|
19
17
|
reject = rj;
|
|
20
18
|
});
|
|
21
|
-
|
|
22
|
-
await this.knexDriver
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.logger.info(`[${table.name}] Creating primary key: id`);
|
|
31
|
-
|
|
32
|
-
if (table.indexes) {
|
|
33
|
-
for (const index of table.indexes) {
|
|
34
|
-
const columnNames = index.columns.map((columnPropertyName) => table.columns[columnPropertyName as string].name)
|
|
35
|
-
tableBuilder.index(columnNames, index.name);
|
|
36
|
-
this.logger.info(`[${table.name}] Creating index: ${columnNames}`);
|
|
19
|
+
|
|
20
|
+
await this.knexDriver
|
|
21
|
+
.getKnex()
|
|
22
|
+
.schema.withSchema(this.knexDriver.getDbName())
|
|
23
|
+
.createTable(table.name, (tableBuilder: knex.TableBuilder) => {
|
|
24
|
+
for (const columnPropertyName in table.columns) {
|
|
25
|
+
const column = table.columns[columnPropertyName];
|
|
26
|
+
this.createColumn(column, table, tableBuilder);
|
|
27
|
+
this.logger.info(`[${table.name}] Creating column: ${column.name}`);
|
|
37
28
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
|
|
30
|
+
tableBuilder.primary(['id']);
|
|
31
|
+
this.logger.info(`[${table.name}] Creating primary key: id`);
|
|
32
|
+
|
|
33
|
+
if (table.indexes) {
|
|
34
|
+
for (const index of table.indexes) {
|
|
35
|
+
const columnNames = index.columns.map(
|
|
36
|
+
(columnPropertyName) => table.columns[columnPropertyName as string].name
|
|
37
|
+
);
|
|
38
|
+
tableBuilder.index(columnNames, index.name);
|
|
39
|
+
this.logger.info(`[${table.name}] Creating index: ${columnNames}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
.catch((reason: any) => {
|
|
44
|
+
reject(`Failed to create table: ${table.name}. reason: ${reason}`);
|
|
45
|
+
})
|
|
46
|
+
.then(() => {
|
|
47
|
+
resolve();
|
|
48
|
+
});
|
|
49
|
+
|
|
45
50
|
return p;
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
async alterTable(table: Table<any>, tableChanges: TableChanges) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
await this.knexDriver.getKnex().schema.withSchema(this.knexDriver.getDbName()).table(table.name, (tableBuilder: knex.TableBuilder) => {
|
|
57
|
-
for (const columnPropertyName of tableChanges.columnsToCreate) {
|
|
58
|
-
const column = table.columns[columnPropertyName];
|
|
59
|
-
this.logger.info(`[${table.name}] Creating column: ${column.name}`);
|
|
60
|
-
this.createColumn(column, table, tableBuilder, tableChanges);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
for (const column of tableChanges.columnsWithUniqueConstraintsToDrop) {
|
|
64
|
-
tableBuilder.dropUnique([column]);
|
|
65
|
-
this.logger.info(`[${table.name}.${column}] Dropping unique constraint`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
for (const column of tableChanges.columnsWithForeignKeysToDrop) {
|
|
69
|
-
tableBuilder.dropForeign([column]);
|
|
70
|
-
this.logger.info(`[${table.name}.${column}] Dropping foreign key`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
for (const index of tableChanges.indexesToDrop) {
|
|
74
|
-
tableBuilder.dropIndex(index.columns);
|
|
75
|
-
this.logger.info(`[${table.name}] Dropping index: ${JSON.stringify(index)}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
for (const columnPropertyName of tableChanges.columnsToAlter) {
|
|
79
|
-
const column = table.columns[columnPropertyName];
|
|
80
|
-
this.logger.info(`[${table.name}.${column.name}] Altering column type to: ${column.constructor.name}`);
|
|
81
|
-
this.createColumn(column, table, tableBuilder, tableChanges).alter();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
for (const columnPropertyName of tableChanges.columnsToRename) {
|
|
85
|
-
const column = table.columns[columnPropertyName];
|
|
86
|
-
if (!column.oldName)
|
|
87
|
-
continue;
|
|
88
|
-
|
|
89
|
-
tableBuilder.renameColumn(column.oldName, column.name);
|
|
90
|
-
this.logger.info(`[${table.name}] Renaming column: ${column.oldName} -> ${column.name}`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
for (const index of tableChanges.indexesToCreate) {
|
|
94
|
-
tableBuilder.index(index.columns);
|
|
95
|
-
this.logger.info(`[${table.name}] Creating index: ${JSON.stringify(index)}`);
|
|
96
|
-
}
|
|
97
|
-
}).catch((reason: any) => {
|
|
98
|
-
reject(`Failed to alter table: ${table.name}. reason: ${reason}`);
|
|
99
|
-
}).then(() => {
|
|
100
|
-
resolve();
|
|
54
|
+
let resolve: any;
|
|
55
|
+
let reject: any;
|
|
56
|
+
const p = new Promise<void>((rs, rj) => {
|
|
57
|
+
resolve = rs;
|
|
58
|
+
reject = rj;
|
|
101
59
|
});
|
|
102
|
-
|
|
103
|
-
return p;
|
|
104
|
-
}
|
|
105
60
|
|
|
106
|
-
|
|
61
|
+
await this.knexDriver
|
|
62
|
+
.getKnex()
|
|
63
|
+
.schema.withSchema(this.knexDriver.getDbName())
|
|
64
|
+
.table(table.name, (tableBuilder: knex.TableBuilder) => {
|
|
65
|
+
for (const columnPropertyName of tableChanges.columnsToCreate) {
|
|
66
|
+
const column = table.columns[columnPropertyName];
|
|
67
|
+
this.logger.info(`[${table.name}] Creating column: ${column.name}`);
|
|
68
|
+
this.createColumn(column, table, tableBuilder, tableChanges);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const column of tableChanges.columnsWithUniqueConstraintsToDrop) {
|
|
72
|
+
tableBuilder.dropUnique([column]);
|
|
73
|
+
this.logger.info(`[${table.name}.${column}] Dropping unique constraint`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (const column of tableChanges.columnsWithForeignKeysToDrop) {
|
|
77
|
+
tableBuilder.dropForeign([column]);
|
|
78
|
+
this.logger.info(`[${table.name}.${column}] Dropping foreign key`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
for (const index of tableChanges.indexesToDrop) {
|
|
82
|
+
tableBuilder.dropIndex(index.columns);
|
|
83
|
+
this.logger.info(`[${table.name}] Dropping index: ${JSON.stringify(index)}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for (const columnPropertyName of tableChanges.columnsToAlter) {
|
|
87
|
+
const column = table.columns[columnPropertyName];
|
|
88
|
+
this.logger.info(`[${table.name}.${column.name}] Altering column type to: ${column.constructor.name}`);
|
|
89
|
+
this.createColumn(column, table, tableBuilder, tableChanges).alter();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const columnPropertyName of tableChanges.columnsToRename) {
|
|
93
|
+
const column = table.columns[columnPropertyName];
|
|
94
|
+
if (!column.oldName) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
tableBuilder.renameColumn(column.oldName, column.name);
|
|
99
|
+
this.logger.info(`[${table.name}] Renaming column: ${column.oldName} -> ${column.name}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const index of tableChanges.indexesToCreate) {
|
|
103
|
+
tableBuilder.index(index.columns);
|
|
104
|
+
this.logger.info(`[${table.name}] Creating index: ${JSON.stringify(index)}`);
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
.catch((reason: any) => {
|
|
108
|
+
reject(`Failed to alter table: ${table.name}. reason: ${reason}`);
|
|
109
|
+
})
|
|
110
|
+
.then(() => {
|
|
111
|
+
resolve();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return p;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private createColumn(
|
|
118
|
+
column: Column<any, any>,
|
|
119
|
+
table: Table<any>,
|
|
120
|
+
tableBuilder: knex.TableBuilder,
|
|
121
|
+
tableChanges?: TableChanges
|
|
122
|
+
) {
|
|
107
123
|
const columnFactory = getColumnFactory(column);
|
|
108
124
|
const columnBuilder = columnFactory.create(column, tableBuilder);
|
|
109
|
-
if (
|
|
125
|
+
if (
|
|
126
|
+
column.options?.unique?.unique &&
|
|
127
|
+
(!tableChanges || tableChanges.columnsWithUniqueConstraintsToCreate.includes(column.name))
|
|
128
|
+
) {
|
|
110
129
|
columnBuilder.unique(column.options.unique.indexName);
|
|
111
130
|
this.logger.info(`[${table.name}.${column.name}] Adding unique constraint`);
|
|
112
131
|
}
|
|
113
|
-
|
|
114
|
-
if (
|
|
132
|
+
|
|
133
|
+
if (
|
|
134
|
+
column.options?.references &&
|
|
135
|
+
(!tableChanges || tableChanges.columnsWithForeignKeysToCreate.includes(column.name))
|
|
136
|
+
) {
|
|
115
137
|
columnBuilder.references('id').inTable(`${this.knexDriver.getDbName()}.${column.options.references.table}`);
|
|
116
138
|
this.logger.info(`[${table.name}.${column.name}] Adding foreign key -> ${column.options.references.table}.id`);
|
|
117
139
|
}
|
|
118
|
-
|
|
140
|
+
|
|
119
141
|
if (typeof column.options?.nullable !== 'undefined') {
|
|
120
|
-
if (column.options?.nullable)
|
|
142
|
+
if (column.options?.nullable) {
|
|
121
143
|
columnBuilder.nullable();
|
|
122
|
-
else
|
|
144
|
+
} else {
|
|
123
145
|
columnBuilder.notNullable();
|
|
124
|
-
|
|
146
|
+
}
|
|
147
|
+
|
|
125
148
|
this.logger.info(`[${table.name}.${column.name}] Adding constraint nullable: ${column.options?.nullable}`);
|
|
126
149
|
}
|
|
127
|
-
|
|
150
|
+
|
|
128
151
|
return columnBuilder;
|
|
129
152
|
}
|
|
130
|
-
}
|
|
153
|
+
}
|