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.
- package/LICENSE +21 -0
- package/README.md +139 -14
- 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 +10 -8
- package/dist/cjs/migration/migrator.d.ts +22 -0
- package/dist/cjs/migration/migrator.js +23 -1
- 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 +52 -12
- 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 +54 -14
- package/dist/cjs/query-builder/insert-query-builder.js +58 -10
- package/dist/cjs/query-builder/returning-interface.d.ts +1 -3
- package/dist/cjs/query-builder/select-query-builder.d.ts +65 -24
- package/dist/cjs/query-builder/select-query-builder.js +64 -15
- package/dist/cjs/query-builder/update-query-builder.d.ts +53 -12
- package/dist/cjs/query-builder/update-query-builder.js +57 -8
- package/dist/cjs/query-compiler/default-query-compiler.js +8 -7
- package/dist/cjs/query-creator.d.ts +2 -2
- package/dist/cjs/query-creator.js +2 -2
- package/dist/cjs/query-executor/query-executor.js +3 -2
- package/dist/cjs/raw-builder/raw-builder.d.ts +2 -2
- package/dist/cjs/raw-builder/raw-builder.js +8 -1
- package/dist/cjs/schema/alter-table-builder.js +3 -3
- package/dist/cjs/schema/create-table-builder.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 +10 -8
- package/dist/esm/migration/migrator.d.ts +22 -0
- package/dist/esm/migration/migrator.js +23 -1
- 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 +52 -12
- 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 +54 -14
- package/dist/esm/query-builder/insert-query-builder.js +58 -10
- package/dist/esm/query-builder/returning-interface.d.ts +1 -3
- package/dist/esm/query-builder/select-query-builder.d.ts +65 -24
- package/dist/esm/query-builder/select-query-builder.js +64 -15
- package/dist/esm/query-builder/update-query-builder.d.ts +53 -12
- package/dist/esm/query-builder/update-query-builder.js +57 -8
- package/dist/esm/query-compiler/default-query-compiler.js +8 -7
- package/dist/esm/query-creator.d.ts +2 -2
- package/dist/esm/query-creator.js +2 -2
- package/dist/esm/query-executor/query-executor.js +3 -2
- package/dist/esm/raw-builder/raw-builder.d.ts +2 -2
- package/dist/esm/raw-builder/raw-builder.js +8 -1
- package/dist/esm/schema/alter-table-builder.js +3 -3
- package/dist/esm/schema/create-table-builder.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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Sami Koskimäki
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
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
|
|
|
@@ -200,14 +204,24 @@ export async function down(db: Kysely<any>): Promise<void> {
|
|
|
200
204
|
```
|
|
201
205
|
|
|
202
206
|
The `up` function is called when you update your database schema to next version and `down`
|
|
203
|
-
when you go back to previous version. The only argument
|
|
204
|
-
`Kysely<any>`. It
|
|
205
|
-
should never depend on the current code of your app because they need to work even
|
|
206
|
-
changes
|
|
207
|
+
when you go back to previous version. The only argument for the functions is an instance of
|
|
208
|
+
`Kysely<any>`. It's important to use `Kysely<any>` and not `Kysely<YourDatabase>`. Migrations
|
|
209
|
+
should never depend on the current code of your app because they need to work even when the app
|
|
210
|
+
changes. Migrations need to be "frozen in time".
|
|
207
211
|
|
|
208
212
|
The migrations can use the [Kysely.schema](https://koskimas.github.io/kysely/classes/SchemaModule.html)
|
|
209
213
|
module to modify the schema. Migrations can also run normal queries to modify data.
|
|
210
214
|
|
|
215
|
+
Execution order of the migrations is the alpabetical order of their names. An excellent way to name your
|
|
216
|
+
migrations is to prefix them with an ISO 8601 date string. A date prefix works well in large teams
|
|
217
|
+
where multiple team members may add migrations at the same time in parallel commits without knowing
|
|
218
|
+
about the other migrations.
|
|
219
|
+
|
|
220
|
+
You don't need to store your migrations as separate files if you don't want to. You can easily
|
|
221
|
+
implement your own [MigrationProvider](https://koskimas.github.io/kysely/interfaces/MigrationProvider.html)
|
|
222
|
+
and give it to the [Migrator](https://koskimas.github.io/kysely/classes/Migrator.html) class
|
|
223
|
+
when you instantiate one.
|
|
224
|
+
|
|
211
225
|
### PostgreSQL migration example
|
|
212
226
|
|
|
213
227
|
```ts
|
|
@@ -291,9 +305,9 @@ const migrator = new Migrator(migratorConfig);
|
|
|
291
305
|
await migrator.migrateToLatest(pathToMigrationsFolder)
|
|
292
306
|
```
|
|
293
307
|
|
|
294
|
-
to run all migrations that have not yet been run.
|
|
295
|
-
|
|
296
|
-
documentation for more info.
|
|
308
|
+
to run all migrations that have not yet been run. See the
|
|
309
|
+
[Migrator](https://koskimas.github.io/kysely/classes/Migrator.html)
|
|
310
|
+
class's documentation for more info.
|
|
297
311
|
|
|
298
312
|
Kysely doesn't have a CLI for running migrations and probably never will. This is because Kysely's
|
|
299
313
|
migrations are also written in typescript. To run the migrations, you need to first build the
|
|
@@ -341,14 +355,125 @@ async function migrateToLatest() {
|
|
|
341
355
|
console.error(error)
|
|
342
356
|
process.exit(1)
|
|
343
357
|
}
|
|
358
|
+
|
|
359
|
+
await db.destroy()
|
|
344
360
|
}
|
|
345
361
|
|
|
346
362
|
migrateToLatest()
|
|
347
363
|
```
|
|
348
364
|
|
|
349
|
-
The migration methods use a lock on the database level
|
|
365
|
+
The migration methods use a lock on the database level and parallel calls are executed serially.
|
|
350
366
|
This means that you can safely call `migrateToLatest` and other migration methods from multiple
|
|
351
|
-
server instances simultaneously and the migrations are guaranteed to only be executed once.
|
|
367
|
+
server instances simultaneously and the migrations are guaranteed to only be executed once. The
|
|
368
|
+
locks are also automatically released if the migration process crashes or the connection to the
|
|
369
|
+
database fails.
|
|
370
|
+
|
|
371
|
+
# Deno
|
|
372
|
+
|
|
373
|
+
Kysely doesn't include drivers for deno, but you can still use Kysely as a query builder
|
|
374
|
+
or implement your own driver:
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
// We use jsdeliver to get Kysely from npm. We also need to
|
|
378
|
+
// import the `dist/esm/index-nodeless.js` file instead of the
|
|
379
|
+
// root which has node dependencies.
|
|
380
|
+
import {
|
|
381
|
+
DummyDriver,
|
|
382
|
+
Generated,
|
|
383
|
+
Kysely,
|
|
384
|
+
PostgresAdapter,
|
|
385
|
+
PostgresIntrospector,
|
|
386
|
+
PostgresQueryCompiler,
|
|
387
|
+
} from 'https://cdn.jsdelivr.net/npm/kysely/dist/esm/index-nodeless.js'
|
|
388
|
+
|
|
389
|
+
interface Person {
|
|
390
|
+
id: Generated<number>
|
|
391
|
+
first_name: string
|
|
392
|
+
last_name: string | null
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
interface Database {
|
|
396
|
+
person: Person
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const db = new Kysely<Database>({
|
|
400
|
+
dialect: {
|
|
401
|
+
createAdapter() {
|
|
402
|
+
return new PostgresAdapter()
|
|
403
|
+
},
|
|
404
|
+
createDriver() {
|
|
405
|
+
// You need a driver to be able to execute queries. In this example
|
|
406
|
+
// we use the dummy driver that never does anything.
|
|
407
|
+
return new DummyDriver()
|
|
408
|
+
},
|
|
409
|
+
createIntrospector(db: Kysely<unknown>) {
|
|
410
|
+
return new PostgresIntrospector(db)
|
|
411
|
+
},
|
|
412
|
+
createQueryCompiler() {
|
|
413
|
+
return new PostgresQueryCompiler()
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
const query = db.selectFrom('person').select('id')
|
|
419
|
+
const sql = query.compile()
|
|
420
|
+
|
|
421
|
+
console.log(sql.sql)
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
# Browser
|
|
425
|
+
|
|
426
|
+
Kysely also runs in the browser as long as you import the `dist/esm/index-nodeless.js`
|
|
427
|
+
module instead of the root that has node dependencies. You can also import the
|
|
428
|
+
`dist/cjs/index-nodeless.js` file if you are using commonjs modules instead of ESM.
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import {
|
|
432
|
+
Kysely,
|
|
433
|
+
Generated,
|
|
434
|
+
DummyDriver,
|
|
435
|
+
SqliteAdapter,
|
|
436
|
+
SqliteIntrospector,
|
|
437
|
+
SqliteQueryCompiler,
|
|
438
|
+
} from 'kysely/dist/esm/index-nodeless.js'
|
|
439
|
+
|
|
440
|
+
interface Person {
|
|
441
|
+
id: Generated<number>
|
|
442
|
+
first_name: string
|
|
443
|
+
last_name: string | null
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
interface Database {
|
|
447
|
+
person: Person
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const db = new Kysely<Database>({
|
|
451
|
+
dialect: {
|
|
452
|
+
createAdapter() {
|
|
453
|
+
return new SqliteAdapter()
|
|
454
|
+
},
|
|
455
|
+
createDriver() {
|
|
456
|
+
return new DummyDriver()
|
|
457
|
+
},
|
|
458
|
+
createIntrospector(db: Kysely<unknown>) {
|
|
459
|
+
return new SqliteIntrospector(db)
|
|
460
|
+
},
|
|
461
|
+
createQueryCompiler() {
|
|
462
|
+
return new SqliteQueryCompiler()
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
window.addEventListener('load', () => {
|
|
468
|
+
const sql = db.selectFrom('person').select('id').compile()
|
|
469
|
+
|
|
470
|
+
const result = document.createElement('span')
|
|
471
|
+
result.id = 'result'
|
|
472
|
+
result.innerHTML = sql.sql
|
|
473
|
+
|
|
474
|
+
document.body.appendChild(result)
|
|
475
|
+
})
|
|
476
|
+
```
|
|
352
477
|
|
|
353
478
|
# Why not just contribute to knex
|
|
354
479
|
|
|
@@ -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>({
|
|
@@ -343,12 +345,12 @@ class ConnectionBuilder {
|
|
|
343
345
|
async execute(callback) {
|
|
344
346
|
const connection = await this.#props.driver.acquireConnection();
|
|
345
347
|
const connectionProvider = new single_connection_provider_js_1.SingleConnectionProvider(connection);
|
|
346
|
-
const
|
|
348
|
+
const db = new Kysely({
|
|
347
349
|
...this.#props,
|
|
348
350
|
executor: this.#props.executor.withConnectionProvider(connectionProvider),
|
|
349
351
|
});
|
|
350
352
|
try {
|
|
351
|
-
return await callback(
|
|
353
|
+
return await callback(db);
|
|
352
354
|
}
|
|
353
355
|
finally {
|
|
354
356
|
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
|
+
}
|
|
@@ -32,6 +32,28 @@ class Migrator {
|
|
|
32
32
|
constructor(props) {
|
|
33
33
|
this.#props = (0, object_utils_js_1.freeze)(props);
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns a {@link MigrationInfo} object for each migration.
|
|
37
|
+
*
|
|
38
|
+
* The returned array is sorted by migration name.
|
|
39
|
+
*/
|
|
40
|
+
async getMigrations() {
|
|
41
|
+
const executedMigrations = (await this.#doesTableExists(exports.MIGRATION_TABLE))
|
|
42
|
+
? await this.#props.db
|
|
43
|
+
.selectFrom(exports.MIGRATION_TABLE)
|
|
44
|
+
.select(['name', 'timestamp'])
|
|
45
|
+
.execute()
|
|
46
|
+
: [];
|
|
47
|
+
const migrations = await this.#resolveMigrations();
|
|
48
|
+
return migrations.map(({ name, ...migration }) => {
|
|
49
|
+
const executed = executedMigrations.find((it) => it.name === name);
|
|
50
|
+
return {
|
|
51
|
+
name,
|
|
52
|
+
migration,
|
|
53
|
+
executedAt: executed ? new Date(executed.timestamp) : undefined,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
35
57
|
/**
|
|
36
58
|
* Runs all migrations that have not yet been run.
|
|
37
59
|
*
|
|
@@ -215,7 +237,7 @@ class Migrator {
|
|
|
215
237
|
try {
|
|
216
238
|
await this.#props.db
|
|
217
239
|
.insertInto(exports.MIGRATION_LOCK_TABLE)
|
|
218
|
-
.values({ id: exports.MIGRATION_LOCK_ID })
|
|
240
|
+
.values({ id: exports.MIGRATION_LOCK_ID, is_locked: 0 })
|
|
219
241
|
.execute();
|
|
220
242
|
}
|
|
221
243
|
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,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
|
+
}
|