kysely 0.7.9 → 0.9.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 (70) hide show
  1. package/README.md +47 -8
  2. package/dist/cjs/dialect/mysql/mysql-driver.js +5 -5
  3. package/dist/cjs/dialect/mysql/mysql-query-compiler.d.ts +0 -2
  4. package/dist/cjs/dialect/mysql/mysql-query-compiler.js +0 -29
  5. package/dist/cjs/dialect/postgres/postgres-driver.js +5 -5
  6. package/dist/cjs/operation-node/create-schema-node.d.ts +1 -1
  7. package/dist/cjs/operation-node/create-schema-node.js +2 -2
  8. package/dist/cjs/operation-node/create-table-node.d.ts +1 -5
  9. package/dist/cjs/operation-node/create-table-node.js +1 -31
  10. package/dist/cjs/operation-node/operation-node-source.d.ts +1 -1
  11. package/dist/cjs/operation-node/operation-node-transformer.js +2 -1
  12. package/dist/cjs/operation-node/primitive-value-list-node.js +1 -1
  13. package/dist/cjs/parser/join-parser.d.ts +6 -3
  14. package/dist/cjs/parser/table-parser.d.ts +18 -7
  15. package/dist/cjs/query-builder/function-builder.d.ts +6 -6
  16. package/dist/cjs/query-builder/function-builder.js +7 -7
  17. package/dist/cjs/query-builder/query-builder.d.ts +7 -7
  18. package/dist/cjs/query-compiler/compiled-query.d.ts +1 -1
  19. package/dist/cjs/query-compiler/default-query-compiler.d.ts +3 -2
  20. package/dist/cjs/query-compiler/default-query-compiler.js +22 -28
  21. package/dist/cjs/query-creator.d.ts +14 -11
  22. package/dist/cjs/query-creator.js +14 -11
  23. package/dist/cjs/raw-builder/raw-builder.d.ts +1 -1
  24. package/dist/cjs/raw-builder/raw-builder.js +6 -6
  25. package/dist/cjs/schema/alter-table-builder.d.ts +3 -0
  26. package/dist/cjs/schema/alter-table-builder.js +3 -0
  27. package/dist/cjs/schema/column-definition-builder.d.ts +14 -5
  28. package/dist/cjs/schema/create-schema-builder.js +1 -1
  29. package/dist/cjs/schema/create-table-builder.d.ts +55 -10
  30. package/dist/cjs/schema/create-table-builder.js +59 -17
  31. package/dist/cjs/schema/schema.d.ts +37 -2
  32. package/dist/cjs/schema/schema.js +36 -1
  33. package/dist/cjs/util/object-utils.d.ts +1 -0
  34. package/dist/cjs/util/object-utils.js +5 -1
  35. package/dist/cjs/util/type-utils.d.ts +3 -0
  36. package/dist/esm/dialect/mysql/mysql-driver.js +5 -5
  37. package/dist/esm/dialect/mysql/mysql-query-compiler.d.ts +0 -2
  38. package/dist/esm/dialect/mysql/mysql-query-compiler.js +0 -29
  39. package/dist/esm/dialect/postgres/postgres-driver.js +5 -5
  40. package/dist/esm/operation-node/create-schema-node.d.ts +1 -1
  41. package/dist/esm/operation-node/create-schema-node.js +2 -2
  42. package/dist/esm/operation-node/create-table-node.d.ts +1 -5
  43. package/dist/esm/operation-node/create-table-node.js +1 -31
  44. package/dist/esm/operation-node/operation-node-source.d.ts +1 -1
  45. package/dist/esm/operation-node/operation-node-transformer.js +2 -1
  46. package/dist/esm/operation-node/primitive-value-list-node.js +1 -1
  47. package/dist/esm/parser/join-parser.d.ts +6 -3
  48. package/dist/esm/parser/table-parser.d.ts +18 -7
  49. package/dist/esm/query-builder/function-builder.d.ts +6 -6
  50. package/dist/esm/query-builder/function-builder.js +7 -7
  51. package/dist/esm/query-builder/query-builder.d.ts +7 -7
  52. package/dist/esm/query-compiler/compiled-query.d.ts +1 -1
  53. package/dist/esm/query-compiler/default-query-compiler.d.ts +3 -2
  54. package/dist/esm/query-compiler/default-query-compiler.js +22 -28
  55. package/dist/esm/query-creator.d.ts +14 -11
  56. package/dist/esm/query-creator.js +14 -11
  57. package/dist/esm/raw-builder/raw-builder.d.ts +1 -1
  58. package/dist/esm/raw-builder/raw-builder.js +6 -6
  59. package/dist/esm/schema/alter-table-builder.d.ts +3 -0
  60. package/dist/esm/schema/alter-table-builder.js +3 -0
  61. package/dist/esm/schema/column-definition-builder.d.ts +14 -5
  62. package/dist/esm/schema/create-schema-builder.js +1 -1
  63. package/dist/esm/schema/create-table-builder.d.ts +55 -10
  64. package/dist/esm/schema/create-table-builder.js +60 -18
  65. package/dist/esm/schema/schema.d.ts +37 -2
  66. package/dist/esm/schema/schema.js +36 -1
  67. package/dist/esm/util/object-utils.d.ts +1 -0
  68. package/dist/esm/util/object-utils.js +3 -0
  69. package/dist/esm/util/type-utils.d.ts +3 -0
  70. package/package.json +6 -6
