UNPKG

kysely

Version:
298 lines (297 loc) 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryCreator = void 0; const select_query_builder_js_1 = require("./query-builder/select-query-builder.js"); const insert_query_builder_js_1 = require("./query-builder/insert-query-builder.js"); const delete_query_builder_js_1 = require("./query-builder/delete-query-builder.js"); const update_query_builder_js_1 = require("./query-builder/update-query-builder.js"); const delete_query_node_js_1 = require("./operation-node/delete-query-node.js"); const insert_query_node_js_1 = require("./operation-node/insert-query-node.js"); const select_query_node_js_1 = require("./operation-node/select-query-node.js"); const update_query_node_js_1 = require("./operation-node/update-query-node.js"); const table_parser_js_1 = require("./parser/table-parser.js"); const with_parser_js_1 = require("./parser/with-parser.js"); const with_node_js_1 = require("./operation-node/with-node.js"); const query_id_js_1 = require("./util/query-id.js"); const with_schema_plugin_js_1 = require("./plugin/with-schema/with-schema-plugin.js"); const object_utils_js_1 = require("./util/object-utils.js"); const select_parser_js_1 = require("./parser/select-parser.js"); const merge_query_builder_js_1 = require("./query-builder/merge-query-builder.js"); const merge_query_node_js_1 = require("./operation-node/merge-query-node.js"); class QueryCreator { #props; constructor(props) { this.#props = (0, object_utils_js_1.freeze)(props); } selectFrom(from) { return (0, select_query_builder_js_1.createSelectQueryBuilder)({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: select_query_node_js_1.SelectQueryNode.createFrom((0, table_parser_js_1.parseTableExpressionOrList)(from), this.#props.withNode), }); } selectNoFrom(selection) { return (0, select_query_builder_js_1.createSelectQueryBuilder)({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: select_query_node_js_1.SelectQueryNode.cloneWithSelections(select_query_node_js_1.SelectQueryNode.create(this.#props.withNode), (0, select_parser_js_1.parseSelectArg)(selection)), }); } /** * Creates an insert query. * * The return value of this query is an instance of {@link InsertResult}. {@link InsertResult} * has the {@link InsertResult.insertId | insertId} field that holds the auto incremented id of * the inserted row if the db returned one. * * See the {@link InsertQueryBuilder.values | values} method for more info and examples. Also see * the {@link ReturningInterface.returning | returning} method for a way to return columns * on supported databases like PostgreSQL. * * ### Examples * * ```ts * const result = await db * .insertInto('person') * .values({ * first_name: 'Jennifer', * last_name: 'Aniston' * }) * .executeTakeFirst() * * console.log(result.insertId) * ``` * * Some databases like PostgreSQL support the `returning` method: * * ```ts * const { id } = await db * .insertInto('person') * .values({ * first_name: 'Jennifer', * last_name: 'Aniston' * }) * .returning('id') * .executeTakeFirst() * ``` */ insertInto(table) { return new insert_query_builder_js_1.InsertQueryBuilder({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: insert_query_node_js_1.InsertQueryNode.create((0, table_parser_js_1.parseTable)(table), this.#props.withNode), }); } /** * Creates a replace query. * * A MySQL-only statement similar to {@link InsertQueryBuilder.onDuplicateKeyUpdate} * that deletes and inserts values on collision instead of updating existing rows. * * The return value of this query is an instance of {@link InsertResult}. {@link InsertResult} * has the {@link InsertResult.insertId | insertId} field that holds the auto incremented id of * the inserted row if the db returned one. * * See the {@link InsertQueryBuilder.values | values} method for more info and examples. * * ### Examples * * ```ts * const result = await db * .replaceInto('person') * .values({ * first_name: 'Jennifer', * last_name: 'Aniston' * }) * .executeTakeFirst() * * console.log(result.insertId) * ``` */ replaceInto(table) { return new insert_query_builder_js_1.InsertQueryBuilder({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: insert_query_node_js_1.InsertQueryNode.create((0, table_parser_js_1.parseTable)(table), this.#props.withNode, true), }); } deleteFrom(tables) { return new delete_query_builder_js_1.DeleteQueryBuilder({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: delete_query_node_js_1.DeleteQueryNode.create((0, table_parser_js_1.parseTableExpressionOrList)(tables), this.#props.withNode), }); } updateTable(table) { return new update_query_builder_js_1.UpdateQueryBuilder({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: update_query_node_js_1.UpdateQueryNode.create((0, table_parser_js_1.parseTableExpression)(table), this.#props.withNode), }); } mergeInto(targetTable) { return new merge_query_builder_js_1.MergeQueryBuilder({ queryId: (0, query_id_js_1.createQueryId)(), executor: this.#props.executor, queryNode: merge_query_node_js_1.MergeQueryNode.create((0, table_parser_js_1.parseAliasedTable)(targetTable), this.#props.withNode), }); } /** * Creates a `with` query (Common Table Expression). * * ### Examples * * ```ts * await db * .with('jennifers', (db) => db * .selectFrom('person') * .where('first_name', '=', 'Jennifer') * .select(['id', 'age']) * ) * .with('adult_jennifers', (db) => db * .selectFrom('jennifers') * .where('age', '>', 18) * .select(['id', 'age']) * ) * .selectFrom('adult_jennifers') * .where('age', '<', 60) * .selectAll() * .execute() * ``` * * The CTE name can optionally specify column names in addition to * a name. In that case Kysely requires the expression to retun * rows with the same columns. * * ```ts * await db * .with('jennifers(id, age)', (db) => db * .selectFrom('person') * .where('first_name', '=', 'Jennifer') * // This is ok since we return columns with the same * // names as specified by `jennifers(id, age)`. * .select(['id', 'age']) * ) * .selectFrom('jennifers') * .selectAll() * .execute() * ``` * * The first argument can also be a callback. The callback is passed * a `CTEBuilder` instance that can be used to configure the CTE: * * ```ts * await db * .with( * (cte) => cte('jennifers').materialized(), * (db) => db * .selectFrom('person') * .where('first_name', '=', 'Jennifer') * .select(['id', 'age']) * ) * .selectFrom('jennifers') * .selectAll() * .execute() * ``` */ with(nameOrBuilder, expression) { const cte = (0, with_parser_js_1.parseCommonTableExpression)(nameOrBuilder, expression); return new QueryCreator({ ...this.#props, withNode: this.#props.withNode ? with_node_js_1.WithNode.cloneWithExpression(this.#props.withNode, cte) : with_node_js_1.WithNode.create(cte), }); } /** * Creates a recursive `with` query (Common Table Expression). * * Note that recursiveness is a property of the whole `with` statement. * You cannot have recursive and non-recursive CTEs in a same `with` statement. * Therefore the recursiveness is determined by the **first** `with` or * `withRecusive` call you make. * * See the {@link with} method for examples and more documentation. */ withRecursive(nameOrBuilder, expression) { const cte = (0, with_parser_js_1.parseCommonTableExpression)(nameOrBuilder, expression); return new QueryCreator({ ...this.#props, withNode: this.#props.withNode ? with_node_js_1.WithNode.cloneWithExpression(this.#props.withNode, cte) : with_node_js_1.WithNode.create(cte, { recursive: true }), }); } /** * Returns a copy of this query creator instance with the given plugin installed. */ withPlugin(plugin) { return new QueryCreator({ ...this.#props, executor: this.#props.executor.withPlugin(plugin), }); } /** * Returns a copy of this query creator instance without any plugins. */ withoutPlugins() { return new QueryCreator({ ...this.#props, executor: this.#props.executor.withoutPlugins(), }); } /** * Sets the schema to be used for all table references that don't explicitly * specify a schema. * * This only affects the query created through the builder returned from * this method and doesn't modify the `db` instance. * * See [this recipe](https://github.com/koskimas/kysely/tree/master/site/docs/recipes/schemas.md) * for a more detailed explanation. * * ### Examples * * ``` * await db * .withSchema('mammals') * .selectFrom('pet') * .selectAll() * .innerJoin('public.person', 'public.person.id', 'pet.owner_id') * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * select * from "mammals"."pet" * inner join "public"."person" * on "public"."person"."id" = "mammals"."pet"."owner_id" * ``` * * `withSchema` is smart enough to not add schema for aliases, * common table expressions or other places where the schema * doesn't belong to: * * ``` * await db * .withSchema('mammals') * .selectFrom('pet as p') * .select('p.name') * .execute() * ``` * * The generated SQL (PostgreSQL): * * ```sql * select "p"."name" from "mammals"."pet" as "p" * ``` */ withSchema(schema) { return new QueryCreator({ ...this.#props, executor: this.#props.executor.withPluginAtFront(new with_schema_plugin_js_1.WithSchemaPlugin(schema)), }); } } exports.QueryCreator = QueryCreator;