@rvoh/dream
    Preparing search index...

    Class QueryDriverBase<DreamInstance>

    Type Parameters

    • DreamInstance extends Dream

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    connectionOverride: DbConnectionType | undefined
    dreamClass: DreamConstructorType<DreamInstance>
    dreamInstance: DreamInstance
    dreamTransaction: DreamTransaction<Dream, any> | null = null
    innerJoinDreamClasses: readonly typeof Dream[] = ...

    stores the Dream models joined in this Query instance

    query: Query<DreamInstance, any>
    supportsAdvisoryTransactionLocks: boolean = false

    Whether this driver implements the transaction-scoped advisory lock seam (acquireAdvisoryTransactionLocks). Adapters that can hold a key-addressed lock for the life of a transaction override this to true. It defaults to false so that a driver without the primitive fails loud for features that depend on it (today, the Sortable decorator) rather than silently racing on position values.

    supportsParallelTestDatabases: boolean = false

    Whether this driver implements the per-worker test-database claim seam (openTestDatabaseLockSession). Adapters that can hold a process-lifetime, auto-releasing lock to reserve one database from the test pool override this to true. It defaults to false so that a new adapter fails loud under vitest rather than silently sharing a single database across overlapping workers — see src/db/testDatabasePool.ts.

    Methods

    • Internal

      Adapter seam for exclusive row locking. Given the select statement about to be executed, return a statement that additionally acquires an exclusive lock on each row it returns, held until the enclosing transaction commits or rolls back (Postgres: SELECT ... FOR UPDATE OF <table>).

      This is only ever reached when a caller opts into a locked read (today, Query#destroy({ lock: true })), and only from inside a transaction. The base implementation throws so that an adapter which has not implemented row locking fails loud rather than silently performing an unlocked read and quietly dropping the compare-and-set guarantee the caller asked for.

      Parameters

      • kyselyQuery: SelectQueryBuilder<any, any, any>

        the select statement to lock

      • tableAlias: string

        the alias of the Query's base table; only rows of that table are locked, so a joined query does not lock unrelated rows and does not fail on the nullable side of an outer join

      Returns SelectQueryBuilder<any, any, any>

    • Internal

      Prevents mutation paths that discard an association query's ownership constraint.

      Returns void

    • Internal

      The order statements that the declared order of the associations the Query is built on or joins contributes to its ORDER BY, in the order they sort, each column namespaced by the alias it is read from. Cursor pagination folds these into its cursor.

      Returns OrderQueryStatement<string>[]

      An array of namespaced order statements

    • Retrieves the average value of the specified column for this Query

      await Game.query().avg('score')
      // 1

      Parameters

      • columnName: string

        a column name on the model

      Returns Promise<any>

      the average of the values of the specified column for this Query

    • Retrieves the average of the specified column within each group, keyed by the value of the provided group column.

      await CompositionAsset.query().avgBy('name', 'score')
      // Map(2) { 'primary' => 5, 'secondary' => 4 }

      Parameters

      • groupColumn: string

        the column to group by

      • aggregatedColumn: string

        the column to average within each group

      Returns Promise<Map<any, any>>

      A Map from each present group value to the average of the aggregated column in that group

    • Retrieves the number of records in the database

      await User.query().count()
      

      Returns Promise<number>

      The number of records in the database

    • Retrieves the number of records in each group, keyed by the value of the provided group column.

      await User.query().countBy('name')
      // Map(2) { 'fred' => 2, 'zed' => 1 }

      Parameters

      • groupColumn: string

        the column to group by

      Returns Promise<Map<any, number>>

      A Map from each present group value to the number of records in that group

    • Internal

      This method is used internally by a Query driver to take the result of a single row in a database, and turn that row into the provided dream instance.

      If needed, the return type can be overriden to explicitly define the resulting dream instance, in cases where a proper type for the dream class cannot be inferred, i.e.

      this.dbResultToDreamInstance<typeof Dream, DreamInstance>(result, this.dreamClass)
      

      Type Parameters

      Parameters

      • result: any
      • dreamClass: typeof Dream

      Returns RetType

    • executes provided query instance as a deletion query.

      Returns Promise<number>

      the number of deleted rows

    • Internal

      Used to hydrate dreams with the provided associations

      Parameters

      • dreams: Dream[]
      • association: AssociationStatement
      • preloadedDreamsAndWhatTheyPointTo: PreloadedDreamsAndWhatTheyPointTo[]

      Returns void

    • Internal

      The primary key of each table the Query reaches through a HasOne or HasMany association (one it joins, one an association it joins goes through, or one its association query is built on), namespaced by the alias it is read from, in join order. Such a join can return a row of the Query's table once for each row it matches, and these keys, with the Query's own primary key, tell those rows apart. Cursor pagination pages by them after the Query's own primary key.

      Returns string[]

      An array of namespaced primary key columns

    • Retrieves the max value of the specified column for this Query

      await User.query().max('id')
      // 99

      Parameters

      • columnName: string

        a column name on the model

      Returns Promise<any>

      the max value of the specified column for this Query

    • Retrieves the max value of the specified column within each group, keyed by the value of the provided group column.

      await CompositionAsset.query().maxBy('name', 'score')
      // Map(2) { 'primary' => 9, 'secondary' => 4 }

      Parameters

      • groupColumn: string

        the column to group by

      • aggregatedColumn: string

        the column to take the max of within each group

      Returns Promise<Map<any, any>>

      A Map from each present group value to the max of the aggregated column in that group

    • Retrieves the min value of the specified column for this Query

      await User.query().min('id')
      // 1

      Parameters

      • columnName: string

        a column name on the model

      Returns Promise<any>

      the min value of the specified column for this Query

    • Retrieves the min value of the specified column within each group, keyed by the value of the provided group column.

      await CompositionAsset.query().minBy('name', 'score')
      // Map(2) { 'primary' => 1, 'secondary' => 4 }

      Parameters

      • groupColumn: string

        the column to group by

      • aggregatedColumn: string

        the column to take the min of within each group

      Returns Promise<Map<any, any>>

      A Map from each present group value to the min of the aggregated column in that group

    • Returns a new Kysely SelectQueryBuilder instance to be used in a sub Query

      const records = await User.where({
      id: Post.query().nestedSelect('userId'),
      }).all()
      // [User{id: 1}, ...]

      Type Parameters

      • SimpleFieldType extends
            | number
            | typeof iterator
            | "toString"
            | "charAt"
            | "charCodeAt"
            | "concat"
            | "indexOf"
            | "lastIndexOf"
            | "localeCompare"
            | "match"
            | "replace"
            | "search"
            | "slice"
            | "split"
            | "substring"
            | "toLowerCase"
            | "toLocaleLowerCase"
            | "toUpperCase"
            | "toLocaleUpperCase"
            | "trim"
            | "length"
            | "substr"
            | "valueOf"
            | "codePointAt"
            | "includes"
            | "endsWith"
            | "normalize"
            | "repeat"
            | "startsWith"
            | "anchor"
            | "big"
            | "blink"
            | "bold"
            | "fixed"
            | "fontcolor"
            | "fontsize"
            | "italics"
            | "link"
            | "small"
            | "strike"
            | "sub"
            | "sup"
            | "padStart"
            | "padEnd"
            | "trimEnd"
            | "trimStart"
            | "trimLeft"
            | "trimRight"
            | "matchAll"
            | "replaceAll"
            | "at"
            | "toLocaleString"
      • PluckThroughFieldType

      Parameters

      Returns SelectQueryBuilder<any, any, any>

      A Kysely SelectQueryBuilder instance

    • Internal

      A page of a select that keeps one row of each group (DISTINCT ON, as a Query that calls distinct, or an association that declares distinct, produces), or null for any other select, whose pages cursor pagination reads as it reads any select's.

      The page is the values of the Query's order statement columns for each row the select returns that matches any of rowsAfter (every row when it is null), sorted by the Query's order statements and limited by its limit. The select chooses each group's row before rowsAfter narrows the rows, so that the page holds only rows the select returns.

      A driver whose selects never keep one row of each group returns null.

      Parameters

      • rowsAfter: Record<string, unknown>[] | null

        where statements, any of which a row of the page matches

      Returns Promise<unknown[][] | null>

      The page's rows, each an array of its order statement columns' values, or null

    • Internal

      For a select that keeps one row of each group (DISTINCT ON, as a Query that calls distinct, or an association that declares distinct, produces), the values of rowKeyColumns for every row it returns, sorted by those columns, ascending; null for any other select. findEach and pluckEach read a select that keeps one row of each group from these keys rather than by a cursor, which would narrow the select before it chooses each group's row.

      A driver whose selects never keep one row of each group returns null.

      Parameters

      • rowKeyColumns: string[]

        the namespaced columns that tell the select's rows apart

      Returns Promise<unknown[][] | null>

      The rows' values of rowKeyColumns, or null

    • Returns the sql that would be executed by this Query

      User.where({ email: 'how@yadoin' }).sql()
      // {
      // query: {
      // kind: 'SelectQueryNode',
      // from: { kind: 'FromNode', froms: [Array] },
      // selections: [ [Object] ],
      // distinctOn: undefined,
      // joins: undefined,
      // groupBy: undefined,
      // orderBy: undefined,
      // where: { kind: 'WhereNode', where: [Object] },
      // frontModifiers: undefined,
      // endModifiers: undefined,
      // limit: undefined,
      // offset: undefined,
      // with: undefined,
      // having: undefined,
      // explain: undefined,
      // setOperations: undefined
      // },
      // sql: 'select "users".* from "users" where ("users"."email" = $1 and "users"."deleted_at" is null)',
      // parameters: [ 'how@yadoin' ]
      //}

      Returns CompiledQuery<object>

      An object representing the underlying sql statement

    • Retrieves the sum value of the specified column for this Query

      await Game.query().sum('score')
      // 1

      Parameters

      • columnName: string

        a column name on the model

      Returns Promise<any>

      the sum of the values of the specified column for this Query

    • Retrieves the sum of the specified column within each group, keyed by the value of the provided group column.

      await CompositionAsset.query().sumBy('name', 'score')
      // Map(2) { 'primary' => 10, 'secondary' => 4 }

      Parameters

      • groupColumn: string

        the column to group by

      • aggregatedColumn: string

        the column to sum within each group

      Returns Promise<Map<any, any>>

      A Map from each present group value to the sum of the aggregated column in that group

    • Retrieves an array containing all records matching the Query. Be careful using this, since it will attempt to pull every record into memory at once. When querying might return a large number of records, consider using .findEach, which will pull the records in batches.

      await User.query().all()
      

      Parameters

      Returns Promise<DreamInstance[]>

      an array of dreams

    • Converts the given dream class into a Kysely query, enabling you to build custom queries using the Kysely API

      await User.query().toKysely('select').where('email', '=', 'how@yadoin').execute()
      

      Type Parameters

      • QueryType extends "update" | "delete" | "select"
      • DbType = DreamInstance["DB"]
      • TableNames = DreamInstance["table"]
      • ToKyselyReturnType = QueryType extends "select"
            ? SelectQueryBuilder<DbType, TableNames & keyof DbType, unknown>
            : QueryType extends "delete"
                ? DeleteQueryBuilder<DbType, TableNames & keyof DbType, unknown>
                : QueryType extends "update"
                    ? UpdateQueryBuilder<
                        DbType,
                        TableNames & keyof DbType,
                        TableNames & keyof DbType,
                        unknown,
                    >
                    : never

      Parameters

      • type: QueryType

        the type of Kysely query builder instance you would like to obtain

      Returns ToKyselyReturnType

      A Kysely query. Depending on the type passed, it will return either a SelectQueryBuilder, DeleteQueryBuilder, or an UpdateQueryBuilder

    • Internal

      Acquire exclusive, transaction-scoped locks on arbitrary keys, waiting until any other transaction holding one of them finishes. The locks are released when the enclosing transaction commits or rolls back — never by an explicit unlock — so callers only ever have to acquire (Postgres: pg_advisory_xact_lock(bigint)).

      Unlike applyRowLock, this does not depend on rows existing: it is the only way to serialize writers that are about to insert into the same logical group. The Sortable decorator uses it to make each sort scope's position computation exclusive, keyed on the physical database, table, position field and scope values.

      The seam takes the whole key set rather than one key at a time so that a driver able to express it can take them in a single round trip — the batched, row-locking query APIs can need one key per candidate record per sortable field. Keys must be acquired in the order given: callers sort them, and that shared order is what keeps two operations over the same scopes from deadlocking. A driver that has no bulk form implements this by looping over the keys in order.

      The wait must be bounded. A caller that finds a key held waits for the holder's transaction, and an implementation that waits forever turns an ordinary mistake — a sortable operation issued without the enclosing transaction, so that it waits on a key that transaction itself holds — into a permanently wedged connection that no deadlock detector can see, because only one side is waiting. So an implementation applies the sortableScopeLockTimeout DreamApp option (milliseconds) to the acquisition and raises SortableScopeLockWaitTimedOut when it elapses. A configured 0 means no bound, and is applied just as literally: the acquisition waits without bound even where the connection carries a wait bound of its own. The bound belongs to the acquisition alone: whatever lock-wait behavior the connection was configured with has to be in force again by the time this returns, so that the row locks applyRowLock takes are unaffected.

      Only ever called when supportsAdvisoryTransactionLocks is true; the base default throws.

      Parameters

      • txn: DreamTransaction<Dream>

        the transaction the locks are scoped to

      • keys: bigint[]

        the 64-bit signed lock keys, in acquisition order

      Returns Promise<void>

    • create the database. Must respond to the NODE_ENV value.

      Parameters

      • connectionName: string

      Returns Promise<void>

    • delete the database. Must respond to the NODE_ENV value.

      Parameters

      • connectionName: string

      Returns Promise<void>

    • destroys a dream, possibly implementing soft delete if reallyDestroy is false and the record being deleted implements soft delete.

      Parameters

      • dream: Dream

        the dream instance you wish to destroy

      • txn: DreamTransaction<Dream>

        a transaction to encapsulate, consistently provided by underlying dream mechanisms

      • reallyDestroy: boolean

        whether or not to reallyDestroy. If false, soft delete will be attempted when relevant

      Returns Promise<number>

      the number of rows this call removed (or soft deleted). Zero means the row was already gone, or that a preventDeletion veto stopped the write — callers distinguish the two by the veto flag, and use the count to decide whether there is anything for the after-destroy hooks to act on.

    • Parameters

      • connectionName: string

      Returns Promise<void>

    • Internal

      returns the foreign key type based on the primary key received. gives the driver the opportunity to switch i.e. bigserial to bigint.

      Parameters

      • primaryKey: LegacyCompatiblePrimaryKeyType

      Returns LegacyCompatiblePrimaryKeyType

    • This should build a new migration file in the migrations folder of your application. This will then need to be read and run whenever the migrate method is called. The filename should contain a timestamp at the front of the filename, so that it is sorted by date in the file tree, and, more importantly, so they can be run in order by your migration runner.

      Parameters

      • connectionName: string
      • migrationName: string
      • columnsWithTypes: string[]

      Returns Promise<void>

    • Reads the tables, columns and enums of the connection's database, from which sync writes the connection's types/db.ts and types/dream.ts. It returns every table the connection can read, sorted by schema and name; sync applies tableIncludePattern and tableExcludePattern itself.

      Parameters

      • connectionName: string

        the connection to read

      Returns Promise<IntrospectedDatabase>

    • Internal

      Whether error is the database aborting a transaction to break a deadlock with another. withConcurrentWriterRetry reruns a transaction of Dream's own that was aborted this way. A driver that does not recognize one reports false, and nothing is retried.

      Parameters

      • error: unknown

      Returns boolean

    • Internal

      Whether error is the database refusing a write for violating a unique constraint. withConcurrentWriterRetry asks this of an error raised at COMMIT, which is where a DEFERRABLE INITIALLY DEFERRED constraint — the one DreamMigrationHelpers.addDeferrableUniqueConstraint declares — reports a collision. A driver that does not recognize one reports false, and nothing is retried.

      Parameters

      • error: unknown

      Returns boolean

    • migrate the database. Must respond to the NODE_ENV value.

      Parameters

      • connectionName: string

      Returns Promise<void>

    • Internal

      Open a dedicated, process-lifetime lock session used to claim one database from the per-worker test pool. Only ever called when supportsParallelTestDatabases is true; the base default throws.

      The returned session wraps a single dedicated connection: the orchestrator (src/db/testDatabasePool.ts) probes many pool indexes on the one session via tryAcquire and keeps whichever it acquires, holding it for the worker's lifetime.

      Parameters

      • connectionName: string

      Returns Promise<TestDatabaseLockSession>

    • Internal

      used to return the computed primary key type based on the primaryKeyType set in the DreamApp class.

      Returns void

    • rollback the database. Must respond to the NODE_ENV value.

      Parameters

      • _: { connectionName: string; steps: number }

      Returns Promise<void>

    • persists any unsaved changes to the database. If a transaction is provided as a second argument, it will use that transaction to encapsulate the persisting of the dream, as well as any subsequent model hooks that are fired.

      Parameters

      Returns Promise<any>

    • Internal

      this method is called when dream is initializing, and is used to configure the database to utilize custom type parsers for a variety of data types.

      Parameters

      • connectionName: string

        the name of the connection you are doing this for

      Returns Promise<void>

      void

    • defines the syncing behavior for dream and psychic, which is run whenever the sync command is called. This is an important step, and will be incredibly comlpex to override. You will need to do the following when overriding this method:

      1. generate a types/db.ts file in the same shape as the existing one. KyselyQueryDriver does this with the ASTDbTypesBuilder, which writes it from introspectDatabase.
      2. generate a types/dream.ts file in the same shape as the existing one. KyselyQueryDriver does this with the ASTSchemaBuilder, which also reads the connection through introspectDatabase.

      Parameters

      • connectionName: string
      • _: () => void | Promise<void>
      • options: { schemaOnly?: boolean } = {}

      Returns Promise<void>

    • Builds a new DreamTransaction instance, provides the instance to the provided callback.

      await ApplicationModel.transaction(async txn => {
      const user = await User.txn(txn).create({ email: 'how@yadoin' })
      await Pet.txn(txn).create({ user })
      })

      Type Parameters

      Parameters

      • dreamInstance: DreamInstance
      • callback: CB

        A callback function to call. The transaction provided to the callback can be passed to subsequent database calls within the transaction callback

      Returns Promise<RetType>

      void