@@ -155,6 +155,9 @@ export class QueryCreator {
155
155
  * Sets the schema to be used for all table references that don't explicitly
156
156
  * specify a schema.
157
157
  *
158
+ * This only affects the query created through the builder returned from
159
+ * this method and doesn't modify the `db` instance.
160
+ *
158
161
  * @example
159
162
  * ```
160
163
  * await db.withSchema('mammals')
@@ -200,10 +203,10 @@ export class QueryCreator {
200
203
  * Provides a way to pass arbitrary SQL into your query and executing completely
201
204
  * raw queries.
202
205
  *
203
- * You can use strings `?` and `??` in the `sql` to bind parameters such as
206
+ * You can use the strings `?` and `??` in the `sql` to bind parameters such as
204
207
  * user input to the SQL. You should never EVER concatenate untrusted user
205
208
  * input to the SQL string to avoid injection vulnerabilities. Instead use `?`
206
- * in place of the value and pass the actual value in the `params` list. See
209
+ * in place of a value and pass the actual value in the `parameters` list. See
207
210
  * the examples below.
208
211
  *
209
212
  * You should only use `raw` when there is no other way to get the job done. This is
@@ -215,11 +218,11 @@ export class QueryCreator {
215
218
  * Raw builder instances can be passed to pretty much anywhere: `select`, `where`,
216
219
  * `*Join`, `groupBy`, `orderBy` etc. Just try it. If the method accepts it, it works.
217
220
  *
218
- * @param sql - The raw SQL. Special strings `?` and `??` can be used to provide
219
- * parameter bindings. `?` for values and `??` for identifiers such as column names
221
+ * @param sql - The raw SQL. Special strings `?` and `??` can be used as parameter
222
+ * placeholders. `?` for values and `??` for identifiers such as column names
220
223
  * or `column.table` references.
221
224
  *
222
- * @param params - The parameters that will be bound to the `?` and `??` bindings in
225
+ * @param params - The parameters that will be bound to the `?` and `??` placeholders in
223
226
  * the sql string.
224
227
  *
225
228
  * @example
@@ -257,7 +260,7 @@ export class QueryCreator {
257
260
  * the output type. In this case you need to use the `castTo` method on the query
258
261
  * to specify a return type for the query.
259
262
  *
260
- * We could've also used `??` bindings to provide `first_name` and `last_name` like
263
+ * We could've also used a `??` placeholder to provide `first_name` and `last_name` like
261
264
  * this:
262
265
  *
263
266
  * ```ts
@@ -272,9 +275,9 @@ export class QueryCreator {
272
275
  *
273
276
  * But it's often cleaner to just write the column names in the SQL. Again remember to
274
277
  * never concatenate column names or any other untrusted user input to the SQL string or you
275
- * are going to create an injection vulnerability. All user input should go to the bindings
278
+ * are going to create an injection vulnerability. All user input should go to the parameters
276
279
  * array, never to the SQL string directly. But if the column names or values are trusted
277
- * and known at compile time, there is no reason to use bindings.
280
+ * and known at compile time, there is no reason to use parameters.
278
281
  *
279
282
  * @example
280
283
  * Example of using `raw` in `where`:
@@ -300,7 +303,7 @@ export class QueryCreator {
300
303
  *
301
304
  * The function in the above example returns people that are older than the given number of
302
305
  * years. The number of years in this example is an untrusted user input, and therefore we use
303
- * a `?` binding for it.
306
+ * a `?` placeholder for it.
304
307
  *
305
308
  * @example
306
309
  * Example of creating a completely raw query from scratch:
@@ -314,12 +317,12 @@ export class QueryCreator {
314
317
  * The result of `execute()` method is always an array. In this case the type of
315
318
  * the `persons` variable is `Person[]`.
316
319
  */
317
- raw(sql, params) {
320
+ raw(sql, parameters) {
318
321
  return new RawBuilder({
319
322
  queryId: createQueryId(),
320
323
  executor: this.#props.executor,
321
324
  sql,
322
- params,
325
+ parameters,
323
326
  });
324
327
  }
325
328
  }
@@ -41,5 +41,5 @@ export interface RawBuilderProps {
41
41
  readonly queryId: QueryId;
42
42
  readonly executor: QueryExecutor;
43
43
  readonly sql: string;
44
- readonly params?: any;
44
+ readonly parameters?: any;
45
45
  }
@@ -25,24 +25,24 @@ export class RawBuilder {
25
25
  });
26
26
  }
27
27
  toOperationNode() {
28
- const bindingRegex = /(\?\??)/g;
28
+ const parameterPlaceholderRegex = /(\?\??)/g;
29
29
  const sql = this.#props.sql;
30
- const params = this.#props.params ?? [];
30
+ const parameters = this.#props.parameters ?? [];
31
31
  const sqlFragments = [];
32
32
  const argNodes = [];
33
33
  let paramIdx = 0;
34
34
  let sqlIdx = 0;
35
35
  let match = null;
36
- while ((match = bindingRegex.exec(sql))) {
36
+ while ((match = parameterPlaceholderRegex.exec(sql))) {
37
37
  const str = match[1];
38
- if (paramIdx >= params.length) {
39
- throw new Error(`value not provided for all bindings in string ${sql}`);
38
+ if (paramIdx >= parameters.length) {
39
+ throw new Error(`value not provided for all placeholders in string ${sql}`);
40
40
  }
41
41
  if (match.index > 0 && sql[match.index - 1] === '\\') {
42
42
  continue;
43
43
  }
44
44
  sqlFragments.push(sql.slice(sqlIdx, match.index).replaceAll('\\?', '?'));
45
- argNodes.push(parseRawArg(str, params[paramIdx]));
45
+ argNodes.push(parseRawArg(str, parameters[paramIdx]));
46
46
  sqlIdx = match.index + str.length;
47
47
  ++paramIdx;
48
48
  }
@@ -12,6 +12,9 @@ import { QueryId } from '../util/query-id.js';
12
12
  import { QueryExecutor } from '../query-executor/query-executor.js';
13
13
  import { DataTypeExpression } from '../parser/data-type-parser.js';
14
14
  import { ForeignKeyConstraintBuilder, ForeignKeyConstraintBuilderInterface } from './foreign-key-constraint-builder.js';
15
+ /**
16
+ * This builder can be used to create a `alter table` query.
17
+ */
15
18
  export declare class AlterTableBuilder {
16
19
  #private;
17
20
  constructor(props: AlterTableBuilderProps);
@@ -20,6 +20,9 @@ import { UniqueConstraintNode } from '../operation-node/unique-constraint-node.j
20
20
  import { CheckConstraintNode } from '../operation-node/check-constraint-node.js';
21
21
  import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constraint-node.js';
22
22
  import { ColumnNode } from '../operation-node/column-node.js';
23
+ /**
24
+ * This builder can be used to create a `alter table` query.
25
+ */
23
26
  export class AlterTableBuilder {
24
27
  #props;
25
28
  constructor(props) {
@@ -6,11 +6,11 @@ import { AnyRawBuilder } from '../util/type-utils.js';
6
6
  import { DefaultValueExpression } from '../parser/default-value-parser.js';
7
7
  export interface ColumnDefinitionBuilderInterface<R> {
8
8
  /**
9
- * Makes the column automatically incrementing.
9
+ * Adds `auto_increment` or `autoincrement` to the column definition
10
+ * depending on the dialect.
10
11
  *
11
- * On some dialects this may change the column type as well. For example
12
- * on postgres this sets the column type to `serial` no matter what you
13
- * have specified before.
12
+ * Some dialects like PostgreSQL don't support this. On PostgreSQL
13
+ * you can use the `serial` or `bigserial` data type instead.
14
14
  */
15
15
  increments(): R;
16
16
  /**
@@ -23,6 +23,10 @@ export interface ColumnDefinitionBuilderInterface<R> {
23
23
  /**
24
24
  * Adds a foreign key constraint for the column.
25
25
  *
26
+ * If your database engine doesn't support foreign key constraints in the
27
+ * column definition (like MySQL 5) you need to call the table level
28
+ * {@link TableBuilder.addForeignKeyConstraint} method instead.
29
+ *
26
30
  * @example
27
31
  * ```ts
28
32
  * col.references('person.id')
@@ -31,6 +35,11 @@ export interface ColumnDefinitionBuilderInterface<R> {
31
35
  references(ref: string): R;
32
36
  /**
33
37
  * Adds an `on delete` constraint for the foreign key column.
38
+ *
39
+ * If your database engine doesn't support foreign key constraints in the
40
+ * column definition (like MySQL 5) you need to call the table level
41
+ * {@link TableBuilder.addForeignKeyConstraint} method instead.
42
+ *
34
43
  */
35
44
  onDelete(onDelete: OnModifyForeignAction): R;
36
45
  /**
@@ -64,7 +73,7 @@ export interface ColumnDefinitionBuilderInterface<R> {
64
73
  * ```ts
65
74
  * db.schema
66
75
  * .createTable('pet')
67
- * .addColumn('number_of_legs', (col) => col.check('number_of_legs < 5', 'integer'))
76
+ * .addColumn('number_of_legs', 'integer', (col) => col.check('number_of_legs < 5'))
68
77
  * .execute()
69
78
  * ```
70
79
  */
@@ -9,7 +9,7 @@ export class CreateSchemaBuilder {
9
9
  ifNotExists() {
10
10
  return new CreateSchemaBuilder({
11
11
  ...this.#props,
12
- createSchemaNode: CreateSchemaNode.cloneWithModifier(this.#props.createSchemaNode, 'IfNotExists'),
12
+ createSchemaNode: CreateSchemaNode.cloneWith(this.#props.createSchemaNode, { modifier: 'IfNotExists' }),
13
13
  });
14
14
  }
15
15
  toOperationNode() {
@@ -7,7 +7,10 @@ import { ColumnDefinitionBuilder } from './column-definition-builder.js';
7
7
  import { QueryId } from '../util/query-id.js';
8
8
  import { ForeignKeyConstraintBuilder } from './foreign-key-constraint-builder.js';
9
9
  import { DataTypeExpression } from '../parser/data-type-parser.js';
10
- export declare class CreateTableBuilder implements OperationNodeSource, Compilable {
10
+ /**
11
+ * This builder can be used to create a `create table` query.
12
+ */
13
+ export declare class CreateTableBuilder<TB extends string, C extends string = never> implements OperationNodeSource, Compilable {
11
14
  #private;
12
15
  constructor(props: CreateTableBuilderProps);
13
16
  /**
@@ -15,7 +18,7 @@ export declare class CreateTableBuilder implements OperationNodeSource, Compilab
15
18
  *
16
19
  * If the table already exists, no error is thrown if this method has been called.
17
20
  */
18
- ifNotExists(): CreateTableBuilder;
21
+ ifNotExists(): CreateTableBuilder<TB, C>;
19
22
  /**
20
23
  * Adds a column to the table.
21
24
  *
@@ -23,44 +26,86 @@ export declare class CreateTableBuilder implements OperationNodeSource, Compilab
23
26
  * ```ts
24
27
  * await db.schema
25
28
  * .createTable('person')
26
- * .addColumn('int', 'id', (col) => col.increments().primary()),
29
+ * .addColumn('id', 'integer', (col) => col.increments().primaryKey()),
27
30
  * .addColumn('first_name', 'varchar(50), (col) => col.notNull())
28
- * .addColumn('varchar', 'last_name')
29
- * .addColumn('numeric(8, 2)', 'bank_balance')
31
+ * .addColumn('last_name', 'varchar')
32
+ * .addColumn('bank_balance', 'numeric(8, 2)')
30
33
  * .addColumn('data', db.raw('customtype'))
34
+ * .addColumn('parent_id', 'integer', (col) =>
35
+ * col.references('person.id').onDelete('cascade'))
36
+ * )
37
+ * ```
38
+ *
39
+ * With this method, it's once again good to remember that Kysely just builds the query
40
+ * that's as close to the structure of your builder method calls as possible, and doesn't
41
+ * provide the same API for all databses. For example, some databases like older MySQL
42
+ * don't support `references` statement in the column definition. Instead foreign key
43
+ * constraints need to be defined in at the level of the `create table` query. See
44
+ * the next example:
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * .addColumn('parent_id', 'integer')
49
+ * .addForeignKeyConstraint(
50
+ * 'person_parent_id_fk', ['parent_id'], 'person', ['id'],
51
+ * (cb) => cb.onDelete('cascade')
52
+ * )
53
+ * ```
54
+ *
55
+ * Another good example is that PostgreSQL doesn't support the `auto_increment`
56
+ * keyword and you need to define an autoincrementing column for example using
57
+ * `serial`:
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * await db.schema
62
+ * .createTable('person')
63
+ * .addColumn('id', 'serial', (col) => col.primaryKey()),
31
64
  * ```
32
65
  */
33
- addColumn(columnName: string, dataType: DataTypeExpression, build?: ColumnBuilderCallback): CreateTableBuilder;
66
+ addColumn<CN extends string>(columnName: CN, dataType: DataTypeExpression, build?: ColumnBuilderCallback): CreateTableBuilder<TB, C | CN>;
34
67
  /**
35
68
  * Adds a primary key constraint for one or more columns.
36
69
  *
70
+ * The constraint name can be anything you want, but it must be unique
71
+ * across the whole database.
72
+ *
37
73
  * @example
38
74
  * ```ts
39
75
  * addPrimaryKeyConstraint('primary_key', ['first_name', 'last_name'])
40
76
  * ```
41
77
  */
42
- addPrimaryKeyConstraint(constraintName: string, columns: string[]): CreateTableBuilder;
78
+ addPrimaryKeyConstraint(constraintName: string, columns: C[]): CreateTableBuilder<TB, C>;
43
79
  /**
44
80
  * Adds a unique constraint for one or more columns.
45
81
  *
82
+ * The constraint name can be anything you want, but it must be unique
83
+ * across the whole database.
84
+ *
46
85
  * @example
47
86
  * ```ts
48
87
  * addUniqueConstraint('first_name_last_name_unique', ['first_name', 'last_name'])
49
88
  * ```
50
89
  */
51
- addUniqueConstraint(constraintName: string, columns: string[]): CreateTableBuilder;
90
+ addUniqueConstraint(constraintName: string, columns: C[]): CreateTableBuilder<TB, C>;
52
91
  /**
53
92
  * Adds a check constraint.
54
93
  *
94
+ * The constraint name can be anything you want, but it must be unique
95
+ * across the whole database.
96
+ *
55
97
  * @example
56
98
  * ```ts
57
99
  * addCheckConstraint('check_legs', 'number_of_legs < 5')
58
100
  * ```
59
101
  */
60
- addCheckConstraint(constraintName: string, checkExpression: string): CreateTableBuilder;
102
+ addCheckConstraint(constraintName: string, checkExpression: string): CreateTableBuilder<TB, C>;
61
103
  /**
62
104
  * Adds a foreign key constraint.
63
105
  *
106
+ * The constraint name can be anything you want, but it must be unique
107
+ * across the whole database.
108
+ *
64
109
  * @example
65
110
  * ```ts
66
111
  * addForeignKeyConstraint(
@@ -82,7 +127,7 @@ export declare class CreateTableBuilder implements OperationNodeSource, Compilab
82
127
  * )
83
128
  * ```
84
129
  */
85
- addForeignKeyConstraint(constraintName: string, columns: string[], targetTable: string, targetColumns: string[], build?: ForeignKeyConstraintBuilderCallback): CreateTableBuilder;
130
+ addForeignKeyConstraint(constraintName: string, columns: C[], targetTable: string, targetColumns: string[], build?: ForeignKeyConstraintBuilderCallback): CreateTableBuilder<TB, C>;
86
131
  toOperationNode(): CreateTableNode;
87
132
  compile(): CompiledQuery;
88
133
  execute(): Promise<void>;
@@ -2,12 +2,18 @@ import { ColumnDefinitionNode } from '../operation-node/column-definition-node.j
2
2
  import { CreateTableNode } from '../operation-node/create-table-node.js';
3
3
  import { preventAwait } from '../util/prevent-await.js';
4
4
  import { ColumnDefinitionBuilder } from './column-definition-builder.js';
5
- import { freeze } from '../util/object-utils.js';
5
+ import { freeze, noop } from '../util/object-utils.js';
6
6
  import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constraint-node.js';
7
7
  import { ColumnNode } from '../operation-node/column-node.js';
8
8
  import { TableNode } from '../operation-node/table-node.js';
9
9
  import { ForeignKeyConstraintBuilder } from './foreign-key-constraint-builder.js';
10
10
  import { parseDataTypeExpression, } from '../parser/data-type-parser.js';
11
+ import { PrimaryConstraintNode } from '../operation-node/primary-constraint-node.js';
12
+ import { UniqueConstraintNode } from '../operation-node/unique-constraint-node.js';
13
+ import { CheckConstraintNode } from '../operation-node/check-constraint-node.js';
14
+ /**
15
+ * This builder can be used to create a `create table` query.
16
+ */
11
17
  export class CreateTableBuilder {
12
18
  #props;
13
19
  constructor(props) {
@@ -31,18 +37,45 @@ export class CreateTableBuilder {
31
37
  * ```ts
32
38
  * await db.schema
33
39
  * .createTable('person')
34
- * .addColumn('int', 'id', (col) => col.increments().primary()),
40
+ * .addColumn('id', 'integer', (col) => col.increments().primaryKey()),
35
41
  * .addColumn('first_name', 'varchar(50), (col) => col.notNull())
36
- * .addColumn('varchar', 'last_name')
37
- * .addColumn('numeric(8, 2)', 'bank_balance')
42
+ * .addColumn('last_name', 'varchar')
43
+ * .addColumn('bank_balance', 'numeric(8, 2)')
38
44
  * .addColumn('data', db.raw('customtype'))
45
+ * .addColumn('parent_id', 'integer', (col) =>
46
+ * col.references('person.id').onDelete('cascade'))
47
+ * )
48
+ * ```
49
+ *
50
+ * With this method, it's once again good to remember that Kysely just builds the query
51
+ * that's as close to the structure of your builder method calls as possible, and doesn't
52
+ * provide the same API for all databses. For example, some databases like older MySQL
53
+ * don't support `references` statement in the column definition. Instead foreign key
54
+ * constraints need to be defined in at the level of the `create table` query. See
55
+ * the next example:
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * .addColumn('parent_id', 'integer')
60
+ * .addForeignKeyConstraint(
61
+ * 'person_parent_id_fk', ['parent_id'], 'person', ['id'],
62
+ * (cb) => cb.onDelete('cascade')
63
+ * )
64
+ * ```
65
+ *
66
+ * Another good example is that PostgreSQL doesn't support the `auto_increment`
67
+ * keyword and you need to define an autoincrementing column for example using
68
+ * `serial`:
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * await db.schema
73
+ * .createTable('person')
74
+ * .addColumn('id', 'serial', (col) => col.primaryKey()),
39
75
  * ```
40
76
  */
41
- addColumn(columnName, dataType, build) {
42
- let columnBuilder = new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType)));
43
- if (build) {
44
- columnBuilder = build(columnBuilder);
45
- }
77
+ addColumn(columnName, dataType, build = noop) {
78
+ const columnBuilder = build(new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType))));
46
79
  return new CreateTableBuilder({
47
80
  ...this.#props,
48
81
  createTableNode: CreateTableNode.cloneWithColumn(this.#props.createTableNode, columnBuilder.toOperationNode()),
@@ -51,6 +84,9 @@ export class CreateTableBuilder {
51
84
  /**
52
85
  * Adds a primary key constraint for one or more columns.
53
86
  *
87
+ * The constraint name can be anything you want, but it must be unique
88
+ * across the whole database.
89
+ *
54
90
  * @example
55
91
  * ```ts
56
92
  * addPrimaryKeyConstraint('primary_key', ['first_name', 'last_name'])
@@ -59,12 +95,15 @@ export class CreateTableBuilder {
59
95
  addPrimaryKeyConstraint(constraintName, columns) {
60
96
  return new CreateTableBuilder({
61
97
  ...this.#props,
62
- createTableNode: CreateTableNode.cloneWithPrimaryKeyConstraint(this.#props.createTableNode, constraintName, columns),
98
+ createTableNode: CreateTableNode.cloneWithConstraint(this.#props.createTableNode, PrimaryConstraintNode.create(columns, constraintName)),
63
99
  });
64
100
  }
65
101
  /**
66
102
  * Adds a unique constraint for one or more columns.
67
103
  *
104
+ * The constraint name can be anything you want, but it must be unique
105
+ * across the whole database.
106
+ *
68
107
  * @example
69
108
  * ```ts
70
109
  * addUniqueConstraint('first_name_last_name_unique', ['first_name', 'last_name'])
@@ -73,12 +112,15 @@ export class CreateTableBuilder {
73
112
  addUniqueConstraint(constraintName, columns) {
74
113
  return new CreateTableBuilder({
75
114
  ...this.#props,
76
- createTableNode: CreateTableNode.cloneWithUniqueConstraint(this.#props.createTableNode, constraintName, columns),
115
+ createTableNode: CreateTableNode.cloneWithConstraint(this.#props.createTableNode, UniqueConstraintNode.create(columns, constraintName)),
77
116
  });
78
117
  }
79
118
  /**
80
119
  * Adds a check constraint.
81
120
  *
121
+ * The constraint name can be anything you want, but it must be unique
122
+ * across the whole database.
123
+ *
82
124
  * @example
83
125
  * ```ts
84
126
  * addCheckConstraint('check_legs', 'number_of_legs < 5')
@@ -87,12 +129,15 @@ export class CreateTableBuilder {
87
129
  addCheckConstraint(constraintName, checkExpression) {
88
130
  return new CreateTableBuilder({
89
131
  ...this.#props,
90
- createTableNode: CreateTableNode.cloneWithCheckConstraint(this.#props.createTableNode, constraintName, checkExpression),
132
+ createTableNode: CreateTableNode.cloneWithConstraint(this.#props.createTableNode, CheckConstraintNode.create(checkExpression, constraintName)),
91
133
  });
92
134
  }
93
135
  /**
94
136
  * Adds a foreign key constraint.
95
137
  *
138
+ * The constraint name can be anything you want, but it must be unique
139
+ * across the whole database.
140
+ *
96
141
  * @example
97
142
  * ```ts
98
143
  * addForeignKeyConstraint(
@@ -114,14 +159,11 @@ export class CreateTableBuilder {
114
159
  * )
115
160
  * ```
116
161
  */
117
- addForeignKeyConstraint(constraintName, columns, targetTable, targetColumns, build) {
118
- let builder = new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), TableNode.create(targetTable), targetColumns.map(ColumnNode.create), constraintName));
119
- if (build) {
120
- builder = build(builder);
121
- }
162
+ addForeignKeyConstraint(constraintName, columns, targetTable, targetColumns, build = noop) {
163
+ const builder = build(new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), TableNode.create(targetTable), targetColumns.map(ColumnNode.create), constraintName)));
122
164
  return new CreateTableBuilder({
123
165
  ...this.#props,
124
- createTableNode: CreateTableNode.cloneWithForeignKeyConstraint(this.#props.createTableNode, builder.toOperationNode()),
166
+ createTableNode: CreateTableNode.cloneWithConstraint(this.#props.createTableNode, builder.toOperationNode()),
125
167
  });
126
168
  }
127
169
  toOperationNode() {
@@ -22,14 +22,49 @@ export declare class SchemaModule {
22
22
  * ```ts
23
23
  * await db.schema
24
24
  * .createTable('person')
25
- * .addColumn('id', 'int', col => col.primaryKey().increments())
25
+ * .addColumn('id', 'integer', col => col.primaryKey().increments())
26
26
  * .addColumn('first_name', 'varchar', col => col.notNull())
27
27
  * .addColumn('last_name', 'varchar', col => col.notNull())
28
28
  * .addColumn('gender', 'varchar')
29
29
  * .execute()
30
30
  * ```
31
+ *
32
+ * @example
33
+ * This example creates a table with a foreign key. Not all database
34
+ * engines support column-level foreign key constraint definitions.
35
+ * For example if you are using MySQL 5.X see the next example after
36
+ * this one.
37
+ *
38
+ * ```ts
39
+ * await db.schema
40
+ * .createTable('pet')
41
+ * .addColumn('id', 'integer', col => col.primaryKey().increments())
42
+ * .addColumn('owner_id', 'integer', col => col
43
+ * .references('person.id')
44
+ * .onDelete('cascade')
45
+ * )
46
+ * .execute()
47
+ * ```
48
+ *
49
+ * @example
50
+ * This example adds a foreign key constraint for a columns just
51
+ * like the previous example, but using a table-level statement.
52
+ * On MySQL 5.X you need to define foreign key constraints like
53
+ * this:
54
+ *
55
+ * ```ts
56
+ * await db.schema
57
+ * .createTable('pet')
58
+ * .addColumn('id', 'integer', col => col.primaryKey().increments())
59
+ * .addColumn('owner_id', 'integer')
60
+ * .addForeignKeyConstraint(
61
+ * 'pet_owner_id_foreign', ['owner_id'], 'person', ['id'],
62
+ * (constraint) => constraint.onDelete('cascade')
63
+ * )
64
+ * .execute()
65
+ * ```
31
66
  */
32
- createTable(table: string): CreateTableBuilder;
67
+ createTable<TB extends string>(table: TB): CreateTableBuilder<TB, never>;
33
68
  /**
34
69
  * Drop a table.
35
70
  *
@@ -33,12 +33,47 @@ export class SchemaModule {
33
33
  * ```ts
34
34
  * await db.schema
35
35
  * .createTable('person')
36
- * .addColumn('id', 'int', col => col.primaryKey().increments())
36
+ * .addColumn('id', 'integer', col => col.primaryKey().increments())
37
37
  * .addColumn('first_name', 'varchar', col => col.notNull())
38
38
  * .addColumn('last_name', 'varchar', col => col.notNull())
39
39
  * .addColumn('gender', 'varchar')
40
40
  * .execute()
41
41
  * ```
42
+ *
43
+ * @example
44
+ * This example creates a table with a foreign key. Not all database
45
+ * engines support column-level foreign key constraint definitions.
46
+ * For example if you are using MySQL 5.X see the next example after
47
+ * this one.
48
+ *
49
+ * ```ts
50
+ * await db.schema
51
+ * .createTable('pet')
52
+ * .addColumn('id', 'integer', col => col.primaryKey().increments())
53
+ * .addColumn('owner_id', 'integer', col => col
54
+ * .references('person.id')
55
+ * .onDelete('cascade')
56
+ * )
57
+ * .execute()
58
+ * ```
59
+ *
60
+ * @example
61
+ * This example adds a foreign key constraint for a columns just
62
+ * like the previous example, but using a table-level statement.
63
+ * On MySQL 5.X you need to define foreign key constraints like
64
+ * this:
65
+ *
66
+ * ```ts
67
+ * await db.schema
68
+ * .createTable('pet')
69
+ * .addColumn('id', 'integer', col => col.primaryKey().increments())
70
+ * .addColumn('owner_id', 'integer')
71
+ * .addForeignKeyConstraint(
72
+ * 'pet_owner_id_foreign', ['owner_id'], 'person', ['id'],
73
+ * (constraint) => constraint.onDelete('cascade')
74
+ * )
75
+ * .execute()
76
+ * ```
42
77
  */
43
78
  createTable(table) {
44
79
  return new CreateTableBuilder({
@@ -16,3 +16,4 @@ export declare function freeze<T>(obj: T): Readonly<T>;
16
16
  export declare function asArray<T>(arg: T | T[]): T[];
17
17
  export declare function asReadonlyArray<T>(arg: T | ReadonlyArray<T>): ReadonlyArray<T>;
18
18
  export declare function isReadonlyArray(arg: unknown): arg is ReadonlyArray<unknown>;
19
+ export declare function noop<T>(obj: T): T;
@@ -68,3 +68,6 @@ export function asReadonlyArray(arg) {
68
68
  export function isReadonlyArray(arg) {
69
69
  return Array.isArray(arg);
70
70
  }
71
+ export function noop(obj) {
72
+ return obj;
73
+ }
@@ -154,4 +154,7 @@ export declare type ManyResultRowType<O> = O extends InsertResultTypeTag ? numbe
154
154
  export declare type SingleResultRowType<O> = O extends InsertResultTypeTag ? number | undefined : O extends DeleteResultTypeTag ? number : O extends UpdateResultTypeTag ? number : O | undefined;
155
155
  export declare type NonEmptySingleResultRowType<O> = O extends InsertResultTypeTag ? number : O extends DeleteResultTypeTag ? number : O extends UpdateResultTypeTag ? number : O;
156
156
  export declare type UnknownRow = Record<string, unknown>;
157
+ export declare type Nullable<T> = {
158
+ [P in keyof T]: T[P] | null;
159
+ };
157
160
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kysely",
3
- "version": "0.7.9",
3
+ "version": "0.9.1",
4
4
  "description": "Type safe SQL query builder",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,7 +32,7 @@
32
32
  "author": "Sami Koskimäki <sami@jakso.me>",
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
- "@types/node": "^16.10.9"
35
+ "@types/node": "^16.11.9"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/chai": "^4.2.22",
@@ -41,12 +41,12 @@
41
41
  "@types/pg": "^8.6.1",
42
42
  "chai": "^4.3.4",
43
43
  "chai-subset": "^1.6.0",
44
- "mocha": "^9.1.2",
45
- "mysql2": "^2.3.2",
44
+ "mocha": "^9.1.3",
45
+ "mysql2": "^2.3.3",
46
46
  "pg": "^8.7.1",
47
47
  "prettier": "^2.4.1",
48
- "tsd": "^0.18.0",
49
- "typedoc": "^0.22.5",
48
+ "tsd": "^0.19.0",
49
+ "typedoc": "^0.22.9",
50
50
  "typescript": "4.5.2"
51
51
  }
52
52
  }