### Install Drizzle Plus with NPM Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Install the drizzle-plus package using NPM. ```bash npm install drizzle-plus ``` -------------------------------- ### Install Drizzle Plus with Yarn Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Install the drizzle-plus package using Yarn. ```bash yarn add drizzle-plus ``` -------------------------------- ### Install Drizzle Plus with PNPM Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Install the drizzle-plus package using PNPM. ```bash pnpm add drizzle-plus ``` -------------------------------- ### PostgreSQL Setup Imports Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Import necessary functions and modules for PostgreSQL operations in drizzle-plus. ```typescript import 'drizzle-plus/pg/upsert' import 'drizzle-plus/pg/updateMany' import 'drizzle-plus/pg/count' import 'drizzle-plus/pg/findUnique' import 'drizzle-plus/pg/findManyAndCount' import 'drizzle-plus/pg/$cursor' import 'drizzle-plus/pg/$findMany' import 'drizzle-plus/pg/$withMaterialized' import 'drizzle-plus/orThrow' import { concat, position, jsonAgg, jsonAggNotNull, jsonBuildObject, uuidv7, uuidExtractTimestamp, rowToJson, cast } from 'drizzle-plus/pg' ``` -------------------------------- ### Install Drizzle ORM Beta Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Install the beta version of drizzle-orm, which is required for drizzle-plus. ```bash pnpm add drizzle-orm@beta ``` -------------------------------- ### MySQL Setup Imports Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Import necessary functions and modules for MySQL operations in drizzle-plus. ```typescript import 'drizzle-plus/mysql/updateMany' import 'drizzle-plus/mysql/count' import 'drizzle-plus/mysql/findUnique' import 'drizzle-plus/mysql/findManyAndCount' import 'drizzle-plus/mysql/$cursor' import 'drizzle-plus/mysql/$findMany' import 'drizzle-plus/orThrow' import { concat, position, jsonArrayAgg, jsonObject, cast } from 'drizzle-plus/mysql' ``` -------------------------------- ### SQLite Setup Imports Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Import necessary functions and modules for SQLite operations in drizzle-plus. ```typescript import 'drizzle-plus/sqlite/upsert' import 'drizzle-plus/sqlite/updateMany' import 'drizzle-plus/sqlite/count' import 'drizzle-plus/sqlite/findUnique' import 'drizzle-plus/sqlite/findManyAndCount' import 'drizzle-plus/sqlite/$cursor' import 'drizzle-plus/sqlite/$findMany' import 'drizzle-plus/orThrow' import { concat, instr, jsonGroupArray, jsonObject, cast } from 'drizzle-plus/sqlite' ``` -------------------------------- ### Example of InferFindManyArgs Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/types.md Shows how InferFindManyArgs infers the arguments structure for a `findMany` operation on the 'users' table. ```typescript type UserFindManyArgs = InferFindManyArgs // => { columns?, where?, orderBy?, limit?, offset?, with?, extras? } ``` -------------------------------- ### Example of InferRelationsFilter Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/types.md Demonstrates how to use InferRelationsFilter to infer the filter type for a specific table's query builder. ```typescript type UserFilter = InferRelationsFilter ``` -------------------------------- ### Setup Drizzle-Plus Extensions for PostgreSQL Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import necessary extension methods for PostgreSQL operations. Ensure these imports are present before using the corresponding query methods. ```typescript import 'drizzle-plus/pg/upsert' import 'drizzle-plus/pg/updateMany' import 'drizzle-plus/pg/count' import 'drizzle-plus/pg/findUnique' import 'drizzle-plus/pg/findManyAndCount' import 'drizzle-plus/pg/$cursor' import 'drizzle-plus/orThrow' ``` -------------------------------- ### PostgreSQL JSON Aggregation Examples Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Demonstrates how to aggregate JSON data in PostgreSQL using drizzle-plus. Use jsonAgg for arrays that can be null, jsonAggNotNull for arrays that are always present, and jsonBuildObject to construct JSON objects. ```typescript import { jsonAgg, jsonAggNotNull, jsonBuildObject } from 'drizzle-plus/pg' // Array aggregation (returns null if no rows) const userPosts = await db.select({ userId: users.id, postIds: jsonAgg(posts.id) }).from(users) .leftJoin(posts, eq(posts.userId, users.id)) .groupBy(users.id) // Array aggregation (returns empty array if no rows) const userComments = await db.select({ userId: users.id, commentIds: jsonAggNotNull(comments.id) }).from(users) .leftJoin(comments, eq(comments.userId, users.id)) .groupBy(users.id) // Build JSON object const userData = await db.select({ user: jsonBuildObject({ id: users.id, name: users.name, email: users.email }) }).from(users) ``` -------------------------------- ### Fixing Subquery Column Count Error in nest() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/errors.md This example shows the correct way to use the nest() function by ensuring the subquery selects only a single column. ```typescript // CORRECT: Only one column const result = await db.query.user.upsert({ data: { id: 42, friendId: nest( db.query.user.findFirst({ columns: { id: true } // Single column only }) ) } }) ``` -------------------------------- ### Update Multiple User Records by Date Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Update multiple user records that were last seen within the last 30 days. This example shows how to set new values and return updated fields. ```typescript const updated = await db.query.users.updateMany({ set: { status: 'active' }, where: { lastSeenAt: { gt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) } }, returning: { id: true, status: true } }) ``` -------------------------------- ### Generating Cursor Parameters Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Use the $cursor method with an orderBy clause and a cursor object to generate the necessary where and orderBy parameters for a query. The cursor object can be null or undefined for the start of the query. ```typescript const cursorParams = db.query.foo.$cursor({ id: 'asc' }, { id: 99 }) ``` -------------------------------- ### Find Substring Position with MySQL position Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/mysql-functions.md Use the `position` function to find the 1-indexed starting position of a substring within a larger string. Returns NULL if the substring is not found. ```typescript import { position } from 'drizzle-plus/mysql' const result = await db.select({ atPos: position('@', users.email) }).from(users) ``` -------------------------------- ### Triggering Subquery Column Count Error in nest() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/errors.md This example demonstrates how selecting more than one column in a subquery passed to the nest() function triggers an error. Ensure subqueries return only a single column. ```typescript import { nest } from 'drizzle-plus' // WRONG: Two columns selected const result = await db.query.user.upsert({ data: { id: 42, friend: nest( db.query.user.findFirst({ columns: { id: true, name: true } // Two columns! }) ) } }) // => throws Error: 'Subquery must have exactly one column' ``` -------------------------------- ### Triggering No Matching Primary Key or Unique Constraint Error in findUnique() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/errors.md This example illustrates how calling findUnique() with a 'where' clause that does not specify all columns of a primary key or unique constraint will result in an error. Ensure all required columns are provided. ```typescript import 'drizzle-plus/pg/findUnique' // Table: users(id PK, email UNIQUE) // Trying to find by a non-unique column const user = await db.query.users.findUnique({ where: { name: 'John' } // name is not unique! }) // => throws Error: 'No matching primary key or unique constraint found' ``` -------------------------------- ### Triggering No Matching Primary Key or Unique Constraint Error in upsert() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/errors.md This example shows how attempting to upsert data without providing any of the table's primary key or unique constraint columns triggers an error. Always include a unique identifier or specify a target. ```typescript import 'drizzle-plus/pg/upsert' // Table: users(id PK, email UNIQUE) // Trying to upsert without providing id or email const result = await db.query.users.upsert({ data: { name: 'John' // Neither id nor email! } }) // => throws Error: 'No matching primary key or unique constraint found' ``` -------------------------------- ### Import Core Utilities Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import helper functions for merging query arguments and filters, SQL generation, and syntax manipulation. Also imports universal SQL functions for date, math, and string operations. ```typescript import { mergeFindManyArgs, mergeRelationsFilter } from 'drizzle-plus' import { toSQL, toSelection, caseWhen, nest } from 'drizzle-plus' import { abs, ceil, floor, round, sqrt, power, mod, upper, lower, trim, length, substring, coalesce, nullif, concatWithSeparator, currentDate, currentTime, currentTimestamp } from 'drizzle-plus' ``` -------------------------------- ### Core Utilities Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import core utility functions for common operations like merging query arguments and filters, SQL conversion, and various mathematical and string manipulation functions. ```APIDOC ## Core Utilities ### Description Import core utility functions for common operations like merging query arguments and filters, SQL conversion, and various mathematical and string manipulation functions. ### Import Paths ```typescript import { mergeFindManyArgs, mergeRelationsFilter } from 'drizzle-plus' import { toSQL, toSelection, caseWhen, nest } from 'drizzle-plus' import { abs, ceil, floor, round, sqrt, power, mod, upper, lower, trim, length, substring, coalesce, nullif, concatWithSeparator, currentDate, currentTime, currentTimestamp } from 'drizzle-plus' ``` ``` -------------------------------- ### Upsert Multiple Rows Example Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Inserts multiple rows or updates them if conflicts occur. Returns the upserted rows. ```typescript const results = await db.query.users.upsert({ data: [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ] }) // => [{ id: 1, ... }, { id: 2, ... }] ``` -------------------------------- ### Count All Rows Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Counts the total number of rows in the users table. This is a simple way to get the total record count. ```typescript import 'drizzle-plus/pg/count' // Count all const total = await db.query.users.count() ``` -------------------------------- ### Main Module Exports Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/module-structure.md Core utilities, syntax helpers, and universal SQL functions exported from the main 'drizzle-plus' module. ```APIDOC ## Main Module (`drizzle-plus`) ### Utilities - `mergeFindManyArgs(left, right)`: Merges two DBQueryConfig objects for query composition. - `mergeRelationsFilter(left, right)`: Merges two where filters. ### Syntax Helpers - `caseWhen(condition, value)`: Starts a CASE WHEN expression. - `SQLCaseWhen`: Builder class for CASE expressions. - `nest(subquery)`: Wraps a single-column subquery. - `toSQL(value)`: Coerces values to SQL expressions. - `toSelection(object)`: Coerces objects to select field maps. ### Universal SQL Functions - `abs(value)`: Calculates the absolute value. - `ceil(value)`: Rounds a number up to the nearest integer. - `floor(value)`: Rounds a number down to the nearest integer. - `round(value, decimals?)`: Rounds a number to a specified number of decimal places. - `sqrt(value)`: Calculates the square root of a number. - `power(base, exponent)`: Calculates the base to the power of the exponent. - `mod(dividend, divisor)`: Calculates the remainder of a division. - `upper(value)`: Converts a string to uppercase. - `lower(value)`: Converts a string to lowercase. - `trim(value)`: Removes whitespace from the beginning and end of a string. - `length(value)`: Returns the length of a string. - `substring(value, start, length?)`: Extracts a portion of a string. - `coalesce(...values)`: Returns the first non-null value from a list of values. - `nullif(value, compareWith)`: Returns NULL if two expressions are equal. - `concatWithSeparator(sep, ...values)`: Concatenates strings with a separator. - `currentDate()`: Returns the current date. - `currentTime()`: Returns the current time. - `currentTimestamp()`: Returns the current timestamp. ### Timestamp Type - `SQLTimestamp`: SQL expression for timestamp values with `.toDate()` method. ``` -------------------------------- ### Get Current Time Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Retrieve the current time using the currentTime function. The result is a SQL expression representing the time as a string. ```typescript import { currentTime } from 'drizzle-plus' const result = await db.select({ now: currentTime() }).from(users) ``` -------------------------------- ### Get Current Date Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Retrieve the current date using the currentDate function. The result is a SQL expression representing the date as a string. ```typescript import { currentDate } from 'drizzle-plus' const result = await db.select({ today: currentDate() }).from(users) ``` -------------------------------- ### Import Utility Functions Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import utility functions like `mergeFindManyArgs` for combining `findMany` query configurations and `mergeRelationsFilter` for combining `where` filters. ```typescript import { mergeFindManyArgs, mergeRelationsFilter } from 'drizzle-plus' ``` -------------------------------- ### Import orThrow Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Import the orThrow extension for QueryPromise. ```typescript import 'drizzle-plus/orThrow' ``` -------------------------------- ### InferRelationsFilter Type Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/types.md Infers the 'where' filter type for a query builder. Use this to get the type of the filter argument for findMany queries. ```typescript type InferRelationsFilter = InferFindManyArgs['where'] extends infer TWhere ? Extract : never ``` -------------------------------- ### Get SQL Expression Decoder Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/utilities.md Retrieves the value decoder for a SQL expression to ensure proper type mapping from driver values. ```typescript function getDecoder( value: SQLExpression ): DriverValueDecoder ``` -------------------------------- ### $cursor Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Generates cursor-based pagination parameters from an order-by clause and cursor object. This is useful for implementing efficient pagination in your queries. ```APIDOC ## $cursor Generates cursor-based pagination parameters from an order-by clause and cursor object. ### Signature ```typescript function $cursor( orderBy: TOrderBy, cursor: Partial> | null | undefined ): RelationalQueryCursor ``` ### Parameters #### Path Parameters - **orderBy** (Record) - Required - Column order. Property order is significant and determines comparison operators. - **cursor** (Record | null | undefined) - Optional - Cursor object from previous result. Null/undefined indicates start of query. ### Returns Interface ```typescript interface RelationalQueryCursor { where: RelationsFilter orderBy: TOrderBy } ``` ### Behavior - For all columns except the last: uses `gte` (ascending) or `lte` (descending) - For the last column: uses `gt` (ascending) or `lt` (descending) - Returns both the `where` filter and the `orderBy` for spread into `findMany()` ### Example - Single Column ```typescript import 'drizzle-plus/pg/$cursor' // First page const page1 = await db.query.users.findMany({ ...db.query.users.$cursor({ id: 'asc' }, null), limit: 10 }) // Next page const page2 = await db.query.users.findMany({ ...db.query.users.$cursor({ id: 'asc' }, { id: page1[page1.length - 1].id }), limit: 10 }) ``` ### Example - Multiple Columns ```typescript const cursorParams = db.query.users.$cursor( { name: 'asc', age: 'desc' }, { name: 'John', age: 30 } ) // => { // where: { name: { gte: 'John' }, age: { lt: 30 } }, // orderBy: { name: 'asc', age: 'desc' } // } ``` ``` -------------------------------- ### Pagination with Limits and Offsets Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Use `limit` and `offset` to paginate through results. The `offset` specifies how many records to skip, and `limit` specifies the maximum number of records to return. ```typescript import 'drizzle-plus/pg/findManyAndCount' const { data, count } = await db.query.users.findManyAndCount({ where: { status: 'active' }, orderBy: { createdAt: 'desc' }, limit: 10, offset: 0 }) // Next page const nextPage = await db.query.users.findManyAndCount({ limit: 10, offset: 10 }) ``` -------------------------------- ### Substring Extraction with Drizzle-Plus Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Extracts a portion of a string using the `substring` function. Specify the starting position and length of the desired substring. ```typescript import { substring } from 'drizzle-plus' const results = await db.select({ areaCode: substring(users.phone, 1, 3) }).from(users) ``` -------------------------------- ### substring Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Extracts a substring from a string. Accepts the source string, a starting position, and an optional length, returning an SQL expression for the substring. ```APIDOC ## substring ### Description Extracts a substring from a string. ### Signature ```typescript function substring>( value: T, start: SQLExpression, length?: SQLExpression ): SQL> ``` ### Parameters #### Path Parameters - **value** (SQLExpression) - Required - The source string - **start** (SQLExpression) - Required - The starting position (1-indexed) - **length** (SQLExpression) - Optional - The number of characters to extract ### Returns `SQL>` - A SQL expression representing the substring. ### Example ```typescript import { substring } from 'drizzle-plus' const result = await db.select({ shortName: substring(users.name, 1, 5) }).from(users) ``` ``` -------------------------------- ### Upsert Single Row Example Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Inserts a single row or updates it if a conflict occurs based on the primary key. Returns specified columns. ```typescript import 'drizzle-plus/pg/upsert' const result = await db.query.users.upsert({ data: { id: 42, name: 'John Doe', email: 'john@example.com' }, returning: { id: true, name: true } }) // => { id: 42, name: 'John Doe' } ``` -------------------------------- ### String Trimming and Length with Drizzle-Plus Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Removes leading/trailing whitespace with `trim` and gets string length with `length`. Useful for data cleaning and validation. ```typescript import { trim, length } from 'drizzle-plus' const results = await db.select({ trimmedName: trim(users.name), nameLength: length(users.name) }).from(users) ``` -------------------------------- ### Utilities Module Exports Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/module-structure.md Low-level utilities for inspecting and manipulating queries and SQL expressions exported from the 'drizzle-plus/utils' module. ```APIDOC ## Utilities Module (`drizzle-plus/utils`) - `getOriginalTableName(table)`: Get table name before aliasing. - `getSelectedFields(query)`: Get fields from query configuration. - `getDecoder(value)`: Get value decoder for SQL expression. - `getSQL(query)`: Get SQL object from query. - `getDialect(query)`: Get dialect from query. - `buildRelationalQuery(query)`: Build and return relational query structure. - `createJsonArrayDecoder(itemDecoder)`: Create decoder for JSON arrays. - `createJsonObjectDecoder(propertyDecoders)`: Create decoder for JSON objects. - `buildJsonProperties(input, decoders?)`: Build JSON key-value pairs. - `getDefinedColumns(columns, data)`: Get columns that are defined in data objects. - `pushStringChunk(chunks, sql)`: Append string chunk to SQL chunks. - `orderSelectedFields(fields, pathPrefix?)`: Order fields for decoder setup. - `mapSelectedFieldsToDecoders(orderedFields)`: Create decoder map from ordered fields. ``` -------------------------------- ### Get Current Timestamp and Convert to Date Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Retrieve the current date and time using currentTimestamp and convert it to a Date object using .toDate(). ```typescript import { currentTimestamp } from 'drizzle-plus' const result = await db.select({ createdAt: currentTimestamp().toDate() }).from(users) ``` -------------------------------- ### Cursor Parameters with Multiple Columns Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Demonstrates generating cursor parameters for pagination involving multiple columns, respecting the order specified in the orderBy clause. The comparison operators (gte/lte, gt/lt) are determined by the column order and sort direction. ```typescript const cursorParams = db.query.user.$cursor( { name: 'asc', age: 'desc' }, { name: 'John', age: 20 } ) ``` -------------------------------- ### Get String Length Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md The `length` function returns the number of characters in a string SQL expression or column. This can be used for validation or data analysis. ```typescript import { length } from 'drizzle-plus' const result = await db.select({ nameLength: length(users.name) }).from(users) ``` -------------------------------- ### Generate Cursor Pagination Parameters Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Use this to generate parameters for cursor-based pagination. It requires an order-by clause and an optional cursor object. The output can be spread into a findMany call. ```typescript import 'drizzle-plus/pg/$cursor' // First page const page1 = await db.query.users.findMany({ ...db.query.users.$cursor({ id: 'asc' }, null), limit: 10 }) // Next page const page2 = await db.query.users.findMany({ ...db.query.users.$cursor({ id: 'asc' }, { id: page1[page1.length - 1].id }), limit: 10 }) ``` -------------------------------- ### Calculate Absolute Value with abs() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Use the `abs` function to get the absolute value of a numeric SQL expression or column. Import it from 'drizzle-plus'. ```typescript import { abs } from 'drizzle-plus' const result = await db.select({ absValue: abs(users.balance) }).from(users) ``` -------------------------------- ### Count Rows and Combine Queries Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Demonstrates counting rows with filters and combining these counts with other query results. This is useful for generating summary statistics. ```typescript // Combine with other queries const { total, verified } = { total: await db.query.users.count(), verified: await db.query.users.count({ emailVerified: true }) } ``` -------------------------------- ### Get Original Table Name Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/utilities.md Returns the original name of a table, useful for scenarios where table aliasing might obscure the base name. ```typescript import { getOriginalTableName } from 'drizzle-plus/utils' const originalName = getOriginalTableName(users) // => 'users' ``` -------------------------------- ### Calculate Power with power() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Use the `power` function to raise a base number to a specified exponent. Both base and exponent should be numeric SQL expressions or columns. Import from 'drizzle-plus'. ```typescript import { power } from 'drizzle-plus' const result = await db.select({ squared: power(numbers.value, 2) }).from(numbers) ``` -------------------------------- ### $findMany Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Defines a query configuration for `findMany()` with optional merging of two configs. This allows for flexible query building by combining different configuration options. ```APIDOC ## $findMany Defines a query configuration for `findMany()` with optional merging of two configs. ### Signature ```typescript function $findMany( config: TConfig ): TConfig function $findMany( baseConfig: TBase, config: TConfig ): MergeFindManyArgs ``` ### Parameters #### Path Parameters - **config** (DBQueryConfig) - Required - Query configuration object - **baseConfig** (DBQueryConfig) - Optional - Optional base config to merge with ### Returns The same config passed in, or the merged result of both configs. ### Merging Behavior - `columns`, `with`, `extras` are merged one level deep - `where` is merged using `mergeRelationsFilter()` - Other properties use rightmost precedence ### Example - Define Query Config ```typescript import 'drizzle-plus/pg/$findMany' const userColumns = db.query.users.$findMany({ columns: { id: true, name: true } }) const activeFilter = db.query.users.$findMany({ where: { status: 'active' } }) // Merge configs const combined = db.query.users.$findMany(userColumns, activeFilter) // Result: { columns: {...}, where: {...} } ``` ``` -------------------------------- ### Extract Substring Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Use the `substring` function to extract a portion of a string SQL expression. You can specify the starting position and the desired length of the substring. ```typescript import { substring } from 'drizzle-plus' const result = await db.select({ shortName: substring(users.name, 1, 5) }).from(users) ``` -------------------------------- ### Enable Upsert for Postgres or SQLite Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import the upsert module for your chosen dialect to enable the upsert method on the query builder. ```typescript // Choose your dialect import 'drizzle-plus/pg/upsert' import 'drizzle-plus/sqlite/upsert' ``` -------------------------------- ### Calculate Remainder with mod() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sql-functions.md Use the `mod` function to get the remainder of a division operation between two numeric SQL expressions or columns. Import it from 'drizzle-plus'. ```typescript import { mod } from 'drizzle-plus' const result = await db.select({ remainder: mod(numbers.value, 10) }).from(numbers) ``` -------------------------------- ### Importing Upsert for PostgreSQL Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Import the upsert extension for PostgreSQL. Ensure you are using the correct dialect module. ```typescript import 'drizzle-plus/pg/upsert' ``` -------------------------------- ### Cursor-Based Pagination Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Implement cursor-based pagination using `$cursor` for efficient navigation through large datasets. Provide the sorting order and the cursor value from the last item of the previous page. ```typescript import 'drizzle-plus/pg/$cursor' // First page const firstPage = await db.query.users.findMany({ ...db.query.users.$cursor({ id: 'asc' }, null), limit: 10 }) // Next page const nextPage = await db.query.users.findMany({ ...db.query.users.$cursor({ id: 'asc' }, { id: firstPage[firstPage.length - 1].id }), limit: 10 }) // Multi-column cursor const page = await db.query.users.findMany({ ...db.query.users.$cursor( { name: 'asc', createdAt: 'desc' }, { name: 'John', createdAt: new Date() } ), limit: 10 }) ``` -------------------------------- ### Count Active User Records Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Count the number of users whose status is 'active'. This is a simple query to get a total count based on a filter. ```typescript const count = await db.query.users.count({ status: 'active' }) ``` -------------------------------- ### PostgreSQL Module Extension Methods Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/module-structure.md Import these to add specific methods to Drizzle's query objects for PostgreSQL. ```typescript import 'drizzle-plus/pg/upsert' import 'drizzle-plus/pg/updateMany' import 'drizzle-plus/pg/count' import 'drizzle-plus/pg/findUnique' import 'drizzle-plus/pg/findManyAndCount' import 'drizzle-plus/pg/$cursor' import 'drizzle-plus/pg/$findMany' import 'drizzle-plus/pg/$withMaterialized' ``` -------------------------------- ### Count Records Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Provides a method to count the number of records in a table, optionally with filters. This is useful for getting aggregate information without fetching the full data. ```APIDOC ## Count Records ### Description Counts the number of records in a table. You can apply filters to count only the records that match specific criteria. ### Method `count` ### Parameters #### Options - **where** (object) - Optional - A filter to specify which records to count. Uses the same API as `findMany`. ### Request Example ```ts // Choose your dialect import 'drizzle-plus/pg/count' const countWithFilter = db.query.foo.count({ id: { gt: 100 }, }) // Inspect the SQL: console.log(countWithFilter.toSQL()) // Execute the query const result = await countWithFilter ``` ### Response Returns a `Promise` representing the count of matching records. ``` -------------------------------- ### Import Extension Modules for QueryBuilder Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import modules to add methods like upsert, updateMany, count, findUnique, findManyAndCount, cursor-based pagination, query composition, and materialized CTEs to the Drizzle QueryBuilder. Note that some extensions are dialect-specific. ```typescript // Upsert (PostgreSQL and SQLite only) import 'drizzle-plus/pg/upsert' import 'drizzle-plus/sqlite/upsert' // Update Many (all dialects) import 'drizzle-plus/pg/updateMany' import 'drizzle-plus/mysql/updateMany' import 'drizzle-plus/sqlite/updateMany' // Count (all dialects) import 'drizzle-plus/pg/count' import 'drizzle-plus/mysql/count' import 'drizzle-plus/sqlite/count' // Find Unique (all dialects) import 'drizzle-plus/pg/findUnique' import 'drizzle-plus/mysql/findUnique' import 'drizzle-plus/sqlite/findUnique' // Find Many and Count (all dialects) import 'drizzle-plus/pg/findManyAndCount' import 'drizzle-plus/mysql/findManyAndCount' import 'drizzle-plus/sqlite/findManyAndCount' // Cursor-based Pagination (all dialects) import 'drizzle-plus/pg/$cursor' import 'drizzle-plus/mysql/$cursor' import 'drizzle-plus/sqlite/$cursor' // Query Composition (all dialects) import 'drizzle-plus/pg/$findMany' import 'drizzle-plus/mysql/$findMany' import 'drizzle-plus/sqlite/$findMany' // Materialized CTEs (PostgreSQL only) import 'drizzle-plus/pg/$withMaterialized' // QueryPromise Extension import 'drizzle-plus/orThrow' ``` -------------------------------- ### Find Substring Position with PostgreSQL Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/quick-reference.md Finds the starting position of a substring within a string using the `position` function. Useful for locating specific characters or patterns. ```typescript import { position } from 'drizzle-plus/pg' const results = await db.select({ atPos: position('@', users.email) }).from(users) ``` -------------------------------- ### Fixing No Matching Primary Key or Unique Constraint Error in findUnique() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/errors.md Shows how to correctly use findUnique() by providing either the primary key, a unique constraint, or all columns of a composite key in the 'where' clause. ```typescript // Option 1: Use primary key const user = await db.query.users.findUnique({ where: { id: 42 } }) // Option 2: Use unique constraint const user = await db.query.users.findUnique({ where: { email: 'john@example.com' } }) // Composite primary key (must include all columns) const user = await db.query.records.findUnique({ where: { tenantId: 'org-1', id: 42 } }) ``` -------------------------------- ### Find Substring Position with PostgreSQL position Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/postgresql-functions.md The position function finds the 1-indexed starting position of a substring within a larger string. It returns NULL if the substring is not found. ```typescript import { position } from 'drizzle-plus/pg' const result = await db.select({ atPos: position('@', users.email) }).from(users) ``` -------------------------------- ### Import SQLite Specific Functions Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import SQLite-specific SQL functions for string manipulation, JSON aggregation, object creation, and casting. ```typescript // SQLite import { concat, instr, jsonGroupArray, jsonObject, cast } from 'drizzle-plus/sqlite' ``` -------------------------------- ### Import MySQL Specific Functions Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import MySQL-specific SQL functions for string manipulation, JSON aggregation, object creation, and casting. ```typescript // MySQL import { concat, position, jsonArrayAgg, jsonObject, cast } from 'drizzle-plus/mysql' ``` -------------------------------- ### Nest Subquery for Upsert Operation Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Use the `nest` utility to embed a subquery within an upsert operation. This example finds a user's ID to use in a friendship record. ```typescript import { nest } from 'drizzle-plus' await db.query.friendships.upsert({ data: { userId: 42, friendId: nest( db.query.users.findFirst({ where: { email: 'friend@example.com' }, columns: { id: true } }) ) } }) ``` -------------------------------- ### Import PostgreSQL Specific Functions Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import PostgreSQL-specific SQL functions for string manipulation, JSON aggregation, object creation, and casting. ```typescript // PostgreSQL import { concat, position, jsonAgg, jsonAggNotNull, jsonBuildObject, uuidv7, uuidExtractTimestamp, rowToJson, cast } from 'drizzle-plus/pg' ``` -------------------------------- ### Importing Universal SQL Functions Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import universal SQL functions like caseWhen from the 'drizzle-plus' module. These functions are compatible with all supported SQL dialects. ```typescript import { caseWhen } from 'drizzle-plus' ``` -------------------------------- ### Upserting Relations within a Transaction Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Perform complex upserts involving relations by using `db.transaction()`. This example shows upserting a user and then a friendship, using a subquery to find the friend's ID. ```typescript import 'drizzle-plus/pg/upsert' import { nest } from 'drizzle-plus' await db.transaction(async tx => { const { id } = await tx.query.user.upsert({ data: { id: 42, name: 'Chewbacca', }, returning: { id: true, }, }) await tx.query.friendship.upsert({ data: { userId: id, friendId: nest( tx.query.user.findFirst({ where: { name: 'Han Solo', }, columns: { id: true, }, }) ), }, }) }) ``` -------------------------------- ### Counting Records with Filters Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import the `count` module to add a `count` method to your query builder. You can apply filters to count specific records. ```typescript // Choose your dialect import 'drizzle-plus/pg/count' import 'drizzle-plus/mysql/count' import 'drizzle-plus/sqlite/count' // Now you can use the `count` method const count = db.query.foo.count() // ^? Promise // Pass filters to the `count` method const countWithFilter = db.query.foo.count({ id: { gt: 100 }, }) // Inspect the SQL: console.log(countWithFilter.toSQL()) // { // sql: `select count(*) from "foo" where "foo"."id" > 100`, // params: [], // } // Execute the query const result = await countWithFilter // => 0 ``` -------------------------------- ### Triggering No Rows Returned Error with orThrow() Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/errors.md This example demonstrates how the .orThrow() extension throws a DrizzleError when the decorated query returns no results, either as null/undefined or an empty array. A custom message can be provided. ```typescript import 'drizzle-plus/orThrow' // Query returns no results const user = await db.query.users.findFirst({ where: { id: 999 } }).orThrow() // => throws DrizzleError: 'No rows returned' // Query returns empty array const users = await db.query.users.findMany({ where: { status: 'deleted' } }).orThrow('No deleted users found') // => throws DrizzleError: 'No deleted users found' ``` -------------------------------- ### jsonBuildObject Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/postgresql-functions.md Builds a JSON object from selected fields. Accepts either a subquery or a plain object with field definitions. ```APIDOC ## jsonBuildObject ### Description Builds a JSON object from selected fields. Accepts either a subquery or a plain object with field definitions. ### Signature ```typescript function jsonBuildObject>( subquery: T ): ToJsonObject ``` ### Parameters #### Path Parameters - **subquery** (AnySelectQuery | Record<string, unknown>) - Required - Either a subquery or a plain object with field definitions ### Response #### Success Response - **ToJsonObject** - A SQL expression representing a JSON object with properly decoded properties. ### Request Example ```typescript import { jsonBuildObject } from 'drizzle-plus/pg' const result = await db.select({ userData: jsonBuildObject({ id: users.id, name: users.name, email: users.email }) }).from(users) ``` ``` -------------------------------- ### MySQL Module Extension Methods Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/module-structure.md Import these to add specific methods to Drizzle's query objects for MySQL. Note that upsert() is not supported. ```typescript import 'drizzle-plus/mysql/updateMany' import 'drizzle-plus/mysql/count' import 'drizzle-plus/mysql/findUnique' import 'drizzle-plus/mysql/findManyAndCount' import 'drizzle-plus/mysql/$cursor' import 'drizzle-plus/mysql/$findMany' ``` -------------------------------- ### Extension Modules Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/README.md Import extension modules to add methods to the Drizzle QueryBuilder for advanced features like upsert, updateMany, count, findUnique, cursor-based pagination, and query composition. ```APIDOC ## Extension Modules (Add Methods to QueryBuilder) ### Description Import extension modules to add methods to the Drizzle QueryBuilder for advanced features like upsert, updateMany, count, findUnique, cursor-based pagination, and query composition. ### Import Paths ```typescript // Upsert (PostgreSQL and SQLite only) import 'drizzle-plus/pg/upsert' import 'drizzle-plus/sqlite/upsert' // Update Many (all dialects) import 'drizzle-plus/pg/updateMany' import 'drizzle-plus/mysql/updateMany' import 'drizzle-plus/sqlite/updateMany' // Count (all dialects) import 'drizzle-plus/pg/count' import 'drizzle-plus/mysql/count' import 'drizzle-plus/sqlite/count' // Find Unique (all dialects) import 'drizzle-plus/pg/findUnique' import 'drizzle-plus/mysql/findUnique' import 'drizzle-plus/sqlite/findUnique' // Find Many and Count (all dialects) import 'drizzle-plus/pg/findManyAndCount' import 'drizzle-plus/mysql/findManyAndCount' import 'drizzle-plus/sqlite/findManyAndCount' // Cursor-based Pagination (all dialects) import 'drizzle-plus/pg/$cursor' import 'drizzle-plus/mysql/$cursor' import 'drizzle-plus/sqlite/$cursor' // Query Composition (all dialects) import 'drizzle-plus/pg/$findMany' import 'drizzle-plus/mysql/$findMany' import 'drizzle-plus/sqlite/$findMany' // Materialized CTEs (PostgreSQL only) import 'drizzle-plus/pg/$withMaterialized' // QueryPromise Extension import 'drizzle-plus/orThrow' ``` ``` -------------------------------- ### Applying Cursor Parameters to a Query Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Spread the generated cursor parameters into your findMany query options to implement cursor-based pagination. Ensure the columns are specified as needed. ```typescript const results = await db.query.foo.findMany({ ...cursorParams, columns: { id: true, name: true, age: true, }, }) ``` -------------------------------- ### Define AnyDBQueryConfig Type Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/types.md A complete and bug-fixed version of Drizzle's DBQueryConfig type. It includes configurations for columns, where clauses, extras, ordering, offset, and limit. ```typescript type AnyDBQueryConfig = { columns?: Record | undefined where?: AnyRelationsFilter | undefined extras?: Record SQLWrapper)> | undefined with?: Record | undefined orderBy?: Record | ((table: Table | View, operators: OrderByOperators) => ValueOrArray) | undefined offset?: number | Placeholder | undefined limit?: number | Placeholder | undefined } ``` -------------------------------- ### Get Selected Fields from a Drizzle Query Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/utilities.md Utilize getSelectedFields to extract selected fields from a Drizzle query object. This utility supports both RelationalQueryBuilder and TypedQueryBuilder patterns. It returns an object mapping field names to their values based on columns, with, and extras configurations. ```typescript import { getSelectedFields } from 'drizzle-plus/utils' const fields = getSelectedFields(db.query.users.findMany({ columns: { id: true, name: true } })) ``` -------------------------------- ### SQLite Module Extension Methods Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/module-structure.md Import these to add specific methods to Drizzle's query objects for SQLite. ```typescript import 'drizzle-plus/sqlite/upsert' import 'drizzle-plus/sqlite/updateMany' import 'drizzle-plus/sqlite/count' import 'drizzle-plus/sqlite/findUnique' import 'drizzle-plus/sqlite/findManyAndCount' import 'drizzle-plus/sqlite/$cursor' import 'drizzle-plus/sqlite/$findMany' ``` -------------------------------- ### Find Substring Position with SQLite instr Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sqlite-functions.md The `instr` function finds the starting position of a substring within a string. It returns a 1-indexed position or 0 if the substring is not found. Note that SQLite's `instr` returns 0 for not found, unlike some other databases. ```typescript import { instr } from 'drizzle-plus/sqlite' const result = await db.select({ atPos: instr(users.email, '@') }).from(users) ``` -------------------------------- ### caseWhen Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/syntax.md Constructs a `CASE WHEN ... THEN ... ELSE ... END` SQL expression with type-safe chaining. It allows for building conditional logic within SQL queries. ```APIDOC ## caseWhen ### Description Constructs a `CASE WHEN ... THEN ... ELSE ... END` SQL expression with type-safe chaining. ### Signature ```typescript function caseWhen( whenExpr: SQLExpression | undefined, thenExpr: SQLValue ): SQLCaseWhen ``` ### Class: SQLCaseWhen ```typescript class SQLCaseWhen { when(whenExpr: SQLExpression | undefined, thenExpr: SQLValue): SQLCaseWhen else(elseExpr: SQLValue): SQL elseNull(): SQL } ``` ### Parameters #### Function Parameters - **whenExpr** (SQLExpression | undefined) - Required - The condition to evaluate. If undefined, this case is skipped. - **thenExpr** (SQLValue<Then>) - Required - The value to return if the condition is true ### Methods #### when() Adds another case to the expression. ```typescript when(whenExpr: SQLExpression | undefined, thenExpr: SQLValue): SQLCaseWhen ``` **Returns:** The same `SQLCaseWhen` instance with the new case added (for chaining). #### else() Completes the expression with an else clause. ```typescript else(elseExpr: SQLValue): SQL ``` **Returns:** `SQL` - A SQL expression that represents the complete CASE statement. #### elseNull() Completes the expression with an implicit `ELSE NULL` clause. ```typescript elseNull(): SQL ``` **Returns:** `SQL` - A SQL expression that returns null if no case matches. ### Example ```typescript import { caseWhen } from 'drizzle-plus' import { sql } from 'drizzle-orm' const statusCase = caseWhen(users.status.eq('active'), 'Active') .when(users.status.eq('inactive'), 'Inactive') .when(users.status.eq('pending'), 'Pending') .else('Unknown') ``` ``` -------------------------------- ### Using findManyAndCount in a Query Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Demonstrates how to use the findManyAndCount method after importing the appropriate dialect module. It returns an object with 'data' and 'count' properties. ```typescript const { data, count } = await db.query.foo.findManyAndCount({ where: { age: { gt: 20 }, }, limit: 2, columns: { id: true, name: true, age: true, }, }) ``` -------------------------------- ### Generated Code File Structure Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/module-structure.md These files are automatically generated during the build process to support different SQL dialects and provide core exports. ```typescript src/generated/*.ts // Dialect-agnostic adapters src/generated/adapters/*.ts // Dialect-specific implementations src/generated/index.ts // Exports dialect functions ``` -------------------------------- ### Import $cursor for MySQL Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import the $cursor module for MySQL to extend the query builder API with type-safe cursor-based pagination. This helps prevent errors related to orderBy clauses or cursor objects. ```typescript import 'drizzle-plus/mysql/$cursor' ``` -------------------------------- ### Import $cursor for PostgreSQL Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import the $cursor module for PostgreSQL to extend the query builder API with type-safe cursor-based pagination. This helps prevent errors related to orderBy clauses or cursor objects. ```typescript import 'drizzle-plus/pg/$cursor' ``` -------------------------------- ### jsonObject Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/sqlite-functions.md Builds a JSON object from key-value pairs. It can accept either a subquery or a plain object with field definitions to construct a JSON object. ```APIDOC ## jsonObject ### Description Builds a JSON object from key-value pairs. It can accept either a subquery or a plain object with field definitions to construct a JSON object. ### Signature ```typescript function jsonObject>( keysAndValues: T ): ToJsonObject ``` ### Parameters #### Path Parameters - **keysAndValues** (AnySelectQuery | Record<string, unknown>) - Required - Either a subquery or a plain object with field definitions ### Returns `ToJsonObject` - A SQL expression representing a JSON object with properly decoded properties. ### Example ```typescript import { jsonObject } from 'drizzle-plus/sqlite' const result = await db.select({ userData: jsonObject({ id: users.id, name: users.name, email: users.email }) }).from(users) ``` ``` -------------------------------- ### Define and Merge Query Configurations Source: https://github.com/alloc/drizzle-plus/blob/main/_autodocs/api-reference/query-methods.md Use $findMany to define query configurations or merge existing ones. It supports merging columns, where clauses, and other properties with specific precedence rules. ```typescript import 'drizzle-plus/pg/$findMany' const userColumns = db.query.users.$findMany({ columns: { id: true, name: true } }) const activeFilter = db.query.users.$findMany({ where: { status: 'active' } }) // Merge configs const combined = db.query.users.$findMany(userColumns, activeFilter) // Result: { columns: {...}, where: {...} } ``` -------------------------------- ### Import $cursor for SQLite Source: https://github.com/alloc/drizzle-plus/blob/main/readme.md Import the $cursor module for SQLite to extend the query builder API with type-safe cursor-based pagination. This helps prevent errors related to orderBy clauses or cursor objects. ```typescript import 'drizzle-plus/sqlite/$cursor' ```