kysely 0.16.9 → 0.17.1

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 (189) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -2
  3. package/dist/cjs/dialect/mysql/mysql-adapter.js +3 -4
  4. package/dist/cjs/dialect/mysql/mysql-introspector.js +2 -1
  5. package/dist/cjs/dialect/postgres/postgres-adapter.js +3 -2
  6. package/dist/cjs/dialect/sqlite/sqlite-introspector.js +2 -1
  7. package/dist/cjs/driver/connection-provider.d.ts +1 -1
  8. package/dist/cjs/driver/default-connection-provider.d.ts +1 -1
  9. package/dist/cjs/driver/default-connection-provider.js +1 -1
  10. package/dist/cjs/driver/single-connection-provider.d.ts +1 -1
  11. package/dist/cjs/driver/single-connection-provider.js +1 -1
  12. package/dist/cjs/index-nodeless.d.ts +2 -0
  13. package/dist/cjs/index-nodeless.js +2 -0
  14. package/dist/cjs/kysely.d.ts +3 -6
  15. package/dist/cjs/kysely.js +30 -41
  16. package/dist/cjs/migration/migrator.js +4 -4
  17. package/dist/cjs/operation-node/delete-query-node.d.ts +7 -0
  18. package/dist/cjs/operation-node/delete-query-node.js +15 -0
  19. package/dist/cjs/operation-node/operation-node-transformer.js +1 -1
  20. package/dist/cjs/operation-node/raw-node.d.ts +4 -2
  21. package/dist/cjs/operation-node/raw-node.js +8 -2
  22. package/dist/cjs/parser/complex-expression-parser.d.ts +5 -5
  23. package/dist/cjs/parser/complex-expression-parser.js +5 -4
  24. package/dist/cjs/parser/filter-parser.d.ts +9 -9
  25. package/dist/cjs/parser/filter-parser.js +31 -30
  26. package/dist/cjs/parser/group-by-parser.d.ts +1 -2
  27. package/dist/cjs/parser/group-by-parser.js +2 -2
  28. package/dist/cjs/parser/insert-values-parser.d.ts +1 -2
  29. package/dist/cjs/parser/insert-values-parser.js +6 -6
  30. package/dist/cjs/parser/join-parser.d.ts +1 -2
  31. package/dist/cjs/parser/join-parser.js +8 -7
  32. package/dist/cjs/parser/order-by-parser.d.ts +1 -2
  33. package/dist/cjs/parser/order-by-parser.js +4 -4
  34. package/dist/cjs/parser/parse-utils.d.ts +10 -0
  35. package/dist/cjs/parser/parse-utils.js +38 -0
  36. package/dist/cjs/parser/reference-parser.d.ts +2 -3
  37. package/dist/cjs/parser/reference-parser.js +5 -5
  38. package/dist/cjs/parser/select-parser.d.ts +1 -2
  39. package/dist/cjs/parser/select-parser.js +5 -5
  40. package/dist/cjs/parser/table-parser.d.ts +2 -3
  41. package/dist/cjs/parser/table-parser.js +5 -5
  42. package/dist/cjs/parser/update-set-parser.d.ts +1 -2
  43. package/dist/cjs/parser/update-set-parser.js +2 -2
  44. package/dist/cjs/parser/value-parser.d.ts +3 -4
  45. package/dist/cjs/parser/value-parser.js +7 -7
  46. package/dist/cjs/parser/with-parser.d.ts +1 -2
  47. package/dist/cjs/parser/with-parser.js +3 -2
  48. package/dist/cjs/query-builder/delete-query-builder.d.ts +77 -20
  49. package/dist/cjs/query-builder/delete-query-builder.js +81 -14
  50. package/dist/cjs/query-builder/expression-builder.d.ts +4 -13
  51. package/dist/cjs/query-builder/expression-builder.js +12 -21
  52. package/dist/cjs/query-builder/function-builder.d.ts +2 -6
  53. package/dist/cjs/query-builder/function-builder.js +5 -8
  54. package/dist/cjs/query-builder/insert-query-builder.d.ts +11 -9
  55. package/dist/cjs/query-builder/insert-query-builder.js +8 -7
  56. package/dist/cjs/query-builder/join-builder.d.ts +0 -2
  57. package/dist/cjs/query-builder/join-builder.js +8 -8
  58. package/dist/cjs/query-builder/on-conflict-builder.d.ts +24 -20
  59. package/dist/cjs/query-builder/on-conflict-builder.js +17 -17
  60. package/dist/cjs/query-builder/returning-interface.d.ts +2 -2
  61. package/dist/cjs/query-builder/select-query-builder.d.ts +43 -32
  62. package/dist/cjs/query-builder/select-query-builder.js +28 -26
  63. package/dist/cjs/query-builder/update-query-builder.d.ts +29 -25
  64. package/dist/cjs/query-builder/update-query-builder.js +22 -20
  65. package/dist/cjs/query-builder/where-interface.d.ts +20 -16
  66. package/dist/cjs/query-compiler/default-query-compiler.js +16 -7
  67. package/dist/cjs/query-creator.d.ts +24 -138
  68. package/dist/cjs/query-creator.js +19 -145
  69. package/dist/cjs/query-executor/default-query-executor.d.ts +14 -3
  70. package/dist/cjs/query-executor/default-query-executor.js +15 -17
  71. package/dist/cjs/query-executor/noop-query-executor.d.ts +13 -2
  72. package/dist/cjs/query-executor/noop-query-executor.js +9 -2
  73. package/dist/cjs/query-executor/query-executor-provider.d.ts +8 -0
  74. package/dist/cjs/query-executor/query-executor-provider.js +2 -0
  75. package/dist/cjs/query-executor/query-executor.d.ts +14 -6
  76. package/dist/cjs/query-executor/query-executor.js +4 -2
  77. package/dist/cjs/raw-builder/raw-builder.d.ts +42 -11
  78. package/dist/cjs/raw-builder/raw-builder.js +55 -56
  79. package/dist/cjs/raw-builder/sql.d.ts +323 -0
  80. package/dist/cjs/raw-builder/sql.js +153 -0
  81. package/dist/cjs/schema/alter-table-builder.d.ts +20 -8
  82. package/dist/cjs/schema/alter-table-builder.js +3 -3
  83. package/dist/cjs/schema/column-definition-builder.d.ts +20 -8
  84. package/dist/cjs/schema/create-index-builder.d.ts +3 -1
  85. package/dist/cjs/schema/create-index-builder.js +3 -1
  86. package/dist/cjs/schema/create-table-builder.d.ts +6 -2
  87. package/dist/cjs/schema/create-table-builder.js +8 -4
  88. package/dist/cjs/schema/create-view-builder.d.ts +3 -3
  89. package/dist/cjs/schema/create-view-builder.js +3 -3
  90. package/dist/cjs/util/query-id.js +10 -4
  91. package/dist/cjs/util/random-string.js +65 -2
  92. package/dist/esm/dialect/mysql/mysql-adapter.js +3 -4
  93. package/dist/esm/dialect/mysql/mysql-introspector.js +2 -1
  94. package/dist/esm/dialect/postgres/postgres-adapter.js +3 -2
  95. package/dist/esm/dialect/sqlite/sqlite-introspector.js +2 -1
  96. package/dist/esm/driver/connection-provider.d.ts +1 -1
  97. package/dist/esm/driver/default-connection-provider.d.ts +1 -1
  98. package/dist/esm/driver/default-connection-provider.js +1 -1
  99. package/dist/esm/driver/single-connection-provider.d.ts +1 -1
  100. package/dist/esm/driver/single-connection-provider.js +1 -1
  101. package/dist/esm/index-nodeless.d.ts +2 -0
  102. package/dist/esm/index-nodeless.js +2 -0
  103. package/dist/esm/kysely.d.ts +3 -6
  104. package/dist/esm/kysely.js +30 -41
  105. package/dist/esm/migration/migrator.js +4 -4
  106. package/dist/esm/operation-node/delete-query-node.d.ts +7 -0
  107. package/dist/esm/operation-node/delete-query-node.js +15 -0
  108. package/dist/esm/operation-node/operation-node-transformer.js +1 -1
  109. package/dist/esm/operation-node/raw-node.d.ts +4 -2
  110. package/dist/esm/operation-node/raw-node.js +8 -2
  111. package/dist/esm/parser/complex-expression-parser.d.ts +5 -5
  112. package/dist/esm/parser/complex-expression-parser.js +5 -4
  113. package/dist/esm/parser/filter-parser.d.ts +9 -9
  114. package/dist/esm/parser/filter-parser.js +31 -30
  115. package/dist/esm/parser/group-by-parser.d.ts +1 -2
  116. package/dist/esm/parser/group-by-parser.js +2 -2
  117. package/dist/esm/parser/insert-values-parser.d.ts +1 -2
  118. package/dist/esm/parser/insert-values-parser.js +6 -6
  119. package/dist/esm/parser/join-parser.d.ts +1 -2
  120. package/dist/esm/parser/join-parser.js +8 -7
  121. package/dist/esm/parser/order-by-parser.d.ts +1 -2
  122. package/dist/esm/parser/order-by-parser.js +4 -4
  123. package/dist/esm/parser/parse-utils.d.ts +10 -0
  124. package/dist/esm/parser/parse-utils.js +32 -0
  125. package/dist/esm/parser/reference-parser.d.ts +2 -3
  126. package/dist/esm/parser/reference-parser.js +5 -5
  127. package/dist/esm/parser/select-parser.d.ts +1 -2
  128. package/dist/esm/parser/select-parser.js +5 -5
  129. package/dist/esm/parser/table-parser.d.ts +2 -3
  130. package/dist/esm/parser/table-parser.js +5 -5
  131. package/dist/esm/parser/update-set-parser.d.ts +1 -2
  132. package/dist/esm/parser/update-set-parser.js +2 -2
  133. package/dist/esm/parser/value-parser.d.ts +3 -4
  134. package/dist/esm/parser/value-parser.js +7 -7
  135. package/dist/esm/parser/with-parser.d.ts +1 -2
  136. package/dist/esm/parser/with-parser.js +3 -2
  137. package/dist/esm/query-builder/delete-query-builder.d.ts +77 -20
  138. package/dist/esm/query-builder/delete-query-builder.js +81 -14
  139. package/dist/esm/query-builder/expression-builder.d.ts +4 -13
  140. package/dist/esm/query-builder/expression-builder.js +12 -21
  141. package/dist/esm/query-builder/function-builder.d.ts +2 -6
  142. package/dist/esm/query-builder/function-builder.js +5 -8
  143. package/dist/esm/query-builder/insert-query-builder.d.ts +11 -9
  144. package/dist/esm/query-builder/insert-query-builder.js +8 -7
  145. package/dist/esm/query-builder/join-builder.d.ts +0 -2
  146. package/dist/esm/query-builder/join-builder.js +8 -8
  147. package/dist/esm/query-builder/on-conflict-builder.d.ts +24 -20
  148. package/dist/esm/query-builder/on-conflict-builder.js +17 -17
  149. package/dist/esm/query-builder/returning-interface.d.ts +2 -2
  150. package/dist/esm/query-builder/select-query-builder.d.ts +43 -32
  151. package/dist/esm/query-builder/select-query-builder.js +28 -26
  152. package/dist/esm/query-builder/update-query-builder.d.ts +29 -25
  153. package/dist/esm/query-builder/update-query-builder.js +22 -20
  154. package/dist/esm/query-builder/where-interface.d.ts +20 -16
  155. package/dist/esm/query-compiler/default-query-compiler.js +16 -7
  156. package/dist/esm/query-creator.d.ts +24 -138
  157. package/dist/esm/query-creator.js +19 -145
  158. package/dist/esm/query-executor/default-query-executor.d.ts +14 -3
  159. package/dist/esm/query-executor/default-query-executor.js +15 -17
  160. package/dist/esm/query-executor/noop-query-executor.d.ts +13 -2
  161. package/dist/esm/query-executor/noop-query-executor.js +8 -1
  162. package/dist/esm/query-executor/query-executor-provider.d.ts +8 -0
  163. package/dist/esm/query-executor/query-executor-provider.js +2 -0
  164. package/dist/esm/query-executor/query-executor.d.ts +14 -6
  165. package/dist/esm/query-executor/query-executor.js +4 -2
  166. package/dist/esm/raw-builder/raw-builder.d.ts +42 -11
  167. package/dist/esm/raw-builder/raw-builder.js +56 -57
  168. package/dist/esm/raw-builder/sql.d.ts +323 -0
  169. package/dist/esm/raw-builder/sql.js +151 -0
  170. package/dist/esm/schema/alter-table-builder.d.ts +20 -8
  171. package/dist/esm/schema/alter-table-builder.js +3 -3
  172. package/dist/esm/schema/column-definition-builder.d.ts +20 -8
  173. package/dist/esm/schema/create-index-builder.d.ts +3 -1
  174. package/dist/esm/schema/create-index-builder.js +3 -1
  175. package/dist/esm/schema/create-table-builder.d.ts +6 -2
  176. package/dist/esm/schema/create-table-builder.js +8 -4
  177. package/dist/esm/schema/create-view-builder.d.ts +3 -3
  178. package/dist/esm/schema/create-view-builder.js +3 -3
  179. package/dist/esm/util/query-id.js +10 -4
  180. package/dist/esm/util/random-string.js +65 -2
  181. package/package.json +13 -13
  182. package/dist/cjs/parser/parse-context.d.ts +0 -55
  183. package/dist/cjs/parser/parse-context.js +0 -50
  184. package/dist/cjs/util/private-symbols.d.ts +0 -5
  185. package/dist/cjs/util/private-symbols.js +0 -8
  186. package/dist/esm/parser/parse-context.d.ts +0 -55
  187. package/dist/esm/parser/parse-context.js +0 -47
  188. package/dist/esm/util/private-symbols.d.ts +0 -5
  189. package/dist/esm/util/private-symbols.js +0 -6
