kysely 0.12.0 → 0.14.0
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/README.md +34 -10
- package/dist/cjs/{introspection → dialect}/database-introspector.d.ts +0 -0
- package/dist/cjs/{introspection → dialect}/database-introspector.js +0 -0
- package/dist/cjs/dialect/dialect-adapter-base.d.ts +36 -0
- package/dist/cjs/dialect/dialect.d.ts +1 -1
- package/dist/cjs/dialect/mysql/mysql-adapter.d.ts +38 -2
- package/dist/cjs/dialect/mysql/mysql-adapter.js +2 -1
- package/dist/cjs/dialect/mysql/mysql-dialect.d.ts +17 -1
- package/dist/cjs/dialect/mysql/mysql-driver.d.ts +29 -0
- package/dist/cjs/dialect/mysql/mysql-introspector.d.ts +4 -1
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +38 -2
- package/dist/cjs/dialect/postgres/postgres-adapter.js +2 -1
- package/dist/cjs/dialect/postgres/postgres-dialect.d.ts +17 -1
- package/dist/cjs/dialect/postgres/postgres-driver.d.ts +29 -0
- package/dist/cjs/dialect/postgres/postgres-introspector.d.ts +4 -1
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +38 -2
- package/dist/cjs/dialect/sqlite/sqlite-dialect.d.ts +17 -1
- package/dist/cjs/dialect/sqlite/sqlite-driver.d.ts +29 -0
- package/dist/cjs/dialect/sqlite/sqlite-introspector.d.ts +4 -1
- package/dist/cjs/driver/default-connection-provider.d.ts +4 -0
- package/dist/cjs/driver/runtime-driver.d.ts +29 -0
- package/dist/cjs/driver/single-connection-provider.d.ts +4 -0
- package/dist/cjs/index.d.ts +4 -3
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/kysely.d.ts +152 -1
- package/dist/cjs/kysely.js +37 -0
- package/dist/cjs/migration/migration.d.ts +154 -11
- package/dist/cjs/migration/migration.js +256 -135
- package/dist/cjs/operation-node/check-constraint-node.d.ts +1 -1
- package/dist/cjs/operation-node/check-constraint-node.js +2 -3
- package/dist/cjs/operation-node/column-definition-node.d.ts +8 -7
- package/dist/cjs/operation-node/column-definition-node.js +0 -4
- package/dist/cjs/operation-node/common-table-expression-name-node.d.ts +15 -0
- package/dist/cjs/operation-node/common-table-expression-name-node.js +23 -0
- package/dist/cjs/operation-node/common-table-expression-node.d.ts +3 -3
- package/dist/cjs/operation-node/data-type-node.d.ts +1 -1
- package/dist/cjs/operation-node/generated-node.d.ts +20 -0
- package/dist/cjs/operation-node/generated-node.js +31 -0
- package/dist/cjs/operation-node/on-conflict-node.d.ts +13 -2
- package/dist/cjs/operation-node/on-conflict-node.js +39 -1
- package/dist/cjs/operation-node/operation-node-transformer.d.ts +4 -2
- package/dist/cjs/operation-node/operation-node-transformer.js +22 -6
- package/dist/cjs/operation-node/operation-node-visitor.d.ts +4 -2
- package/dist/cjs/operation-node/operation-node-visitor.js +2 -1
- package/dist/cjs/operation-node/operation-node.d.ts +1 -1
- package/dist/cjs/operation-node/with-node.d.ts +3 -1
- package/dist/cjs/operation-node/with-node.js +2 -1
- package/dist/cjs/package.json +1 -3
- package/dist/cjs/parser/parse-context.d.ts +14 -0
- package/dist/cjs/parser/with-parser.d.ts +32 -5
- package/dist/cjs/parser/with-parser.js +13 -2
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +36 -2
- package/dist/cjs/plugin/immediate-value.ts/immediate-value-plugin.d.ts +34 -0
- package/dist/cjs/plugin/with-schema/with-schema-plugin.d.ts +34 -0
- package/dist/cjs/plugin/with-schema/with-schema-transformer.js +8 -0
- package/dist/cjs/query-builder/delete-query-builder.d.ts +545 -0
- package/dist/cjs/query-builder/insert-query-builder.d.ts +142 -76
- package/dist/cjs/query-builder/insert-query-builder.js +150 -15
- package/dist/cjs/query-builder/join-interface.d.ts +3 -6
- package/dist/cjs/query-builder/on-conflict-builder.d.ts +684 -0
- package/dist/cjs/query-builder/on-conflict-builder.js +323 -0
- package/dist/cjs/query-builder/returning-interface.d.ts +1 -1
- package/dist/cjs/query-builder/select-query-builder.d.ts +513 -2
- package/dist/cjs/query-builder/select-query-builder.js +2 -2
- package/dist/cjs/query-builder/update-query-builder.d.ts +547 -2
- package/dist/cjs/query-builder/update-query-builder.js +2 -2
- package/dist/cjs/query-builder/where-interface.d.ts +7 -10
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +4 -2
- package/dist/cjs/query-compiler/default-query-compiler.js +48 -8
- package/dist/cjs/query-creator.d.ts +27 -3
- package/dist/cjs/query-creator.js +33 -1
- package/dist/cjs/query-executor/default-query-executor.d.ts +19 -0
- package/dist/cjs/query-executor/noop-query-executor.d.ts +19 -0
- package/dist/cjs/raw-builder/raw-builder.js +1 -1
- package/dist/cjs/schema/alter-table-builder.d.ts +253 -5
- package/dist/cjs/schema/alter-table-builder.js +45 -9
- package/dist/cjs/schema/column-definition-builder.d.ts +146 -6
- package/dist/cjs/schema/column-definition-builder.js +21 -8
- package/dist/cjs/schema/create-index-builder.d.ts +3 -2
- package/dist/cjs/schema/create-index-builder.js +2 -2
- package/dist/cjs/schema/create-table-builder.d.ts +3 -2
- package/dist/cjs/schema/create-table-builder.js +2 -2
- package/dist/esm/{introspection → dialect}/database-introspector.d.ts +0 -0
- package/dist/esm/{introspection → dialect}/database-introspector.js +0 -0
- package/dist/esm/dialect/dialect-adapter-base.d.ts +36 -0
- package/dist/esm/dialect/dialect.d.ts +1 -1
- package/dist/esm/dialect/mysql/mysql-adapter.d.ts +38 -2
- package/dist/esm/dialect/mysql/mysql-adapter.js +2 -1
- package/dist/esm/dialect/mysql/mysql-dialect.d.ts +17 -1
- package/dist/esm/dialect/mysql/mysql-driver.d.ts +29 -0
- package/dist/esm/dialect/mysql/mysql-introspector.d.ts +4 -1
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +38 -2
- package/dist/esm/dialect/postgres/postgres-adapter.js +2 -1
- package/dist/esm/dialect/postgres/postgres-dialect.d.ts +17 -1
- package/dist/esm/dialect/postgres/postgres-driver.d.ts +29 -0
- package/dist/esm/dialect/postgres/postgres-introspector.d.ts +4 -1
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +38 -2
- package/dist/esm/dialect/sqlite/sqlite-dialect.d.ts +17 -1
- package/dist/esm/dialect/sqlite/sqlite-driver.d.ts +29 -0
- package/dist/esm/dialect/sqlite/sqlite-introspector.d.ts +4 -1
- package/dist/esm/driver/default-connection-provider.d.ts +4 -0
- package/dist/esm/driver/runtime-driver.d.ts +29 -0
- package/dist/esm/driver/single-connection-provider.d.ts +4 -0
- package/dist/esm/index.d.ts +4 -3
- package/dist/esm/index.js +3 -2
- package/dist/esm/kysely.d.ts +152 -1
- package/dist/esm/kysely.js +37 -0
- package/dist/esm/migration/migration.d.ts +154 -11
- package/dist/esm/migration/migration.js +255 -134
- package/dist/esm/operation-node/check-constraint-node.d.ts +1 -1
- package/dist/esm/operation-node/check-constraint-node.js +2 -3
- package/dist/esm/operation-node/column-definition-node.d.ts +8 -7
- package/dist/esm/operation-node/column-definition-node.js +0 -4
- package/dist/esm/operation-node/common-table-expression-name-node.d.ts +15 -0
- package/dist/esm/operation-node/common-table-expression-name-node.js +20 -0
- package/dist/esm/operation-node/common-table-expression-node.d.ts +3 -3
- package/dist/esm/operation-node/data-type-node.d.ts +1 -1
- package/dist/esm/operation-node/generated-node.d.ts +20 -0
- package/dist/esm/operation-node/generated-node.js +28 -0
- package/dist/esm/operation-node/on-conflict-node.d.ts +13 -2
- package/dist/esm/operation-node/on-conflict-node.js +39 -1
- package/dist/esm/operation-node/operation-node-transformer.d.ts +4 -2
- package/dist/esm/operation-node/operation-node-transformer.js +22 -6
- package/dist/esm/operation-node/operation-node-visitor.d.ts +4 -2
- package/dist/esm/operation-node/operation-node-visitor.js +2 -1
- package/dist/esm/operation-node/operation-node.d.ts +1 -1
- package/dist/esm/operation-node/with-node.d.ts +3 -1
- package/dist/esm/operation-node/with-node.js +2 -1
- package/dist/esm/package.json +1 -3
- package/dist/esm/parser/parse-context.d.ts +14 -0
- package/dist/esm/parser/with-parser.d.ts +32 -5
- package/dist/esm/parser/with-parser.js +13 -2
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +36 -2
- package/dist/esm/plugin/immediate-value.ts/immediate-value-plugin.d.ts +34 -0
- package/dist/esm/plugin/with-schema/with-schema-plugin.d.ts +34 -0
- package/dist/esm/plugin/with-schema/with-schema-transformer.js +8 -0
- package/dist/esm/query-builder/delete-query-builder.d.ts +545 -0
- package/dist/esm/query-builder/insert-query-builder.d.ts +142 -76
- package/dist/esm/query-builder/insert-query-builder.js +150 -15
- package/dist/esm/query-builder/join-interface.d.ts +3 -6
- package/dist/esm/query-builder/on-conflict-builder.d.ts +684 -0
- package/dist/esm/query-builder/on-conflict-builder.js +317 -0
- package/dist/esm/query-builder/returning-interface.d.ts +1 -1
- package/dist/esm/query-builder/select-query-builder.d.ts +513 -2
- package/dist/esm/query-builder/select-query-builder.js +2 -2
- package/dist/esm/query-builder/update-query-builder.d.ts +547 -2
- package/dist/esm/query-builder/update-query-builder.js +2 -2
- package/dist/esm/query-builder/where-interface.d.ts +7 -10
- package/dist/esm/query-compiler/default-query-compiler.d.ts +4 -2
- package/dist/esm/query-compiler/default-query-compiler.js +48 -8
- package/dist/esm/query-creator.d.ts +27 -3
- package/dist/esm/query-creator.js +33 -1
- package/dist/esm/query-executor/default-query-executor.d.ts +19 -0
- package/dist/esm/query-executor/noop-query-executor.d.ts +19 -0
- package/dist/esm/raw-builder/raw-builder.js +1 -1
- package/dist/esm/schema/alter-table-builder.d.ts +253 -5
- package/dist/esm/schema/alter-table-builder.js +45 -9
- package/dist/esm/schema/column-definition-builder.d.ts +146 -6
- package/dist/esm/schema/column-definition-builder.js +21 -8
- package/dist/esm/schema/create-index-builder.d.ts +3 -2
- package/dist/esm/schema/create-index-builder.js +2 -2
- package/dist/esm/schema/create-table-builder.d.ts +3 -2
- package/dist/esm/schema/create-table-builder.js +2 -2
- package/package.json +8 -6
- package/dist/cjs/operation-node/generated-always-as-node.d.ts +0 -16
- package/dist/cjs/operation-node/generated-always-as-node.js +0 -25
- package/dist/cjs/parser/on-conflict-parser.d.ts +0 -10
- package/dist/cjs/parser/on-conflict-parser.js +0 -35
- package/dist/esm/operation-node/generated-always-as-node.d.ts +0 -16
- package/dist/esm/operation-node/generated-always-as-node.js +0 -22
- package/dist/esm/parser/on-conflict-parser.d.ts +0 -10
- package/dist/esm/parser/on-conflict-parser.js +0 -30
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MigrationModule = exports.MIGRATION_LOCK_ID = exports.MIGRATION_LOCK_TABLE = exports.MIGRATION_TABLE = void 0;
|
|
3
|
+
exports.MigrationModule = exports.NO_MIGRATIONS = exports.MIGRATION_LOCK_ID = exports.MIGRATION_LOCK_TABLE = exports.MIGRATION_TABLE = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const object_utils_js_1 = require("../util/object-utils.js");
|
|
7
7
|
exports.MIGRATION_TABLE = 'kysely_migration';
|
|
8
8
|
exports.MIGRATION_LOCK_TABLE = 'kysely_migration_lock';
|
|
9
9
|
exports.MIGRATION_LOCK_ID = 'migration_lock';
|
|
10
|
+
exports.NO_MIGRATIONS = (0, object_utils_js_1.freeze)({ __noMigrations__: true });
|
|
10
11
|
class MigrationModule {
|
|
11
12
|
#db;
|
|
12
13
|
#adapter;
|
|
@@ -15,171 +16,291 @@ class MigrationModule {
|
|
|
15
16
|
this.#adapter = adapter;
|
|
16
17
|
}
|
|
17
18
|
async migrateToLatest(migrationsOrFolderPath) {
|
|
18
|
-
|
|
19
|
-
const allMigrations = await this.#getAllMigrations(migrationsOrFolderPath);
|
|
20
|
-
await this.#migrateToLatest(allMigrations);
|
|
19
|
+
return this.#migrate(migrationsOrFolderPath, ({ migrations }) => migrations.length - 1);
|
|
21
20
|
}
|
|
22
|
-
async
|
|
23
|
-
return (
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
async migrateTo(migrationsOrFolderPath, targetMigrationName) {
|
|
22
|
+
return this.#migrate(migrationsOrFolderPath, ({ migrations }) => {
|
|
23
|
+
if (targetMigrationName === exports.NO_MIGRATIONS) {
|
|
24
|
+
return -1;
|
|
25
|
+
}
|
|
26
|
+
const index = migrations.findIndex((it) => it.name === targetMigrationName);
|
|
27
|
+
if (index === -1) {
|
|
28
|
+
throw new Error(`migration "${targetMigrationName}" doesn't exist`);
|
|
29
|
+
}
|
|
30
|
+
return index;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async migrateUp(migrationsOrFolderPath) {
|
|
34
|
+
return this.#migrate(migrationsOrFolderPath, ({ currentIndex, migrations }) => Math.min(currentIndex + 1, migrations.length - 1));
|
|
35
|
+
}
|
|
36
|
+
async migrateDown(migrationsOrFolderPath) {
|
|
37
|
+
return this.#migrate(migrationsOrFolderPath, ({ currentIndex }) => Math.max(currentIndex - 1, -1));
|
|
38
|
+
}
|
|
39
|
+
async #migrate(migrationsOrFolderPath, getTargetMigration) {
|
|
40
|
+
try {
|
|
41
|
+
await this.#ensureMigrationTablesExists();
|
|
42
|
+
return await this.#runMigrations(migrationsOrFolderPath, getTargetMigration);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof MigrationResultSetError) {
|
|
46
|
+
return error.resultSet;
|
|
47
|
+
}
|
|
48
|
+
return { error };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async #ensureMigrationTablesExists() {
|
|
52
|
+
await this.#ensureMigrationTableExists();
|
|
53
|
+
await this.#ensureMigrationLockTableExists();
|
|
54
|
+
await this.#ensureLockRowExists();
|
|
26
55
|
}
|
|
27
|
-
async #
|
|
56
|
+
async #ensureMigrationTableExists() {
|
|
57
|
+
if (!(await this.#doesTableExists(exports.MIGRATION_TABLE))) {
|
|
58
|
+
try {
|
|
59
|
+
await this.#db.schema
|
|
60
|
+
.createTable(exports.MIGRATION_TABLE)
|
|
61
|
+
.ifNotExists()
|
|
62
|
+
.addColumn('name', 'varchar(255)', (col) => col.notNull().primaryKey())
|
|
63
|
+
// The migration run time as ISO string. This is not a real date type as we
|
|
64
|
+
// can't know which data type is supported by all future dialects.
|
|
65
|
+
.addColumn('timestamp', 'varchar(255)', (col) => col.notNull())
|
|
66
|
+
.execute();
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// At least on PostgreSQL, `if not exists` doesn't guarantee the `create table`
|
|
70
|
+
// query doesn't throw if the table already exits. That's why we check if
|
|
71
|
+
// the table exist here and ignore the error if it does.
|
|
72
|
+
if (!(await this.#doesTableExists(exports.MIGRATION_TABLE))) {
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async #ensureMigrationLockTableExists() {
|
|
79
|
+
if (!(await this.#doesTableExists(exports.MIGRATION_LOCK_TABLE))) {
|
|
80
|
+
try {
|
|
81
|
+
await this.#db.schema
|
|
82
|
+
.createTable(exports.MIGRATION_LOCK_TABLE)
|
|
83
|
+
.ifNotExists()
|
|
84
|
+
.addColumn('id', 'varchar(255)', (col) => col.notNull().primaryKey())
|
|
85
|
+
.addColumn('is_locked', 'integer', (col) => col.notNull().defaultTo(0))
|
|
86
|
+
.execute();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
// At least on PostgreSQL, `if not exists` doesn't guarantee the `create table`
|
|
90
|
+
// query doesn't throw if the table already exits. That's why we check if
|
|
91
|
+
// the table exist here and ignore the error if it does.
|
|
92
|
+
if (!(await this.#doesTableExists(exports.MIGRATION_LOCK_TABLE))) {
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async #ensureLockRowExists() {
|
|
99
|
+
if (!(await this.#doesLockRowExists())) {
|
|
100
|
+
try {
|
|
101
|
+
await this.#db
|
|
102
|
+
.insertInto(exports.MIGRATION_LOCK_TABLE)
|
|
103
|
+
.values({ id: exports.MIGRATION_LOCK_ID })
|
|
104
|
+
.execute();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (!(await this.#doesLockRowExists())) {
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async #doesTableExists(tableName) {
|
|
114
|
+
const metadata = await this.#db.introspection.getMetadata({
|
|
115
|
+
withInternalKyselyTables: true,
|
|
116
|
+
});
|
|
117
|
+
return !!metadata.tables.find((it) => it.name === tableName);
|
|
118
|
+
}
|
|
119
|
+
async #doesLockRowExists() {
|
|
120
|
+
const lockRow = await this.#db
|
|
121
|
+
.selectFrom(exports.MIGRATION_LOCK_TABLE)
|
|
122
|
+
.where('id', '=', exports.MIGRATION_LOCK_ID)
|
|
123
|
+
.select('id')
|
|
124
|
+
.executeTakeFirst();
|
|
125
|
+
return !!lockRow;
|
|
126
|
+
}
|
|
127
|
+
async #runMigrations(migrationsOrFolderPath, getTargetMigration) {
|
|
28
128
|
const run = async (db) => {
|
|
29
129
|
try {
|
|
30
130
|
await this.#adapter.acquireMigrationLock(db);
|
|
31
|
-
await
|
|
131
|
+
const state = await this.#getState(db, migrationsOrFolderPath);
|
|
132
|
+
if (state.migrations.length === 0) {
|
|
133
|
+
return { results: [] };
|
|
134
|
+
}
|
|
135
|
+
const targetIndex = getTargetMigration(state);
|
|
136
|
+
if (targetIndex === undefined) {
|
|
137
|
+
return { results: [] };
|
|
138
|
+
}
|
|
139
|
+
if (targetIndex < state.currentIndex) {
|
|
140
|
+
return await this.#migrateDown(db, state, targetIndex);
|
|
141
|
+
}
|
|
142
|
+
else if (targetIndex > state.currentIndex) {
|
|
143
|
+
return await this.#migrateUp(db, state, targetIndex);
|
|
144
|
+
}
|
|
145
|
+
return { results: [] };
|
|
32
146
|
}
|
|
33
147
|
finally {
|
|
34
148
|
await this.#adapter.releaseMigrationLock(db);
|
|
35
149
|
}
|
|
36
150
|
};
|
|
37
151
|
if (this.#adapter.supportsTransactionalDdl) {
|
|
38
|
-
|
|
152
|
+
return this.#db.transaction().execute(run);
|
|
39
153
|
}
|
|
40
154
|
else {
|
|
41
|
-
|
|
155
|
+
return this.#db.connection().execute(run);
|
|
42
156
|
}
|
|
43
157
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
158
|
+
async #getState(db, migrationsOrFolderPath) {
|
|
159
|
+
const migrations = await this.#resolveMigrations(migrationsOrFolderPath);
|
|
160
|
+
const executedMigrations = await this.#getExecutedMigrations(db);
|
|
161
|
+
this.#ensureMigrationsNotCorrupted(migrations, executedMigrations);
|
|
162
|
+
return (0, object_utils_js_1.freeze)({
|
|
163
|
+
migrations,
|
|
164
|
+
currentIndex: migrations.findIndex((it) => it.name === (0, object_utils_js_1.getLast)(executedMigrations)),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async #resolveMigrations(migrationsOrFolderPath) {
|
|
168
|
+
const allMigrations = (0, object_utils_js_1.isString)(migrationsOrFolderPath)
|
|
169
|
+
? await this.#readMigrationsFromFolder(migrationsOrFolderPath)
|
|
170
|
+
: migrationsOrFolderPath;
|
|
171
|
+
return Object.keys(allMigrations)
|
|
172
|
+
.sort()
|
|
173
|
+
.map((name) => ({
|
|
174
|
+
...allMigrations[name],
|
|
175
|
+
name,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
async #readMigrationsFromFolder(migrationsFolderPath) {
|
|
179
|
+
const files = await fs_1.promises.readdir(migrationsFolderPath);
|
|
180
|
+
const migrations = {};
|
|
181
|
+
for (const file of files) {
|
|
182
|
+
if ((file.endsWith('.js') || file.endsWith('.ts')) &&
|
|
183
|
+
!file.endsWith('.d.ts')) {
|
|
184
|
+
const migration = await Promise.resolve().then(() => require(path.join(migrationsFolderPath, file)));
|
|
185
|
+
if (isMigration(migration)) {
|
|
186
|
+
migrations[file.substring(0, file.length - 3)] = migration;
|
|
187
|
+
}
|
|
69
188
|
}
|
|
70
189
|
}
|
|
190
|
+
return migrations;
|
|
71
191
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
192
|
+
async #getExecutedMigrations(db) {
|
|
193
|
+
const executedMigrations = await db
|
|
194
|
+
.selectFrom(exports.MIGRATION_TABLE)
|
|
195
|
+
.select('name')
|
|
196
|
+
.orderBy('name')
|
|
197
|
+
.execute();
|
|
198
|
+
return executedMigrations.map((it) => it.name);
|
|
199
|
+
}
|
|
200
|
+
#ensureMigrationsNotCorrupted(migrations, executedMigrations) {
|
|
201
|
+
for (const executed of executedMigrations) {
|
|
202
|
+
if (!migrations.some((it) => it.name === executed)) {
|
|
203
|
+
throw new Error(`corrupted migrations: previously executed migration ${executed} is missing`);
|
|
204
|
+
}
|
|
82
205
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
throw
|
|
206
|
+
// Now we know all executed migrations exist in the `migrations` list.
|
|
207
|
+
// Next we need to make sure that the executed migrations are the first
|
|
208
|
+
// ones in the migration list.
|
|
209
|
+
for (let i = 0; i < executedMigrations.length; ++i) {
|
|
210
|
+
if (migrations[i].name !== executedMigrations[i]) {
|
|
211
|
+
throw new Error(`corrupted migrations: expected previously executed migration ${executedMigrations[i]} to be at index ${i} but ${migrations[i].name} was found in its place. New migrations must always have a name that comes alphabetically after the last executed migration.`);
|
|
89
212
|
}
|
|
90
213
|
}
|
|
91
214
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
215
|
+
async #migrateDown(db, state, targetIndex) {
|
|
216
|
+
const results = [];
|
|
217
|
+
for (let i = state.currentIndex; i > targetIndex; --i) {
|
|
218
|
+
results.push({
|
|
219
|
+
migrationName: state.migrations[i].name,
|
|
220
|
+
direction: 'Down',
|
|
221
|
+
status: 'NotExecuted',
|
|
222
|
+
});
|
|
100
223
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
224
|
+
for (let i = 0; i < results.length; ++i) {
|
|
225
|
+
const migration = state.migrations.find((it) => it.name === results[i].migrationName);
|
|
226
|
+
try {
|
|
227
|
+
if (migration.down) {
|
|
228
|
+
await migration.down(db);
|
|
229
|
+
await db
|
|
230
|
+
.deleteFrom(exports.MIGRATION_TABLE)
|
|
231
|
+
.where('name', '=', migration.name)
|
|
232
|
+
.execute();
|
|
233
|
+
results[i] = {
|
|
234
|
+
migrationName: migration.name,
|
|
235
|
+
direction: 'Down',
|
|
236
|
+
status: 'Success',
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
results[i] = {
|
|
242
|
+
migrationName: migration.name,
|
|
243
|
+
direction: 'Down',
|
|
244
|
+
status: 'Error',
|
|
245
|
+
};
|
|
246
|
+
throw new MigrationResultSetError({
|
|
247
|
+
error,
|
|
248
|
+
results,
|
|
249
|
+
});
|
|
104
250
|
}
|
|
105
251
|
}
|
|
252
|
+
return { results };
|
|
106
253
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
254
|
+
async #migrateUp(db, state, targetIndex) {
|
|
255
|
+
const results = [];
|
|
256
|
+
for (let i = state.currentIndex + 1; i <= targetIndex; ++i) {
|
|
257
|
+
results.push({
|
|
258
|
+
migrationName: state.migrations[i].name,
|
|
259
|
+
direction: 'Up',
|
|
260
|
+
status: 'NotExecuted',
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
for (let i = 0; i < results.length; ++i) {
|
|
264
|
+
const migration = state.migrations.find((it) => it.name === results[i].migrationName);
|
|
265
|
+
try {
|
|
266
|
+
await migration.up(db);
|
|
267
|
+
await db
|
|
268
|
+
.insertInto(exports.MIGRATION_TABLE)
|
|
269
|
+
.values({
|
|
270
|
+
name: migration.name,
|
|
271
|
+
timestamp: new Date().toISOString(),
|
|
272
|
+
})
|
|
273
|
+
.execute();
|
|
274
|
+
results[i] = {
|
|
275
|
+
migrationName: migration.name,
|
|
276
|
+
direction: 'Up',
|
|
277
|
+
status: 'Success',
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
results[i] = {
|
|
282
|
+
migrationName: migration.name,
|
|
283
|
+
direction: 'Up',
|
|
284
|
+
status: 'Error',
|
|
285
|
+
};
|
|
286
|
+
throw new MigrationResultSetError({
|
|
287
|
+
error,
|
|
288
|
+
results,
|
|
289
|
+
});
|
|
131
290
|
}
|
|
132
291
|
}
|
|
133
|
-
|
|
134
|
-
return migrations;
|
|
135
|
-
}
|
|
136
|
-
async function runNewMigrations(db, allMigrations) {
|
|
137
|
-
const sortedMigrations = Object.keys(allMigrations)
|
|
138
|
-
.sort()
|
|
139
|
-
.map((name) => ({
|
|
140
|
-
...allMigrations[name],
|
|
141
|
-
name,
|
|
142
|
-
}));
|
|
143
|
-
const executedMigrations = await db
|
|
144
|
-
.selectFrom(exports.MIGRATION_TABLE)
|
|
145
|
-
.select('name')
|
|
146
|
-
.orderBy('name')
|
|
147
|
-
.execute();
|
|
148
|
-
const lastExecuted = (0, object_utils_js_1.getLast)(executedMigrations);
|
|
149
|
-
const lastExecutedIndex = sortedMigrations.findIndex((it) => it.name === lastExecuted?.name);
|
|
150
|
-
if (lastExecuted && lastExecutedIndex === -1) {
|
|
151
|
-
throw new Error(`corrupted migrations: previously executed migration ${lastExecuted.name} is missing`);
|
|
152
|
-
}
|
|
153
|
-
const oldMigrations = lastExecuted
|
|
154
|
-
? sortedMigrations.slice(0, lastExecutedIndex + 1)
|
|
155
|
-
: [];
|
|
156
|
-
const newMigrations = lastExecuted
|
|
157
|
-
? sortedMigrations.slice(lastExecutedIndex + 1)
|
|
158
|
-
: sortedMigrations;
|
|
159
|
-
ensureMigrationsAreNotCorrupted(executedMigrations.map((it) => it.name), oldMigrations.map((it) => it.name));
|
|
160
|
-
for (const migration of newMigrations) {
|
|
161
|
-
await migration.up(db);
|
|
162
|
-
await db
|
|
163
|
-
.insertInto(exports.MIGRATION_TABLE)
|
|
164
|
-
.values({
|
|
165
|
-
name: migration.name,
|
|
166
|
-
timestamp: new Date().toISOString(),
|
|
167
|
-
})
|
|
168
|
-
.execute();
|
|
292
|
+
return { results };
|
|
169
293
|
}
|
|
170
294
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
295
|
+
exports.MigrationModule = MigrationModule;
|
|
296
|
+
class MigrationResultSetError extends Error {
|
|
297
|
+
#resultSet;
|
|
298
|
+
constructor(result) {
|
|
299
|
+
super();
|
|
300
|
+
this.#resultSet = result;
|
|
178
301
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
throw new Error(`corrupted migrations: new migration ${it} comes alphabetically before the last executed migration. New migrations must always have a name that comes alphabetically after the last executed migration.`);
|
|
182
|
-
}
|
|
302
|
+
get resultSet() {
|
|
303
|
+
return this.#resultSet;
|
|
183
304
|
}
|
|
184
305
|
}
|
|
185
306
|
function isMigration(obj) {
|
|
@@ -11,5 +11,5 @@ export interface CheckConstraintNode extends OperationNode {
|
|
|
11
11
|
*/
|
|
12
12
|
export declare const CheckConstraintNode: Readonly<{
|
|
13
13
|
is(node: OperationNode): node is CheckConstraintNode;
|
|
14
|
-
create(
|
|
14
|
+
create(expression: RawNode, constraintName?: string | undefined): CheckConstraintNode;
|
|
15
15
|
}>;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CheckConstraintNode = void 0;
|
|
4
4
|
const object_utils_js_1 = require("../util/object-utils.js");
|
|
5
|
-
const raw_node_js_1 = require("./raw-node.js");
|
|
6
5
|
const identifier_node_js_1 = require("./identifier-node.js");
|
|
7
6
|
/**
|
|
8
7
|
* @internal
|
|
@@ -11,10 +10,10 @@ exports.CheckConstraintNode = (0, object_utils_js_1.freeze)({
|
|
|
11
10
|
is(node) {
|
|
12
11
|
return node.kind === 'CheckConstraintNode';
|
|
13
12
|
},
|
|
14
|
-
create(
|
|
13
|
+
create(expression, constraintName) {
|
|
15
14
|
return (0, object_utils_js_1.freeze)({
|
|
16
15
|
kind: 'CheckConstraintNode',
|
|
17
|
-
expression
|
|
16
|
+
expression,
|
|
18
17
|
name: constraintName ? identifier_node_js_1.IdentifierNode.create(constraintName) : undefined,
|
|
19
18
|
});
|
|
20
19
|
},
|
|
@@ -2,24 +2,25 @@ import { CheckConstraintNode } from './check-constraint-node.js';
|
|
|
2
2
|
import { ColumnNode } from './column-node.js';
|
|
3
3
|
import { DataTypeNode } from './data-type-node.js';
|
|
4
4
|
import { DefaultValueNode } from './default-value-node.js';
|
|
5
|
-
import {
|
|
5
|
+
import { GeneratedNode } from './generated-node.js';
|
|
6
6
|
import { OperationNode } from './operation-node.js';
|
|
7
7
|
import { RawNode } from './raw-node.js';
|
|
8
8
|
import { ReferencesNode } from './references-node.js';
|
|
9
|
-
export declare type ColumnDefinitionNodeProps = Omit<Partial<ColumnDefinitionNode>, 'kind'>;
|
|
9
|
+
export declare type ColumnDefinitionNodeProps = Omit<Partial<ColumnDefinitionNode>, 'kind' | 'dataType'>;
|
|
10
10
|
export declare type ColumnDataTypeNode = DataTypeNode | RawNode;
|
|
11
11
|
export interface ColumnDefinitionNode extends OperationNode {
|
|
12
12
|
readonly kind: 'ColumnDefinitionNode';
|
|
13
13
|
readonly column: ColumnNode;
|
|
14
14
|
readonly dataType: ColumnDataTypeNode;
|
|
15
15
|
readonly references?: ReferencesNode;
|
|
16
|
-
readonly primaryKey
|
|
17
|
-
readonly autoIncrement
|
|
18
|
-
readonly unique
|
|
19
|
-
readonly
|
|
16
|
+
readonly primaryKey?: boolean;
|
|
17
|
+
readonly autoIncrement?: boolean;
|
|
18
|
+
readonly unique?: boolean;
|
|
19
|
+
readonly notNull?: boolean;
|
|
20
20
|
readonly defaultTo?: DefaultValueNode;
|
|
21
21
|
readonly check?: CheckConstraintNode;
|
|
22
|
-
readonly
|
|
22
|
+
readonly generated?: GeneratedNode;
|
|
23
|
+
readonly unsigned?: boolean;
|
|
23
24
|
}
|
|
24
25
|
/**
|
|
25
26
|
* @internal
|
|
@@ -15,10 +15,6 @@ exports.ColumnDefinitionNode = (0, object_utils_js_1.freeze)({
|
|
|
15
15
|
kind: 'ColumnDefinitionNode',
|
|
16
16
|
column: column_node_js_1.ColumnNode.create(column),
|
|
17
17
|
dataType,
|
|
18
|
-
primaryKey: false,
|
|
19
|
-
autoIncrement: false,
|
|
20
|
-
unique: false,
|
|
21
|
-
nullable: true,
|
|
22
18
|
});
|
|
23
19
|
},
|
|
24
20
|
cloneWith(node, props) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ColumnNode } from './column-node.js';
|
|
2
|
+
import { OperationNode } from './operation-node.js';
|
|
3
|
+
import { TableNode } from './table-node.js';
|
|
4
|
+
export interface CommonTableExpressionNameNode extends OperationNode {
|
|
5
|
+
readonly kind: 'CommonTableExpressionNameNode';
|
|
6
|
+
readonly table: TableNode;
|
|
7
|
+
readonly columns?: ReadonlyArray<ColumnNode>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const CommonTableExpressionNameNode: Readonly<{
|
|
13
|
+
is(node: OperationNode): node is CommonTableExpressionNameNode;
|
|
14
|
+
create(tableName: string, columnNames?: readonly string[] | undefined): CommonTableExpressionNameNode;
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CommonTableExpressionNameNode = void 0;
|
|
4
|
+
const object_utils_js_1 = require("../util/object-utils.js");
|
|
5
|
+
const column_node_js_1 = require("./column-node.js");
|
|
6
|
+
const table_node_js_1 = require("./table-node.js");
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
exports.CommonTableExpressionNameNode = (0, object_utils_js_1.freeze)({
|
|
11
|
+
is(node) {
|
|
12
|
+
return node.kind === 'CommonTableExpressionNameNode';
|
|
13
|
+
},
|
|
14
|
+
create(tableName, columnNames) {
|
|
15
|
+
return (0, object_utils_js_1.freeze)({
|
|
16
|
+
kind: 'CommonTableExpressionNameNode',
|
|
17
|
+
table: table_node_js_1.TableNode.create(tableName),
|
|
18
|
+
columns: columnNames
|
|
19
|
+
? (0, object_utils_js_1.freeze)(columnNames.map(column_node_js_1.ColumnNode.create))
|
|
20
|
+
: undefined,
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommonTableExpressionNameNode } from './common-table-expression-name-node.js';
|
|
2
2
|
import { OperationNode } from './operation-node.js';
|
|
3
3
|
import { QueryNode } from './query-node.js';
|
|
4
4
|
import { RawNode } from './raw-node.js';
|
|
5
5
|
export interface CommonTableExpressionNode extends OperationNode {
|
|
6
6
|
readonly kind: 'CommonTableExpressionNode';
|
|
7
|
-
readonly name:
|
|
7
|
+
readonly name: CommonTableExpressionNameNode;
|
|
8
8
|
readonly expression: QueryNode | RawNode;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
@@ -12,5 +12,5 @@ export interface CommonTableExpressionNode extends OperationNode {
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const CommonTableExpressionNode: Readonly<{
|
|
14
14
|
is(node: OperationNode): node is CommonTableExpressionNode;
|
|
15
|
-
create(name:
|
|
15
|
+
create(name: CommonTableExpressionNameNode, expression: QueryNode | RawNode): CommonTableExpressionNode;
|
|
16
16
|
}>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OperationNode } from './operation-node.js';
|
|
2
|
-
export declare type ColumnDataType = 'varchar' | `varchar(${number})` | 'text' | 'integer' | 'int2' | 'int4' | 'int8' | 'bigint' | 'boolean' | 'real' | 'double precision' | 'float4' | 'float8' | 'decimal' | `decimal(${number}, ${number})` | 'numeric' | `numeric(${number}, ${number})` | 'binary' | 'date' | 'datetime' | 'time' | 'timetz' | 'timestamp' | 'timestamptz' | 'serial' | 'bigserial' | 'uuid' | 'json' | 'jsonb';
|
|
2
|
+
export declare type ColumnDataType = 'varchar' | `varchar(${number})` | 'text' | 'integer' | 'int2' | 'int4' | 'int8' | 'bigint' | 'boolean' | 'real' | 'double precision' | 'float4' | 'float8' | 'decimal' | `decimal(${number}, ${number})` | 'numeric' | `numeric(${number}, ${number})` | 'binary' | 'date' | 'datetime' | 'time' | 'timetz' | 'timestamp' | 'timestamptz' | 'serial' | 'bigserial' | 'uuid' | 'json' | 'jsonb' | 'blob';
|
|
3
3
|
export declare type DataTypeParams = Omit<DataTypeNode, 'kind' | 'dataType'>;
|
|
4
4
|
export interface DataTypeNode extends OperationNode {
|
|
5
5
|
readonly kind: 'DataTypeNode';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { OperationNode } from './operation-node.js';
|
|
2
|
+
import { RawNode } from './raw-node.js';
|
|
3
|
+
export declare type GeneratedNodeParams = Omit<GeneratedNode, 'kind' | 'expression'>;
|
|
4
|
+
export interface GeneratedNode extends OperationNode {
|
|
5
|
+
readonly kind: 'GeneratedNode';
|
|
6
|
+
readonly byDefault?: boolean;
|
|
7
|
+
readonly always?: boolean;
|
|
8
|
+
readonly identity?: boolean;
|
|
9
|
+
readonly stored?: boolean;
|
|
10
|
+
readonly expression?: RawNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare const GeneratedNode: Readonly<{
|
|
16
|
+
is(node: OperationNode): node is GeneratedNode;
|
|
17
|
+
create(params: GeneratedNodeParams): GeneratedNode;
|
|
18
|
+
createWithExpression(expression: RawNode): GeneratedNode;
|
|
19
|
+
cloneWith(node: GeneratedNode, params: GeneratedNodeParams): GeneratedNode;
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GeneratedNode = void 0;
|
|
4
|
+
const object_utils_js_1 = require("../util/object-utils.js");
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
exports.GeneratedNode = (0, object_utils_js_1.freeze)({
|
|
9
|
+
is(node) {
|
|
10
|
+
return node.kind === 'GeneratedNode';
|
|
11
|
+
},
|
|
12
|
+
create(params) {
|
|
13
|
+
return (0, object_utils_js_1.freeze)({
|
|
14
|
+
kind: 'GeneratedNode',
|
|
15
|
+
...params,
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
createWithExpression(expression) {
|
|
19
|
+
return (0, object_utils_js_1.freeze)({
|
|
20
|
+
kind: 'GeneratedNode',
|
|
21
|
+
always: true,
|
|
22
|
+
expression,
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
cloneWith(node, params) {
|
|
26
|
+
return (0, object_utils_js_1.freeze)({
|
|
27
|
+
...node,
|
|
28
|
+
...params,
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
});
|