UNPKG

kysely

Version:
601 lines (600 loc) 18.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnDefinitionBuilder = void 0; const check_constraint_node_js_1 = require("../operation-node/check-constraint-node.js"); const references_node_js_1 = require("../operation-node/references-node.js"); const select_all_node_js_1 = require("../operation-node/select-all-node.js"); const reference_parser_js_1 = require("../parser/reference-parser.js"); const column_definition_node_js_1 = require("../operation-node/column-definition-node.js"); const default_value_parser_js_1 = require("../parser/default-value-parser.js"); const generated_node_js_1 = require("../operation-node/generated-node.js"); const default_value_node_js_1 = require("../operation-node/default-value-node.js"); const on_modify_action_parser_js_1 = require("../parser/on-modify-action-parser.js"); class ColumnDefinitionBuilder { #node; constructor(node) { this.#node = node; } /** * Adds `auto_increment` or `autoincrement` to the column definition * depending on the dialect. * * Some dialects like PostgreSQL don't support this. On PostgreSQL * you can use the `serial` or `bigserial` data type instead. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.autoIncrement().primaryKey()) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `id` integer primary key auto_increment * ) * ``` */ autoIncrement() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { autoIncrement: true })); } /** * Makes the column an identity column. * * This only works on some dialects like MS SQL Server (MSSQL). * * For PostgreSQL's `generated always as identity` use {@link generatedAlwaysAsIdentity}. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.identity().primaryKey()) * .execute() * ``` * * The generated SQL (MSSQL): * * ```sql * create table "person" ( * "id" integer identity primary key * ) * ``` */ identity() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { identity: true })); } /** * Makes the column the primary key. * * If you want to specify a composite primary key use the * {@link CreateTableBuilder.addPrimaryKeyConstraint} method. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.primaryKey()) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `id` integer primary key * ) */ primaryKey() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { primaryKey: true })); } /** * Adds a foreign key constraint for the column. * * If your database engine doesn't support foreign key constraints in the * column definition (like MySQL 5) you need to call the table level * {@link CreateTableBuilder.addForeignKeyConstraint} method instead. * * ### Examples * * ```ts * await db.schema * .createTable('pet') * .addColumn('owner_id', 'integer', (col) => col.references('person.id')) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * create table "pet" ( * "owner_id" integer references "person" ("id") * ) * ``` */ references(ref) { const references = (0, reference_parser_js_1.parseStringReference)(ref); if (!references.table || select_all_node_js_1.SelectAllNode.is(references.column)) { throw new Error(`invalid call references('${ref}'). The reference must have format table.column or schema.table.column`); } return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { references: references_node_js_1.ReferencesNode.create(references.table, [ references.column, ]), })); } /** * Adds an `on delete` constraint for the foreign key column. * * If your database engine doesn't support foreign key constraints in the * column definition (like MySQL 5) you need to call the table level * {@link CreateTableBuilder.addForeignKeyConstraint} method instead. * * ### Examples * * ```ts * await db.schema * .createTable('pet') * .addColumn( * 'owner_id', * 'integer', * (col) => col.references('person.id').onDelete('cascade') * ) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * create table "pet" ( * "owner_id" integer references "person" ("id") on delete cascade * ) * ``` */ onDelete(onDelete) { if (!this.#node.references) { throw new Error('on delete constraint can only be added for foreign keys'); } return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { references: references_node_js_1.ReferencesNode.cloneWithOnDelete(this.#node.references, (0, on_modify_action_parser_js_1.parseOnModifyForeignAction)(onDelete)), })); } /** * Adds an `on update` constraint for the foreign key column. * * If your database engine doesn't support foreign key constraints in the * column definition (like MySQL 5) you need to call the table level * {@link CreateTableBuilder.addForeignKeyConstraint} method instead. * * ### Examples * * ```ts * await db.schema * .createTable('pet') * .addColumn( * 'owner_id', * 'integer', * (col) => col.references('person.id').onUpdate('cascade') * ) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * create table "pet" ( * "owner_id" integer references "person" ("id") on update cascade * ) * ``` */ onUpdate(onUpdate) { if (!this.#node.references) { throw new Error('on update constraint can only be added for foreign keys'); } return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { references: references_node_js_1.ReferencesNode.cloneWithOnUpdate(this.#node.references, (0, on_modify_action_parser_js_1.parseOnModifyForeignAction)(onUpdate)), })); } /** * Adds a unique constraint for the column. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('email', 'varchar(255)', col => col.unique()) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `email` varchar(255) unique * ) * ``` */ unique() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { unique: true })); } /** * Adds a `not null` constraint for the column. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('first_name', 'varchar(255)', col => col.notNull()) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `first_name` varchar(255) not null * ) * ``` */ notNull() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { notNull: true })); } /** * Adds a `unsigned` modifier for the column. * * This only works on some dialects like MySQL. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('age', 'integer', col => col.unsigned()) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `age` integer unsigned * ) * ``` */ unsigned() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { unsigned: true })); } /** * Adds a default value constraint for the column. * * ### Examples * * ```ts * await db.schema * .createTable('pet') * .addColumn('number_of_legs', 'integer', (col) => col.defaultTo(4)) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `pet` ( * `number_of_legs` integer default 4 * ) * ``` * * Values passed to `defaultTo` are interpreted as value literals by default. You can define * an arbitrary SQL expression using the {@link sql} template tag: * * ```ts * import { sql } from 'kysely' * * await db.schema * .createTable('pet') * .addColumn( * 'created_at', * 'timestamp', * (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`) * ) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `pet` ( * `created_at` timestamp default CURRENT_TIMESTAMP * ) * ``` */ defaultTo(value) { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { defaultTo: default_value_node_js_1.DefaultValueNode.create((0, default_value_parser_js_1.parseDefaultValueExpression)(value)), })); } /** * Adds a check constraint for the column. * * ### Examples * * ```ts * import { sql } from 'kysely' * * await db.schema * .createTable('pet') * .addColumn('number_of_legs', 'integer', (col) => * col.check(sql`number_of_legs < 5`) * ) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `pet` ( * `number_of_legs` integer check (number_of_legs < 5) * ) * ``` */ check(expression) { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { check: check_constraint_node_js_1.CheckConstraintNode.create(expression.toOperationNode()), })); } /** * Makes the column a generated column using a `generated always as` statement. * * ### Examples * * ```ts * import { sql } from 'kysely' * * await db.schema * .createTable('person') * .addColumn('full_name', 'varchar(255)', * (col) => col.generatedAlwaysAs(sql`concat(first_name, ' ', last_name)`) * ) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `full_name` varchar(255) generated always as (concat(first_name, ' ', last_name)) * ) * ``` */ generatedAlwaysAs(expression) { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { generated: generated_node_js_1.GeneratedNode.createWithExpression(expression.toOperationNode()), })); } /** * Adds the `generated always as identity` specifier. * * This only works on some dialects like PostgreSQL. * * For MS SQL Server (MSSQL)'s identity column use {@link identity}. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.generatedAlwaysAsIdentity().primaryKey()) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * create table "person" ( * "id" integer generated always as identity primary key * ) * ``` */ generatedAlwaysAsIdentity() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { generated: generated_node_js_1.GeneratedNode.create({ identity: true, always: true }), })); } /** * Adds the `generated by default as identity` specifier on supported dialects. * * This only works on some dialects like PostgreSQL. * * For MS SQL Server (MSSQL)'s identity column use {@link identity}. * * ### Examples * * ```ts * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.generatedByDefaultAsIdentity().primaryKey()) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * create table "person" ( * "id" integer generated by default as identity primary key * ) * ``` */ generatedByDefaultAsIdentity() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { generated: generated_node_js_1.GeneratedNode.create({ identity: true, byDefault: true }), })); } /** * Makes a generated column stored instead of virtual. This method can only * be used with {@link generatedAlwaysAs} * * ### Examples * * ```ts * import { sql } from 'kysely' * * await db.schema * .createTable('person') * .addColumn('full_name', 'varchar(255)', (col) => col * .generatedAlwaysAs(sql`concat(first_name, ' ', last_name)`) * .stored() * ) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `full_name` varchar(255) generated always as (concat(first_name, ' ', last_name)) stored * ) * ``` */ stored() { if (!this.#node.generated) { throw new Error('stored() can only be called after generatedAlwaysAs'); } return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { generated: generated_node_js_1.GeneratedNode.cloneWith(this.#node.generated, { stored: true, }), })); } /** * This can be used to add any additional SQL right after the column's data type. * * ### Examples * * ```ts * import { sql } from 'kysely' * * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.primaryKey()) * .addColumn( * 'first_name', * 'varchar(36)', * (col) => col.modifyFront(sql`collate utf8mb4_general_ci`).notNull() * ) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `id` integer primary key, * `first_name` varchar(36) collate utf8mb4_general_ci not null * ) * ``` */ modifyFront(modifier) { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWithFrontModifier(this.#node, modifier.toOperationNode())); } /** * Adds `nulls not distinct` specifier. * Should be used with `unique` constraint. * * This only works on some dialects like PostgreSQL. * * ### Examples * * ```ts * db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.primaryKey()) * .addColumn('first_name', 'varchar(30)', col => col.unique().nullsNotDistinct()) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * create table "person" ( * "id" integer primary key, * "first_name" varchar(30) unique nulls not distinct * ) * ``` */ nullsNotDistinct() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { nullsNotDistinct: true })); } /** * Adds `if not exists` specifier. This only works for PostgreSQL. * * ### Examples * * ```ts * await db.schema * .alterTable('person') * .addColumn('email', 'varchar(255)', col => col.unique().ifNotExists()) * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * alter table "person" add column if not exists "email" varchar(255) unique * ``` */ ifNotExists() { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWith(this.#node, { ifNotExists: true })); } /** * This can be used to add any additional SQL to the end of the column definition. * * ### Examples * * ```ts * import { sql } from 'kysely' * * await db.schema * .createTable('person') * .addColumn('id', 'integer', col => col.primaryKey()) * .addColumn( * 'age', * 'integer', * col => col.unsigned() * .notNull() * .modifyEnd(sql`comment ${sql.lit('it is not polite to ask a woman her age')}`) * ) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * create table `person` ( * `id` integer primary key, * `age` integer unsigned not null comment 'it is not polite to ask a woman her age' * ) * ``` */ modifyEnd(modifier) { return new ColumnDefinitionBuilder(column_definition_node_js_1.ColumnDefinitionNode.cloneWithEndModifier(this.#node, modifier.toOperationNode())); } /** * Simply calls the provided function passing `this` as the only argument. `$call` returns * what the provided function returns. */ $call(func) { return func(this); } toOperationNode() { return this.#node; } } exports.ColumnDefinitionBuilder = ColumnDefinitionBuilder;