@@ -1,18 +1,20 @@
1
1
  import { ConnectionProvider } from '../driver/connection-provider.js';
2
- import { QueryResult } from '../driver/database-connection.js';
2
+ import { DatabaseConnection, QueryResult } from '../driver/database-connection.js';
3
3
  import { CompiledQuery } from '../query-compiler/compiled-query.js';
4
4
  import { RootOperationNode } from '../query-compiler/query-compiler.js';
5
5
  import { KyselyPlugin } from '../plugin/kysely-plugin.js';
6
6
  import { QueryId } from '../util/query-id.js';
7
+ import { DialectAdapter } from '../dialect/dialect-adapter.js';
7
8
  /**
8
9
  * This class abstracts away the details of how to compile a query into SQL
9
10
  * and execute it. Instead of passing around all those details, {@link SelectQueryBuilder}
10
11
  * and other classes that execute queries can just pass around and instance of
11
12
  * `QueryExecutor`.
12
13
  */
13
- export declare abstract class QueryExecutor {
14
+ export declare abstract class QueryExecutor implements ConnectionProvider {
14
15
  #private;
15
16
  constructor(plugins?: KyselyPlugin[]);
17
+ abstract get adapter(): DialectAdapter;
16
18
  get plugins(): ReadonlyArray<KyselyPlugin>;
17
19
  /**
18
20
  * Given the query the user has built (expressed as an operation node tree)
@@ -26,15 +28,16 @@ export declare abstract class QueryExecutor {
26
28
  * compile any query using this method.
27
29
  */
28
30
  abstract compileQuery(node: RootOperationNode, queryId: QueryId): CompiledQuery;
31
+ /**
32
+ * Provides a connection for the callback and takes care of disposing
33
+ * the connection after the callback has been run.
34
+ */
35
+ abstract provideConnection<T>(consumer: (connection: DatabaseConnection) => Promise<T>): Promise<T>;
29
36
  /**
30
37
  * Executes a compiled query and runs the result through all plugins'
31
38
  * `transformResult` method.
32
39
  */
33
40
  executeQuery<R>(compiledQuery: CompiledQuery, queryId: QueryId): Promise<QueryResult<R>>;
34
- /**
35
- * Executes a compiled query.
36
- */
37
- protected abstract executeQueryImpl<R>(compiledQuery: CompiledQuery, queryId: QueryId): Promise<QueryResult<R>>;
38
41
  /**
39
42
  * Returns a copy of this executor with a new connection provider.
40
43
  */
@@ -44,6 +47,11 @@ export declare abstract class QueryExecutor {
44
47
  * last plugin.
45
48
  */
46
49
  abstract withPlugin(plugin: KyselyPlugin): QueryExecutor;
50
+ /**
51
+ * Returns a copy of this executor with a list of plugins added
52
+ * as the last plugins.
53
+ */
54
+ abstract withPlugins(plugin: ReadonlyArray<KyselyPlugin>): QueryExecutor;
47
55
  /**
48
56
  * Returns a copy of this executor with a plugin added as the
49
57
  * first plugin.
@@ -44,8 +44,10 @@ export class QueryExecutor {
44
44
  * `transformResult` method.
45
45
  */
46
46
  async executeQuery(compiledQuery, queryId) {
47
- const result = await this.executeQueryImpl(compiledQuery, queryId);
48
- return this.#transformResult(result, queryId);
47
+ return await this.provideConnection(async (connection) => {
48
+ const result = await connection.executeQuery(compiledQuery);
49
+ return this.#transformResult(result, queryId);
50
+ });
49
51
  }
50
52
  async #transformResult(result, queryId) {
51
53
  for (const plugin of this.#plugins) {
@@ -2,25 +2,57 @@ import { QueryResult } from '../driver/database-connection.js';
2
2
  import { AliasNode } from '../operation-node/alias-node.js';
3
3
  import { OperationNodeSource } from '../operation-node/operation-node-source.js';
4
4
  import { RawNode } from '../operation-node/raw-node.js';
5
- import { CompiledQuery } from '../query-compiler/compiled-query.js';
6
- import { QueryExecutor } from '../query-executor/query-executor.js';
7
- import { QueryId } from '../util/query-id.js';
8
5
  import { KyselyPlugin } from '../plugin/kysely-plugin.js';
6
+ import { QueryExecutorProvider } from '../query-executor/query-executor-provider.js';
7
+ import { QueryId } from '../util/query-id.js';
8
+ /**
9
+ * An instance of this class can be used to create raw SQL snippets or queries.
10
+ *
11
+ * You shouldn't need to create `RawBuilder` instances directly. Instead you should
12
+ * use the {@link sql} template tag.
13
+ */
9
14
  export declare class RawBuilder<O = unknown> implements OperationNodeSource {
10
15
  #private;
11
16
  constructor(props: RawBuilderProps);
17
+ /**
18
+ * Returns an aliased version of the SQL expression.
19
+ *
20
+ * In addition to slapping `as "the_alias"` to the end of the SQL,
21
+ * this method also provides strict typing:
22
+ *
23
+ * ```ts
24
+ * const result = await db
25
+ * .selectFrom('person')
26
+ * .select(
27
+ * sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
28
+ * )
29
+ * .executeTakeFirstOrThrow()
30
+ *
31
+ * // `full_name: string` field exists in the result type.
32
+ * console.log(result.full_name)
33
+ * ```
34
+ *
35
+ * The generated SQL (PostgreSQL):
36
+ *
37
+ * ```ts
38
+ * select concat(first_name, ' ', last_name) as "full_name"
39
+ * from "person"
40
+ * ```
41
+ */
12
42
  as<A extends string>(alias: A): AliasedRawBuilder<O, A>;
13
43
  /**
14
44
  * Change the output type of the raw expression.
15
45
  *
16
- * This doesn't produce any SQL. This methods simply returns a copy
17
- * of this `RawBuilder` with a new output type.
46
+ * This method call doesn't change the SQL in any way. This methods simply
47
+ * returns a copy of this `RawBuilder` with a new output type.
18
48
  */
19
49
  castTo<T>(): RawBuilder<T>;
50
+ /**
51
+ * Adds a plugin for this SQL snippet.
52
+ */
20
53
  withPlugin(plugin: KyselyPlugin): RawBuilder<O>;
21
54
  toOperationNode(): RawNode;
22
- compile(): CompiledQuery;
23
- execute(): Promise<QueryResult<O>>;
55
+ execute(executorProvider: QueryExecutorProvider): Promise<QueryResult<O>>;
24
56
  }
25
57
  /**
26
58
  * {@link RawBuilder} with an alias. The result of calling {@link RawBuilder.as}.
@@ -40,8 +72,7 @@ export declare class AliasedRawBuilder<O = unknown, A extends string = never> im
40
72
  constructor(rawBuilder: RawBuilder<O>, alias: A);
41
73
  }
42
74
  export interface RawBuilderProps {
43
- readonly queryId?: QueryId;
44
- readonly executor?: QueryExecutor;
45
- readonly sql: string;
46
- readonly parameters?: ReadonlyArray<unknown>;
75
+ readonly queryId: QueryId;
76
+ readonly rawNode: RawNode;
77
+ readonly plugins?: ReadonlyArray<KyselyPlugin>;
47
78
  }
@@ -1,74 +1,84 @@
1
1
  /// <reference types="./raw-builder.d.ts" />
2
2
  import { AliasNode } from '../operation-node/alias-node.js';
3
- import { isOperationNodeSource, } from '../operation-node/operation-node-source.js';
4
- import { RawNode } from '../operation-node/raw-node.js';
5
- import { ValueNode } from '../operation-node/value-node.js';
6
- import { parseStringReference } from '../parser/reference-parser.js';
7
3
  import { preventAwait } from '../util/prevent-await.js';
8
- import { createQueryId } from '../util/query-id.js';
9
4
  import { freeze } from '../util/object-utils.js';
10
- import { NoopQueryExecutor } from '../query-executor/noop-query-executor.js';
5
+ import { NOOP_QUERY_EXECUTOR } from '../query-executor/noop-query-executor.js';
6
+ /**
7
+ * An instance of this class can be used to create raw SQL snippets or queries.
8
+ *
9
+ * You shouldn't need to create `RawBuilder` instances directly. Instead you should
10
+ * use the {@link sql} template tag.
11
+ */
11
12
  export class RawBuilder {
12
13
  #props;
13
14
  constructor(props) {
14
- this.#props = freeze({
15
- queryId: props.queryId ?? createQueryId(),
16
- executor: props.executor ?? new NoopQueryExecutor(),
17
- sql: props.sql,
18
- parameters: props.parameters,
19
- });
15
+ this.#props = freeze(props);
20
16
  }
17
+ /**
18
+ * Returns an aliased version of the SQL expression.
19
+ *
20
+ * In addition to slapping `as "the_alias"` to the end of the SQL,
21
+ * this method also provides strict typing:
22
+ *
23
+ * ```ts
24
+ * const result = await db
25
+ * .selectFrom('person')
26
+ * .select(
27
+ * sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
28
+ * )
29
+ * .executeTakeFirstOrThrow()
30
+ *
31
+ * // `full_name: string` field exists in the result type.
32
+ * console.log(result.full_name)
33
+ * ```
34
+ *
35
+ * The generated SQL (PostgreSQL):
36
+ *
37
+ * ```ts
38
+ * select concat(first_name, ' ', last_name) as "full_name"
39
+ * from "person"
40
+ * ```
41
+ */
21
42
  as(alias) {
22
43
  return new AliasedRawBuilder(this, alias);
23
44
  }
24
45
  /**
25
46
  * Change the output type of the raw expression.
26
47
  *
27
- * This doesn't produce any SQL. This methods simply returns a copy
28
- * of this `RawBuilder` with a new output type.
48
+ * This method call doesn't change the SQL in any way. This methods simply
49
+ * returns a copy of this `RawBuilder` with a new output type.
29
50
  */
30
51
  castTo() {
31
- return new RawBuilder({
32
- ...this.#props,
33
- });
52
+ return new RawBuilder({ ...this.#props });
34
53
  }
54
+ /**
55
+ * Adds a plugin for this SQL snippet.
56
+ */
35
57
  withPlugin(plugin) {
36
58
  return new RawBuilder({
37
59
  ...this.#props,
38
- executor: this.#props.executor.withPlugin(plugin),
60
+ plugins: this.#props.plugins !== undefined
61
+ ? freeze([...this.#props.plugins, plugin])
62
+ : freeze([plugin]),
39
63
  });
40
64
  }
41
65
  toOperationNode() {
42
- const parameterPlaceholderRegex = /(\?\??)/g;
43
- const sql = this.#props.sql;
44
- const parameters = this.#props.parameters ?? [];
45
- const sqlFragments = [];
46
- const argNodes = [];
47
- let paramIdx = 0;
48
- let sqlIdx = 0;
49
- let match = null;
50
- while ((match = parameterPlaceholderRegex.exec(sql))) {
51
- const str = match[1];
52
- if (paramIdx >= parameters.length) {
53
- throw new Error(`value not provided for all placeholders in string ${sql}`);
54
- }
55
- if (match.index > 0 && sql[match.index - 1] === '\\') {
56
- continue;
57
- }
58
- sqlFragments.push(sql.slice(sqlIdx, match.index).replace(/\\\?/g, '?'));
59
- argNodes.push(parseRawArg(str, parameters[paramIdx]));
60
- sqlIdx = match.index + str.length;
61
- ++paramIdx;
62
- }
63
- sqlFragments.push(sql.slice(sqlIdx));
64
- const rawNode = RawNode.create(sqlFragments, argNodes);
65
- return this.#props.executor.transformQuery(rawNode, this.#props.queryId);
66
+ const executor = this.#props.plugins !== undefined
67
+ ? NOOP_QUERY_EXECUTOR.withPlugins(this.#props.plugins)
68
+ : NOOP_QUERY_EXECUTOR;
69
+ return this.#toOperationNode(executor);
66
70
  }
67
- compile() {
68
- return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
71
+ async execute(executorProvider) {
72
+ const executor = this.#props.plugins !== undefined
73
+ ? executorProvider.getExecutor().withPlugins(this.#props.plugins)
74
+ : executorProvider.getExecutor();
75
+ return executor.executeQuery(this.#compile(executor), this.#props.queryId);
69
76
  }
70
- async execute() {
71
- return this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
77
+ #toOperationNode(executor) {
78
+ return executor.transformQuery(this.#props.rawNode, this.#props.queryId);
79
+ }
80
+ #compile(executor) {
81
+ return executor.compileQuery(this.#toOperationNode(executor), this.#props.queryId);
72
82
  }
73
83
  }
74
84
  preventAwait(RawBuilder, "don't await RawBuilder instances directly. To execute the query you need to call `execute`");
@@ -97,14 +107,3 @@ export class AliasedRawBuilder {
97
107
  this.#alias = alias;
98
108
  }
99
109
  }
100
- function parseRawArg(match, arg) {
101
- if (isOperationNodeSource(arg)) {
102
- return arg.toOperationNode();
103
- }
104
- else if (match === '??') {
105
- return parseStringReference(arg);
106
- }
107
- else {
108
- return ValueNode.create(arg);
109
- }
110
- }
@@ -0,0 +1,323 @@
1
+ import { RawBuilder } from './raw-builder.js';
2
+ export interface Sql {
3
+ <T = unknown>(sqlFragments: TemplateStringsArray, ...parameters: unknown[]): RawBuilder<T>;
4
+ /**
5
+ * This can be used to add runtime column references to SQL snippets.
6
+ *
7
+ * By default `${}` substitutions in {@link sql} template strings get
8
+ * transformed into parameters. You can use this function to tell
9
+ * Kysely to interpret them as column references instead.
10
+ *
11
+ * WARNING! Using this with unchecked inputs WILL lead to SQL injection
12
+ * vulnerabilities. The input is not checked or escaped by Kysely in any way.
13
+ *
14
+ * ```ts
15
+ * const columnRef = 'first_name'
16
+ *
17
+ * sql`select ${sql.ref(columnRef)} from person`
18
+ * ```
19
+ *
20
+ * The generated SQL (PostgreSQL):
21
+ *
22
+ * ```sql
23
+ * select "first_name" from person
24
+ * ```
25
+ *
26
+ * The refefences can also include a table name:
27
+ *
28
+ * ```ts
29
+ * const columnRef = 'person.first_name'
30
+ *
31
+ * sql`select ${sql.ref(columnRef)}} from person`
32
+ * ```
33
+ *
34
+ * The generated SQL (PostgreSQL):
35
+ *
36
+ * ```sql
37
+ * select "person"."first_name" from person
38
+ * ```
39
+ *
40
+ * The refefences can also include a schema on supported databases:
41
+ *
42
+ * ```ts
43
+ * const columnRef = 'public.person.first_name'
44
+ *
45
+ * sql`select ${sql.ref(columnRef)}} from person`
46
+ * ```
47
+ *
48
+ * The generated SQL (PostgreSQL):
49
+ *
50
+ * ```sql
51
+ * select "public"."person"."first_name" from person
52
+ * ```
53
+ */
54
+ ref(columnReference: string): RawBuilder<unknown>;
55
+ /**
56
+ * This can be used to add runtime table references to SQL snippets.
57
+ *
58
+ * By default `${}` substitutions in {@link sql} template strings get
59
+ * transformed into parameters. You can use this function to tell
60
+ * Kysely to interpret them as table references instead.
61
+ *
62
+ * WARNING! Using this with unchecked inputs WILL lead to SQL injection
63
+ * vulnerabilities. The input is not checked or escaped by Kysely in any way.
64
+ *
65
+ * ```ts
66
+ * const table = 'person'
67
+ *
68
+ * sql`select first_name from ${sql.table(table)}`
69
+ * ```
70
+ *
71
+ * The generated SQL (PostgreSQL):
72
+ *
73
+ * ```sql
74
+ * select first_name from "person"
75
+ * ```
76
+ *
77
+ * The refefences can also include a schema on supported databases:
78
+ *
79
+ * ```ts
80
+ * const table = 'public.person'
81
+ *
82
+ * sql`select first_name from ${sql.table(table)}`
83
+ * ```
84
+ *
85
+ * The generated SQL (PostgreSQL):
86
+ *
87
+ * ```sql
88
+ * select first_name from "public"."person"
89
+ * ```
90
+ */
91
+ table(tableReference: string): RawBuilder<unknown>;
92
+ /**
93
+ * This can be used to add arbitrary identifiers to SQL snippets.
94
+ *
95
+ * Does the same thing as {@link Sql.ref | ref} and {@link Sql.table | table}
96
+ * but can also be used for any other identifiers like index names.
97
+ *
98
+ * You should use {@link Sql.ref | ref} and {@link Sql.table | table}
99
+ * instead of this whenever possible as they produce a more sematic
100
+ * operation node tree.
101
+ *
102
+ * WARNING! Using this with unchecked inputs WILL lead to SQL injection
103
+ * vulnerabilities. The input is not checked or escaped by Kysely in any way.
104
+ *
105
+ * ```ts
106
+ * const indexName = 'person_first_name_index'
107
+ *
108
+ * sql`create index ${indexName} on person`
109
+ * ```
110
+ *
111
+ * The generated SQL (PostgreSQL):
112
+ *
113
+ * ```sql
114
+ * create index "person_first_name_index" on person
115
+ * ```
116
+ *
117
+ * Multiple identifiers get separated by dots:
118
+ *
119
+ * ```ts
120
+ * const schema = 'public'
121
+ * const columnName = 'first_name'
122
+ * const table = 'person'
123
+ *
124
+ * sql`select ${sql.id(schema, table, columnName)}} from ${sql.id(schema, table)}`
125
+ * ```
126
+ *
127
+ * The generated SQL (PostgreSQL):
128
+ *
129
+ * ```sql
130
+ * select "public"."person"."first_name" from "public"."person"
131
+ * ```
132
+ */
133
+ id(...ids: string[]): RawBuilder<unknown>;
134
+ /**
135
+ * This can be used to add literal values to SQL snippets.
136
+ *
137
+ * WARNING! Using this with unchecked inputs WILL lead to SQL injection
138
+ * vulnerabilities. The input is not checked or escaped by Kysely in any way.
139
+ * You almost always want to use normal substitutions that get sent to the
140
+ * db as parameters.
141
+ *
142
+ * ```ts
143
+ * const firstName = 'first_name'
144
+ *
145
+ * sql`select * from person where first_name = ${sql.literal(firstName)}`
146
+ * ```
147
+ *
148
+ * The generated SQL (PostgreSQL):
149
+ *
150
+ * ```sql
151
+ * select * from person where first_name = 'first_name'
152
+ * ```
153
+ *
154
+ * As you can see from the example above, the value was added directly to
155
+ * the SQL string instead of as a parameter. Only use this function when
156
+ * something can't be sent as a parameter.
157
+ */
158
+ literal(value: unknown): RawBuilder<unknown>;
159
+ /**
160
+ * This can be used to add arbitrary runtime SQL to SQL snippets.
161
+ *
162
+ * WARNING! Using this with unchecked inputs WILL lead to SQL injection
163
+ * vulnerabilities. The input is not checked or escaped by Kysely in any way.
164
+ *
165
+ * ```ts
166
+ * const firstName = "'first_name'"
167
+ *
168
+ * sql`select * from person where first_name = ${sql.raw(firstName)}`
169
+ * ```
170
+ *
171
+ * The generated SQL (PostgreSQL):
172
+ *
173
+ * ```sql
174
+ * select * from person where first_name = 'first_name'
175
+ * ```
176
+ *
177
+ * Note that the difference to `sql.literal` is that this function
178
+ * doesn't assume the inputs are values. The input to this function
179
+ * can be any sql and it's simply glued to the parent string as-is.
180
+ */
181
+ raw(anySql: string): RawBuilder<unknown>;
182
+ /**
183
+ * This can be used to add lists of things to SQL snippets.
184
+ *
185
+ * ### Examples
186
+ *
187
+ * ```ts
188
+ * function findByNicknames(nicknames: string[]): Promise<Person[]> {
189
+ * return db
190
+ * .selectFrom('person')
191
+ * .selectAll()
192
+ * .where('nicknames', '@>', sql`ARRAY[${sql.join(nicknames)}]`)
193
+ * .execute()
194
+ * }
195
+ * ```
196
+ *
197
+ * The generated SQL (PostgreSQL):
198
+ *
199
+ * ```sql
200
+ * select * from "person"
201
+ * where "nicknames" @> ARRAY[$1, $2, $3, $4, $5, $6, $7, $8]
202
+ * ```
203
+ *
204
+ * The second argument is the joining SQL expression that defaults
205
+ * to
206
+ *
207
+ * ```ts
208
+ * sql`, `
209
+ * ```
210
+ *
211
+ * In addition to values, items in the list can be also {@link sql}
212
+ * expressions, queries or anything else the normal substitutions
213
+ * support:
214
+ *
215
+ * ```ts
216
+ * const things = [
217
+ * 123,
218
+ * sql`(1 == 1)`,
219
+ * db.selectFrom('person').selectAll(),
220
+ * sql.literal(false),
221
+ * sql.id('first_name')
222
+ * ]
223
+ *
224
+ * sql`BEFORE ${sql.array(things, sql`::varchar, `)} AFTER`
225
+ * ```
226
+ *
227
+ * The generated SQL (PostgreSQL):
228
+ *
229
+ * ```sql
230
+ * BEFORE $1::varchar, (1 == 1)::varchar, (select * from "person")::varchar, false::varchar, "first_name" AFTER
231
+ * ```
232
+ */
233
+ join(array: unknown[], separator?: RawBuilder<any>): RawBuilder<unknown>;
234
+ }
235
+ /**
236
+ * Template tag for creating raw SQL snippets and queries.
237
+ *
238
+ * ```ts
239
+ * import { sql } from 'kysely'
240
+ *
241
+ * const id = 123
242
+ *
243
+ * const snippet = sql<Person[]>`select * from person where id = ${id}`
244
+ * ```
245
+ *
246
+ * Substitutions (the things inside `${}`) are automatically passed to the database
247
+ * as parameters and are NOT interpolated to the SQL string. There's no need to worry
248
+ * about SQL injection vulnerabilities.
249
+ *
250
+ * If you need your substitutions to be interpreted as identifiers, value literals or
251
+ * lists of things, see the {@link Sql.ref}, {@link Sql.table}, {@link Sql.id},
252
+ * {@link Sql.literal}, {@link Sql.raw} and {@link Sql.join} functions.
253
+ *
254
+ * You can pass sql snippets returned by the `sql` tag pretty much anywhere. Whenever
255
+ * something can't be done using the Kysely API, you should be able to drop down to
256
+ * raw SQL using the `sql` tag. Here's an example query that uses raw sql in a bunch
257
+ * of methods:
258
+ *
259
+ * ```ts
260
+ * const persons = await db
261
+ * .selectFrom('person')
262
+ * .select(
263
+ * // If you use `sql` in a select statement, remember to call the `as`
264
+ * // method to give it an alias. Otherwise Kysely is not able to add
265
+ * // the column to the result type.
266
+ * sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
267
+ * )
268
+ * .where(sql`birthdate between ${date1} and ${date2}`)
269
+ * // Here we assume we have list of nicknames for the person
270
+ * // (a list of strings) and we use the PostgreSQL `@>` operator
271
+ * // to test if all of them are valid nicknames for the user.
272
+ * .where('nicknames', '@>', sql`ARRAY[${sql.join(nicknames)}]`)
273
+ * .orderBy(sql`concat(first_name, ' ', last_name)`)
274
+ * .execute()
275
+ * ```
276
+ *
277
+ * The generated SQL (PostgreSQL):
278
+ *
279
+ * ```sql
280
+ * select concat(first_name, ' ', last_name) as "full_name"
281
+ * from "person"
282
+ * where birthdate between $1 and $2
283
+ * and "nicknames" @> ARRAY[$3, $4, $5, $6, $7, $8, $9, $10]
284
+ * order by concate(first_name, ' ', last_name)
285
+ * ```
286
+ *
287
+ * SQL snippets can be executed by calling the `execute` method and passing a `Kysely`
288
+ * instance as the only argument:
289
+ *
290
+ * ```ts
291
+ * const result = await sql<Person[]>`select * from person`.execute(db)
292
+ * ```
293
+ *
294
+ * You can merge other `sql` expressions and queries using substitutions:
295
+ *
296
+ * ```ts
297
+ * const petName = db.selectFrom('pet').select('name').limit(1)
298
+ * const fullName = sql`concat(first_name, ' ', last_name)`
299
+ *
300
+ * sql`
301
+ * select ${fullName} as full_name, ${petName} as pet_name
302
+ * from person
303
+ * `
304
+ * ```
305
+ *
306
+ * Substitutions also handle {@link ExpressionBuilder.ref},
307
+ * {@link DynamicModule.ref} and pretty much anything else you
308
+ * throw at it. Here's an example of calling a function in a
309
+ * type-safe way:
310
+ *
311
+ * ```ts
312
+ * db.selectFrom('person')
313
+ * .select([
314
+ * 'first_name',
315
+ * 'last_name',
316
+ * (eb) => sql<string>`concat(${eb.ref('first_name')}, ' ', ${eb.ref('last_name')})`.as('full_name')
317
+ * ])
318
+ * ```
319
+ *
320
+ * don't know if that amount of ceremony is worth the small increase in
321
+ * type-safety though... But it's possible.
322
+ */
323
+ export declare const sql: Sql;