kysely 0.12.2 → 0.13.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/dialect/mysql/mysql-adapter.d.ts +2 -2
- package/dist/cjs/dialect/mysql/mysql-adapter.js +2 -1
- package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +2 -2
- package/dist/cjs/dialect/postgres/postgres-adapter.js +2 -1
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +2 -2
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/migration/migration.d.ts +154 -11
- package/dist/cjs/migration/migration.js +256 -135
- package/dist/cjs/operation-node/column-definition-node.d.ts +6 -5
- package/dist/cjs/operation-node/column-definition-node.js +0 -4
- package/dist/cjs/operation-node/operation-node-transformer.js +2 -1
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +2 -2
- package/dist/cjs/query-compiler/default-query-compiler.js +4 -1
- package/dist/cjs/schema/alter-table-builder.d.ts +12 -0
- package/dist/cjs/schema/alter-table-builder.js +12 -0
- package/dist/cjs/schema/column-definition-builder.d.ts +12 -0
- package/dist/cjs/schema/column-definition-builder.js +4 -1
- package/dist/esm/dialect/mysql/mysql-adapter.d.ts +2 -2
- package/dist/esm/dialect/mysql/mysql-adapter.js +2 -1
- package/dist/esm/dialect/postgres/postgres-adapter.d.ts +2 -2
- package/dist/esm/dialect/postgres/postgres-adapter.js +2 -1
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +2 -2
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/migration/migration.d.ts +154 -11
- package/dist/esm/migration/migration.js +255 -134
- package/dist/esm/operation-node/column-definition-node.d.ts +6 -5
- package/dist/esm/operation-node/column-definition-node.js +0 -4
- package/dist/esm/operation-node/operation-node-transformer.js +2 -1
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +2 -2
- package/dist/esm/query-compiler/default-query-compiler.js +4 -1
- package/dist/esm/schema/alter-table-builder.d.ts +12 -0
- package/dist/esm/schema/alter-table-builder.js +12 -0
- package/dist/esm/schema/column-definition-builder.d.ts +12 -0
- package/dist/esm/schema/column-definition-builder.js +4 -1
- package/package.json +1 -1
|
@@ -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) {
|
|
@@ -6,20 +6,21 @@ import { GeneratedAlwaysAsNode } from './generated-always-as-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
22
|
readonly generatedAlwaysAs?: GeneratedAlwaysAsNode;
|
|
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) {
|
|
@@ -284,7 +284,8 @@ class OperationNodeTransformer {
|
|
|
284
284
|
primaryKey: node.primaryKey,
|
|
285
285
|
autoIncrement: node.autoIncrement,
|
|
286
286
|
unique: node.unique,
|
|
287
|
-
|
|
287
|
+
notNull: node.notNull,
|
|
288
|
+
unsigned: node.unsigned,
|
|
288
289
|
defaultTo: this.transformNode(node.defaultTo),
|
|
289
290
|
check: this.transformNode(node.check),
|
|
290
291
|
generatedAlwaysAs: this.transformNode(node.generatedAlwaysAs),
|
|
@@ -12,8 +12,8 @@ export interface CamelCasePluginOptions {
|
|
|
12
12
|
upperCase?: boolean;
|
|
13
13
|
/**
|
|
14
14
|
* If true, an underscore is added before each digit when converting
|
|
15
|
-
* camelCase to snake_case. For example `
|
|
16
|
-
* `
|
|
15
|
+
* camelCase to snake_case. For example `foo12Bar => foo_12_bar` and
|
|
16
|
+
* `foo_12_bar => foo12Bar`
|
|
17
17
|
*
|
|
18
18
|
* Defaults to false.
|
|
19
19
|
*/
|
|
@@ -324,6 +324,9 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
324
324
|
this.visitNode(node.column);
|
|
325
325
|
this.append(' ');
|
|
326
326
|
this.visitNode(node.dataType);
|
|
327
|
+
if (node.unsigned) {
|
|
328
|
+
this.append(' unsigned');
|
|
329
|
+
}
|
|
327
330
|
if (node.generatedAlwaysAs) {
|
|
328
331
|
this.append(' ');
|
|
329
332
|
this.visitNode(node.generatedAlwaysAs);
|
|
@@ -332,7 +335,7 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
|
|
|
332
335
|
this.append(' ');
|
|
333
336
|
this.visitNode(node.defaultTo);
|
|
334
337
|
}
|
|
335
|
-
if (
|
|
338
|
+
if (node.notNull) {
|
|
336
339
|
this.append(' not null');
|
|
337
340
|
}
|
|
338
341
|
if (node.unique) {
|
|
@@ -124,6 +124,12 @@ export declare class AlterTableAddColumnBuilder implements ColumnDefinitionBuild
|
|
|
124
124
|
* Adds a `not null` constraint for the column.
|
|
125
125
|
*/
|
|
126
126
|
notNull(): AlterTableAddColumnBuilder;
|
|
127
|
+
/**
|
|
128
|
+
* Adds a `unsigned` modifier for the column.
|
|
129
|
+
*
|
|
130
|
+
* This only works on some dialects like MySQL.
|
|
131
|
+
*/
|
|
132
|
+
unsigned(): AlterTableAddColumnBuilder;
|
|
127
133
|
/**
|
|
128
134
|
* Adds a default value constraint for the column.
|
|
129
135
|
*
|
|
@@ -253,6 +259,12 @@ export declare class AlterTableModifyColumnBuilder implements ColumnDefinitionBu
|
|
|
253
259
|
* Adds a `not null` constraint for the column.
|
|
254
260
|
*/
|
|
255
261
|
notNull(): AlterTableModifyColumnBuilder;
|
|
262
|
+
/**
|
|
263
|
+
* Adds a `unsigned` modifier for the column.
|
|
264
|
+
*
|
|
265
|
+
* This only works on some dialects like MySQL.
|
|
266
|
+
*/
|
|
267
|
+
unsigned(): AlterTableModifyColumnBuilder;
|
|
256
268
|
/**
|
|
257
269
|
* Adds a default value constraint for the column.
|
|
258
270
|
*
|
|
@@ -232,6 +232,12 @@ class AlterTableAddColumnBuilder {
|
|
|
232
232
|
columnBuilder: this.#props.columnBuilder.notNull(),
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
|
+
unsigned() {
|
|
236
|
+
return new AlterTableAddColumnBuilder({
|
|
237
|
+
...this.#props,
|
|
238
|
+
columnBuilder: this.#props.columnBuilder.unsigned(),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
235
241
|
defaultTo(value) {
|
|
236
242
|
return new AlterTableAddColumnBuilder({
|
|
237
243
|
...this.#props,
|
|
@@ -316,6 +322,12 @@ class AlterTableModifyColumnBuilder {
|
|
|
316
322
|
columnBuilder: this.#props.columnBuilder.notNull(),
|
|
317
323
|
});
|
|
318
324
|
}
|
|
325
|
+
unsigned() {
|
|
326
|
+
return new AlterTableModifyColumnBuilder({
|
|
327
|
+
...this.#props,
|
|
328
|
+
columnBuilder: this.#props.columnBuilder.unsigned(),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
319
331
|
defaultTo(value) {
|
|
320
332
|
return new AlterTableModifyColumnBuilder({
|
|
321
333
|
...this.#props,
|
|
@@ -66,6 +66,12 @@ export interface ColumnDefinitionBuilderInterface {
|
|
|
66
66
|
* Adds a `not null` constraint for the column.
|
|
67
67
|
*/
|
|
68
68
|
notNull(): ColumnDefinitionBuilderInterface;
|
|
69
|
+
/**
|
|
70
|
+
* Adds a `unsigned` modifier for the column.
|
|
71
|
+
*
|
|
72
|
+
* This only works on some dialects like MySQL.
|
|
73
|
+
*/
|
|
74
|
+
unsigned(): ColumnDefinitionBuilderInterface;
|
|
69
75
|
/**
|
|
70
76
|
* Adds a default value constraint for the column.
|
|
71
77
|
*
|
|
@@ -189,6 +195,12 @@ export declare class ColumnDefinitionBuilder implements ColumnDefinitionBuilderI
|
|
|
189
195
|
* Adds a `not null` constraint for the column.
|
|
190
196
|
*/
|
|
191
197
|
notNull(): ColumnDefinitionBuilder;
|
|
198
|
+
/**
|
|
199
|
+
* Adds a `unsigned` modifier for the column.
|
|
200
|
+
*
|
|
201
|
+
* This only works on some dialects like MySQL.
|
|
202
|
+
*/
|
|
203
|
+
unsigned(): ColumnDefinitionBuilder;
|
|
192
204
|
/**
|
|
193
205
|
* Adds a default value constraint for the column.
|
|
194
206
|
*
|
|
@@ -53,7 +53,10 @@ class ColumnDefinitionBuilder {
|
|
|
53
53
|
return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { unique: true }));
|
|
54
54
|
}
|
|
55
55
|
notNull() {
|
|
56
|
-
return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, {
|
|
56
|
+
return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { notNull: true }));
|
|
57
|
+
}
|
|
58
|
+
unsigned() {
|
|
59
|
+
return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { unsigned: true }));
|
|
57
60
|
}
|
|
58
61
|
defaultTo(value) {
|
|
59
62
|
return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Kysely } from '../../kysely.js';
|
|
2
|
-
import {
|
|
3
|
-
export declare class MysqlAdapter
|
|
2
|
+
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
3
|
+
export declare class MysqlAdapter extends DialectAdapterBase {
|
|
4
4
|
/**
|
|
5
5
|
* Whether or not this dialect supports transactional DDL.
|
|
6
6
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
1
2
|
const LOCK_ID = 'ea586330-2c93-47c8-908d-981d9d270f9d';
|
|
2
3
|
const LOCK_TIMEOUT_SECONDS = 60 * 60;
|
|
3
|
-
export class MysqlAdapter {
|
|
4
|
+
export class MysqlAdapter extends DialectAdapterBase {
|
|
4
5
|
get supportsTransactionalDdl() {
|
|
5
6
|
return false;
|
|
6
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Kysely } from '../../kysely.js';
|
|
2
|
-
import {
|
|
3
|
-
export declare class PostgresAdapter
|
|
2
|
+
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
3
|
+
export declare class PostgresAdapter extends DialectAdapterBase {
|
|
4
4
|
/**
|
|
5
5
|
* Whether or not this dialect supports transactional DDL.
|
|
6
6
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
|
1
2
|
// Random id for our transaction lock.
|
|
2
3
|
const LOCK_ID = '3853314791062309107';
|
|
3
|
-
export class PostgresAdapter {
|
|
4
|
+
export class PostgresAdapter extends DialectAdapterBase {
|
|
4
5
|
get supportsTransactionalDdl() {
|
|
5
6
|
return true;
|
|
6
7
|
}
|