kysely 0.12.2 → 0.15.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 +115 -31
- 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.d.ts +1 -1
- 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/mysql/mysql-dialect.d.ts +1 -1
- package/dist/cjs/dialect/mysql/mysql-introspector.d.ts +1 -1
- package/dist/cjs/dialect/mysql/mysql-introspector.js +3 -3
- 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/postgres/postgres-dialect.d.ts +1 -1
- package/dist/cjs/dialect/postgres/postgres-introspector.d.ts +1 -1
- package/dist/cjs/dialect/postgres/postgres-introspector.js +3 -3
- package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-dialect.d.ts +1 -1
- package/dist/cjs/dialect/sqlite/sqlite-introspector.d.ts +1 -1
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +3 -3
- package/dist/cjs/index.d.ts +7 -4
- package/dist/cjs/index.js +6 -3
- package/dist/cjs/kysely.d.ts +8 -40
- package/dist/cjs/kysely.js +8 -40
- package/dist/cjs/migration/file-migration-provider.d.ts +52 -0
- package/dist/cjs/migration/file-migration-provider.js +52 -0
- package/dist/cjs/migration/migrator.d.ts +234 -0
- package/dist/cjs/migration/migrator.js +417 -0
- 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/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 +2 -2
- package/dist/cjs/operation-node/operation-node-transformer.js +13 -6
- package/dist/cjs/operation-node/operation-node-visitor.d.ts +2 -2
- package/dist/cjs/operation-node/operation-node-visitor.js +1 -1
- package/dist/cjs/operation-node/operation-node.d.ts +1 -1
- package/dist/cjs/parser/insert-values-parser.d.ts +4 -4
- package/dist/cjs/parser/insert-values-parser.js +2 -3
- package/dist/cjs/parser/reference-parser.d.ts +4 -3
- package/dist/cjs/parser/select-parser.d.ts +10 -4
- package/dist/cjs/parser/update-set-parser.d.ts +2 -1
- package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +2 -2
- package/dist/cjs/query-builder/delete-query-builder.d.ts +0 -3
- package/dist/cjs/query-builder/insert-query-builder.d.ts +78 -94
- package/dist/cjs/query-builder/insert-query-builder.js +145 -15
- package/dist/cjs/query-builder/on-conflict-builder.d.ts +686 -0
- package/dist/cjs/query-builder/on-conflict-builder.js +323 -0
- package/dist/cjs/query-builder/returning-interface.d.ts +0 -3
- package/dist/cjs/query-builder/update-query-builder.d.ts +0 -3
- package/dist/cjs/query-compiler/default-query-compiler.d.ts +2 -2
- package/dist/cjs/query-compiler/default-query-compiler.js +37 -8
- package/dist/cjs/query-creator.d.ts +0 -2
- package/dist/cjs/query-creator.js +0 -2
- package/dist/cjs/schema/alter-table-builder.d.ts +41 -9
- package/dist/cjs/schema/alter-table-builder.js +45 -9
- package/dist/cjs/schema/column-definition-builder.d.ts +40 -8
- 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/cjs/util/column-type.d.ts +165 -0
- package/dist/cjs/util/column-type.js +2 -0
- package/dist/cjs/util/private-symbols.d.ts +5 -0
- package/dist/cjs/util/private-symbols.js +8 -0
- package/dist/cjs/util/type-utils.d.ts +6 -42
- 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.d.ts +1 -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/mysql/mysql-dialect.d.ts +1 -1
- package/dist/esm/dialect/mysql/mysql-introspector.d.ts +1 -1
- package/dist/esm/dialect/mysql/mysql-introspector.js +1 -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/postgres/postgres-dialect.d.ts +1 -1
- package/dist/esm/dialect/postgres/postgres-introspector.d.ts +1 -1
- package/dist/esm/dialect/postgres/postgres-introspector.js +1 -1
- package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +2 -2
- package/dist/esm/dialect/sqlite/sqlite-dialect.d.ts +1 -1
- package/dist/esm/dialect/sqlite/sqlite-introspector.d.ts +1 -1
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +1 -1
- package/dist/esm/index.d.ts +7 -4
- package/dist/esm/index.js +6 -3
- package/dist/esm/kysely.d.ts +8 -40
- package/dist/esm/kysely.js +8 -40
- package/dist/esm/migration/file-migration-provider.d.ts +52 -0
- package/dist/esm/migration/file-migration-provider.js +48 -0
- package/dist/esm/migration/migrator.d.ts +234 -0
- package/dist/esm/migration/migrator.js +413 -0
- 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/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 +2 -2
- package/dist/esm/operation-node/operation-node-transformer.js +13 -6
- package/dist/esm/operation-node/operation-node-visitor.d.ts +2 -2
- package/dist/esm/operation-node/operation-node-visitor.js +1 -1
- package/dist/esm/operation-node/operation-node.d.ts +1 -1
- package/dist/esm/parser/insert-values-parser.d.ts +4 -4
- package/dist/esm/parser/insert-values-parser.js +2 -3
- package/dist/esm/parser/reference-parser.d.ts +4 -3
- package/dist/esm/parser/select-parser.d.ts +10 -4
- package/dist/esm/parser/update-set-parser.d.ts +2 -1
- package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +2 -2
- package/dist/esm/query-builder/delete-query-builder.d.ts +0 -3
- package/dist/esm/query-builder/insert-query-builder.d.ts +78 -94
- package/dist/esm/query-builder/insert-query-builder.js +145 -15
- package/dist/esm/query-builder/on-conflict-builder.d.ts +686 -0
- package/dist/esm/query-builder/on-conflict-builder.js +317 -0
- package/dist/esm/query-builder/returning-interface.d.ts +0 -3
- package/dist/esm/query-builder/update-query-builder.d.ts +0 -3
- package/dist/esm/query-compiler/default-query-compiler.d.ts +2 -2
- package/dist/esm/query-compiler/default-query-compiler.js +37 -8
- package/dist/esm/query-creator.d.ts +0 -2
- package/dist/esm/query-creator.js +0 -2
- package/dist/esm/schema/alter-table-builder.d.ts +41 -9
- package/dist/esm/schema/alter-table-builder.js +45 -9
- package/dist/esm/schema/column-definition-builder.d.ts +40 -8
- 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/dist/esm/util/column-type.d.ts +165 -0
- package/dist/esm/util/column-type.js +1 -0
- package/dist/esm/util/private-symbols.d.ts +5 -0
- package/dist/esm/util/private-symbols.js +5 -0
- package/dist/esm/util/type-utils.d.ts +6 -42
- package/package.json +1 -1
- package/dist/cjs/migration/migration.d.ts +0 -66
- package/dist/cjs/migration/migration.js +0 -187
- 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/cjs/util/generated-placeholder.d.ts +0 -3
- package/dist/cjs/util/generated-placeholder.js +0 -11
- package/dist/esm/migration/migration.d.ts +0 -66
- package/dist/esm/migration/migration.js +0 -183
- 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
- package/dist/esm/util/generated-placeholder.d.ts +0 -3
- package/dist/esm/util/generated-placeholder.js +0 -7
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MigrationModule = exports.MIGRATION_LOCK_ID = exports.MIGRATION_LOCK_TABLE = exports.MIGRATION_TABLE = void 0;
|
|
4
|
-
const path = require("path");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const object_utils_js_1 = require("../util/object-utils.js");
|
|
7
|
-
exports.MIGRATION_TABLE = 'kysely_migration';
|
|
8
|
-
exports.MIGRATION_LOCK_TABLE = 'kysely_migration_lock';
|
|
9
|
-
exports.MIGRATION_LOCK_ID = 'migration_lock';
|
|
10
|
-
class MigrationModule {
|
|
11
|
-
#db;
|
|
12
|
-
#adapter;
|
|
13
|
-
constructor(db, adapter) {
|
|
14
|
-
this.#db = db;
|
|
15
|
-
this.#adapter = adapter;
|
|
16
|
-
}
|
|
17
|
-
async migrateToLatest(migrationsOrFolderPath) {
|
|
18
|
-
await ensureMigrationTablesExists(this.#db);
|
|
19
|
-
const allMigrations = await this.#getAllMigrations(migrationsOrFolderPath);
|
|
20
|
-
await this.#migrateToLatest(allMigrations);
|
|
21
|
-
}
|
|
22
|
-
async #getAllMigrations(migrationsOrFolderPath) {
|
|
23
|
-
return (0, object_utils_js_1.isString)(migrationsOrFolderPath)
|
|
24
|
-
? await readMigrationsFromFolder(migrationsOrFolderPath)
|
|
25
|
-
: migrationsOrFolderPath;
|
|
26
|
-
}
|
|
27
|
-
async #migrateToLatest(allMigrations) {
|
|
28
|
-
const run = async (db) => {
|
|
29
|
-
try {
|
|
30
|
-
await this.#adapter.acquireMigrationLock(db);
|
|
31
|
-
await runNewMigrations(db, allMigrations);
|
|
32
|
-
}
|
|
33
|
-
finally {
|
|
34
|
-
await this.#adapter.releaseMigrationLock(db);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
if (this.#adapter.supportsTransactionalDdl) {
|
|
38
|
-
await this.#db.transaction().execute(run);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
await this.#db.connection().execute(run);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
exports.MigrationModule = MigrationModule;
|
|
46
|
-
async function ensureMigrationTablesExists(db) {
|
|
47
|
-
await ensureMigrationTableExists(db);
|
|
48
|
-
await ensureMigrationLockTableExists(db);
|
|
49
|
-
await ensureLockRowExists(db);
|
|
50
|
-
}
|
|
51
|
-
async function ensureMigrationTableExists(db) {
|
|
52
|
-
if (!(await doesTableExists(db, exports.MIGRATION_TABLE))) {
|
|
53
|
-
try {
|
|
54
|
-
await db.schema
|
|
55
|
-
.createTable(exports.MIGRATION_TABLE)
|
|
56
|
-
.ifNotExists()
|
|
57
|
-
.addColumn('name', 'varchar(255)', (col) => col.notNull().primaryKey())
|
|
58
|
-
// The migration run time as ISO string. This is not a real date type as we
|
|
59
|
-
// can't know which data type is supported by all future dialects.
|
|
60
|
-
.addColumn('timestamp', 'varchar(255)', (col) => col.notNull())
|
|
61
|
-
.execute();
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
// At least on PostgreSQL, `if not exists` doesn't guarantee the `create table`
|
|
65
|
-
// query doesn't throw if the table already exits. That's why we check if
|
|
66
|
-
// the table exist here and ignore the error if it does.
|
|
67
|
-
if (!(await doesTableExists(db, exports.MIGRATION_TABLE))) {
|
|
68
|
-
throw error;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function ensureMigrationLockTableExists(db) {
|
|
74
|
-
if (!(await doesTableExists(db, exports.MIGRATION_LOCK_TABLE))) {
|
|
75
|
-
try {
|
|
76
|
-
await db.schema
|
|
77
|
-
.createTable(exports.MIGRATION_LOCK_TABLE)
|
|
78
|
-
.ifNotExists()
|
|
79
|
-
.addColumn('id', 'varchar(255)', (col) => col.notNull().primaryKey())
|
|
80
|
-
.addColumn('is_locked', 'integer', (col) => col.notNull().defaultTo(0))
|
|
81
|
-
.execute();
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
// At least on PostgreSQL, `if not exists` doesn't guarantee the `create table`
|
|
85
|
-
// query doesn't throw if the table already exits. That's why we check if
|
|
86
|
-
// the table exist here and ignore the error if it does.
|
|
87
|
-
if (!(await doesTableExists(db, exports.MIGRATION_LOCK_TABLE))) {
|
|
88
|
-
throw error;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
async function ensureLockRowExists(db) {
|
|
94
|
-
if (!(await doesLockRowExists(db))) {
|
|
95
|
-
try {
|
|
96
|
-
await db
|
|
97
|
-
.insertInto(exports.MIGRATION_LOCK_TABLE)
|
|
98
|
-
.values({ id: exports.MIGRATION_LOCK_ID })
|
|
99
|
-
.execute();
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
if (!(await doesLockRowExists(db))) {
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
async function doesTableExists(db, tableName) {
|
|
109
|
-
const metadata = await db.introspection.getMetadata({
|
|
110
|
-
withInternalKyselyTables: true,
|
|
111
|
-
});
|
|
112
|
-
return !!metadata.tables.find((it) => it.name === tableName);
|
|
113
|
-
}
|
|
114
|
-
async function doesLockRowExists(db) {
|
|
115
|
-
const lockRow = await db
|
|
116
|
-
.selectFrom(exports.MIGRATION_LOCK_TABLE)
|
|
117
|
-
.where('id', '=', exports.MIGRATION_LOCK_ID)
|
|
118
|
-
.select('id')
|
|
119
|
-
.executeTakeFirst();
|
|
120
|
-
return !!lockRow;
|
|
121
|
-
}
|
|
122
|
-
async function readMigrationsFromFolder(migrationsFolderPath) {
|
|
123
|
-
const files = await fs_1.promises.readdir(migrationsFolderPath);
|
|
124
|
-
const migrations = {};
|
|
125
|
-
for (const file of files) {
|
|
126
|
-
if ((file.endsWith('.js') || file.endsWith('.ts')) &&
|
|
127
|
-
!file.endsWith('.d.ts')) {
|
|
128
|
-
const migration = await Promise.resolve().then(() => require(path.join(migrationsFolderPath, file)));
|
|
129
|
-
if (isMigration(migration)) {
|
|
130
|
-
migrations[file.substring(0, file.length - 3)] = migration;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
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();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function ensureMigrationsAreNotCorrupted(executedMigrationNames, oldMigrationNames) {
|
|
172
|
-
const executedSet = new Set(executedMigrationNames);
|
|
173
|
-
const oldMigrationSet = new Set(oldMigrationNames);
|
|
174
|
-
for (const it of executedSet) {
|
|
175
|
-
if (!oldMigrationSet.has(it)) {
|
|
176
|
-
throw new Error(`corrupted migrations: previously executed migration ${it} is missing`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
for (const it of oldMigrationSet) {
|
|
180
|
-
if (!executedSet.has(it)) {
|
|
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
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
function isMigration(obj) {
|
|
186
|
-
return (0, object_utils_js_1.isObject)(obj) && (0, object_utils_js_1.isFunction)(obj.up);
|
|
187
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { OperationNode } from './operation-node.js';
|
|
2
|
-
import { RawNode } from './raw-node.js';
|
|
3
|
-
export declare type GeneratedAlwaysAsNodeParams = Omit<GeneratedAlwaysAsNode, 'kind' | 'expression'>;
|
|
4
|
-
export interface GeneratedAlwaysAsNode extends OperationNode {
|
|
5
|
-
readonly kind: 'GeneratedAlwaysAsNode';
|
|
6
|
-
readonly expression: RawNode;
|
|
7
|
-
readonly stored?: boolean;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
export declare const GeneratedAlwaysAsNode: Readonly<{
|
|
13
|
-
is(node: OperationNode): node is GeneratedAlwaysAsNode;
|
|
14
|
-
create(expression: string): GeneratedAlwaysAsNode;
|
|
15
|
-
cloneWith(node: GeneratedAlwaysAsNode, params: GeneratedAlwaysAsNodeParams): GeneratedAlwaysAsNode;
|
|
16
|
-
}>;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GeneratedAlwaysAsNode = void 0;
|
|
4
|
-
const object_utils_js_1 = require("../util/object-utils.js");
|
|
5
|
-
const raw_node_js_1 = require("./raw-node.js");
|
|
6
|
-
/**
|
|
7
|
-
* @internal
|
|
8
|
-
*/
|
|
9
|
-
exports.GeneratedAlwaysAsNode = (0, object_utils_js_1.freeze)({
|
|
10
|
-
is(node) {
|
|
11
|
-
return node.kind === 'GeneratedAlwaysAsNode';
|
|
12
|
-
},
|
|
13
|
-
create(expression) {
|
|
14
|
-
return (0, object_utils_js_1.freeze)({
|
|
15
|
-
kind: 'GeneratedAlwaysAsNode',
|
|
16
|
-
expression: raw_node_js_1.RawNode.createWithSql(expression),
|
|
17
|
-
});
|
|
18
|
-
},
|
|
19
|
-
cloneWith(node, params) {
|
|
20
|
-
return (0, object_utils_js_1.freeze)({
|
|
21
|
-
...node,
|
|
22
|
-
...params,
|
|
23
|
-
});
|
|
24
|
-
},
|
|
25
|
-
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { OnConflictNode } from '../operation-node/on-conflict-node.js';
|
|
2
|
-
import { AnyColumn } from '../util/type-utils.js';
|
|
3
|
-
import { ParseContext } from './parse-context.js';
|
|
4
|
-
import { MutationObject } from './update-set-parser.js';
|
|
5
|
-
export declare type OnConflictConstraintTarget = {
|
|
6
|
-
constraint: string;
|
|
7
|
-
};
|
|
8
|
-
export declare type OnConflictTargetExpression<DB, TB extends keyof DB> = AnyColumn<DB, TB> | ReadonlyArray<AnyColumn<DB, TB>> | OnConflictConstraintTarget;
|
|
9
|
-
export declare function parseOnConflictDoNothing(target: OnConflictTargetExpression<any, any>): OnConflictNode;
|
|
10
|
-
export declare function parseOnConflictUpdate(ctx: ParseContext, target: OnConflictTargetExpression<any, any>, updates: MutationObject<any, any>): OnConflictNode;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseOnConflictUpdate = exports.parseOnConflictDoNothing = void 0;
|
|
4
|
-
const identifier_node_js_1 = require("../operation-node/identifier-node.js");
|
|
5
|
-
const on_conflict_node_js_1 = require("../operation-node/on-conflict-node.js");
|
|
6
|
-
const object_utils_js_1 = require("../util/object-utils.js");
|
|
7
|
-
const reference_parser_js_1 = require("./reference-parser.js");
|
|
8
|
-
const update_set_parser_js_1 = require("./update-set-parser.js");
|
|
9
|
-
function parseOnConflictDoNothing(target) {
|
|
10
|
-
return on_conflict_node_js_1.OnConflictNode.create({
|
|
11
|
-
...parseConflictTarget(target),
|
|
12
|
-
doNothing: true,
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
exports.parseOnConflictDoNothing = parseOnConflictDoNothing;
|
|
16
|
-
function parseOnConflictUpdate(ctx, target, updates) {
|
|
17
|
-
return on_conflict_node_js_1.OnConflictNode.create({
|
|
18
|
-
...parseConflictTarget(target),
|
|
19
|
-
updates: (0, update_set_parser_js_1.parseUpdateObject)(ctx, updates),
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
exports.parseOnConflictUpdate = parseOnConflictUpdate;
|
|
23
|
-
function parseConflictTarget(target) {
|
|
24
|
-
if ((0, object_utils_js_1.isString)(target) || (0, object_utils_js_1.isReadonlyArray)(target)) {
|
|
25
|
-
return {
|
|
26
|
-
columns: (0, object_utils_js_1.asReadonlyArray)(target).map(reference_parser_js_1.parseColumnName),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
if ((0, object_utils_js_1.isObject)(target) && !(0, object_utils_js_1.isReadonlyArray)(target)) {
|
|
30
|
-
return {
|
|
31
|
-
constraint: identifier_node_js_1.IdentifierNode.create(target.constraint),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
throw new Error(`invalid on conflict target ${JSON.stringify(target)}`);
|
|
35
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isGeneratedPlaceholder = exports.GENERATED_PLACEHOLDER = void 0;
|
|
4
|
-
const object_utils_js_1 = require("./object-utils.js");
|
|
5
|
-
exports.GENERATED_PLACEHOLDER = (0, object_utils_js_1.freeze)({
|
|
6
|
-
__isGeneratedPlaceholder__: true,
|
|
7
|
-
});
|
|
8
|
-
function isGeneratedPlaceholder(obj) {
|
|
9
|
-
return (0, object_utils_js_1.isObject)(obj) && obj.__isGeneratedPlaceholder__ === true;
|
|
10
|
-
}
|
|
11
|
-
exports.isGeneratedPlaceholder = isGeneratedPlaceholder;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Kysely } from '../kysely.js';
|
|
2
|
-
import { DialectAdapter } from '../dialect/dialect-adapter.js';
|
|
3
|
-
export declare const MIGRATION_TABLE = "kysely_migration";
|
|
4
|
-
export declare const MIGRATION_LOCK_TABLE = "kysely_migration_lock";
|
|
5
|
-
export declare const MIGRATION_LOCK_ID = "migration_lock";
|
|
6
|
-
export declare class MigrationModule {
|
|
7
|
-
#private;
|
|
8
|
-
constructor(db: Kysely<any>, adapter: DialectAdapter);
|
|
9
|
-
/**
|
|
10
|
-
* Runs all migrations that have not yet been run.
|
|
11
|
-
*
|
|
12
|
-
* The only argument must either be a file path to the folder that contains all migrations
|
|
13
|
-
* OR an object that contains all migrations (not just the ones that need to be run).
|
|
14
|
-
* The keys in the object must be the unique migration names.
|
|
15
|
-
*
|
|
16
|
-
* This method goes through all possible migrations (passed as the argument) and runs the
|
|
17
|
-
* ones whose names are alphabetically after the last migration that has been run. If the
|
|
18
|
-
* list of executed migrations doesn't match the list of possible migrations, and error
|
|
19
|
-
* is thrown.
|
|
20
|
-
*
|
|
21
|
-
* ### Examples
|
|
22
|
-
*
|
|
23
|
-
* ```ts
|
|
24
|
-
* await db.migration.migrateToLatest(
|
|
25
|
-
* path.join(__dirname, 'migrations')
|
|
26
|
-
* )
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* In the next example, we use a record of migration objects instead of file folder path.
|
|
30
|
-
* The keys in the object are migration names that can be anything you want. The order of
|
|
31
|
-
* the migrations is determined based on the alphabetical order of the keys in the record.
|
|
32
|
-
* This can be useful if you are using a bundler like webpack or esbuild.
|
|
33
|
-
*
|
|
34
|
-
* ```ts
|
|
35
|
-
* await db.migration.migrateToLatest({
|
|
36
|
-
* migration1: {
|
|
37
|
-
* async up(db: Kysely<any>): Promise<void> {
|
|
38
|
-
* ...
|
|
39
|
-
* },
|
|
40
|
-
*
|
|
41
|
-
* async down(db: Kysely<any>): Promise<void> {
|
|
42
|
-
* ...
|
|
43
|
-
* }
|
|
44
|
-
* },
|
|
45
|
-
*
|
|
46
|
-
* migration2: {
|
|
47
|
-
* async up(db: Kysely<any>): Promise<void> {
|
|
48
|
-
* ...
|
|
49
|
-
* },
|
|
50
|
-
*
|
|
51
|
-
* async down(db: Kysely<any>): Promise<void> {
|
|
52
|
-
* ...
|
|
53
|
-
* }
|
|
54
|
-
* },
|
|
55
|
-
*
|
|
56
|
-
* ...
|
|
57
|
-
* })
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
migrateToLatest(migrationsFolderPath: string): Promise<void>;
|
|
61
|
-
migrateToLatest(allMigrations: Record<string, Migration>): Promise<void>;
|
|
62
|
-
}
|
|
63
|
-
export interface Migration {
|
|
64
|
-
up(db: Kysely<any>): Promise<void>;
|
|
65
|
-
down?(db: Kysely<any>): Promise<void>;
|
|
66
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import * as path from 'path';
|
|
2
|
-
import { promises as fs } from 'fs';
|
|
3
|
-
import { getLast, isFunction, isObject, isString, } from '../util/object-utils.js';
|
|
4
|
-
export const MIGRATION_TABLE = 'kysely_migration';
|
|
5
|
-
export const MIGRATION_LOCK_TABLE = 'kysely_migration_lock';
|
|
6
|
-
export const MIGRATION_LOCK_ID = 'migration_lock';
|
|
7
|
-
export class MigrationModule {
|
|
8
|
-
#db;
|
|
9
|
-
#adapter;
|
|
10
|
-
constructor(db, adapter) {
|
|
11
|
-
this.#db = db;
|
|
12
|
-
this.#adapter = adapter;
|
|
13
|
-
}
|
|
14
|
-
async migrateToLatest(migrationsOrFolderPath) {
|
|
15
|
-
await ensureMigrationTablesExists(this.#db);
|
|
16
|
-
const allMigrations = await this.#getAllMigrations(migrationsOrFolderPath);
|
|
17
|
-
await this.#migrateToLatest(allMigrations);
|
|
18
|
-
}
|
|
19
|
-
async #getAllMigrations(migrationsOrFolderPath) {
|
|
20
|
-
return isString(migrationsOrFolderPath)
|
|
21
|
-
? await readMigrationsFromFolder(migrationsOrFolderPath)
|
|
22
|
-
: migrationsOrFolderPath;
|
|
23
|
-
}
|
|
24
|
-
async #migrateToLatest(allMigrations) {
|
|
25
|
-
const run = async (db) => {
|
|
26
|
-
try {
|
|
27
|
-
await this.#adapter.acquireMigrationLock(db);
|
|
28
|
-
await runNewMigrations(db, allMigrations);
|
|
29
|
-
}
|
|
30
|
-
finally {
|
|
31
|
-
await this.#adapter.releaseMigrationLock(db);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
if (this.#adapter.supportsTransactionalDdl) {
|
|
35
|
-
await this.#db.transaction().execute(run);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
await this.#db.connection().execute(run);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
async function ensureMigrationTablesExists(db) {
|
|
43
|
-
await ensureMigrationTableExists(db);
|
|
44
|
-
await ensureMigrationLockTableExists(db);
|
|
45
|
-
await ensureLockRowExists(db);
|
|
46
|
-
}
|
|
47
|
-
async function ensureMigrationTableExists(db) {
|
|
48
|
-
if (!(await doesTableExists(db, MIGRATION_TABLE))) {
|
|
49
|
-
try {
|
|
50
|
-
await db.schema
|
|
51
|
-
.createTable(MIGRATION_TABLE)
|
|
52
|
-
.ifNotExists()
|
|
53
|
-
.addColumn('name', 'varchar(255)', (col) => col.notNull().primaryKey())
|
|
54
|
-
// The migration run time as ISO string. This is not a real date type as we
|
|
55
|
-
// can't know which data type is supported by all future dialects.
|
|
56
|
-
.addColumn('timestamp', 'varchar(255)', (col) => col.notNull())
|
|
57
|
-
.execute();
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
// At least on PostgreSQL, `if not exists` doesn't guarantee the `create table`
|
|
61
|
-
// query doesn't throw if the table already exits. That's why we check if
|
|
62
|
-
// the table exist here and ignore the error if it does.
|
|
63
|
-
if (!(await doesTableExists(db, MIGRATION_TABLE))) {
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
async function ensureMigrationLockTableExists(db) {
|
|
70
|
-
if (!(await doesTableExists(db, MIGRATION_LOCK_TABLE))) {
|
|
71
|
-
try {
|
|
72
|
-
await db.schema
|
|
73
|
-
.createTable(MIGRATION_LOCK_TABLE)
|
|
74
|
-
.ifNotExists()
|
|
75
|
-
.addColumn('id', 'varchar(255)', (col) => col.notNull().primaryKey())
|
|
76
|
-
.addColumn('is_locked', 'integer', (col) => col.notNull().defaultTo(0))
|
|
77
|
-
.execute();
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
// At least on PostgreSQL, `if not exists` doesn't guarantee the `create table`
|
|
81
|
-
// query doesn't throw if the table already exits. That's why we check if
|
|
82
|
-
// the table exist here and ignore the error if it does.
|
|
83
|
-
if (!(await doesTableExists(db, MIGRATION_LOCK_TABLE))) {
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
async function ensureLockRowExists(db) {
|
|
90
|
-
if (!(await doesLockRowExists(db))) {
|
|
91
|
-
try {
|
|
92
|
-
await db
|
|
93
|
-
.insertInto(MIGRATION_LOCK_TABLE)
|
|
94
|
-
.values({ id: MIGRATION_LOCK_ID })
|
|
95
|
-
.execute();
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
if (!(await doesLockRowExists(db))) {
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
async function doesTableExists(db, tableName) {
|
|
105
|
-
const metadata = await db.introspection.getMetadata({
|
|
106
|
-
withInternalKyselyTables: true,
|
|
107
|
-
});
|
|
108
|
-
return !!metadata.tables.find((it) => it.name === tableName);
|
|
109
|
-
}
|
|
110
|
-
async function doesLockRowExists(db) {
|
|
111
|
-
const lockRow = await db
|
|
112
|
-
.selectFrom(MIGRATION_LOCK_TABLE)
|
|
113
|
-
.where('id', '=', MIGRATION_LOCK_ID)
|
|
114
|
-
.select('id')
|
|
115
|
-
.executeTakeFirst();
|
|
116
|
-
return !!lockRow;
|
|
117
|
-
}
|
|
118
|
-
async function readMigrationsFromFolder(migrationsFolderPath) {
|
|
119
|
-
const files = await fs.readdir(migrationsFolderPath);
|
|
120
|
-
const migrations = {};
|
|
121
|
-
for (const file of files) {
|
|
122
|
-
if ((file.endsWith('.js') || file.endsWith('.ts')) &&
|
|
123
|
-
!file.endsWith('.d.ts')) {
|
|
124
|
-
const migration = await import(path.join(migrationsFolderPath, file));
|
|
125
|
-
if (isMigration(migration)) {
|
|
126
|
-
migrations[file.substring(0, file.length - 3)] = migration;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return migrations;
|
|
131
|
-
}
|
|
132
|
-
async function runNewMigrations(db, allMigrations) {
|
|
133
|
-
const sortedMigrations = Object.keys(allMigrations)
|
|
134
|
-
.sort()
|
|
135
|
-
.map((name) => ({
|
|
136
|
-
...allMigrations[name],
|
|
137
|
-
name,
|
|
138
|
-
}));
|
|
139
|
-
const executedMigrations = await db
|
|
140
|
-
.selectFrom(MIGRATION_TABLE)
|
|
141
|
-
.select('name')
|
|
142
|
-
.orderBy('name')
|
|
143
|
-
.execute();
|
|
144
|
-
const lastExecuted = getLast(executedMigrations);
|
|
145
|
-
const lastExecutedIndex = sortedMigrations.findIndex((it) => it.name === lastExecuted?.name);
|
|
146
|
-
if (lastExecuted && lastExecutedIndex === -1) {
|
|
147
|
-
throw new Error(`corrupted migrations: previously executed migration ${lastExecuted.name} is missing`);
|
|
148
|
-
}
|
|
149
|
-
const oldMigrations = lastExecuted
|
|
150
|
-
? sortedMigrations.slice(0, lastExecutedIndex + 1)
|
|
151
|
-
: [];
|
|
152
|
-
const newMigrations = lastExecuted
|
|
153
|
-
? sortedMigrations.slice(lastExecutedIndex + 1)
|
|
154
|
-
: sortedMigrations;
|
|
155
|
-
ensureMigrationsAreNotCorrupted(executedMigrations.map((it) => it.name), oldMigrations.map((it) => it.name));
|
|
156
|
-
for (const migration of newMigrations) {
|
|
157
|
-
await migration.up(db);
|
|
158
|
-
await db
|
|
159
|
-
.insertInto(MIGRATION_TABLE)
|
|
160
|
-
.values({
|
|
161
|
-
name: migration.name,
|
|
162
|
-
timestamp: new Date().toISOString(),
|
|
163
|
-
})
|
|
164
|
-
.execute();
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
function ensureMigrationsAreNotCorrupted(executedMigrationNames, oldMigrationNames) {
|
|
168
|
-
const executedSet = new Set(executedMigrationNames);
|
|
169
|
-
const oldMigrationSet = new Set(oldMigrationNames);
|
|
170
|
-
for (const it of executedSet) {
|
|
171
|
-
if (!oldMigrationSet.has(it)) {
|
|
172
|
-
throw new Error(`corrupted migrations: previously executed migration ${it} is missing`);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
for (const it of oldMigrationSet) {
|
|
176
|
-
if (!executedSet.has(it)) {
|
|
177
|
-
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.`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function isMigration(obj) {
|
|
182
|
-
return isObject(obj) && isFunction(obj.up);
|
|
183
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { OperationNode } from './operation-node.js';
|
|
2
|
-
import { RawNode } from './raw-node.js';
|
|
3
|
-
export declare type GeneratedAlwaysAsNodeParams = Omit<GeneratedAlwaysAsNode, 'kind' | 'expression'>;
|
|
4
|
-
export interface GeneratedAlwaysAsNode extends OperationNode {
|
|
5
|
-
readonly kind: 'GeneratedAlwaysAsNode';
|
|
6
|
-
readonly expression: RawNode;
|
|
7
|
-
readonly stored?: boolean;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
export declare const GeneratedAlwaysAsNode: Readonly<{
|
|
13
|
-
is(node: OperationNode): node is GeneratedAlwaysAsNode;
|
|
14
|
-
create(expression: string): GeneratedAlwaysAsNode;
|
|
15
|
-
cloneWith(node: GeneratedAlwaysAsNode, params: GeneratedAlwaysAsNodeParams): GeneratedAlwaysAsNode;
|
|
16
|
-
}>;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { freeze } from '../util/object-utils.js';
|
|
2
|
-
import { RawNode } from './raw-node.js';
|
|
3
|
-
/**
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
export const GeneratedAlwaysAsNode = freeze({
|
|
7
|
-
is(node) {
|
|
8
|
-
return node.kind === 'GeneratedAlwaysAsNode';
|
|
9
|
-
},
|
|
10
|
-
create(expression) {
|
|
11
|
-
return freeze({
|
|
12
|
-
kind: 'GeneratedAlwaysAsNode',
|
|
13
|
-
expression: RawNode.createWithSql(expression),
|
|
14
|
-
});
|
|
15
|
-
},
|
|
16
|
-
cloneWith(node, params) {
|
|
17
|
-
return freeze({
|
|
18
|
-
...node,
|
|
19
|
-
...params,
|
|
20
|
-
});
|
|
21
|
-
},
|
|
22
|
-
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { OnConflictNode } from '../operation-node/on-conflict-node.js';
|
|
2
|
-
import { AnyColumn } from '../util/type-utils.js';
|
|
3
|
-
import { ParseContext } from './parse-context.js';
|
|
4
|
-
import { MutationObject } from './update-set-parser.js';
|
|
5
|
-
export declare type OnConflictConstraintTarget = {
|
|
6
|
-
constraint: string;
|
|
7
|
-
};
|
|
8
|
-
export declare type OnConflictTargetExpression<DB, TB extends keyof DB> = AnyColumn<DB, TB> | ReadonlyArray<AnyColumn<DB, TB>> | OnConflictConstraintTarget;
|
|
9
|
-
export declare function parseOnConflictDoNothing(target: OnConflictTargetExpression<any, any>): OnConflictNode;
|
|
10
|
-
export declare function parseOnConflictUpdate(ctx: ParseContext, target: OnConflictTargetExpression<any, any>, updates: MutationObject<any, any>): OnConflictNode;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { IdentifierNode } from '../operation-node/identifier-node.js';
|
|
2
|
-
import { OnConflictNode } from '../operation-node/on-conflict-node.js';
|
|
3
|
-
import { asReadonlyArray, isObject, isReadonlyArray, isString, } from '../util/object-utils.js';
|
|
4
|
-
import { parseColumnName } from './reference-parser.js';
|
|
5
|
-
import { parseUpdateObject } from './update-set-parser.js';
|
|
6
|
-
export function parseOnConflictDoNothing(target) {
|
|
7
|
-
return OnConflictNode.create({
|
|
8
|
-
...parseConflictTarget(target),
|
|
9
|
-
doNothing: true,
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
export function parseOnConflictUpdate(ctx, target, updates) {
|
|
13
|
-
return OnConflictNode.create({
|
|
14
|
-
...parseConflictTarget(target),
|
|
15
|
-
updates: parseUpdateObject(ctx, updates),
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
function parseConflictTarget(target) {
|
|
19
|
-
if (isString(target) || isReadonlyArray(target)) {
|
|
20
|
-
return {
|
|
21
|
-
columns: asReadonlyArray(target).map(parseColumnName),
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
if (isObject(target) && !isReadonlyArray(target)) {
|
|
25
|
-
return {
|
|
26
|
-
constraint: IdentifierNode.create(target.constraint),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
throw new Error(`invalid on conflict target ${JSON.stringify(target)}`);
|
|
30
|
-
}
|