@rvoh/dream
    Preparing search index...

    Class KyselyQueryDriver<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

      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. They are read off the same join code that emits them, by building the select.

      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 (base or joined-association-namespaced)

      • 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 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 (base or joined-association-namespaced)

      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

    • 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. They are read off the same join code that emits the joins, by building the select.

      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 (base or joined-association-namespaced)

      • 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 (base or joined-association-namespaced)

      • 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

    • Parameters

      • direction: OrderDir | null

      Returns (obj: OrderByItemBuilder) => OrderByItemBuilder

    • Internal

      A page of a select that carries DISTINCT ON (as a Query that calls distinct, or an association that declares distinct, produces), or null for any other select.

      Such a select keeps the row of each group that sorts first in its ORDER BY, so narrowing it to the rows after a cursor would let it keep a row it does not return (a group's later row, once the cursor has passed the group's first). It is read as a derived table instead, and narrowed to rowsAfter, sorted and limited outside it. The Query's order statements follow the select's own ORDER BY, if it has one, so that the select keeps the same row of each group every time it runs, and each of their columns is read out of it under a short alias (as pluck reads them), since a joined table's column cannot be named outside it.

      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 carries 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.

      The select runs as all() runs it, with its own ORDER BY choosing each group's row, and is read as a derived table, sorted outside it. Each of rowKeyColumns is read out of it under a short alias (as pluck reads them), since a joined table's column cannot be named outside it.

      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<{ [key: string]: any }>

      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 (base or joined-association-namespaced)

      • 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

    • Internal

      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

    • 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>

    • destroys a dream, possibly implementing soft delete if reallyDestroy is false and the record being deleted implements soft delete. Does nothing at all when a beforeDestroy hook called preventDeletion.

      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 removed — zero when a preventDeletion veto stopped the write, and zero when the row was already gone, which on the soft delete path includes a row that is already soft deleted

    • 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 "bigint" | "integer" | "uuid"

    • 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

    • 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>

    • 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.

      RETURNING * (rather than enumerating the compiled column list) keeps writes working under schema/image skew: during a rolling deploy, a container built before a drop-column migration would otherwise name the dropped column in RETURNING and fail with 42703 column does not exist on every write, even writes that never touch that column. The SET/VALUES half still names only dirty attributes, so a write that actually sets a dropped column still fails loudly. The returned row is filtered to the compiled column list before hydration (see internal/saveDream.ts), so a column the image doesn't know about never reaches setAttributes.

      KNOWN CONSTRAINT: star-selects are only safe because nothing in this stack uses named prepared statements — node-postgres prepares a statement only when given an explicit name, and Kysely never names them, so every query is re-planned. With named prepared statements, a concurrent ADD COLUMN changes a cached plan's result shape and Postgres raises cached plan must not change result type (the reason Rails added enumerate_columns_in_select_statements). If a future driver or pooling layer enables named prepared statements, revisit every RETURNING * / select * in this driver.

      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.

      Parameters

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

      Returns Promise<void>