kysely 0.16.6 → 0.16.10

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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -14
  3. package/dist/cjs/dialect/mysql/mysql-dialect.js +2 -1
  4. package/dist/cjs/dialect/mysql/mysql-driver.js +1 -1
  5. package/dist/cjs/dialect/postgres/postgres-dialect.js +2 -1
  6. package/dist/cjs/dialect/postgres/postgres-driver.js +1 -1
  7. package/dist/cjs/dialect/sqlite/sqlite-dialect.js +2 -1
  8. package/dist/cjs/dialect/sqlite/sqlite-driver.js +1 -1
  9. package/dist/cjs/driver/dummy-driver.d.ts +28 -0
  10. package/dist/cjs/driver/dummy-driver.js +31 -3
  11. package/dist/cjs/index-nodeless.d.ts +1 -0
  12. package/dist/cjs/index-nodeless.js +1 -0
  13. package/dist/cjs/kysely.d.ts +8 -6
  14. package/dist/cjs/kysely.js +10 -8
  15. package/dist/cjs/migration/migrator.d.ts +22 -0
  16. package/dist/cjs/migration/migrator.js +23 -1
  17. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  18. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +19 -0
  19. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  20. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +42 -0
  21. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  22. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  23. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  24. package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  25. package/dist/cjs/query-builder/delete-query-builder.d.ts +52 -12
  26. package/dist/cjs/query-builder/delete-query-builder.js +56 -8
  27. package/dist/cjs/query-builder/function-builder.d.ts +29 -5
  28. package/dist/cjs/query-builder/function-builder.js +31 -7
  29. package/dist/cjs/query-builder/insert-query-builder.d.ts +54 -14
  30. package/dist/cjs/query-builder/insert-query-builder.js +58 -10
  31. package/dist/cjs/query-builder/returning-interface.d.ts +1 -3
  32. package/dist/cjs/query-builder/select-query-builder.d.ts +65 -24
  33. package/dist/cjs/query-builder/select-query-builder.js +64 -15
  34. package/dist/cjs/query-builder/update-query-builder.d.ts +53 -12
  35. package/dist/cjs/query-builder/update-query-builder.js +57 -8
  36. package/dist/cjs/query-compiler/default-query-compiler.js +8 -7
  37. package/dist/cjs/query-creator.d.ts +2 -2
  38. package/dist/cjs/query-creator.js +2 -2
  39. package/dist/cjs/query-executor/query-executor.js +3 -2
  40. package/dist/cjs/raw-builder/raw-builder.d.ts +2 -2
  41. package/dist/cjs/raw-builder/raw-builder.js +8 -1
  42. package/dist/cjs/schema/alter-table-builder.js +3 -3
  43. package/dist/cjs/schema/create-table-builder.js +2 -2
  44. package/dist/cjs/schema/create-view-builder.js +1 -1
  45. package/dist/cjs/util/object-utils.d.ts +1 -0
  46. package/dist/cjs/util/object-utils.js +50 -1
  47. package/dist/cjs/util/type-utils.d.ts +21 -0
  48. package/dist/esm/dialect/mysql/mysql-dialect.js +2 -1
  49. package/dist/esm/dialect/mysql/mysql-driver.js +2 -2
  50. package/dist/esm/dialect/postgres/postgres-dialect.js +2 -1
  51. package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
  52. package/dist/esm/dialect/sqlite/sqlite-dialect.js +2 -1
  53. package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
  54. package/dist/esm/driver/dummy-driver.d.ts +28 -0
  55. package/dist/esm/driver/dummy-driver.js +31 -3
  56. package/dist/esm/index-nodeless.d.ts +1 -0
  57. package/dist/esm/index-nodeless.js +1 -0
  58. package/dist/esm/kysely.d.ts +8 -6
  59. package/dist/esm/kysely.js +10 -8
  60. package/dist/esm/migration/migrator.d.ts +22 -0
  61. package/dist/esm/migration/migrator.js +23 -1
  62. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
  63. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +16 -0
  64. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
  65. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +39 -0
  66. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
  67. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
  68. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
  69. package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
  70. package/dist/esm/query-builder/delete-query-builder.d.ts +52 -12
  71. package/dist/esm/query-builder/delete-query-builder.js +56 -8
  72. package/dist/esm/query-builder/function-builder.d.ts +29 -5
  73. package/dist/esm/query-builder/function-builder.js +31 -7
  74. package/dist/esm/query-builder/insert-query-builder.d.ts +54 -14
  75. package/dist/esm/query-builder/insert-query-builder.js +58 -10
  76. package/dist/esm/query-builder/returning-interface.d.ts +1 -3
  77. package/dist/esm/query-builder/select-query-builder.d.ts +65 -24
  78. package/dist/esm/query-builder/select-query-builder.js +64 -15
  79. package/dist/esm/query-builder/update-query-builder.d.ts +53 -12
  80. package/dist/esm/query-builder/update-query-builder.js +57 -8
  81. package/dist/esm/query-compiler/default-query-compiler.js +8 -7
  82. package/dist/esm/query-creator.d.ts +2 -2
  83. package/dist/esm/query-creator.js +2 -2
  84. package/dist/esm/query-executor/query-executor.js +3 -2
  85. package/dist/esm/raw-builder/raw-builder.d.ts +2 -2
  86. package/dist/esm/raw-builder/raw-builder.js +8 -1
  87. package/dist/esm/schema/alter-table-builder.js +3 -3
  88. package/dist/esm/schema/create-table-builder.js +2 -2
  89. package/dist/esm/schema/create-view-builder.js +1 -1
  90. package/dist/esm/util/object-utils.d.ts +1 -0
  91. package/dist/esm/util/object-utils.js +48 -0
  92. package/dist/esm/util/type-utils.d.ts +21 -0
  93. package/package.json +4 -2
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noop = exports.isReadonlyArray = exports.asReadonlyArray = exports.asArray = exports.freeze = exports.getLast = exports.isObject = exports.isFunction = exports.isBuffer = exports.isBigInt = exports.isDate = exports.isNull = exports.isBoolean = exports.isNumber = exports.isString = exports.isEmpty = void 0;
3
+ exports.compare = exports.noop = exports.isReadonlyArray = exports.asReadonlyArray = exports.asArray = exports.freeze = exports.getLast = exports.isObject = exports.isFunction = exports.isBuffer = exports.isBigInt = exports.isDate = exports.isNull = exports.isBoolean = exports.isNumber = exports.isString = exports.isEmpty = void 0;
4
4
  function isEmpty(obj) {
5
5
  if (Array.isArray(obj) || isString(obj) || isBuffer(obj)) {
6
6
  return obj.length === 0;
@@ -83,3 +83,52 @@ function noop(obj) {
83
83
  return obj;
84
84
  }
85
85
  exports.noop = noop;
86
+ function compare(obj1, obj2) {
87
+ if (isReadonlyArray(obj1) && isReadonlyArray(obj2)) {
88
+ return compareArrays(obj1, obj2);
89
+ }
90
+ else if (isObject(obj1) && isObject(obj2)) {
91
+ return compareObjects(obj1, obj2);
92
+ }
93
+ return obj1 === obj2;
94
+ }
95
+ exports.compare = compare;
96
+ function compareArrays(arr1, arr2) {
97
+ if (arr1.length !== arr2.length) {
98
+ return false;
99
+ }
100
+ for (let i = 0; i < arr1.length; ++i) {
101
+ if (!compare(arr1[i], arr2[i])) {
102
+ return false;
103
+ }
104
+ }
105
+ return true;
106
+ }
107
+ function compareObjects(obj1, obj2) {
108
+ if (isBuffer(obj1) && isBuffer(obj2)) {
109
+ return compareBuffers(obj1, obj2);
110
+ }
111
+ else if (isDate(obj1) && isDate(obj2)) {
112
+ return compareDates(obj1, obj2);
113
+ }
114
+ return compareGenericObjects(obj1, obj2);
115
+ }
116
+ function compareBuffers(buf1, buf2) {
117
+ return Buffer.compare(buf1, buf2) === 0;
118
+ }
119
+ function compareDates(date1, date2) {
120
+ return date1.getTime() === date2.getTime();
121
+ }
122
+ function compareGenericObjects(obj1, obj2) {
123
+ const keys1 = Object.keys(obj1);
124
+ const keys2 = Object.keys(obj2);
125
+ if (keys1.length !== keys2.length) {
126
+ return false;
127
+ }
128
+ for (const key of keys1) {
129
+ if (!compare(obj1[key], obj2[key])) {
130
+ return false;
131
+ }
132
+ }
133
+ return true;
134
+ }
@@ -111,3 +111,24 @@ export declare type UnknownRow = Record<string, unknown>;
111
111
  export declare type Nullable<T> = {
112
112
  [P in keyof T]: T[P] | null;
113
113
  };
114
+ /**
115
+ * Takes all properties from T1 and merges all properties from T2
116
+ * that don't exist in T1 as optional properties.
117
+ *
118
+ * Example:
119
+ *
120
+ * interface Person {
121
+ * name: string
122
+ * age: number
123
+ * }
124
+ *
125
+ * interface Pet {
126
+ * name: string
127
+ * species: 'cat' | 'dog'
128
+ * }
129
+ *
130
+ * type Merged = MergePartial<Person, Pet>
131
+ *
132
+ * // { name: string, age: number, species?: 'cat' | 'dog' }
133
+ */
134
+ export declare type MergePartial<T1, T2> = T1 & Partial<Omit<T2, keyof T1>>;
@@ -3,6 +3,7 @@ import { MysqlDriver } from './mysql-driver.js';
3
3
  import { MysqlQueryCompiler } from './mysql-query-compiler.js';
4
4
  import { MysqlIntrospector } from './mysql-introspector.js';
5
5
  import { MysqlAdapter } from './mysql-adapter.js';
6
+ import { freeze } from '../../util/object-utils.js';
6
7
  /**
7
8
  * MySQL dialect that uses the [mysql2](https://github.com/sidorares/node-mysql2#readme) library.
8
9
  *
@@ -13,7 +14,7 @@ import { MysqlAdapter } from './mysql-adapter.js';
13
14
  export class MysqlDialect {
14
15
  #config;
15
16
  constructor(config) {
16
- this.#config = config;
17
+ this.#config = freeze({ ...config });
17
18
  }
18
19
  createDriver() {
19
20
  return new MysqlDriver(this.#config);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="./mysql-driver.d.ts" />
2
2
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
3
- import { isFunction, isObject } from '../../util/object-utils.js';
3
+ import { isFunction, isObject, freeze } from '../../util/object-utils.js';
4
4
  const PRIVATE_RELEASE_METHOD = Symbol();
5
5
  export class MysqlDriver {
6
6
  #config;
7
7
  #connections = new WeakMap();
8
8
  #pool;
9
9
  constructor(config) {
10
- this.#config = config;
10
+ this.#config = freeze({ ...config });
11
11
  }
12
12
  async init() {
13
13
  // Import the `mysql2` module here instead at the top of the file
@@ -3,6 +3,7 @@ import { PostgresDriver } from './postgres-driver.js';
3
3
  import { PostgresIntrospector } from './postgres-introspector.js';
4
4
  import { PostgresQueryCompiler } from './postgres-query-compiler.js';
5
5
  import { PostgresAdapter } from './postgres-adapter.js';
6
+ import { freeze } from '../../util/object-utils.js';
6
7
  /**
7
8
  * PostgreSQL dialect that uses the [pg](https://node-postgres.com/) library.
8
9
  *
@@ -16,7 +17,7 @@ import { PostgresAdapter } from './postgres-adapter.js';
16
17
  export class PostgresDialect {
17
18
  #config;
18
19
  constructor(config) {
19
- this.#config = config;
20
+ this.#config = freeze({ ...config });
20
21
  }
21
22
  createDriver() {
22
23
  return new PostgresDriver(this.#config);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="./postgres-driver.d.ts" />
2
2
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
3
- import { isFunction } from '../../util/object-utils.js';
3
+ import { isFunction, freeze } from '../../util/object-utils.js';
4
4
  const PRIVATE_RELEASE_METHOD = Symbol();
5
5
  export class PostgresDriver {
6
6
  #config;
7
7
  #connections = new WeakMap();
8
8
  #pool = null;
9
9
  constructor(config) {
10
- this.#config = config;
10
+ this.#config = freeze({ ...config });
11
11
  }
12
12
  async init() {
13
13
  // Import the `pg` module here instead at the top of the file
@@ -3,6 +3,7 @@ import { SqliteDriver } from './sqlite-driver.js';
3
3
  import { SqliteQueryCompiler } from './sqlite-query-compiler.js';
4
4
  import { SqliteIntrospector } from './sqlite-introspector.js';
5
5
  import { SqliteAdapter } from './sqlite-adapter.js';
6
+ import { freeze } from '../../util/object-utils.js';
6
7
  /**
7
8
  * SQLite dialect that uses the [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3) library.
8
9
  *
@@ -13,7 +14,7 @@ import { SqliteAdapter } from './sqlite-adapter.js';
13
14
  export class SqliteDialect {
14
15
  #config;
15
16
  constructor(config) {
16
- this.#config = config;
17
+ this.#config = freeze({ ...config });
17
18
  }
18
19
  createDriver() {
19
20
  return new SqliteDriver(this.#config);
@@ -1,13 +1,13 @@
1
1
  /// <reference types="./sqlite-driver.d.ts" />
2
2
  import { CompiledQuery } from '../../query-compiler/compiled-query.js';
3
- import { isBoolean, isFunction, isNumber } from '../../util/object-utils.js';
3
+ import { freeze, isBoolean, isFunction, isNumber, } from '../../util/object-utils.js';
4
4
  export class SqliteDriver {
5
5
  #config;
6
6
  #connectionMutex = new ConnectionMutex();
7
7
  #db;
8
8
  #connection;
9
9
  constructor(config) {
10
- this.#config = config;
10
+ this.#config = freeze({ ...config });
11
11
  }
12
12
  async init() {
13
13
  // Import the `better-sqlite3` module here instead at the top of the file
@@ -1,5 +1,33 @@
1
1
  import { DatabaseConnection } from './database-connection.js';
2
2
  import { Driver } from './driver.js';
3
+ /**
4
+ * A driver that does absolutely nothing.
5
+ *
6
+ * You can use this to create Kysely instances solely for building queries
7
+ *
8
+ * ### Examples
9
+ *
10
+ * This example creates a Kysely instance for building postgres queries:
11
+ *
12
+ * ```ts
13
+ * const db = new Kysely<Database>({
14
+ * dialect: {
15
+ * createAdapter() {
16
+ * return new PostgresAdapter()
17
+ * },
18
+ * createDriver() {
19
+ * return new DummyDriver()
20
+ * },
21
+ * createIntrospector(db: Kysely<any>) {
22
+ * return new PostgresIntrospector(db)
23
+ * },
24
+ * createQueryCompiler() {
25
+ * return new PostgresQueryCompiler()
26
+ * },
27
+ * },
28
+ * })
29
+ * ```
30
+ */
3
31
  export declare class DummyDriver implements Driver {
4
32
  /**
5
33
  * Initializes the driver.
@@ -1,7 +1,35 @@
1
1
  /// <reference types="./dummy-driver.d.ts" />
2
+ /**
3
+ * A driver that does absolutely nothing.
4
+ *
5
+ * You can use this to create Kysely instances solely for building queries
6
+ *
7
+ * ### Examples
8
+ *
9
+ * This example creates a Kysely instance for building postgres queries:
10
+ *
11
+ * ```ts
12
+ * const db = new Kysely<Database>({
13
+ * dialect: {
14
+ * createAdapter() {
15
+ * return new PostgresAdapter()
16
+ * },
17
+ * createDriver() {
18
+ * return new DummyDriver()
19
+ * },
20
+ * createIntrospector(db: Kysely<any>) {
21
+ * return new PostgresIntrospector(db)
22
+ * },
23
+ * createQueryCompiler() {
24
+ * return new PostgresQueryCompiler()
25
+ * },
26
+ * },
27
+ * })
28
+ * ```
29
+ */
2
30
  export class DummyDriver {
3
- init() {
4
- throw new Error('Method not implemented.');
31
+ async init() {
32
+ // Nothing to do here.
5
33
  }
6
34
  async acquireConnection() {
7
35
  return new DummyConnection();
@@ -23,7 +51,7 @@ export class DummyDriver {
23
51
  }
24
52
  }
25
53
  class DummyConnection {
26
- async executeQuery(compiledQuery) {
54
+ async executeQuery() {
27
55
  return {
28
56
  rows: [],
29
57
  };
@@ -59,6 +59,7 @@ export * from './query-compiler/query-compiler.js';
59
59
  export * from './migration/migrator.js';
60
60
  export * from './plugin/kysely-plugin.js';
61
61
  export * from './plugin/camel-case/camel-case-plugin.js';
62
+ export * from './plugin/deduplicate-joins/deduplicate-joins-plugin.js';
62
63
  export * from './operation-node/add-column-node.js';
63
64
  export * from './operation-node/add-constraint-node.js';
64
65
  export * from './operation-node/alias-node.js';
@@ -60,6 +60,7 @@ export * from './query-compiler/query-compiler.js';
60
60
  export * from './migration/migrator.js';
61
61
  export * from './plugin/kysely-plugin.js';
62
62
  export * from './plugin/camel-case/camel-case-plugin.js';
63
+ export * from './plugin/deduplicate-joins/deduplicate-joins-plugin.js';
63
64
  export * from './operation-node/add-column-node.js';
64
65
  export * from './operation-node/add-constraint-node.js';
65
66
  export * from './operation-node/alias-node.js';
@@ -22,22 +22,24 @@ import { DialectAdapter } from './dialect/dialect-adapter.js';
22
22
  * This example assumes your database has tables `person` and `pet`:
23
23
  *
24
24
  * ```ts
25
- * interface Person {
26
- * id: number
25
+ * import { Kysely, Generated, PostgresDialect } from 'kysely'
26
+ *
27
+ * interface PersonTable {
28
+ * id: Generated<number>
27
29
  * first_name: string
28
30
  * last_name: string
29
31
  * }
30
32
  *
31
- * interface Pet {
32
- * id: number
33
+ * interface PetTable {
34
+ * id: Generated<number>
33
35
  * owner_id: number
34
36
  * name: string
35
37
  * species 'cat' | 'dog'
36
38
  * }
37
39
  *
38
40
  * interface Database {
39
- * person: Person,
40
- * pet: Pet
41
+ * person: PersonTable,
42
+ * pet: PetTable
41
43
  * }
42
44
  *
43
45
  * const db = new Kysely<Database>({
@@ -24,22 +24,24 @@ import { PRIVATE_ADAPTER } from './util/private-symbols.js';
24
24
  * This example assumes your database has tables `person` and `pet`:
25
25
  *
26
26
  * ```ts
27
- * interface Person {
28
- * id: number
27
+ * import { Kysely, Generated, PostgresDialect } from 'kysely'
28
+ *
29
+ * interface PersonTable {
30
+ * id: Generated<number>
29
31
  * first_name: string
30
32
  * last_name: string
31
33
  * }
32
34
  *
33
- * interface Pet {
34
- * id: number
35
+ * interface PetTable {
36
+ * id: Generated<number>
35
37
  * owner_id: number
36
38
  * name: string
37
39
  * species 'cat' | 'dog'
38
40
  * }
39
41
  *
40
42
  * interface Database {
41
- * person: Person,
42
- * pet: Pet
43
+ * person: PersonTable,
44
+ * pet: PetTable
43
45
  * }
44
46
  *
45
47
  * const db = new Kysely<Database>({
@@ -338,12 +340,12 @@ export class ConnectionBuilder {
338
340
  async execute(callback) {
339
341
  const connection = await this.#props.driver.acquireConnection();
340
342
  const connectionProvider = new SingleConnectionProvider(connection);
341
- const transaction = new Kysely({
343
+ const db = new Kysely({
342
344
  ...this.#props,
343
345
  executor: this.#props.executor.withConnectionProvider(connectionProvider),
344
346
  });
345
347
  try {
346
- return await callback(transaction);
348
+ return await callback(db);
347
349
  }
348
350
  finally {
349
351
  await this.#props.driver.releaseConnection(connection);
@@ -36,6 +36,12 @@ export interface Migration {
36
36
  export declare class Migrator {
37
37
  #private;
38
38
  constructor(props: MigratorProps);
39
+ /**
40
+ * Returns a {@link MigrationInfo} object for each migration.
41
+ *
42
+ * The returned array is sorted by migration name.
43
+ */
44
+ getMigrations(): Promise<ReadonlyArray<MigrationInfo>>;
39
45
  /**
40
46
  * Runs all migrations that have not yet been run.
41
47
  *
@@ -219,3 +225,19 @@ export interface MigrationProvider {
219
225
  export interface NoMigrations {
220
226
  readonly __noMigrations__: true;
221
227
  }
228
+ export interface MigrationInfo {
229
+ /**
230
+ * Name of the migration.
231
+ */
232
+ name: string;
233
+ /**
234
+ * The actual migration.
235
+ */
236
+ migration: Migration;
237
+ /**
238
+ * When was the migration executed.
239
+ *
240
+ * If this is undefined, the migration hasn't been executed yet.
241
+ */
242
+ executedAt?: Date;
243
+ }
@@ -30,6 +30,28 @@ export class Migrator {
30
30
  constructor(props) {
31
31
  this.#props = freeze(props);
32
32
  }
33
+ /**
34
+ * Returns a {@link MigrationInfo} object for each migration.
35
+ *
36
+ * The returned array is sorted by migration name.
37
+ */
38
+ async getMigrations() {
39
+ const executedMigrations = (await this.#doesTableExists(MIGRATION_TABLE))
40
+ ? await this.#props.db
41
+ .selectFrom(MIGRATION_TABLE)
42
+ .select(['name', 'timestamp'])
43
+ .execute()
44
+ : [];
45
+ const migrations = await this.#resolveMigrations();
46
+ return migrations.map(({ name, ...migration }) => {
47
+ const executed = executedMigrations.find((it) => it.name === name);
48
+ return {
49
+ name,
50
+ migration,
51
+ executedAt: executed ? new Date(executed.timestamp) : undefined,
52
+ };
53
+ });
54
+ }
33
55
  /**
34
56
  * Runs all migrations that have not yet been run.
35
57
  *
@@ -213,7 +235,7 @@ export class Migrator {
213
235
  try {
214
236
  await this.#props.db
215
237
  .insertInto(MIGRATION_LOCK_TABLE)
216
- .values({ id: MIGRATION_LOCK_ID })
238
+ .values({ id: MIGRATION_LOCK_ID, is_locked: 0 })
217
239
  .execute();
218
240
  }
219
241
  catch (error) {
@@ -0,0 +1,48 @@
1
+ import { QueryResult } from '../../driver/database-connection.js';
2
+ import { RootOperationNode } from '../../query-compiler/query-compiler.js';
3
+ import { UnknownRow } from '../../util/type-utils.js';
4
+ import { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs } from '../kysely-plugin.js';
5
+ /**
6
+ * Plugin that removes duplicate joins from queries.
7
+ *
8
+ * See [this recipe](https://github.com/koskimas/kysely/tree/master/recipes/deduplicate-joins.md)
9
+ */
10
+ export declare class DeduplicateJoinsPlugin implements KyselyPlugin {
11
+ #private;
12
+ /**
13
+ * This is called for each query before it is executed. You can modify the query by
14
+ * transforming its {@link OperationNode} tree provided in {@link PluginTransformQueryArgs.node | args.node}
15
+ * and returning the transformed tree. You'd usually want to use an {@link OperationNodeTransformer}
16
+ * for this.
17
+ *
18
+ * If you need to pass some query-related data between this method and `transformResult` you
19
+ * can use a `WeakMap` with {@link PluginTransformQueryArgs.queryId | args.queryId} as the key:
20
+ *
21
+ * ```ts
22
+ * const plugin = {
23
+ * data: new WeakMap<QueryId, SomeData>(),
24
+ *
25
+ * transformQuery(args: PluginTransformQueryArgs): RootOperationNode {
26
+ * this.data.set(args.queryId, something)
27
+ * return args.node
28
+ * },
29
+ *
30
+ * transformResult(args: PluginTransformResultArgs): QueryResult<UnknownRow> {
31
+ * const data = this.data.get(args.queryId)
32
+ * return args.result
33
+ * }
34
+ * }
35
+ * ```
36
+ *
37
+ * You should use a `WeakMap` instead of a `Map` or some other strong references because `transformQuery`
38
+ * is not always matched by a call to `transformResult` which would leave orphaned items in the map
39
+ * and cause a memory leak.
40
+ */
41
+ transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
42
+ /**
43
+ * This method is called for each query after it has been executed. The result
44
+ * of the query can be accessed through {@link PluginTransformResultArgs.result | args.result}.
45
+ * You can modify the result and return the modifier result.
46
+ */
47
+ transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
48
+ }
@@ -0,0 +1,16 @@
1
+ /// <reference types="./deduplicate-joins-plugin.d.ts" />
2
+ import { DeduplicateJoinsTransformer } from './deduplicate-joins-transformer.js';
3
+ /**
4
+ * Plugin that removes duplicate joins from queries.
5
+ *
6
+ * See [this recipe](https://github.com/koskimas/kysely/tree/master/recipes/deduplicate-joins.md)
7
+ */
8
+ export class DeduplicateJoinsPlugin {
9
+ #transformer = new DeduplicateJoinsTransformer();
10
+ transformQuery(args) {
11
+ return this.#transformer.transformNode(args.node);
12
+ }
13
+ transformResult(args) {
14
+ return Promise.resolve(args.result);
15
+ }
16
+ }
@@ -0,0 +1,9 @@
1
+ import { DeleteQueryNode, UpdateQueryNode } from '../../index-nodeless.js';
2
+ import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { SelectQueryNode } from '../../operation-node/select-query-node.js';
4
+ export declare class DeduplicateJoinsTransformer extends OperationNodeTransformer {
5
+ #private;
6
+ protected transformSelectQuery(node: SelectQueryNode): SelectQueryNode;
7
+ protected transformUpdateQuery(node: UpdateQueryNode): UpdateQueryNode;
8
+ protected transformDeleteQuery(node: DeleteQueryNode): DeleteQueryNode;
9
+ }
@@ -0,0 +1,39 @@
1
+ /// <reference types="./deduplicate-joins-transformer.d.ts" />
2
+ import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { compare, freeze } from '../../util/object-utils.js';
4
+ export class DeduplicateJoinsTransformer extends OperationNodeTransformer {
5
+ transformSelectQuery(node) {
6
+ return this.#transformQuery(super.transformSelectQuery(node));
7
+ }
8
+ transformUpdateQuery(node) {
9
+ return this.#transformQuery(super.transformUpdateQuery(node));
10
+ }
11
+ transformDeleteQuery(node) {
12
+ return this.#transformQuery(super.transformDeleteQuery(node));
13
+ }
14
+ #transformQuery(node) {
15
+ if (!node.joins || node.joins.length === 0) {
16
+ return node;
17
+ }
18
+ return freeze({
19
+ ...node,
20
+ joins: this.#deduplicateJoins(node.joins),
21
+ });
22
+ }
23
+ #deduplicateJoins(joins) {
24
+ const out = [];
25
+ for (let i = 0; i < joins.length; ++i) {
26
+ let foundDuplicate = false;
27
+ for (let j = i + 1; j < joins.length; ++j) {
28
+ if (compare(joins[i], joins[j])) {
29
+ foundDuplicate = true;
30
+ break;
31
+ }
32
+ }
33
+ if (!foundDuplicate) {
34
+ out.push(joins[i]);
35
+ }
36
+ }
37
+ return freeze(out);
38
+ }
39
+ }