import { SelectQueryBuilder } from './query-builder/select-query-builder.js' ; import { InsertQueryBuilder } from './query-builder/insert-query-builder.js' ; import { DeleteQueryBuilder } from './query-builder/delete-query-builder.js' ; import { UpdateQueryBuilder } from './query-builder/update-query-builder.js' ; import { DeleteQueryNode } from './operation-node/delete-query-node.js' ; import { InsertQueryNode } from './operation-node/insert-query-node.js' ; import { SelectQueryNode } from './operation-node/select-query-node.js' ; import { UpdateQueryNode } from './operation-node/update-query-node.js' ; import { parseTable , parseTableExpression , parseTableExpressionOrList , TableExpression , TableExpressionDatabase , TableExpressionOrList , TableExpressionTables , TableReference , } from './parser/table-parser.js' ; import { QueryExecutor } from './query-executor/query-executor.js' ; import { RawBuilder } from './raw-builder/raw-builder.js' ; import { CommonTableExpression , parseCommonTableExpression , QueryCreatorWithCommonTableExpression , RecursiveCommonTableExpression , } from './parser/with-parser.js' ; import { WithNode } from './operation-node/with-node.js' ; import { createQueryId } from './util/query-id.js' ; import { WithSchemaPlugin } from './plugin/with-schema/with-schema-plugin.js' ; import { freeze } from './util/object-utils.js' ; import { ParseContext } from './parser/parse-context.js' ; import { InsertResult } from './query-builder/insert-result.js' ; import { DeleteResult } from './query-builder/delete-result.js' ; import { UpdateResult } from './query-builder/update-result.js' ; export class QueryCreator < DB > { readonly #props : QueryCreatorProps ; constructor ( props ) { this . #props = freeze ( props ) ; } /**
     * Creates a `select` query builder for the given table or tables.
     *
     * The tables passed to this method are built as the query's `from` clause.
     *
     * ### Examples
     *
     * Create a select query for one table:
     *
     * ```ts
     * db.selectFrom('person').selectAll()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select * from "person"
     * ```
     *
     * Create a select query for one table with an alias:
     *
     * ```ts
     * const persons = await db.selectFrom('person as p')
     *   .select(['p.id', 'first_name'])
     *   .execute()
     *
     * console.log(persons[0].id)
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "p"."id", "first_name" from "person" as "p"
     * ```
     *
     * Create a select query from a subquery:
     *
     * ```ts
     * const persons = await db.selectFrom(
     *     (eb) => eb.selectFrom('person').select('person.id as identifier').as('p')
     *   )
     *   .select('p.identifier')
     *   .execute()
     *
     * console.log(persons[0].identifier)
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "p"."identifier",
     * from (
     *   select "person"."id" as "identifier" from "person"
     * ) as p
     * ```
     *
     * Create a select query from raw sql:
     *
     * ```ts
     * const items = await db.selectFrom(
     *     db.raw<{ one: number }>('(select 1 as one)').as('q')
     *   )
     *   .select('q.one')
     *   .execute()
     *
     * console.log(items[0].one)
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "q"."one",
     * from (
     *   select 1 as one
     * ) as q
     * ```
     *
     * When you use `raw` you need to also provide the result type of the
     * raw segment / query so that Kysely can figure out what columns are
     * available for the query.
     *
     * The `selectFrom` method also accepts an array for multiple tables. All
     * the above examples can also be used in an array.
     *
     * ```ts
     * const items = await db.selectFrom([
     *     'person as p',
     *     db.selectFrom('pet').select('pet.species').as('a'),
     *     db.raw<{ one: number }>('(select 1 as one)').as('q')
     *   ])
     *   .select(['p.id', 'a.species', 'q.one'])
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "p".id, "a"."species", "q"."one"
     * from
     *   "person" as "p",
     *   (select "pet"."species" from "pet") as a,
     *   (select 1 as one) as "q"
     * ```
     */ selectFrom < TE extends TableExpression < DB , keyof DB > > ( from ) ; selectFrom < TE extends TableExpression < DB , keyof DB > > ( from ) ; selectFrom ( from ) { return new SelectQueryBuilder ( { queryId : createQueryId ( ) , executor : this . #props . executor , parseContext : this . #props . parseContext , queryNode : SelectQueryNode . create ( parseTableExpressionOrList ( this . #props . parseContext , from ) , this . #props . withNode ) , } ) ; } /**
     * Creates an insert query.
     *
     * The return value of this query is an instance of  InsertResult .  InsertResult * has the  InsertResult . insertId field that holds the auto incremented id of
     * the inserted row if the db returned one.
     *
     * See the  InsertQueryBuilder . values method for more info and examples. Also see
     * the  ReturningInterface . 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 < T extends keyof DB & string > ( table ) { return new InsertQueryBuilder ( { queryId : createQueryId ( ) , executor : this . #props . executor , parseContext : this . #props . parseContext , queryNode : InsertQueryNode . create ( parseTable ( table ) , this . #props . withNode ) , } ) ; } /**
     * Creates a delete query.
     *
     * See the  WhereInterface . where method for examples on how to specify
     * a where clause for the delete operation.
     *
     * The return value of the query is an instance of  DeleteResult .
     *
     * ### Examples
     *
     * ```ts
     * const result = await db
     *   .deleteFrom('person')
     *   .where('person.id', '=', 1)
     *   .executeTakeFirst()
     *
     * console.log(result.numDeletedRows)
     * ```
      deleteFrom < TR extends TableReference < DB > > ( table ) { return new DeleteQueryBuilder ( { queryId : createQueryId ( ) , executor : this . #props . executor , parseContext : this . #props . parseContext , queryNode : DeleteQueryNode . create ( parseTableExpression ( this . #props . parseContext , table ) , this . #props . withNode ) , } ) ; } /**
     * Creates an update query.
     *
     * See the  WhereInterface . where method for examples on how to specify
     * a where clause for the update operation.
     *
     * See the  UpdateQueryBuilder . set method for examples on how to
     * specify the updates.
     *
     * The return value of the query is an  UpdateResult .
     *
     * ### Examples
     *
     * ```ts
     * const result = await db
     *   .updateTable('person')
     *   .set({ first_name: 'Jennifer' })
     *   .where('person.id', '=', 1)
     *   .executeTakeFirst()
     *
     * console.log(result.numUpdatedRows)
     * ```
      updateTable < TR extends TableReference < DB > > ( table ) { return new UpdateQueryBuilder ( { queryId : createQueryId ( ) , executor : this . #props . executor , parseContext : this . #props . parseContext , queryNode : UpdateQueryNode . create ( parseTableExpression ( this . #props . parseContext , table ) , 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()
     * ```
     */ with < N extends string , E extends CommonTableExpression < DB , N > > ( name , expression ) { const cte = parseCommonTableExpression ( this . #props . parseContext , name , expression ) ; return new QueryCreator ( { ... this . #props , withNode : this . #props . withNode ? WithNode . cloneWithExpression ( this . #props . withNode , cte ) : WithNode . create ( cte ) , } ) ; } /**
     * Creates a recursive `with` query (Common Table Expression).
     *
     * See the  with method for examples and more documentation.
      withRecursive < N extends string , E extends RecursiveCommonTableExpression < DB , N > > ( name , expression ) { const cte = parseCommonTableExpression ( this . #props . parseContext , name , expression ) ; return new QueryCreator ( { ... this . #props , withNode : this . #props . withNode ? WithNode . cloneWithExpression ( this . #props . withNode , cte ) : WithNode . create ( cte , { recursive : true } ) , } ) ; } /**
     * 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.
     *
     * ### 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 WithSchemaPlugin ( schema ) ) , } ) ; } param sql param params raw < T = unknown > ( sql , parameters ? ) { return new RawBuilder ( { queryId : createQueryId ( ) , executor : this . #props . executor , sql , parameters , } ) ; } } export interface QueryCreatorProps { readonly executor : QueryExecutor ; readonly parseContext : ParseContext ; readonly withNode ? : WithNode ; }