kysely 0.16.6 → 0.16.7
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 +118 -5
- package/dist/cjs/dialect/mysql/mysql-dialect.js +2 -1
- package/dist/cjs/dialect/mysql/mysql-driver.js +1 -1
- package/dist/cjs/dialect/postgres/postgres-dialect.js +2 -1
- package/dist/cjs/dialect/postgres/postgres-driver.js +1 -1
- package/dist/cjs/dialect/sqlite/sqlite-dialect.js +2 -1
- package/dist/cjs/dialect/sqlite/sqlite-driver.js +1 -1
- package/dist/cjs/driver/dummy-driver.d.ts +28 -0
- package/dist/cjs/driver/dummy-driver.js +31 -3
- package/dist/cjs/index-nodeless.d.ts +1 -0
- package/dist/cjs/index-nodeless.js +1 -0
- package/dist/cjs/kysely.d.ts +8 -6
- package/dist/cjs/kysely.js +8 -6
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +19 -0
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
- package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +42 -0
- package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
- package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
- package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
- package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
- package/dist/cjs/query-builder/delete-query-builder.d.ts +51 -9
- package/dist/cjs/query-builder/delete-query-builder.js +56 -8
- package/dist/cjs/query-builder/function-builder.d.ts +29 -5
- package/dist/cjs/query-builder/function-builder.js +31 -7
- package/dist/cjs/query-builder/insert-query-builder.d.ts +53 -11
- package/dist/cjs/query-builder/insert-query-builder.js +58 -10
- package/dist/cjs/query-builder/select-query-builder.d.ts +58 -16
- package/dist/cjs/query-builder/select-query-builder.js +64 -15
- package/dist/cjs/query-builder/update-query-builder.d.ts +52 -9
- package/dist/cjs/query-builder/update-query-builder.js +57 -8
- package/dist/cjs/query-creator.d.ts +2 -2
- package/dist/cjs/query-creator.js +2 -2
- package/dist/cjs/schema/create-view-builder.js +1 -1
- package/dist/cjs/util/object-utils.d.ts +1 -0
- package/dist/cjs/util/object-utils.js +50 -1
- package/dist/cjs/util/type-utils.d.ts +21 -0
- package/dist/esm/dialect/mysql/mysql-dialect.js +2 -1
- package/dist/esm/dialect/mysql/mysql-driver.js +2 -2
- package/dist/esm/dialect/postgres/postgres-dialect.js +2 -1
- package/dist/esm/dialect/postgres/postgres-driver.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-dialect.js +2 -1
- package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/esm/driver/dummy-driver.d.ts +28 -0
- package/dist/esm/driver/dummy-driver.js +31 -3
- package/dist/esm/index-nodeless.d.ts +1 -0
- package/dist/esm/index-nodeless.js +1 -0
- package/dist/esm/kysely.d.ts +8 -6
- package/dist/esm/kysely.js +8 -6
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.d.ts +48 -0
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +16 -0
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +9 -0
- package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +39 -0
- package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.d.ts +0 -0
- package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-plugin.js +0 -0
- package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts +0 -0
- package/dist/esm/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js +0 -0
- package/dist/esm/query-builder/delete-query-builder.d.ts +51 -9
- package/dist/esm/query-builder/delete-query-builder.js +56 -8
- package/dist/esm/query-builder/function-builder.d.ts +29 -5
- package/dist/esm/query-builder/function-builder.js +31 -7
- package/dist/esm/query-builder/insert-query-builder.d.ts +53 -11
- package/dist/esm/query-builder/insert-query-builder.js +58 -10
- package/dist/esm/query-builder/select-query-builder.d.ts +58 -16
- package/dist/esm/query-builder/select-query-builder.js +64 -15
- package/dist/esm/query-builder/update-query-builder.d.ts +52 -9
- package/dist/esm/query-builder/update-query-builder.js +57 -8
- package/dist/esm/query-creator.d.ts +2 -2
- package/dist/esm/query-creator.js +2 -2
- package/dist/esm/schema/create-view-builder.js +1 -1
- package/dist/esm/util/object-utils.d.ts +1 -0
- package/dist/esm/util/object-utils.js +48 -0
- package/dist/esm/util/type-utils.d.ts +21 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
# [Kysely](https://koskimas.github.io/kysely/index.html)
|
|
5
5
|
|
|
6
|
-
A type-safe and autocompletion-friendly typescript SQL query builder
|
|
7
|
-
[
|
|
6
|
+
A type-safe and autocompletion-friendly typescript SQL query builder. Inspired by [knex](http://knexjs.org/).
|
|
7
|
+
Mainly developed for [node.js](https://nodejs.org/en/) but also runs on [deno](https://deno.land/) and
|
|
8
|
+
in the browser.
|
|
8
9
|
|
|
9
10
|

|
|
10
11
|
|
|
11
|
-
Kysely
|
|
12
|
-
you are writing. The result type only has the selected columns with correct types and aliases.
|
|
13
|
-
|
|
12
|
+
Kysely makes sure you only refer to tables and columns that are visible to the part of the query
|
|
13
|
+
you are writing. The result type only has the selected columns with correct types and aliases. As an
|
|
14
|
+
added bonus you get autocompletion for all that stuff.
|
|
14
15
|
|
|
15
16
|
As you can see in the gif above, through the pure magic of modern typescript, Kysely is even able to parse
|
|
16
17
|
the alias given to `pet.name` and add the `pet_name` column to the result row type. Kysely is able to infer
|
|
@@ -32,7 +33,10 @@ You can find a more thorough introduction [here](https://www.jakso.me/blog/kysel
|
|
|
32
33
|
- [Installation](#installation)
|
|
33
34
|
- [Minimal example](#minimal-example)
|
|
34
35
|
- [Query examples](#query-examples)
|
|
36
|
+
- [Recipes](https://github.com/koskimas/kysely/tree/master/recipes)
|
|
35
37
|
- [Migrations](#migrations)
|
|
38
|
+
- [Deno](#deno)
|
|
39
|
+
- [Browser](#browser)
|
|
36
40
|
- [API reference](https://koskimas.github.io/kysely/index.html)
|
|
37
41
|
- [Changelog](https://github.com/koskimas/kysely/releases)
|
|
38
42
|
|
|
@@ -341,6 +345,8 @@ async function migrateToLatest() {
|
|
|
341
345
|
console.error(error)
|
|
342
346
|
process.exit(1)
|
|
343
347
|
}
|
|
348
|
+
|
|
349
|
+
await db.destroy()
|
|
344
350
|
}
|
|
345
351
|
|
|
346
352
|
migrateToLatest()
|
|
@@ -350,6 +356,113 @@ The migration methods use a lock on the database level, and parallel calls are e
|
|
|
350
356
|
This means that you can safely call `migrateToLatest` and other migration methods from multiple
|
|
351
357
|
server instances simultaneously and the migrations are guaranteed to only be executed once.
|
|
352
358
|
|
|
359
|
+
# Deno
|
|
360
|
+
|
|
361
|
+
Kysely doesn't include drivers for deno, but you can still use Kysely as a query builder
|
|
362
|
+
or implement your own driver:
|
|
363
|
+
|
|
364
|
+
```ts
|
|
365
|
+
// We use jsdeliver to get Kysely from npm. We also need to
|
|
366
|
+
// import the `dist/esm/index-nodeless.js` file instead of the
|
|
367
|
+
// root which has node dependencies.
|
|
368
|
+
import {
|
|
369
|
+
DummyDriver,
|
|
370
|
+
Generated,
|
|
371
|
+
Kysely,
|
|
372
|
+
PostgresAdapter,
|
|
373
|
+
PostgresIntrospector,
|
|
374
|
+
PostgresQueryCompiler,
|
|
375
|
+
} from 'https://cdn.jsdelivr.net/npm/kysely/dist/esm/index-nodeless.js'
|
|
376
|
+
|
|
377
|
+
interface Person {
|
|
378
|
+
id: Generated<number>
|
|
379
|
+
first_name: string
|
|
380
|
+
last_name: string | null
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
interface Database {
|
|
384
|
+
person: Person
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const db = new Kysely<Database>({
|
|
388
|
+
dialect: {
|
|
389
|
+
createAdapter() {
|
|
390
|
+
return new PostgresAdapter()
|
|
391
|
+
},
|
|
392
|
+
createDriver() {
|
|
393
|
+
// You need a driver to be able to execute queries. In this example
|
|
394
|
+
// we use the dummy driver that never does anything.
|
|
395
|
+
return new DummyDriver()
|
|
396
|
+
},
|
|
397
|
+
createIntrospector(db: Kysely<unknown>) {
|
|
398
|
+
return new PostgresIntrospector(db)
|
|
399
|
+
},
|
|
400
|
+
createQueryCompiler() {
|
|
401
|
+
return new PostgresQueryCompiler()
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
const query = db.selectFrom('person').select('id')
|
|
407
|
+
const sql = query.compile()
|
|
408
|
+
|
|
409
|
+
console.log(sql.sql)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
# Browser
|
|
413
|
+
|
|
414
|
+
Kysely also runs in the browser as long as you import the `dist/esm/index-nodeless.js`
|
|
415
|
+
module instead of the root that has node dependencies. You can also import the
|
|
416
|
+
`dist/cjs/index-nodeless.js` file if you are using commonjs modules instead of ESM.
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
import {
|
|
420
|
+
Kysely,
|
|
421
|
+
Generated,
|
|
422
|
+
DummyDriver,
|
|
423
|
+
SqliteAdapter,
|
|
424
|
+
SqliteIntrospector,
|
|
425
|
+
SqliteQueryCompiler,
|
|
426
|
+
} from 'kysely/dist/esm/index-nodeless.js'
|
|
427
|
+
|
|
428
|
+
interface Person {
|
|
429
|
+
id: Generated<number>
|
|
430
|
+
first_name: string
|
|
431
|
+
last_name: string | null
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
interface Database {
|
|
435
|
+
person: Person
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const db = new Kysely<Database>({
|
|
439
|
+
dialect: {
|
|
440
|
+
createAdapter() {
|
|
441
|
+
return new SqliteAdapter()
|
|
442
|
+
},
|
|
443
|
+
createDriver() {
|
|
444
|
+
return new DummyDriver()
|
|
445
|
+
},
|
|
446
|
+
createIntrospector(db: Kysely<unknown>) {
|
|
447
|
+
return new SqliteIntrospector(db)
|
|
448
|
+
},
|
|
449
|
+
createQueryCompiler() {
|
|
450
|
+
return new SqliteQueryCompiler()
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
window.addEventListener('load', () => {
|
|
456
|
+
const sql = db.selectFrom('person').select('id').compile()
|
|
457
|
+
|
|
458
|
+
const result = document.createElement('span')
|
|
459
|
+
result.id = 'result'
|
|
460
|
+
result.innerHTML = sql.sql
|
|
461
|
+
|
|
462
|
+
document.body.appendChild(result)
|
|
463
|
+
})
|
|
464
|
+
```
|
|
465
|
+
|
|
353
466
|
# Why not just contribute to knex
|
|
354
467
|
|
|
355
468
|
Kysely is very similar to knex, but it also attempts to fix things that I personally find not-so-good
|
|
@@ -5,6 +5,7 @@ const mysql_driver_js_1 = require("./mysql-driver.js");
|
|
|
5
5
|
const mysql_query_compiler_js_1 = require("./mysql-query-compiler.js");
|
|
6
6
|
const mysql_introspector_js_1 = require("./mysql-introspector.js");
|
|
7
7
|
const mysql_adapter_js_1 = require("./mysql-adapter.js");
|
|
8
|
+
const object_utils_js_1 = require("../../util/object-utils.js");
|
|
8
9
|
/**
|
|
9
10
|
* MySQL dialect that uses the [mysql2](https://github.com/sidorares/node-mysql2#readme) library.
|
|
10
11
|
*
|
|
@@ -15,7 +16,7 @@ const mysql_adapter_js_1 = require("./mysql-adapter.js");
|
|
|
15
16
|
class MysqlDialect {
|
|
16
17
|
#config;
|
|
17
18
|
constructor(config) {
|
|
18
|
-
this.#config = config;
|
|
19
|
+
this.#config = (0, object_utils_js_1.freeze)({ ...config });
|
|
19
20
|
}
|
|
20
21
|
createDriver() {
|
|
21
22
|
return new mysql_driver_js_1.MysqlDriver(this.#config);
|
|
@@ -9,7 +9,7 @@ class MysqlDriver {
|
|
|
9
9
|
#connections = new WeakMap();
|
|
10
10
|
#pool;
|
|
11
11
|
constructor(config) {
|
|
12
|
-
this.#config = config;
|
|
12
|
+
this.#config = (0, object_utils_js_1.freeze)({ ...config });
|
|
13
13
|
}
|
|
14
14
|
async init() {
|
|
15
15
|
// Import the `mysql2` module here instead at the top of the file
|
|
@@ -5,6 +5,7 @@ const postgres_driver_js_1 = require("./postgres-driver.js");
|
|
|
5
5
|
const postgres_introspector_js_1 = require("./postgres-introspector.js");
|
|
6
6
|
const postgres_query_compiler_js_1 = require("./postgres-query-compiler.js");
|
|
7
7
|
const postgres_adapter_js_1 = require("./postgres-adapter.js");
|
|
8
|
+
const object_utils_js_1 = require("../../util/object-utils.js");
|
|
8
9
|
/**
|
|
9
10
|
* PostgreSQL dialect that uses the [pg](https://node-postgres.com/) library.
|
|
10
11
|
*
|
|
@@ -18,7 +19,7 @@ const postgres_adapter_js_1 = require("./postgres-adapter.js");
|
|
|
18
19
|
class PostgresDialect {
|
|
19
20
|
#config;
|
|
20
21
|
constructor(config) {
|
|
21
|
-
this.#config = config;
|
|
22
|
+
this.#config = (0, object_utils_js_1.freeze)({ ...config });
|
|
22
23
|
}
|
|
23
24
|
createDriver() {
|
|
24
25
|
return new postgres_driver_js_1.PostgresDriver(this.#config);
|
|
@@ -9,7 +9,7 @@ class PostgresDriver {
|
|
|
9
9
|
#connections = new WeakMap();
|
|
10
10
|
#pool = null;
|
|
11
11
|
constructor(config) {
|
|
12
|
-
this.#config = config;
|
|
12
|
+
this.#config = (0, object_utils_js_1.freeze)({ ...config });
|
|
13
13
|
}
|
|
14
14
|
async init() {
|
|
15
15
|
// Import the `pg` module here instead at the top of the file
|
|
@@ -5,6 +5,7 @@ const sqlite_driver_js_1 = require("./sqlite-driver.js");
|
|
|
5
5
|
const sqlite_query_compiler_js_1 = require("./sqlite-query-compiler.js");
|
|
6
6
|
const sqlite_introspector_js_1 = require("./sqlite-introspector.js");
|
|
7
7
|
const sqlite_adapter_js_1 = require("./sqlite-adapter.js");
|
|
8
|
+
const object_utils_js_1 = require("../../util/object-utils.js");
|
|
8
9
|
/**
|
|
9
10
|
* SQLite dialect that uses the [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3) library.
|
|
10
11
|
*
|
|
@@ -15,7 +16,7 @@ const sqlite_adapter_js_1 = require("./sqlite-adapter.js");
|
|
|
15
16
|
class SqliteDialect {
|
|
16
17
|
#config;
|
|
17
18
|
constructor(config) {
|
|
18
|
-
this.#config = config;
|
|
19
|
+
this.#config = (0, object_utils_js_1.freeze)({ ...config });
|
|
19
20
|
}
|
|
20
21
|
createDriver() {
|
|
21
22
|
return new sqlite_driver_js_1.SqliteDriver(this.#config);
|
|
@@ -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,9 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DummyDriver = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A driver that does absolutely nothing.
|
|
6
|
+
*
|
|
7
|
+
* You can use this to create Kysely instances solely for building queries
|
|
8
|
+
*
|
|
9
|
+
* ### Examples
|
|
10
|
+
*
|
|
11
|
+
* This example creates a Kysely instance for building postgres queries:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* const db = new Kysely<Database>({
|
|
15
|
+
* dialect: {
|
|
16
|
+
* createAdapter() {
|
|
17
|
+
* return new PostgresAdapter()
|
|
18
|
+
* },
|
|
19
|
+
* createDriver() {
|
|
20
|
+
* return new DummyDriver()
|
|
21
|
+
* },
|
|
22
|
+
* createIntrospector(db: Kysely<any>) {
|
|
23
|
+
* return new PostgresIntrospector(db)
|
|
24
|
+
* },
|
|
25
|
+
* createQueryCompiler() {
|
|
26
|
+
* return new PostgresQueryCompiler()
|
|
27
|
+
* },
|
|
28
|
+
* },
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
4
32
|
class DummyDriver {
|
|
5
|
-
init() {
|
|
6
|
-
|
|
33
|
+
async init() {
|
|
34
|
+
// Nothing to do here.
|
|
7
35
|
}
|
|
8
36
|
async acquireConnection() {
|
|
9
37
|
return new DummyConnection();
|
|
@@ -26,7 +54,7 @@ class DummyDriver {
|
|
|
26
54
|
}
|
|
27
55
|
exports.DummyDriver = DummyDriver;
|
|
28
56
|
class DummyConnection {
|
|
29
|
-
async executeQuery(
|
|
57
|
+
async executeQuery() {
|
|
30
58
|
return {
|
|
31
59
|
rows: [],
|
|
32
60
|
};
|
|
@@ -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';
|
|
@@ -71,6 +71,7 @@ __exportStar(require("./query-compiler/query-compiler.js"), exports);
|
|
|
71
71
|
__exportStar(require("./migration/migrator.js"), exports);
|
|
72
72
|
__exportStar(require("./plugin/kysely-plugin.js"), exports);
|
|
73
73
|
__exportStar(require("./plugin/camel-case/camel-case-plugin.js"), exports);
|
|
74
|
+
__exportStar(require("./plugin/deduplicate-joins/deduplicate-joins-plugin.js"), exports);
|
|
74
75
|
__exportStar(require("./operation-node/add-column-node.js"), exports);
|
|
75
76
|
__exportStar(require("./operation-node/add-constraint-node.js"), exports);
|
|
76
77
|
__exportStar(require("./operation-node/alias-node.js"), exports);
|
package/dist/cjs/kysely.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
26
|
-
*
|
|
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
|
|
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:
|
|
40
|
-
* pet:
|
|
41
|
+
* person: PersonTable,
|
|
42
|
+
* pet: PetTable
|
|
41
43
|
* }
|
|
42
44
|
*
|
|
43
45
|
* const db = new Kysely<Database>({
|
package/dist/cjs/kysely.js
CHANGED
|
@@ -26,22 +26,24 @@ const private_symbols_js_1 = require("./util/private-symbols.js");
|
|
|
26
26
|
* This example assumes your database has tables `person` and `pet`:
|
|
27
27
|
*
|
|
28
28
|
* ```ts
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* import { Kysely, Generated, PostgresDialect } from 'kysely'
|
|
30
|
+
*
|
|
31
|
+
* interface PersonTable {
|
|
32
|
+
* id: Generated<number>
|
|
31
33
|
* first_name: string
|
|
32
34
|
* last_name: string
|
|
33
35
|
* }
|
|
34
36
|
*
|
|
35
|
-
* interface
|
|
36
|
-
* id: number
|
|
37
|
+
* interface PetTable {
|
|
38
|
+
* id: Generated<number>
|
|
37
39
|
* owner_id: number
|
|
38
40
|
* name: string
|
|
39
41
|
* species 'cat' | 'dog'
|
|
40
42
|
* }
|
|
41
43
|
*
|
|
42
44
|
* interface Database {
|
|
43
|
-
* person:
|
|
44
|
-
* pet:
|
|
45
|
+
* person: PersonTable,
|
|
46
|
+
* pet: PetTable
|
|
45
47
|
* }
|
|
46
48
|
*
|
|
47
49
|
* const db = new Kysely<Database>({
|
|
@@ -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,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeduplicateJoinsPlugin = void 0;
|
|
4
|
+
const deduplicate_joins_transformer_js_1 = require("./deduplicate-joins-transformer.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
|
+
class DeduplicateJoinsPlugin {
|
|
11
|
+
#transformer = new deduplicate_joins_transformer_js_1.DeduplicateJoinsTransformer();
|
|
12
|
+
transformQuery(args) {
|
|
13
|
+
return this.#transformer.transformNode(args.node);
|
|
14
|
+
}
|
|
15
|
+
transformResult(args) {
|
|
16
|
+
return Promise.resolve(args.result);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.DeduplicateJoinsPlugin = DeduplicateJoinsPlugin;
|
|
@@ -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,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeduplicateJoinsTransformer = void 0;
|
|
4
|
+
const operation_node_transformer_js_1 = require("../../operation-node/operation-node-transformer.js");
|
|
5
|
+
const object_utils_js_1 = require("../../util/object-utils.js");
|
|
6
|
+
class DeduplicateJoinsTransformer extends operation_node_transformer_js_1.OperationNodeTransformer {
|
|
7
|
+
transformSelectQuery(node) {
|
|
8
|
+
return this.#transformQuery(super.transformSelectQuery(node));
|
|
9
|
+
}
|
|
10
|
+
transformUpdateQuery(node) {
|
|
11
|
+
return this.#transformQuery(super.transformUpdateQuery(node));
|
|
12
|
+
}
|
|
13
|
+
transformDeleteQuery(node) {
|
|
14
|
+
return this.#transformQuery(super.transformDeleteQuery(node));
|
|
15
|
+
}
|
|
16
|
+
#transformQuery(node) {
|
|
17
|
+
if (!node.joins || node.joins.length === 0) {
|
|
18
|
+
return node;
|
|
19
|
+
}
|
|
20
|
+
return (0, object_utils_js_1.freeze)({
|
|
21
|
+
...node,
|
|
22
|
+
joins: this.#deduplicateJoins(node.joins),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
#deduplicateJoins(joins) {
|
|
26
|
+
const out = [];
|
|
27
|
+
for (let i = 0; i < joins.length; ++i) {
|
|
28
|
+
let foundDuplicate = false;
|
|
29
|
+
for (let j = i + 1; j < joins.length; ++j) {
|
|
30
|
+
if ((0, object_utils_js_1.compare)(joins[i], joins[j])) {
|
|
31
|
+
foundDuplicate = true;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (!foundDuplicate) {
|
|
36
|
+
out.push(joins[i]);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return (0, object_utils_js_1.freeze)(out);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.DeduplicateJoinsTransformer = DeduplicateJoinsTransformer;
|
|
File without changes
|
|
File without changes
|
package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.d.ts
RENAMED
|
File without changes
|
package/dist/cjs/plugin/{immediate-value.ts → immediate-value}/immediate-value-transformer.js
RENAMED
|
File without changes
|
|
@@ -6,7 +6,7 @@ import { SelectExpression } from '../parser/select-parser.js';
|
|
|
6
6
|
import { ExistsExpression, FilterOperator, FilterValueExpressionOrList, WhereGrouper } from '../parser/filter-parser.js';
|
|
7
7
|
import { ReturningRow } from '../parser/returning-parser.js';
|
|
8
8
|
import { ReferenceExpression } from '../parser/reference-parser.js';
|
|
9
|
-
import { AnyRawBuilder, SingleResultType } from '../util/type-utils.js';
|
|
9
|
+
import { AnyRawBuilder, MergePartial, SingleResultType } from '../util/type-utils.js';
|
|
10
10
|
import { Compilable } from '../util/compilable.js';
|
|
11
11
|
import { QueryExecutor } from '../query-executor/query-executor.js';
|
|
12
12
|
import { QueryId } from '../util/query-id.js';
|
|
@@ -16,6 +16,7 @@ import { WhereInterface } from './where-interface.js';
|
|
|
16
16
|
import { JoinInterface } from './join-interface.js';
|
|
17
17
|
import { ReturningInterface } from './returning-interface.js';
|
|
18
18
|
import { NoResultErrorConstructor } from './no-result-error.js';
|
|
19
|
+
import { DeleteResult } from './delete-result.js';
|
|
19
20
|
import { DeleteQueryNode } from '../operation-node/delete-query-node.js';
|
|
20
21
|
import { Selectable } from '../util/column-type.js';
|
|
21
22
|
export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements WhereInterface<DB, TB>, JoinInterface<DB, TB>, ReturningInterface<DB, TB, O>, OperationNodeSource, Compilable {
|
|
@@ -589,23 +590,61 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
|
|
|
589
590
|
/**
|
|
590
591
|
* Simply calls the given function passing `this` as the only argument.
|
|
591
592
|
*
|
|
592
|
-
*
|
|
593
|
+
* If you want to conditionally call a method on `this`, see
|
|
594
|
+
* the {@link if} method.
|
|
593
595
|
*
|
|
594
596
|
* ### Examples
|
|
595
597
|
*
|
|
598
|
+
* The next example uses a helper funtion `log` to log a query:
|
|
599
|
+
*
|
|
596
600
|
* ```ts
|
|
601
|
+
* function log<T extends Compilable>(qb: T): T {
|
|
602
|
+
* console.log(qb.compile())
|
|
603
|
+
* return qb
|
|
604
|
+
* }
|
|
605
|
+
*
|
|
597
606
|
* db.deleteFrom('person')
|
|
598
|
-
* .call(
|
|
599
|
-
* if (something) {
|
|
600
|
-
* return qb.where('something', '=', something)
|
|
601
|
-
* } else {
|
|
602
|
-
* return qb.where('somethingElse', '=', somethingElse)
|
|
603
|
-
* }
|
|
604
|
-
* })
|
|
607
|
+
* .call(log)
|
|
605
608
|
* .execute()
|
|
606
609
|
* ```
|
|
607
610
|
*/
|
|
608
611
|
call<T>(func: (qb: this) => T): T;
|
|
612
|
+
/**
|
|
613
|
+
* Call `func(this)` if `condition` is true.
|
|
614
|
+
*
|
|
615
|
+
* This method is especially handy with optional selects. Any `returning` or `returningAll`
|
|
616
|
+
* method calls add columns as optional fields to the output type when called inside
|
|
617
|
+
* the `func` callback. This is because we can't know if those selections were actually
|
|
618
|
+
* made before running the code.
|
|
619
|
+
*
|
|
620
|
+
* You can also call any other methods inside the callback.
|
|
621
|
+
*
|
|
622
|
+
* ### Examples
|
|
623
|
+
*
|
|
624
|
+
* ```ts
|
|
625
|
+
* async function deletePerson(id: number, returnLastName: boolean) {
|
|
626
|
+
* return await db
|
|
627
|
+
* .deleteFrom('person')
|
|
628
|
+
* .where('id', '=', id)
|
|
629
|
+
* .returning(['id', 'first_name'])
|
|
630
|
+
* .if(returnLastName, (qb) => qb.returning('last_name'))
|
|
631
|
+
* .executeTakeFirstOrThrow()
|
|
632
|
+
* }
|
|
633
|
+
* ```
|
|
634
|
+
*
|
|
635
|
+
* Any selections added inside the `if` callback will be added as optional fields to the
|
|
636
|
+
* output type since we can't know if the selections were actually made before running
|
|
637
|
+
* the code. In the example above the return type of the `deletePerson` function is:
|
|
638
|
+
*
|
|
639
|
+
* ```ts
|
|
640
|
+
* {
|
|
641
|
+
* id: number
|
|
642
|
+
* first_name: string
|
|
643
|
+
* last_name?: string
|
|
644
|
+
* }
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
if<O2>(condition: boolean, func: (qb: this) => DeleteQueryBuilder<DB, TB, O2>): DeleteQueryBuilder<DB, TB, O2 extends DeleteResult ? DeleteResult : O extends DeleteResult ? Partial<O2> : MergePartial<O, O2>>;
|
|
609
648
|
/**
|
|
610
649
|
* Change the output type of the query.
|
|
611
650
|
*
|
|
@@ -613,6 +652,9 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
|
|
|
613
652
|
* don't support your use case.
|
|
614
653
|
*/
|
|
615
654
|
castTo<T>(): DeleteQueryBuilder<DB, TB, T>;
|
|
655
|
+
/**
|
|
656
|
+
* Returns a copy of this DeleteQueryBuilder instance with the given plugin installed.
|
|
657
|
+
*/
|
|
616
658
|
withPlugin(plugin: KyselyPlugin): DeleteQueryBuilder<DB, TB, O>;
|
|
617
659
|
toOperationNode(): DeleteQueryNode;
|
|
618
660
|
compile(): CompiledQuery;
|