drizzle-orm 1.0.0-beta.1-251c8ba → 1.0.0-beta.1-00df263
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_relations.d.cts +6 -6
- package/_relations.d.ts +6 -6
- package/gel-core/columns/custom.cjs.map +1 -1
- package/gel-core/columns/custom.d.cts +4 -4
- package/gel-core/columns/custom.d.ts +4 -4
- package/gel-core/columns/custom.js.map +1 -1
- package/gel-core/expressions.cjs +3 -3
- package/gel-core/expressions.cjs.map +1 -1
- package/gel-core/expressions.d.cts +1 -1
- package/gel-core/expressions.d.ts +1 -1
- package/gel-core/expressions.js +2 -2
- package/gel-core/expressions.js.map +1 -1
- package/index.cjs +0 -2
- package/index.cjs.map +1 -1
- package/index.d.cts +0 -1
- package/index.d.ts +0 -1
- package/index.js +0 -1
- package/index.js.map +1 -1
- package/mysql-core/columns/custom.cjs.map +1 -1
- package/mysql-core/columns/custom.d.cts +4 -4
- package/mysql-core/columns/custom.d.ts +4 -4
- package/mysql-core/columns/custom.js.map +1 -1
- package/mysql-core/columns/enum.cjs +40 -5
- package/mysql-core/columns/enum.cjs.map +1 -1
- package/mysql-core/columns/enum.d.cts +25 -2
- package/mysql-core/columns/enum.d.ts +25 -2
- package/mysql-core/columns/enum.js +38 -5
- package/mysql-core/columns/enum.js.map +1 -1
- package/mysql-core/dialect.cjs +1 -1
- package/mysql-core/dialect.cjs.map +1 -1
- package/mysql-core/dialect.js +1 -1
- package/mysql-core/dialect.js.map +1 -1
- package/mysql-core/expressions.cjs +3 -3
- package/mysql-core/expressions.cjs.map +1 -1
- package/mysql-core/expressions.d.cts +1 -1
- package/mysql-core/expressions.d.ts +1 -1
- package/mysql-core/expressions.js +2 -2
- package/mysql-core/expressions.js.map +1 -1
- package/package.json +55 -65
- package/pg-core/columns/custom.cjs.map +1 -1
- package/pg-core/columns/custom.d.cts +4 -4
- package/pg-core/columns/custom.d.ts +4 -4
- package/pg-core/columns/custom.js.map +1 -1
- package/pg-core/columns/enum.cjs +46 -2
- package/pg-core/columns/enum.cjs.map +1 -1
- package/pg-core/columns/enum.d.cts +39 -1
- package/pg-core/columns/enum.d.ts +39 -1
- package/pg-core/columns/enum.js +43 -2
- package/pg-core/columns/enum.js.map +1 -1
- package/pg-core/expressions.cjs +3 -3
- package/pg-core/expressions.cjs.map +1 -1
- package/pg-core/expressions.d.cts +1 -1
- package/pg-core/expressions.d.ts +1 -1
- package/pg-core/expressions.js +2 -2
- package/pg-core/expressions.js.map +1 -1
- package/pg-core/schema.cjs +6 -2
- package/pg-core/schema.cjs.map +1 -1
- package/pg-core/schema.d.cts +1 -2
- package/pg-core/schema.d.ts +1 -2
- package/pg-core/schema.js +7 -3
- package/pg-core/schema.js.map +1 -1
- package/planetscale-serverless/session.cjs.map +1 -1
- package/planetscale-serverless/session.js.map +1 -1
- package/relations.d.cts +6 -6
- package/relations.d.ts +6 -6
- package/singlestore-core/columns/custom.cjs.map +1 -1
- package/singlestore-core/columns/custom.d.cts +4 -4
- package/singlestore-core/columns/custom.d.ts +4 -4
- package/singlestore-core/columns/custom.js.map +1 -1
- package/singlestore-core/dialect.cjs +1 -1
- package/singlestore-core/dialect.cjs.map +1 -1
- package/singlestore-core/dialect.js +1 -1
- package/singlestore-core/dialect.js.map +1 -1
- package/singlestore-core/expressions.cjs +3 -3
- package/singlestore-core/expressions.cjs.map +1 -1
- package/singlestore-core/expressions.d.cts +1 -1
- package/singlestore-core/expressions.d.ts +1 -1
- package/singlestore-core/expressions.js +2 -2
- package/singlestore-core/expressions.js.map +1 -1
- package/sql/expressions/conditions.cjs.map +1 -1
- package/sql/expressions/conditions.d.cts +2 -2
- package/sql/expressions/conditions.d.ts +2 -2
- package/sql/expressions/conditions.js.map +1 -1
- package/sqlite-core/columns/custom.cjs.map +1 -1
- package/sqlite-core/columns/custom.d.cts +4 -4
- package/sqlite-core/columns/custom.d.ts +4 -4
- package/sqlite-core/columns/custom.js.map +1 -1
- package/sqlite-core/expressions.cjs +3 -3
- package/sqlite-core/expressions.cjs.map +1 -1
- package/sqlite-core/expressions.d.cts +1 -1
- package/sqlite-core/expressions.d.ts +1 -1
- package/sqlite-core/expressions.js +2 -2
- package/sqlite-core/expressions.js.map +1 -1
- package/table.cjs.map +1 -1
- package/table.d.cts +3 -0
- package/table.d.ts +3 -0
- package/table.js.map +1 -1
- package/utils.cjs.map +1 -1
- package/utils.d.cts +1 -0
- package/utils.d.ts +1 -0
- package/utils.js.map +1 -1
- package/version.cjs +1 -1
- package/version.d.cts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/expressions.cjs +0 -23
- package/expressions.cjs.map +0 -1
- package/expressions.d.cts +0 -1
- package/expressions.d.ts +0 -1
- package/expressions.js +0 -2
- package/expressions.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/sql/expressions/conditions.ts"],"sourcesContent":["import { type AnyColumn, Column, type GetColumnData } from '~/column.ts';\nimport { is } from '~/entity.ts';\nimport { Table } from '~/table.ts';\nimport {\n\tisDriverValueEncoder,\n\tisSQLWrapper,\n\tParam,\n\tPlaceholder,\n\tSQL,\n\tsql,\n\ttype SQLChunk,\n\ttype SQLWrapper,\n\tStringChunk,\n\tView,\n} from '../sql.ts';\n\nexport function bindIfParam(value: unknown, column: SQLWrapper): SQLChunk {\n\tif (\n\t\tisDriverValueEncoder(column)\n\t\t&& !isSQLWrapper(value)\n\t\t&& !is(value, Param)\n\t\t&& !is(value, Placeholder)\n\t\t&& !is(value, Column)\n\t\t&& !is(value, Table)\n\t\t&& !is(value, View)\n\t) {\n\t\treturn new Param(value, column);\n\t}\n\treturn value as SQLChunk;\n}\n\nexport interface BinaryOperator {\n\t<TColumn extends Column>(\n\t\tleft: TColumn,\n\t\tright: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\t): SQL;\n\t<T>(left: SQL.Aliased<T>, right: T | SQLWrapper): SQL;\n\t<T extends SQLWrapper>(\n\t\tleft: Exclude<T, SQL.Aliased | Column>,\n\t\tright: unknown,\n\t): SQL;\n}\n\n/**\n * Test that two values are equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is null, you may want to use\n * `isNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford\n * db.select().from(cars)\n * .where(eq(cars.make, 'Ford'))\n * ```\n *\n * @see isNull for a way to test equality to NULL.\n */\nexport const eq: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} = ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that two values are not equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is not null, you may want to use\n * `isNotNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars not made by Ford\n * db.select().from(cars)\n * .where(ne(cars.make, 'Ford'))\n * ```\n *\n * @see isNotNull for a way to test whether a value is not null.\n */\nexport const ne: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <> ${bindIfParam(right, left)}`;\n};\n\n/**\n * Combine a list of conditions with the `and` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * and(\n * eq(cars.make, 'Volvo'),\n * eq(cars.year, 1950),\n * )\n * )\n * ```\n */\nexport function and(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function and(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' and ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Combine a list of conditions with the `or` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * or(\n * eq(cars.make, 'GM'),\n * eq(cars.make, 'Ford'),\n * )\n * )\n * ```\n */\nexport function or(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function or(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' or ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Negate the meaning of an expression using the `not` keyword.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars _not_ made by GM or Ford.\n * db.select().from(cars)\n * .where(not(inArray(cars.make, ['GM', 'Ford'])))\n * ```\n */\nexport function not(condition: SQLWrapper): SQL {\n\treturn sql`not ${condition}`;\n}\n\n/**\n * Test that the first expression passed is greater than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made after 2000.\n * db.select().from(cars)\n * .where(gt(cars.year, 2000))\n * ```\n *\n * @see gte for greater-than-or-equal\n */\nexport const gt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} > ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is greater than\n * or equal to the second expression. Use `gt` to\n * test whether an expression is strictly greater\n * than another.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made on or after 2000.\n * db.select().from(cars)\n * .where(gte(cars.year, 2000))\n * ```\n *\n * @see gt for a strictly greater-than condition\n */\nexport const gte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} >= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lt(cars.year, 2000))\n * ```\n *\n * @see lte for less-than-or-equal\n */\nexport const lt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} < ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * or equal to the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lte(cars.year, 2000))\n * ```\n *\n * @see lt for a strictly less-than condition\n */\nexport const lte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value from a list passed as the second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford or GM.\n * db.select().from(cars)\n * .where(inArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see notInArray for the inverse of this test\n */\nexport function inArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`false`;\n\t\t}\n\t\treturn sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value that is not present in a list passed as the\n * second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by any company except Ford or GM.\n * db.select().from(cars)\n * .where(notInArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see inArray for the inverse of this test\n */\nexport function notInArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`true`;\n\t\t}\n\t\treturn sql`${column} not in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} not in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether an expression is NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have no discontinuedAt date.\n * db.select().from(cars)\n * .where(isNull(cars.discontinuedAt))\n * ```\n *\n * @see isNotNull for the inverse of this test\n */\nexport function isNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is null`;\n}\n\n/**\n * Test whether an expression is not NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have been discontinued.\n * db.select().from(cars)\n * .where(isNotNull(cars.discontinuedAt))\n * ```\n *\n * @see isNull for the inverse of this test\n */\nexport function isNotNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is not null`;\n}\n\n/**\n * Test whether a subquery evaluates to have any rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column has a match in a cities\n * // table.\n * db\n * .select()\n * .from(users)\n * .where(\n * exists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see notExists for the inverse of this test\n */\nexport function exists(subquery: SQLWrapper): SQL {\n\treturn sql`exists ${subquery}`;\n}\n\n/**\n * Test whether a subquery doesn't include any result\n * rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column doesn't match\n * // a row in the cities table.\n * db\n * .select()\n * .from(users)\n * .where(\n * notExists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see exists for the inverse of this test\n */\nexport function notExists(subquery: SQLWrapper): SQL {\n\treturn sql`not exists ${subquery}`;\n}\n\n/**\n * Test whether an expression is between two values. This\n * is an easier way to express range tests, which would be\n * expressed mathematically as `x <= a <= y` but in SQL\n * would have to be like `a >= x AND a <= y`.\n *\n * Between is inclusive of the endpoints: if `column`\n * is equal to `min` or `max`, it will be TRUE.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made between 1990 and 2000\n * db.select().from(cars)\n * .where(between(cars.year, 1990, 2000))\n * ```\n *\n * @see notBetween for the inverse of this test\n */\nexport function between<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function between<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function between<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function between(column: SQLWrapper, min: unknown, max: unknown): SQL {\n\treturn sql`${column} between ${bindIfParam(min, column)} and ${\n\t\tbindIfParam(\n\t\t\tmax,\n\t\t\tcolumn,\n\t\t)\n\t}`;\n}\n\n/**\n * Test whether an expression is not between two values.\n *\n * This, like `between`, includes its endpoints, so if\n * the `column` is equal to `min` or `max`, in this case\n * it will evaluate to FALSE.\n *\n * ## Examples\n *\n * ```ts\n * // Exclude cars made in the 1970s\n * db.select().from(cars)\n * .where(notBetween(cars.year, 1970, 1979))\n * ```\n *\n * @see between for the inverse of this test\n */\nexport function notBetween<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function notBetween<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function notBetween<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function notBetween(\n\tcolumn: SQLWrapper,\n\tmin: unknown,\n\tmax: unknown,\n): SQL {\n\treturn sql`${column} not between ${\n\t\tbindIfParam(\n\t\t\tmin,\n\t\t\tcolumn,\n\t\t)\n\t} and ${bindIfParam(max, column)}`;\n}\n\n/**\n * Compare a column to a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(like(cars.name, '%Turbo%'))\n * ```\n *\n * @see ilike for a case-insensitive version of this condition\n */\nexport function like(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} like ${value}`;\n}\n\n/**\n * The inverse of like - this tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"ROver\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see like for the inverse condition\n * @see notIlike for a case-insensitive version of this condition\n */\nexport function notLike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not like ${value}`;\n}\n\n/**\n * Case-insensitively compare a column to a pattern,\n * which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * Unlike like, this performs a case-insensitive comparison.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(ilike(cars.name, '%Turbo%'))\n * ```\n *\n * @see like for a case-sensitive version of this condition\n */\nexport function ilike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} ilike ${value}`;\n}\n\n/**\n * The inverse of ilike - this case-insensitively tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"Rover\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see ilike for the inverse condition\n * @see notLike for a case-sensitive version of this condition\n */\nexport function notIlike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not ilike ${value}`;\n}\n\n/**\n * Test that a column or expression contains all elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\" and \"ORM\".\n * db.select().from(posts)\n * .where(arrayContains(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContained to find if an array contains all elements of a column or expression\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContains<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContains(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContains requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} @> ${array}`;\n\t}\n\n\treturn sql`${column} @> ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that the list passed as the second argument contains\n * all elements of a column or expression.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both,\n * // but filtering posts that have additional tags.\n * db.select().from(posts)\n * .where(arrayContained(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContained<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContained(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContained requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} <@ ${array}`;\n\t}\n\n\treturn sql`${column} <@ ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that a column or expression contains any elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both.\n * db.select().from(posts)\n * .where(arrayOverlaps(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayContained to find if an array contains all elements of a column or expression\n */\nexport function arrayOverlaps<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayOverlaps(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayOverlaps requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} && ${array}`;\n\t}\n\n\treturn sql`${column} && ${bindIfParam(values, column)}`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/sql/expressions/conditions.ts"],"sourcesContent":["import { type AnyColumn, Column, type GetColumnData } from '~/column.ts';\nimport { is } from '~/entity.ts';\nimport { Table } from '~/table.ts';\nimport {\n\tisDriverValueEncoder,\n\tisSQLWrapper,\n\tParam,\n\tPlaceholder,\n\tSQL,\n\tsql,\n\ttype SQLChunk,\n\ttype SQLWrapper,\n\tStringChunk,\n\tView,\n} from '../sql.ts';\n\nexport function bindIfParam(value: unknown, column: SQLWrapper): SQLChunk {\n\tif (\n\t\tisDriverValueEncoder(column)\n\t\t&& !isSQLWrapper(value)\n\t\t&& !is(value, Param)\n\t\t&& !is(value, Placeholder)\n\t\t&& !is(value, Column)\n\t\t&& !is(value, Table)\n\t\t&& !is(value, View)\n\t) {\n\t\treturn new Param(value, column);\n\t}\n\treturn value as SQLChunk;\n}\n\nexport interface BinaryOperator {\n\t<TColumn extends Column>(\n\t\tleft: TColumn,\n\t\tright: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\t): SQL;\n\t<T>(left: SQL.Aliased<T>, right: T | SQLWrapper): SQL;\n\t<T extends SQLWrapper>(\n\t\tleft: Exclude<T, SQL.Aliased | Column>,\n\t\tright: unknown,\n\t): SQL;\n}\n\n/**\n * Test that two values are equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is null, you may want to use\n * `isNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford\n * db.select().from(cars)\n * .where(eq(cars.make, 'Ford'))\n * ```\n *\n * @see isNull for a way to test equality to NULL.\n */\nexport const eq: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} = ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that two values are not equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is not null, you may want to use\n * `isNotNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars not made by Ford\n * db.select().from(cars)\n * .where(ne(cars.make, 'Ford'))\n * ```\n *\n * @see isNotNull for a way to test whether a value is not null.\n */\nexport const ne: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <> ${bindIfParam(right, left)}`;\n};\n\n/**\n * Combine a list of conditions with the `and` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * and(\n * eq(cars.make, 'Volvo'),\n * eq(cars.year, 1950),\n * )\n * )\n * ```\n */\nexport function and(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function and(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' and ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Combine a list of conditions with the `or` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * or(\n * eq(cars.make, 'GM'),\n * eq(cars.make, 'Ford'),\n * )\n * )\n * ```\n */\nexport function or(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function or(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' or ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Negate the meaning of an expression using the `not` keyword.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars _not_ made by GM or Ford.\n * db.select().from(cars)\n * .where(not(inArray(cars.make, ['GM', 'Ford'])))\n * ```\n */\nexport function not(condition: SQLWrapper): SQL {\n\treturn sql`not ${condition}`;\n}\n\n/**\n * Test that the first expression passed is greater than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made after 2000.\n * db.select().from(cars)\n * .where(gt(cars.year, 2000))\n * ```\n *\n * @see gte for greater-than-or-equal\n */\nexport const gt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} > ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is greater than\n * or equal to the second expression. Use `gt` to\n * test whether an expression is strictly greater\n * than another.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made on or after 2000.\n * db.select().from(cars)\n * .where(gte(cars.year, 2000))\n * ```\n *\n * @see gt for a strictly greater-than condition\n */\nexport const gte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} >= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lt(cars.year, 2000))\n * ```\n *\n * @see lte for less-than-or-equal\n */\nexport const lt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} < ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * or equal to the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lte(cars.year, 2000))\n * ```\n *\n * @see lt for a strictly less-than condition\n */\nexport const lte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value from a list passed as the second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford or GM.\n * db.select().from(cars)\n * .where(inArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see notInArray for the inverse of this test\n */\nexport function inArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: ReadonlyArray<GetColumnData<TColumn, 'raw'> | Placeholder> | SQLWrapper,\n): SQL;\nexport function inArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: ReadonlyArray<unknown | Placeholder> | SQLWrapper,\n): SQL;\nexport function inArray(\n\tcolumn: SQLWrapper,\n\tvalues: ReadonlyArray<unknown | Placeholder> | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`false`;\n\t\t}\n\t\treturn sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value that is not present in a list passed as the\n * second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by any company except Ford or GM.\n * db.select().from(cars)\n * .where(notInArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see inArray for the inverse of this test\n */\nexport function notInArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`true`;\n\t\t}\n\t\treturn sql`${column} not in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} not in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether an expression is NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have no discontinuedAt date.\n * db.select().from(cars)\n * .where(isNull(cars.discontinuedAt))\n * ```\n *\n * @see isNotNull for the inverse of this test\n */\nexport function isNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is null`;\n}\n\n/**\n * Test whether an expression is not NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have been discontinued.\n * db.select().from(cars)\n * .where(isNotNull(cars.discontinuedAt))\n * ```\n *\n * @see isNull for the inverse of this test\n */\nexport function isNotNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is not null`;\n}\n\n/**\n * Test whether a subquery evaluates to have any rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column has a match in a cities\n * // table.\n * db\n * .select()\n * .from(users)\n * .where(\n * exists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see notExists for the inverse of this test\n */\nexport function exists(subquery: SQLWrapper): SQL {\n\treturn sql`exists ${subquery}`;\n}\n\n/**\n * Test whether a subquery doesn't include any result\n * rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column doesn't match\n * // a row in the cities table.\n * db\n * .select()\n * .from(users)\n * .where(\n * notExists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see exists for the inverse of this test\n */\nexport function notExists(subquery: SQLWrapper): SQL {\n\treturn sql`not exists ${subquery}`;\n}\n\n/**\n * Test whether an expression is between two values. This\n * is an easier way to express range tests, which would be\n * expressed mathematically as `x <= a <= y` but in SQL\n * would have to be like `a >= x AND a <= y`.\n *\n * Between is inclusive of the endpoints: if `column`\n * is equal to `min` or `max`, it will be TRUE.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made between 1990 and 2000\n * db.select().from(cars)\n * .where(between(cars.year, 1990, 2000))\n * ```\n *\n * @see notBetween for the inverse of this test\n */\nexport function between<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function between<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function between<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function between(column: SQLWrapper, min: unknown, max: unknown): SQL {\n\treturn sql`${column} between ${bindIfParam(min, column)} and ${\n\t\tbindIfParam(\n\t\t\tmax,\n\t\t\tcolumn,\n\t\t)\n\t}`;\n}\n\n/**\n * Test whether an expression is not between two values.\n *\n * This, like `between`, includes its endpoints, so if\n * the `column` is equal to `min` or `max`, in this case\n * it will evaluate to FALSE.\n *\n * ## Examples\n *\n * ```ts\n * // Exclude cars made in the 1970s\n * db.select().from(cars)\n * .where(notBetween(cars.year, 1970, 1979))\n * ```\n *\n * @see between for the inverse of this test\n */\nexport function notBetween<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function notBetween<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function notBetween<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function notBetween(\n\tcolumn: SQLWrapper,\n\tmin: unknown,\n\tmax: unknown,\n): SQL {\n\treturn sql`${column} not between ${\n\t\tbindIfParam(\n\t\t\tmin,\n\t\t\tcolumn,\n\t\t)\n\t} and ${bindIfParam(max, column)}`;\n}\n\n/**\n * Compare a column to a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(like(cars.name, '%Turbo%'))\n * ```\n *\n * @see ilike for a case-insensitive version of this condition\n */\nexport function like(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} like ${value}`;\n}\n\n/**\n * The inverse of like - this tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"ROver\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see like for the inverse condition\n * @see notIlike for a case-insensitive version of this condition\n */\nexport function notLike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not like ${value}`;\n}\n\n/**\n * Case-insensitively compare a column to a pattern,\n * which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * Unlike like, this performs a case-insensitive comparison.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(ilike(cars.name, '%Turbo%'))\n * ```\n *\n * @see like for a case-sensitive version of this condition\n */\nexport function ilike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} ilike ${value}`;\n}\n\n/**\n * The inverse of ilike - this case-insensitively tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"Rover\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see ilike for the inverse condition\n * @see notLike for a case-sensitive version of this condition\n */\nexport function notIlike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not ilike ${value}`;\n}\n\n/**\n * Test that a column or expression contains all elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\" and \"ORM\".\n * db.select().from(posts)\n * .where(arrayContains(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContained to find if an array contains all elements of a column or expression\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContains<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContains(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContains requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} @> ${array}`;\n\t}\n\n\treturn sql`${column} @> ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that the list passed as the second argument contains\n * all elements of a column or expression.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both,\n * // but filtering posts that have additional tags.\n * db.select().from(posts)\n * .where(arrayContained(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContained<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContained(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContained requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} <@ ${array}`;\n\t}\n\n\treturn sql`${column} <@ ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that a column or expression contains any elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both.\n * db.select().from(posts)\n * .where(arrayOverlaps(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayContained to find if an array contains all elements of a column or expression\n */\nexport function arrayOverlaps<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayOverlaps(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayOverlaps requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} && ${array}`;\n\t}\n\n\treturn sql`${column} && ${bindIfParam(values, column)}`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -167,8 +167,8 @@ export declare const lte: BinaryOperator;
|
|
|
167
167
|
* @see notInArray for the inverse of this test
|
|
168
168
|
*/
|
|
169
169
|
export declare function inArray<T>(column: SQL.Aliased<T>, values: (T | Placeholder)[] | SQLWrapper): SQL;
|
|
170
|
-
export declare function inArray<TColumn extends Column>(column: TColumn, values:
|
|
171
|
-
export declare function inArray<T extends SQLWrapper>(column: Exclude<T, SQL.Aliased | Column>, values:
|
|
170
|
+
export declare function inArray<TColumn extends Column>(column: TColumn, values: ReadonlyArray<GetColumnData<TColumn, 'raw'> | Placeholder> | SQLWrapper): SQL;
|
|
171
|
+
export declare function inArray<T extends SQLWrapper>(column: Exclude<T, SQL.Aliased | Column>, values: ReadonlyArray<unknown | Placeholder> | SQLWrapper): SQL;
|
|
172
172
|
/**
|
|
173
173
|
* Test whether the first parameter, a column or expression,
|
|
174
174
|
* has a value that is not present in a list passed as the
|
|
@@ -167,8 +167,8 @@ export declare const lte: BinaryOperator;
|
|
|
167
167
|
* @see notInArray for the inverse of this test
|
|
168
168
|
*/
|
|
169
169
|
export declare function inArray<T>(column: SQL.Aliased<T>, values: (T | Placeholder)[] | SQLWrapper): SQL;
|
|
170
|
-
export declare function inArray<TColumn extends Column>(column: TColumn, values:
|
|
171
|
-
export declare function inArray<T extends SQLWrapper>(column: Exclude<T, SQL.Aliased | Column>, values:
|
|
170
|
+
export declare function inArray<TColumn extends Column>(column: TColumn, values: ReadonlyArray<GetColumnData<TColumn, 'raw'> | Placeholder> | SQLWrapper): SQL;
|
|
171
|
+
export declare function inArray<T extends SQLWrapper>(column: Exclude<T, SQL.Aliased | Column>, values: ReadonlyArray<unknown | Placeholder> | SQLWrapper): SQL;
|
|
172
172
|
/**
|
|
173
173
|
* Test whether the first parameter, a column or expression,
|
|
174
174
|
* has a value that is not present in a list passed as the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/sql/expressions/conditions.ts"],"sourcesContent":["import { type AnyColumn, Column, type GetColumnData } from '~/column.ts';\nimport { is } from '~/entity.ts';\nimport { Table } from '~/table.ts';\nimport {\n\tisDriverValueEncoder,\n\tisSQLWrapper,\n\tParam,\n\tPlaceholder,\n\tSQL,\n\tsql,\n\ttype SQLChunk,\n\ttype SQLWrapper,\n\tStringChunk,\n\tView,\n} from '../sql.ts';\n\nexport function bindIfParam(value: unknown, column: SQLWrapper): SQLChunk {\n\tif (\n\t\tisDriverValueEncoder(column)\n\t\t&& !isSQLWrapper(value)\n\t\t&& !is(value, Param)\n\t\t&& !is(value, Placeholder)\n\t\t&& !is(value, Column)\n\t\t&& !is(value, Table)\n\t\t&& !is(value, View)\n\t) {\n\t\treturn new Param(value, column);\n\t}\n\treturn value as SQLChunk;\n}\n\nexport interface BinaryOperator {\n\t<TColumn extends Column>(\n\t\tleft: TColumn,\n\t\tright: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\t): SQL;\n\t<T>(left: SQL.Aliased<T>, right: T | SQLWrapper): SQL;\n\t<T extends SQLWrapper>(\n\t\tleft: Exclude<T, SQL.Aliased | Column>,\n\t\tright: unknown,\n\t): SQL;\n}\n\n/**\n * Test that two values are equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is null, you may want to use\n * `isNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford\n * db.select().from(cars)\n * .where(eq(cars.make, 'Ford'))\n * ```\n *\n * @see isNull for a way to test equality to NULL.\n */\nexport const eq: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} = ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that two values are not equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is not null, you may want to use\n * `isNotNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars not made by Ford\n * db.select().from(cars)\n * .where(ne(cars.make, 'Ford'))\n * ```\n *\n * @see isNotNull for a way to test whether a value is not null.\n */\nexport const ne: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <> ${bindIfParam(right, left)}`;\n};\n\n/**\n * Combine a list of conditions with the `and` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * and(\n * eq(cars.make, 'Volvo'),\n * eq(cars.year, 1950),\n * )\n * )\n * ```\n */\nexport function and(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function and(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' and ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Combine a list of conditions with the `or` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * or(\n * eq(cars.make, 'GM'),\n * eq(cars.make, 'Ford'),\n * )\n * )\n * ```\n */\nexport function or(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function or(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' or ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Negate the meaning of an expression using the `not` keyword.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars _not_ made by GM or Ford.\n * db.select().from(cars)\n * .where(not(inArray(cars.make, ['GM', 'Ford'])))\n * ```\n */\nexport function not(condition: SQLWrapper): SQL {\n\treturn sql`not ${condition}`;\n}\n\n/**\n * Test that the first expression passed is greater than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made after 2000.\n * db.select().from(cars)\n * .where(gt(cars.year, 2000))\n * ```\n *\n * @see gte for greater-than-or-equal\n */\nexport const gt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} > ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is greater than\n * or equal to the second expression. Use `gt` to\n * test whether an expression is strictly greater\n * than another.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made on or after 2000.\n * db.select().from(cars)\n * .where(gte(cars.year, 2000))\n * ```\n *\n * @see gt for a strictly greater-than condition\n */\nexport const gte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} >= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lt(cars.year, 2000))\n * ```\n *\n * @see lte for less-than-or-equal\n */\nexport const lt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} < ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * or equal to the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lte(cars.year, 2000))\n * ```\n *\n * @see lt for a strictly less-than condition\n */\nexport const lte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value from a list passed as the second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford or GM.\n * db.select().from(cars)\n * .where(inArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see notInArray for the inverse of this test\n */\nexport function inArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`false`;\n\t\t}\n\t\treturn sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value that is not present in a list passed as the\n * second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by any company except Ford or GM.\n * db.select().from(cars)\n * .where(notInArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see inArray for the inverse of this test\n */\nexport function notInArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`true`;\n\t\t}\n\t\treturn sql`${column} not in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} not in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether an expression is NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have no discontinuedAt date.\n * db.select().from(cars)\n * .where(isNull(cars.discontinuedAt))\n * ```\n *\n * @see isNotNull for the inverse of this test\n */\nexport function isNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is null`;\n}\n\n/**\n * Test whether an expression is not NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have been discontinued.\n * db.select().from(cars)\n * .where(isNotNull(cars.discontinuedAt))\n * ```\n *\n * @see isNull for the inverse of this test\n */\nexport function isNotNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is not null`;\n}\n\n/**\n * Test whether a subquery evaluates to have any rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column has a match in a cities\n * // table.\n * db\n * .select()\n * .from(users)\n * .where(\n * exists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see notExists for the inverse of this test\n */\nexport function exists(subquery: SQLWrapper): SQL {\n\treturn sql`exists ${subquery}`;\n}\n\n/**\n * Test whether a subquery doesn't include any result\n * rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column doesn't match\n * // a row in the cities table.\n * db\n * .select()\n * .from(users)\n * .where(\n * notExists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see exists for the inverse of this test\n */\nexport function notExists(subquery: SQLWrapper): SQL {\n\treturn sql`not exists ${subquery}`;\n}\n\n/**\n * Test whether an expression is between two values. This\n * is an easier way to express range tests, which would be\n * expressed mathematically as `x <= a <= y` but in SQL\n * would have to be like `a >= x AND a <= y`.\n *\n * Between is inclusive of the endpoints: if `column`\n * is equal to `min` or `max`, it will be TRUE.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made between 1990 and 2000\n * db.select().from(cars)\n * .where(between(cars.year, 1990, 2000))\n * ```\n *\n * @see notBetween for the inverse of this test\n */\nexport function between<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function between<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function between<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function between(column: SQLWrapper, min: unknown, max: unknown): SQL {\n\treturn sql`${column} between ${bindIfParam(min, column)} and ${\n\t\tbindIfParam(\n\t\t\tmax,\n\t\t\tcolumn,\n\t\t)\n\t}`;\n}\n\n/**\n * Test whether an expression is not between two values.\n *\n * This, like `between`, includes its endpoints, so if\n * the `column` is equal to `min` or `max`, in this case\n * it will evaluate to FALSE.\n *\n * ## Examples\n *\n * ```ts\n * // Exclude cars made in the 1970s\n * db.select().from(cars)\n * .where(notBetween(cars.year, 1970, 1979))\n * ```\n *\n * @see between for the inverse of this test\n */\nexport function notBetween<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function notBetween<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function notBetween<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function notBetween(\n\tcolumn: SQLWrapper,\n\tmin: unknown,\n\tmax: unknown,\n): SQL {\n\treturn sql`${column} not between ${\n\t\tbindIfParam(\n\t\t\tmin,\n\t\t\tcolumn,\n\t\t)\n\t} and ${bindIfParam(max, column)}`;\n}\n\n/**\n * Compare a column to a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(like(cars.name, '%Turbo%'))\n * ```\n *\n * @see ilike for a case-insensitive version of this condition\n */\nexport function like(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} like ${value}`;\n}\n\n/**\n * The inverse of like - this tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"ROver\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see like for the inverse condition\n * @see notIlike for a case-insensitive version of this condition\n */\nexport function notLike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not like ${value}`;\n}\n\n/**\n * Case-insensitively compare a column to a pattern,\n * which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * Unlike like, this performs a case-insensitive comparison.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(ilike(cars.name, '%Turbo%'))\n * ```\n *\n * @see like for a case-sensitive version of this condition\n */\nexport function ilike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} ilike ${value}`;\n}\n\n/**\n * The inverse of ilike - this case-insensitively tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"Rover\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see ilike for the inverse condition\n * @see notLike for a case-sensitive version of this condition\n */\nexport function notIlike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not ilike ${value}`;\n}\n\n/**\n * Test that a column or expression contains all elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\" and \"ORM\".\n * db.select().from(posts)\n * .where(arrayContains(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContained to find if an array contains all elements of a column or expression\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContains<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContains(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContains requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} @> ${array}`;\n\t}\n\n\treturn sql`${column} @> ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that the list passed as the second argument contains\n * all elements of a column or expression.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both,\n * // but filtering posts that have additional tags.\n * db.select().from(posts)\n * .where(arrayContained(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContained<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContained(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContained requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} <@ ${array}`;\n\t}\n\n\treturn sql`${column} <@ ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that a column or expression contains any elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both.\n * db.select().from(posts)\n * .where(arrayOverlaps(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayContained to find if an array contains all elements of a column or expression\n */\nexport function arrayOverlaps<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayOverlaps(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayOverlaps requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} && ${array}`;\n\t}\n\n\treturn sql`${column} && ${bindIfParam(values, column)}`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/sql/expressions/conditions.ts"],"sourcesContent":["import { type AnyColumn, Column, type GetColumnData } from '~/column.ts';\nimport { is } from '~/entity.ts';\nimport { Table } from '~/table.ts';\nimport {\n\tisDriverValueEncoder,\n\tisSQLWrapper,\n\tParam,\n\tPlaceholder,\n\tSQL,\n\tsql,\n\ttype SQLChunk,\n\ttype SQLWrapper,\n\tStringChunk,\n\tView,\n} from '../sql.ts';\n\nexport function bindIfParam(value: unknown, column: SQLWrapper): SQLChunk {\n\tif (\n\t\tisDriverValueEncoder(column)\n\t\t&& !isSQLWrapper(value)\n\t\t&& !is(value, Param)\n\t\t&& !is(value, Placeholder)\n\t\t&& !is(value, Column)\n\t\t&& !is(value, Table)\n\t\t&& !is(value, View)\n\t) {\n\t\treturn new Param(value, column);\n\t}\n\treturn value as SQLChunk;\n}\n\nexport interface BinaryOperator {\n\t<TColumn extends Column>(\n\t\tleft: TColumn,\n\t\tright: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\t): SQL;\n\t<T>(left: SQL.Aliased<T>, right: T | SQLWrapper): SQL;\n\t<T extends SQLWrapper>(\n\t\tleft: Exclude<T, SQL.Aliased | Column>,\n\t\tright: unknown,\n\t): SQL;\n}\n\n/**\n * Test that two values are equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is null, you may want to use\n * `isNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford\n * db.select().from(cars)\n * .where(eq(cars.make, 'Ford'))\n * ```\n *\n * @see isNull for a way to test equality to NULL.\n */\nexport const eq: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} = ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that two values are not equal.\n *\n * Remember that the SQL standard dictates that\n * two NULL values are not equal, so if you want to test\n * whether a value is not null, you may want to use\n * `isNotNull` instead.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars not made by Ford\n * db.select().from(cars)\n * .where(ne(cars.make, 'Ford'))\n * ```\n *\n * @see isNotNull for a way to test whether a value is not null.\n */\nexport const ne: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <> ${bindIfParam(right, left)}`;\n};\n\n/**\n * Combine a list of conditions with the `and` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * and(\n * eq(cars.make, 'Volvo'),\n * eq(cars.year, 1950),\n * )\n * )\n * ```\n */\nexport function and(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function and(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' and ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Combine a list of conditions with the `or` operator. Conditions\n * that are equal `undefined` are automatically ignored.\n *\n * ## Examples\n *\n * ```ts\n * db.select().from(cars)\n * .where(\n * or(\n * eq(cars.make, 'GM'),\n * eq(cars.make, 'Ford'),\n * )\n * )\n * ```\n */\nexport function or(...conditions: (SQLWrapper | undefined)[]): SQL | undefined;\nexport function or(\n\t...unfilteredConditions: (SQLWrapper | undefined)[]\n): SQL | undefined {\n\tconst conditions = unfilteredConditions.filter(\n\t\t(c): c is Exclude<typeof c, undefined> => c !== undefined,\n\t);\n\n\tif (conditions.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (conditions.length === 1) {\n\t\treturn new SQL(conditions);\n\t}\n\n\treturn new SQL([\n\t\tnew StringChunk('('),\n\t\tsql.join(conditions, new StringChunk(' or ')),\n\t\tnew StringChunk(')'),\n\t]);\n}\n\n/**\n * Negate the meaning of an expression using the `not` keyword.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars _not_ made by GM or Ford.\n * db.select().from(cars)\n * .where(not(inArray(cars.make, ['GM', 'Ford'])))\n * ```\n */\nexport function not(condition: SQLWrapper): SQL {\n\treturn sql`not ${condition}`;\n}\n\n/**\n * Test that the first expression passed is greater than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made after 2000.\n * db.select().from(cars)\n * .where(gt(cars.year, 2000))\n * ```\n *\n * @see gte for greater-than-or-equal\n */\nexport const gt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} > ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is greater than\n * or equal to the second expression. Use `gt` to\n * test whether an expression is strictly greater\n * than another.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made on or after 2000.\n * db.select().from(cars)\n * .where(gte(cars.year, 2000))\n * ```\n *\n * @see gt for a strictly greater-than condition\n */\nexport const gte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} >= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lt(cars.year, 2000))\n * ```\n *\n * @see lte for less-than-or-equal\n */\nexport const lt: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} < ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test that the first expression passed is less than\n * or equal to the second expression.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made before 2000.\n * db.select().from(cars)\n * .where(lte(cars.year, 2000))\n * ```\n *\n * @see lt for a strictly less-than condition\n */\nexport const lte: BinaryOperator = (left: SQLWrapper, right: unknown): SQL => {\n\treturn sql`${left} <= ${bindIfParam(right, left)}`;\n};\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value from a list passed as the second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by Ford or GM.\n * db.select().from(cars)\n * .where(inArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see notInArray for the inverse of this test\n */\nexport function inArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function inArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: ReadonlyArray<GetColumnData<TColumn, 'raw'> | Placeholder> | SQLWrapper,\n): SQL;\nexport function inArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: ReadonlyArray<unknown | Placeholder> | SQLWrapper,\n): SQL;\nexport function inArray(\n\tcolumn: SQLWrapper,\n\tvalues: ReadonlyArray<unknown | Placeholder> | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`false`;\n\t\t}\n\t\treturn sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether the first parameter, a column or expression,\n * has a value that is not present in a list passed as the\n * second argument.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made by any company except Ford or GM.\n * db.select().from(cars)\n * .where(notInArray(cars.make, ['Ford', 'GM']))\n * ```\n *\n * @see inArray for the inverse of this test\n */\nexport function notInArray<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function notInArray(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\treturn sql`true`;\n\t\t}\n\t\treturn sql`${column} not in ${values.map((v) => bindIfParam(v, column))}`;\n\t}\n\n\treturn sql`${column} not in ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test whether an expression is NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have no discontinuedAt date.\n * db.select().from(cars)\n * .where(isNull(cars.discontinuedAt))\n * ```\n *\n * @see isNotNull for the inverse of this test\n */\nexport function isNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is null`;\n}\n\n/**\n * Test whether an expression is not NULL. By the SQL standard,\n * NULL is neither equal nor not equal to itself, so\n * it's recommended to use `isNull` and `notIsNull` for\n * comparisons to NULL.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars that have been discontinued.\n * db.select().from(cars)\n * .where(isNotNull(cars.discontinuedAt))\n * ```\n *\n * @see isNull for the inverse of this test\n */\nexport function isNotNull(value: SQLWrapper): SQL {\n\treturn sql`${value} is not null`;\n}\n\n/**\n * Test whether a subquery evaluates to have any rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column has a match in a cities\n * // table.\n * db\n * .select()\n * .from(users)\n * .where(\n * exists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see notExists for the inverse of this test\n */\nexport function exists(subquery: SQLWrapper): SQL {\n\treturn sql`exists ${subquery}`;\n}\n\n/**\n * Test whether a subquery doesn't include any result\n * rows.\n *\n * ## Examples\n *\n * ```ts\n * // Users whose `homeCity` column doesn't match\n * // a row in the cities table.\n * db\n * .select()\n * .from(users)\n * .where(\n * notExists(db.select()\n * .from(cities)\n * .where(eq(users.homeCity, cities.id))),\n * );\n * ```\n *\n * @see exists for the inverse of this test\n */\nexport function notExists(subquery: SQLWrapper): SQL {\n\treturn sql`not exists ${subquery}`;\n}\n\n/**\n * Test whether an expression is between two values. This\n * is an easier way to express range tests, which would be\n * expressed mathematically as `x <= a <= y` but in SQL\n * would have to be like `a >= x AND a <= y`.\n *\n * Between is inclusive of the endpoints: if `column`\n * is equal to `min` or `max`, it will be TRUE.\n *\n * ## Examples\n *\n * ```ts\n * // Select cars made between 1990 and 2000\n * db.select().from(cars)\n * .where(between(cars.year, 1990, 2000))\n * ```\n *\n * @see notBetween for the inverse of this test\n */\nexport function between<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function between<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function between<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function between(column: SQLWrapper, min: unknown, max: unknown): SQL {\n\treturn sql`${column} between ${bindIfParam(min, column)} and ${\n\t\tbindIfParam(\n\t\t\tmax,\n\t\t\tcolumn,\n\t\t)\n\t}`;\n}\n\n/**\n * Test whether an expression is not between two values.\n *\n * This, like `between`, includes its endpoints, so if\n * the `column` is equal to `min` or `max`, in this case\n * it will evaluate to FALSE.\n *\n * ## Examples\n *\n * ```ts\n * // Exclude cars made in the 1970s\n * db.select().from(cars)\n * .where(notBetween(cars.year, 1970, 1979))\n * ```\n *\n * @see between for the inverse of this test\n */\nexport function notBetween<T>(\n\tcolumn: SQL.Aliased,\n\tmin: T | SQLWrapper,\n\tmax: T | SQLWrapper,\n): SQL;\nexport function notBetween<TColumn extends AnyColumn>(\n\tcolumn: TColumn,\n\tmin: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n\tmax: GetColumnData<TColumn, 'raw'> | SQLWrapper,\n): SQL;\nexport function notBetween<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tmin: unknown,\n\tmax: unknown,\n): SQL;\nexport function notBetween(\n\tcolumn: SQLWrapper,\n\tmin: unknown,\n\tmax: unknown,\n): SQL {\n\treturn sql`${column} not between ${\n\t\tbindIfParam(\n\t\t\tmin,\n\t\t\tcolumn,\n\t\t)\n\t} and ${bindIfParam(max, column)}`;\n}\n\n/**\n * Compare a column to a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(like(cars.name, '%Turbo%'))\n * ```\n *\n * @see ilike for a case-insensitive version of this condition\n */\nexport function like(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} like ${value}`;\n}\n\n/**\n * The inverse of like - this tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"ROver\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see like for the inverse condition\n * @see notIlike for a case-insensitive version of this condition\n */\nexport function notLike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not like ${value}`;\n}\n\n/**\n * Case-insensitively compare a column to a pattern,\n * which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * Unlike like, this performs a case-insensitive comparison.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars with 'Turbo' in their names.\n * db.select().from(cars)\n * .where(ilike(cars.name, '%Turbo%'))\n * ```\n *\n * @see like for a case-sensitive version of this condition\n */\nexport function ilike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} ilike ${value}`;\n}\n\n/**\n * The inverse of ilike - this case-insensitively tests that a given column\n * does not match a pattern, which can include `%` and `_`\n * characters to match multiple variations. Including `%`\n * in the pattern matches zero or more characters, and including\n * `_` will match a single character.\n *\n * ## Examples\n *\n * ```ts\n * // Select all cars that don't have \"Rover\" in their name.\n * db.select().from(cars)\n * .where(notLike(cars.name, '%Rover%'))\n * ```\n *\n * @see ilike for the inverse condition\n * @see notLike for a case-sensitive version of this condition\n */\nexport function notIlike(column: Column | SQL.Aliased | SQL | SQLWrapper, value: string | SQLWrapper): SQL {\n\treturn sql`${column} not ilike ${value}`;\n}\n\n/**\n * Test that a column or expression contains all elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\" and \"ORM\".\n * db.select().from(posts)\n * .where(arrayContains(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContained to find if an array contains all elements of a column or expression\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContains<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContains<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContains(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContains requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} @> ${array}`;\n\t}\n\n\treturn sql`${column} @> ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that the list passed as the second argument contains\n * all elements of a column or expression.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both,\n * // but filtering posts that have additional tags.\n * db.select().from(posts)\n * .where(arrayContained(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayOverlaps to find if a column or expression contains any elements of an array\n */\nexport function arrayContained<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayContained<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayContained(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayContained requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} <@ ${array}`;\n\t}\n\n\treturn sql`${column} <@ ${bindIfParam(values, column)}`;\n}\n\n/**\n * Test that a column or expression contains any elements of\n * the list passed as the second argument.\n *\n * ## Throws\n *\n * The argument passed in the second array can't be empty:\n * if an empty is provided, this method will throw.\n *\n * ## Examples\n *\n * ```ts\n * // Select posts where its tags contain \"Typescript\", \"ORM\" or both.\n * db.select().from(posts)\n * .where(arrayOverlaps(posts.tags, ['Typescript', 'ORM']))\n * ```\n *\n * @see arrayContains to find if a column or expression contains all elements of an array\n * @see arrayContained to find if an array contains all elements of a column or expression\n */\nexport function arrayOverlaps<T>(\n\tcolumn: SQL.Aliased<T>,\n\tvalues: (T | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<TColumn extends Column>(\n\tcolumn: TColumn,\n\tvalues: (GetColumnData<TColumn, 'raw'> | Placeholder) | SQLWrapper,\n): SQL;\nexport function arrayOverlaps<T extends SQLWrapper>(\n\tcolumn: Exclude<T, SQL.Aliased | Column>,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL;\nexport function arrayOverlaps(\n\tcolumn: SQLWrapper,\n\tvalues: (unknown | Placeholder)[] | SQLWrapper,\n): SQL {\n\tif (Array.isArray(values)) {\n\t\tif (values.length === 0) {\n\t\t\tthrow new Error('arrayOverlaps requires at least one value');\n\t\t}\n\t\tconst array = sql`${bindIfParam(values, column)}`;\n\t\treturn sql`${column} && ${array}`;\n\t}\n\n\treturn sql`${column} && ${bindIfParam(values, column)}`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/sqlite-core/columns/custom.ts"],"sourcesContent":["import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts';\nimport type { ColumnBaseConfig } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { SQL, SQLGenerator } from '~/sql/sql.ts';\nimport type { AnySQLiteTable } from '~/sqlite-core/table.ts';\nimport { type Equal, getColumnNameAndConfig } from '~/utils.ts';\nimport { SQLiteColumn, SQLiteColumnBuilder } from './common.ts';\n\nexport type ConvertCustomConfig<TName extends string, T extends Partial<CustomTypeValues>> =\n\t& {\n\t\tname: TName;\n\t\tdataType: 'custom';\n\t\tcolumnType: 'SQLiteCustomColumn';\n\t\tdata: T['data'];\n\t\tdriverParam: T['driverData'];\n\t\tenumValues: undefined;\n\t}\n\t& (T['notNull'] extends true ? { notNull: true } : {})\n\t& (T['default'] extends true ? { hasDefault: true } : {});\n\nexport interface SQLiteCustomColumnInnerConfig {\n\tcustomTypeValues: CustomTypeValues;\n}\n\nexport class SQLiteCustomColumnBuilder<T extends ColumnBuilderBaseConfig<'custom', 'SQLiteCustomColumn'>>\n\textends SQLiteColumnBuilder<\n\t\tT,\n\t\t{\n\t\t\tfieldConfig: CustomTypeValues['config'];\n\t\t\tcustomTypeParams: CustomTypeParams<any>;\n\t\t},\n\t\t{\n\t\t\tsqliteColumnBuilderBrand: 'SQLiteCustomColumnBuilderBrand';\n\t\t}\n\t>\n{\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumnBuilder';\n\n\tconstructor(\n\t\tname: T['name'],\n\t\tfieldConfig: CustomTypeValues['config'],\n\t\tcustomTypeParams: CustomTypeParams<any>,\n\t) {\n\t\tsuper(name, 'custom', 'SQLiteCustomColumn');\n\t\tthis.config.fieldConfig = fieldConfig;\n\t\tthis.config.customTypeParams = customTypeParams;\n\t}\n\n\t/** @internal */\n\tbuild<TTableName extends string>(\n\t\ttable: AnySQLiteTable<{ name: TTableName }>,\n\t): SQLiteCustomColumn<MakeColumnConfig<T, TTableName>> {\n\t\treturn new SQLiteCustomColumn<MakeColumnConfig<T, TTableName>>(\n\t\t\ttable,\n\t\t\tthis.config as ColumnBuilderRuntimeConfig<any, any>,\n\t\t);\n\t}\n}\n\nexport class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>> extends SQLiteColumn<T> {\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumn';\n\n\tprivate sqlName: string;\n\tprivate mapTo?: (value: T['data']) => T['driverParam'];\n\tprivate mapFrom?: (value: T['driverParam']) => T['data'];\n\tprivate mapJson?: (value: unknown) => T['data'];\n\tprivate forJsonSelect?: (name: SQL, sql: SQLGenerator) => SQL;\n\n\tconstructor(\n\t\ttable: AnySQLiteTable<{ name: T['tableName'] }>,\n\t\tconfig: SQLiteCustomColumnBuilder<T>['config'],\n\t) {\n\t\tsuper(table, config);\n\t\tthis.sqlName = config.customTypeParams.dataType(config.fieldConfig);\n\t\tthis.mapTo = config.customTypeParams.toDriver;\n\t\tthis.mapFrom = config.customTypeParams.fromDriver;\n\t\tthis.mapJson = config.customTypeParams.fromJson;\n\t\tthis.forJsonSelect = config.customTypeParams.forJsonSelect;\n\t}\n\n\tgetSQLType(): string {\n\t\treturn this.sqlName;\n\t}\n\n\toverride mapFromDriverValue(value: T['driverParam']): T['data'] {\n\t\treturn typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data'];\n\t}\n\n\tmapFromJsonValue(value: unknown): T['data'] {\n\t\treturn typeof this.mapJson === 'function' ? this.mapJson(value) : this.mapFromDriverValue(value) as T['data'];\n\t}\n\n\tjsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL {\n\t\tif (typeof this.forJsonSelect === 'function') return this.forJsonSelect(identifier, sql);\n\n\t\tconst rawType = this.getSQLType().toLowerCase();\n\t\tconst parenPos = rawType.indexOf('(');\n\t\tconst type = (parenPos + 1) ? rawType.slice(0, parenPos) : rawType;\n\n\t\tswitch (type) {\n\t\t\tcase 'numeric':\n\t\t\tcase 'decimal':\n\t\t\tcase 'bigint': {\n\t\t\t\treturn sql`cast(${identifier} as text)`;\n\t\t\t}\n\t\t\tcase 'blob': {\n\t\t\t\treturn sql`hex(${identifier})`;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn identifier;\n\t\t\t}\n\t\t}\n\t}\n\n\toverride mapToDriverValue(value: T['data']): T['driverParam'] {\n\t\treturn typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data'];\n\t}\n}\n\nexport interface CustomTypeValues {\n\t/**\n\t * Required type for custom column, that will infer proper type model\n\t *\n\t * Examples:\n\t *\n\t * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar`\n\t *\n\t * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer`\n\t */\n\tdata: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is accepting for specific database data type\n\t */\n\tdriverData?: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is returning for specific database data type\n\t *\n\t * Needed only in case driver's output and input for type differ\n\t *\n\t * Defaults to {@link driverData}\n\t */\n\tdriverOutput?: unknown;\n\n\t/**\n\t * Type helper, that represents what type field returns after being aggregated to JSON\n\t */\n\tjsonData?: unknown;\n\n\t/**\n\t * What config type should be used for {@link CustomTypeParams} `dataType` generation\n\t */\n\tconfig?: Record<string, any>;\n\n\t/**\n\t * Whether the config argument should be required or not\n\t * @default false\n\t */\n\tconfigRequired?: boolean;\n\n\t/**\n\t * If your custom data type should be notNull by default you can use `notNull: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tnotNull?: boolean;\n\n\t/**\n\t * If your custom data type has default you can use `default: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tdefault?: boolean;\n}\n\nexport interface CustomTypeParams<T extends CustomTypeValues> {\n\t/**\n\t * Database data type string representation, that is used for migrations\n\t * @example\n\t * ```\n\t * `jsonb`, `text`\n\t * ```\n\t *\n\t * If database data type needs additional params you can use them from `config` param\n\t * @example\n\t * ```\n\t * `varchar(256)`, `numeric(2,3)`\n\t * ```\n\t *\n\t * To make `config` be of specific type please use config generic in {@link CustomTypeValues}\n\t *\n\t * @example\n\t * Usage example\n\t * ```\n\t * dataType() {\n\t * return 'boolean';\n\t * },\n\t * ```\n\t * Or\n\t * ```\n\t * dataType(config) {\n\t * \t return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`;\n\t * \t }\n\t * ```\n\t */\n\tdataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;\n\n\t/**\n\t * Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver\n\t * @example\n\t * For example, when using jsonb we need to map JS/TS object to string before writing to database\n\t * ```\n\t * toDriver(value: TData): string {\n\t * \t return JSON.stringify(value);\n\t * }\n\t * ```\n\t */\n\ttoDriver?: (value: T['data']) => T['driverData'] | SQL;\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by driver to desired column's output format\n\t * @example\n\t * For example, when using timestamp we need to map string Date representation to JS Date\n\t * ```\n\t * fromDriver(value: string): Date {\n\t * \treturn new Date(value);\n\t * }\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"2025-04-07T03:25:16.635Z\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: new Date(\"2025-04-07T03:25:16.635Z\");\n\t * }\n\t * ```\n\t */\n\tfromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/docs/rqb-v2)\n\t *\n\t * Defaults to {@link fromDriver} function\n\t * @example\n\t * For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query\n\t * To handle that, we need a separate function to handle such field's mapping:\n\t * ```\n\t * fromJson(value: string): Buffer {\n\t * \treturn Buffer.from(value, 'hex');\n\t * },\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"04A8...\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: Buffer([...]);\n\t * }\n\t * ```\n\t */\n\tfromJson?: (value: T['jsonData']) => T['data'];\n\n\t/**\n\t * Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/docs/json-functions)\n\t *\n\t * Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/docs/rqb-v2)\n\t *\n\t * Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)\n\t * @example\n\t * For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity\n\t * ```\n\t * forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {\n\t * \treturn sql`cast(${identifier} as text)`\n\t * },\n\t * ```\n\t *\n\t * This will change query from:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\t`table`.`custom_bigint` AS \"bigint\"\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t * to:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\tcast(`table`.`custom_bigint` as text) AS `bigint`\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t *\n\t * Returned by query object will change from:\n\t * ```\n\t * {\n\t * \tbigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tbigint: \"5044565289845416380\"; // Data is preserved due to conversion of field to text before JSON-ification\n\t * }\n\t * ```\n\t */\n\tforJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;\n}\n\n/**\n * Custom sqlite database data type generator\n */\nexport function customType<T extends CustomTypeValues = CustomTypeValues>(\n\tcustomTypeParams: CustomTypeParams<T>,\n): Equal<T['configRequired'], true> extends true ? {\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n\t: {\n\t\t(): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig?: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig?: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n{\n\treturn <TName extends string>(\n\t\ta?: TName | T['config'],\n\t\tb?: T['config'],\n\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>> => {\n\t\tconst { name, config } = getColumnNameAndConfig<T['config']>(a, b);\n\t\treturn new SQLiteCustomColumnBuilder(\n\t\t\tname as ConvertCustomConfig<TName, T>['name'],\n\t\t\tconfig,\n\t\t\tcustomTypeParams,\n\t\t);\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA2B;AAG3B,mBAAmD;AACnD,oBAAkD;AAkB3C,MAAM,kCACJ,kCAUT;AAAA,EACC,QAA0B,wBAAU,IAAY;AAAA,EAEhD,YACC,MACA,aACA,kBACC;AACD,UAAM,MAAM,UAAU,oBAAoB;AAC1C,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,mBAAmB;AAAA,EAChC;AAAA;AAAA,EAGA,MACC,OACsD;AACtD,WAAO,IAAI;AAAA,MACV;AAAA,MACA,KAAK;AAAA,IACN;AAAA,EACD;AACD;AAEO,MAAM,2BAAuF,2BAAgB;AAAA,EACnH,QAA0B,wBAAU,IAAY;AAAA,EAExC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,OACA,QACC;AACD,UAAM,OAAO,MAAM;AACnB,SAAK,UAAU,OAAO,iBAAiB,SAAS,OAAO,WAAW;AAClE,SAAK,QAAQ,OAAO,iBAAiB;AACrC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,gBAAgB,OAAO,iBAAiB;AAAA,EAC9C;AAAA,EAEA,aAAqB;AACpB,WAAO,KAAK;AAAA,EACb;AAAA,EAES,mBAAmB,OAAoC;AAC/D,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI;AAAA,EACnE;AAAA,EAEA,iBAAiB,OAA2B;AAC3C,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI,KAAK,mBAAmB,KAAK;AAAA,EAChG;AAAA,EAEA,qBAAqB,YAAiB,KAAwB;AAC7D,QAAI,OAAO,KAAK,kBAAkB;AAAY,aAAO,KAAK,cAAc,YAAY,GAAG;AAEvF,UAAM,UAAU,KAAK,WAAW,EAAE,YAAY;AAC9C,UAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,UAAM,OAAQ,WAAW,IAAK,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAE3D,YAAQ,MAAM;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AACd,eAAO,WAAW,UAAU;AAAA,MAC7B;AAAA,MACA,KAAK,QAAQ;AACZ,eAAO,UAAU,UAAU;AAAA,MAC5B;AAAA,MACA,SAAS;AACR,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EAES,iBAAiB,OAAoC;AAC7D,WAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D;AACD;AAoOO,SAAS,WACf,kBAoBD;AACC,SAAO,CACN,GACA,MAC8D;AAC9D,UAAM,EAAE,MAAM,OAAO,QAAI,qCAAoC,GAAG,CAAC;AACjE,WAAO,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/sqlite-core/columns/custom.ts"],"sourcesContent":["import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts';\nimport type { ColumnBaseConfig } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { SQL, SQLGenerator } from '~/sql/sql.ts';\nimport type { AnySQLiteTable } from '~/sqlite-core/table.ts';\nimport { type Equal, getColumnNameAndConfig } from '~/utils.ts';\nimport { SQLiteColumn, SQLiteColumnBuilder } from './common.ts';\n\nexport type ConvertCustomConfig<TName extends string, T extends Partial<CustomTypeValues>> =\n\t& {\n\t\tname: TName;\n\t\tdataType: 'custom';\n\t\tcolumnType: 'SQLiteCustomColumn';\n\t\tdata: T['data'];\n\t\tdriverParam: T['driverData'];\n\t\tenumValues: undefined;\n\t}\n\t& (T['notNull'] extends true ? { notNull: true } : {})\n\t& (T['default'] extends true ? { hasDefault: true } : {});\n\nexport interface SQLiteCustomColumnInnerConfig {\n\tcustomTypeValues: CustomTypeValues;\n}\n\nexport class SQLiteCustomColumnBuilder<T extends ColumnBuilderBaseConfig<'custom', 'SQLiteCustomColumn'>>\n\textends SQLiteColumnBuilder<\n\t\tT,\n\t\t{\n\t\t\tfieldConfig: CustomTypeValues['config'];\n\t\t\tcustomTypeParams: CustomTypeParams<any>;\n\t\t},\n\t\t{\n\t\t\tsqliteColumnBuilderBrand: 'SQLiteCustomColumnBuilderBrand';\n\t\t}\n\t>\n{\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumnBuilder';\n\n\tconstructor(\n\t\tname: T['name'],\n\t\tfieldConfig: CustomTypeValues['config'],\n\t\tcustomTypeParams: CustomTypeParams<any>,\n\t) {\n\t\tsuper(name, 'custom', 'SQLiteCustomColumn');\n\t\tthis.config.fieldConfig = fieldConfig;\n\t\tthis.config.customTypeParams = customTypeParams;\n\t}\n\n\t/** @internal */\n\tbuild<TTableName extends string>(\n\t\ttable: AnySQLiteTable<{ name: TTableName }>,\n\t): SQLiteCustomColumn<MakeColumnConfig<T, TTableName>> {\n\t\treturn new SQLiteCustomColumn<MakeColumnConfig<T, TTableName>>(\n\t\t\ttable,\n\t\t\tthis.config as ColumnBuilderRuntimeConfig<any, any>,\n\t\t);\n\t}\n}\n\nexport class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>> extends SQLiteColumn<T> {\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumn';\n\n\tprivate sqlName: string;\n\tprivate mapTo?: (value: T['data']) => T['driverParam'];\n\tprivate mapFrom?: (value: T['driverParam']) => T['data'];\n\tprivate mapJson?: (value: unknown) => T['data'];\n\tprivate forJsonSelect?: (name: SQL, sql: SQLGenerator) => SQL;\n\n\tconstructor(\n\t\ttable: AnySQLiteTable<{ name: T['tableName'] }>,\n\t\tconfig: SQLiteCustomColumnBuilder<T>['config'],\n\t) {\n\t\tsuper(table, config);\n\t\tthis.sqlName = config.customTypeParams.dataType(config.fieldConfig);\n\t\tthis.mapTo = config.customTypeParams.toDriver;\n\t\tthis.mapFrom = config.customTypeParams.fromDriver;\n\t\tthis.mapJson = config.customTypeParams.fromJson;\n\t\tthis.forJsonSelect = config.customTypeParams.forJsonSelect;\n\t}\n\n\tgetSQLType(): string {\n\t\treturn this.sqlName;\n\t}\n\n\toverride mapFromDriverValue(value: T['driverParam']): T['data'] {\n\t\treturn typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data'];\n\t}\n\n\tmapFromJsonValue(value: unknown): T['data'] {\n\t\treturn typeof this.mapJson === 'function' ? this.mapJson(value) : this.mapFromDriverValue(value) as T['data'];\n\t}\n\n\tjsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL {\n\t\tif (typeof this.forJsonSelect === 'function') return this.forJsonSelect(identifier, sql);\n\n\t\tconst rawType = this.getSQLType().toLowerCase();\n\t\tconst parenPos = rawType.indexOf('(');\n\t\tconst type = (parenPos + 1) ? rawType.slice(0, parenPos) : rawType;\n\n\t\tswitch (type) {\n\t\t\tcase 'numeric':\n\t\t\tcase 'decimal':\n\t\t\tcase 'bigint': {\n\t\t\t\treturn sql`cast(${identifier} as text)`;\n\t\t\t}\n\t\t\tcase 'blob': {\n\t\t\t\treturn sql`hex(${identifier})`;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn identifier;\n\t\t\t}\n\t\t}\n\t}\n\n\toverride mapToDriverValue(value: T['data']): T['driverParam'] {\n\t\treturn typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data'];\n\t}\n}\n\nexport interface CustomTypeValues {\n\t/**\n\t * Required type for custom column, that will infer proper type model\n\t *\n\t * Examples:\n\t *\n\t * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar`\n\t *\n\t * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer`\n\t */\n\tdata: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is accepting for specific database data type\n\t */\n\tdriverData?: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is returning for specific database data type\n\t *\n\t * Needed only in case driver's output and input for type differ\n\t *\n\t * Defaults to {@link driverData}\n\t */\n\tdriverOutput?: unknown;\n\n\t/**\n\t * Type helper, that represents what type field returns after being aggregated to JSON\n\t */\n\tjsonData?: unknown;\n\n\t/**\n\t * What config type should be used for {@link CustomTypeParams} `dataType` generation\n\t */\n\tconfig?: Record<string, any>;\n\n\t/**\n\t * Whether the config argument should be required or not\n\t * @default false\n\t */\n\tconfigRequired?: boolean;\n\n\t/**\n\t * If your custom data type should be notNull by default you can use `notNull: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tnotNull?: boolean;\n\n\t/**\n\t * If your custom data type has default you can use `default: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tdefault?: boolean;\n}\n\nexport interface CustomTypeParams<T extends CustomTypeValues> {\n\t/**\n\t * Database data type string representation, that is used for migrations\n\t * @example\n\t * ```\n\t * `jsonb`, `text`\n\t * ```\n\t *\n\t * If database data type needs additional params you can use them from `config` param\n\t * @example\n\t * ```\n\t * `varchar(256)`, `numeric(2,3)`\n\t * ```\n\t *\n\t * To make `config` be of specific type please use config generic in {@link CustomTypeValues}\n\t *\n\t * @example\n\t * Usage example\n\t * ```\n\t * dataType() {\n\t * return 'boolean';\n\t * },\n\t * ```\n\t * Or\n\t * ```\n\t * dataType(config) {\n\t * \t return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`;\n\t * \t }\n\t * ```\n\t */\n\tdataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;\n\n\t/**\n\t * Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver\n\t * @example\n\t * For example, when using jsonb we need to map JS/TS object to string before writing to database\n\t * ```\n\t * toDriver(value: TData): string {\n\t * \t return JSON.stringify(value);\n\t * }\n\t * ```\n\t */\n\ttoDriver?: (value: T['data']) => T['driverData'] | SQL;\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by driver to desired column's output format\n\t * @example\n\t * For example, when using timestamp we need to map string Date representation to JS Date\n\t * ```\n\t * fromDriver(value: string): Date {\n\t * \treturn new Date(value);\n\t * }\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"2025-04-07T03:25:16.635Z\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: new Date(\"2025-04-07T03:25:16.635Z\");\n\t * }\n\t * ```\n\t */\n\tfromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)\n\t *\n\t * Defaults to {@link fromDriver} function\n\t * @example\n\t * For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query\n\t * To handle that, we need a separate function to handle such field's mapping:\n\t * ```\n\t * fromJson(value: string): Buffer {\n\t * \treturn Buffer.from(value, 'hex');\n\t * },\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"04A8...\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: Buffer([...]);\n\t * }\n\t * ```\n\t */\n\tfromJson?: (value: T['jsonData']) => T['data'];\n\n\t/**\n\t * Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)\n\t *\n\t * Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)\n\t *\n\t * Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)\n\t * @example\n\t * For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity\n\t * ```\n\t * forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {\n\t * \treturn sql`cast(${identifier} as text)`\n\t * },\n\t * ```\n\t *\n\t * This will change query from:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\t`table`.`custom_bigint` AS \"bigint\"\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t * to:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\tcast(`table`.`custom_bigint` as text) AS `bigint`\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t *\n\t * Returned by query object will change from:\n\t * ```\n\t * {\n\t * \tbigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tbigint: \"5044565289845416380\"; // Data is preserved due to conversion of field to text before JSON-ification\n\t * }\n\t * ```\n\t */\n\tforJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;\n}\n\n/**\n * Custom sqlite database data type generator\n */\nexport function customType<T extends CustomTypeValues = CustomTypeValues>(\n\tcustomTypeParams: CustomTypeParams<T>,\n): Equal<T['configRequired'], true> extends true ? {\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n\t: {\n\t\t(): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig?: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig?: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n{\n\treturn <TName extends string>(\n\t\ta?: TName | T['config'],\n\t\tb?: T['config'],\n\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>> => {\n\t\tconst { name, config } = getColumnNameAndConfig<T['config']>(a, b);\n\t\treturn new SQLiteCustomColumnBuilder(\n\t\t\tname as ConvertCustomConfig<TName, T>['name'],\n\t\t\tconfig,\n\t\t\tcustomTypeParams,\n\t\t);\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA2B;AAG3B,mBAAmD;AACnD,oBAAkD;AAkB3C,MAAM,kCACJ,kCAUT;AAAA,EACC,QAA0B,wBAAU,IAAY;AAAA,EAEhD,YACC,MACA,aACA,kBACC;AACD,UAAM,MAAM,UAAU,oBAAoB;AAC1C,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,mBAAmB;AAAA,EAChC;AAAA;AAAA,EAGA,MACC,OACsD;AACtD,WAAO,IAAI;AAAA,MACV;AAAA,MACA,KAAK;AAAA,IACN;AAAA,EACD;AACD;AAEO,MAAM,2BAAuF,2BAAgB;AAAA,EACnH,QAA0B,wBAAU,IAAY;AAAA,EAExC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,OACA,QACC;AACD,UAAM,OAAO,MAAM;AACnB,SAAK,UAAU,OAAO,iBAAiB,SAAS,OAAO,WAAW;AAClE,SAAK,QAAQ,OAAO,iBAAiB;AACrC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,gBAAgB,OAAO,iBAAiB;AAAA,EAC9C;AAAA,EAEA,aAAqB;AACpB,WAAO,KAAK;AAAA,EACb;AAAA,EAES,mBAAmB,OAAoC;AAC/D,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI;AAAA,EACnE;AAAA,EAEA,iBAAiB,OAA2B;AAC3C,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI,KAAK,mBAAmB,KAAK;AAAA,EAChG;AAAA,EAEA,qBAAqB,YAAiB,KAAwB;AAC7D,QAAI,OAAO,KAAK,kBAAkB;AAAY,aAAO,KAAK,cAAc,YAAY,GAAG;AAEvF,UAAM,UAAU,KAAK,WAAW,EAAE,YAAY;AAC9C,UAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,UAAM,OAAQ,WAAW,IAAK,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAE3D,YAAQ,MAAM;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AACd,eAAO,WAAW,UAAU;AAAA,MAC7B;AAAA,MACA,KAAK,QAAQ;AACZ,eAAO,UAAU,UAAU;AAAA,MAC5B;AAAA,MACA,SAAS;AACR,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EAES,iBAAiB,OAAoC;AAC7D,WAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D;AACD;AAoOO,SAAS,WACf,kBAoBD;AACC,SAAO,CACN,GACA,MAC8D;AAC9D,UAAM,EAAE,MAAM,OAAO,QAAI,qCAAoC,GAAG,CAAC;AACjE,WAAO,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
@@ -173,11 +173,11 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
173
173
|
/**
|
|
174
174
|
* Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format
|
|
175
175
|
*
|
|
176
|
-
* Used by [relational queries](https://orm.drizzle.team/docs/
|
|
176
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
177
177
|
*
|
|
178
178
|
* Defaults to {@link fromDriver} function
|
|
179
179
|
* @example
|
|
180
|
-
* For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/
|
|
180
|
+
* For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query
|
|
181
181
|
* To handle that, we need a separate function to handle such field's mapping:
|
|
182
182
|
* ```
|
|
183
183
|
* fromJson(value: string): Buffer {
|
|
@@ -200,11 +200,11 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
200
200
|
*/
|
|
201
201
|
fromJson?: (value: T['jsonData']) => T['data'];
|
|
202
202
|
/**
|
|
203
|
-
* Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/
|
|
203
|
+
* Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)
|
|
204
204
|
*
|
|
205
205
|
* Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function
|
|
206
206
|
*
|
|
207
|
-
* Used by [relational queries](https://orm.drizzle.team/docs/
|
|
207
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
208
208
|
*
|
|
209
209
|
* Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)
|
|
210
210
|
* @example
|
|
@@ -173,11 +173,11 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
173
173
|
/**
|
|
174
174
|
* Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format
|
|
175
175
|
*
|
|
176
|
-
* Used by [relational queries](https://orm.drizzle.team/docs/
|
|
176
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
177
177
|
*
|
|
178
178
|
* Defaults to {@link fromDriver} function
|
|
179
179
|
* @example
|
|
180
|
-
* For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/
|
|
180
|
+
* For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query
|
|
181
181
|
* To handle that, we need a separate function to handle such field's mapping:
|
|
182
182
|
* ```
|
|
183
183
|
* fromJson(value: string): Buffer {
|
|
@@ -200,11 +200,11 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
|
|
|
200
200
|
*/
|
|
201
201
|
fromJson?: (value: T['jsonData']) => T['data'];
|
|
202
202
|
/**
|
|
203
|
-
* Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/
|
|
203
|
+
* Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)
|
|
204
204
|
*
|
|
205
205
|
* Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function
|
|
206
206
|
*
|
|
207
|
-
* Used by [relational queries](https://orm.drizzle.team/docs/
|
|
207
|
+
* Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)
|
|
208
208
|
*
|
|
209
209
|
* Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)
|
|
210
210
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/sqlite-core/columns/custom.ts"],"sourcesContent":["import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts';\nimport type { ColumnBaseConfig } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { SQL, SQLGenerator } from '~/sql/sql.ts';\nimport type { AnySQLiteTable } from '~/sqlite-core/table.ts';\nimport { type Equal, getColumnNameAndConfig } from '~/utils.ts';\nimport { SQLiteColumn, SQLiteColumnBuilder } from './common.ts';\n\nexport type ConvertCustomConfig<TName extends string, T extends Partial<CustomTypeValues>> =\n\t& {\n\t\tname: TName;\n\t\tdataType: 'custom';\n\t\tcolumnType: 'SQLiteCustomColumn';\n\t\tdata: T['data'];\n\t\tdriverParam: T['driverData'];\n\t\tenumValues: undefined;\n\t}\n\t& (T['notNull'] extends true ? { notNull: true } : {})\n\t& (T['default'] extends true ? { hasDefault: true } : {});\n\nexport interface SQLiteCustomColumnInnerConfig {\n\tcustomTypeValues: CustomTypeValues;\n}\n\nexport class SQLiteCustomColumnBuilder<T extends ColumnBuilderBaseConfig<'custom', 'SQLiteCustomColumn'>>\n\textends SQLiteColumnBuilder<\n\t\tT,\n\t\t{\n\t\t\tfieldConfig: CustomTypeValues['config'];\n\t\t\tcustomTypeParams: CustomTypeParams<any>;\n\t\t},\n\t\t{\n\t\t\tsqliteColumnBuilderBrand: 'SQLiteCustomColumnBuilderBrand';\n\t\t}\n\t>\n{\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumnBuilder';\n\n\tconstructor(\n\t\tname: T['name'],\n\t\tfieldConfig: CustomTypeValues['config'],\n\t\tcustomTypeParams: CustomTypeParams<any>,\n\t) {\n\t\tsuper(name, 'custom', 'SQLiteCustomColumn');\n\t\tthis.config.fieldConfig = fieldConfig;\n\t\tthis.config.customTypeParams = customTypeParams;\n\t}\n\n\t/** @internal */\n\tbuild<TTableName extends string>(\n\t\ttable: AnySQLiteTable<{ name: TTableName }>,\n\t): SQLiteCustomColumn<MakeColumnConfig<T, TTableName>> {\n\t\treturn new SQLiteCustomColumn<MakeColumnConfig<T, TTableName>>(\n\t\t\ttable,\n\t\t\tthis.config as ColumnBuilderRuntimeConfig<any, any>,\n\t\t);\n\t}\n}\n\nexport class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>> extends SQLiteColumn<T> {\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumn';\n\n\tprivate sqlName: string;\n\tprivate mapTo?: (value: T['data']) => T['driverParam'];\n\tprivate mapFrom?: (value: T['driverParam']) => T['data'];\n\tprivate mapJson?: (value: unknown) => T['data'];\n\tprivate forJsonSelect?: (name: SQL, sql: SQLGenerator) => SQL;\n\n\tconstructor(\n\t\ttable: AnySQLiteTable<{ name: T['tableName'] }>,\n\t\tconfig: SQLiteCustomColumnBuilder<T>['config'],\n\t) {\n\t\tsuper(table, config);\n\t\tthis.sqlName = config.customTypeParams.dataType(config.fieldConfig);\n\t\tthis.mapTo = config.customTypeParams.toDriver;\n\t\tthis.mapFrom = config.customTypeParams.fromDriver;\n\t\tthis.mapJson = config.customTypeParams.fromJson;\n\t\tthis.forJsonSelect = config.customTypeParams.forJsonSelect;\n\t}\n\n\tgetSQLType(): string {\n\t\treturn this.sqlName;\n\t}\n\n\toverride mapFromDriverValue(value: T['driverParam']): T['data'] {\n\t\treturn typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data'];\n\t}\n\n\tmapFromJsonValue(value: unknown): T['data'] {\n\t\treturn typeof this.mapJson === 'function' ? this.mapJson(value) : this.mapFromDriverValue(value) as T['data'];\n\t}\n\n\tjsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL {\n\t\tif (typeof this.forJsonSelect === 'function') return this.forJsonSelect(identifier, sql);\n\n\t\tconst rawType = this.getSQLType().toLowerCase();\n\t\tconst parenPos = rawType.indexOf('(');\n\t\tconst type = (parenPos + 1) ? rawType.slice(0, parenPos) : rawType;\n\n\t\tswitch (type) {\n\t\t\tcase 'numeric':\n\t\t\tcase 'decimal':\n\t\t\tcase 'bigint': {\n\t\t\t\treturn sql`cast(${identifier} as text)`;\n\t\t\t}\n\t\t\tcase 'blob': {\n\t\t\t\treturn sql`hex(${identifier})`;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn identifier;\n\t\t\t}\n\t\t}\n\t}\n\n\toverride mapToDriverValue(value: T['data']): T['driverParam'] {\n\t\treturn typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data'];\n\t}\n}\n\nexport interface CustomTypeValues {\n\t/**\n\t * Required type for custom column, that will infer proper type model\n\t *\n\t * Examples:\n\t *\n\t * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar`\n\t *\n\t * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer`\n\t */\n\tdata: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is accepting for specific database data type\n\t */\n\tdriverData?: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is returning for specific database data type\n\t *\n\t * Needed only in case driver's output and input for type differ\n\t *\n\t * Defaults to {@link driverData}\n\t */\n\tdriverOutput?: unknown;\n\n\t/**\n\t * Type helper, that represents what type field returns after being aggregated to JSON\n\t */\n\tjsonData?: unknown;\n\n\t/**\n\t * What config type should be used for {@link CustomTypeParams} `dataType` generation\n\t */\n\tconfig?: Record<string, any>;\n\n\t/**\n\t * Whether the config argument should be required or not\n\t * @default false\n\t */\n\tconfigRequired?: boolean;\n\n\t/**\n\t * If your custom data type should be notNull by default you can use `notNull: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tnotNull?: boolean;\n\n\t/**\n\t * If your custom data type has default you can use `default: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tdefault?: boolean;\n}\n\nexport interface CustomTypeParams<T extends CustomTypeValues> {\n\t/**\n\t * Database data type string representation, that is used for migrations\n\t * @example\n\t * ```\n\t * `jsonb`, `text`\n\t * ```\n\t *\n\t * If database data type needs additional params you can use them from `config` param\n\t * @example\n\t * ```\n\t * `varchar(256)`, `numeric(2,3)`\n\t * ```\n\t *\n\t * To make `config` be of specific type please use config generic in {@link CustomTypeValues}\n\t *\n\t * @example\n\t * Usage example\n\t * ```\n\t * dataType() {\n\t * return 'boolean';\n\t * },\n\t * ```\n\t * Or\n\t * ```\n\t * dataType(config) {\n\t * \t return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`;\n\t * \t }\n\t * ```\n\t */\n\tdataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;\n\n\t/**\n\t * Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver\n\t * @example\n\t * For example, when using jsonb we need to map JS/TS object to string before writing to database\n\t * ```\n\t * toDriver(value: TData): string {\n\t * \t return JSON.stringify(value);\n\t * }\n\t * ```\n\t */\n\ttoDriver?: (value: T['data']) => T['driverData'] | SQL;\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by driver to desired column's output format\n\t * @example\n\t * For example, when using timestamp we need to map string Date representation to JS Date\n\t * ```\n\t * fromDriver(value: string): Date {\n\t * \treturn new Date(value);\n\t * }\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"2025-04-07T03:25:16.635Z\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: new Date(\"2025-04-07T03:25:16.635Z\");\n\t * }\n\t * ```\n\t */\n\tfromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/docs/rqb-v2)\n\t *\n\t * Defaults to {@link fromDriver} function\n\t * @example\n\t * For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query\n\t * To handle that, we need a separate function to handle such field's mapping:\n\t * ```\n\t * fromJson(value: string): Buffer {\n\t * \treturn Buffer.from(value, 'hex');\n\t * },\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"04A8...\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: Buffer([...]);\n\t * }\n\t * ```\n\t */\n\tfromJson?: (value: T['jsonData']) => T['data'];\n\n\t/**\n\t * Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/docs/json-functions)\n\t *\n\t * Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/docs/rqb-v2)\n\t *\n\t * Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)\n\t * @example\n\t * For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity\n\t * ```\n\t * forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {\n\t * \treturn sql`cast(${identifier} as text)`\n\t * },\n\t * ```\n\t *\n\t * This will change query from:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\t`table`.`custom_bigint` AS \"bigint\"\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t * to:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\tcast(`table`.`custom_bigint` as text) AS `bigint`\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t *\n\t * Returned by query object will change from:\n\t * ```\n\t * {\n\t * \tbigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tbigint: \"5044565289845416380\"; // Data is preserved due to conversion of field to text before JSON-ification\n\t * }\n\t * ```\n\t */\n\tforJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;\n}\n\n/**\n * Custom sqlite database data type generator\n */\nexport function customType<T extends CustomTypeValues = CustomTypeValues>(\n\tcustomTypeParams: CustomTypeParams<T>,\n): Equal<T['configRequired'], true> extends true ? {\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n\t: {\n\t\t(): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig?: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig?: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n{\n\treturn <TName extends string>(\n\t\ta?: TName | T['config'],\n\t\tb?: T['config'],\n\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>> => {\n\t\tconst { name, config } = getColumnNameAndConfig<T['config']>(a, b);\n\t\treturn new SQLiteCustomColumnBuilder(\n\t\t\tname as ConvertCustomConfig<TName, T>['name'],\n\t\t\tconfig,\n\t\t\tcustomTypeParams,\n\t\t);\n\t};\n}\n"],"mappings":"AAEA,SAAS,kBAAkB;AAG3B,SAAqB,8BAA8B;AACnD,SAAS,cAAc,2BAA2B;AAkB3C,MAAM,kCACJ,oBAUT;AAAA,EACC,QAA0B,UAAU,IAAY;AAAA,EAEhD,YACC,MACA,aACA,kBACC;AACD,UAAM,MAAM,UAAU,oBAAoB;AAC1C,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,mBAAmB;AAAA,EAChC;AAAA;AAAA,EAGA,MACC,OACsD;AACtD,WAAO,IAAI;AAAA,MACV;AAAA,MACA,KAAK;AAAA,IACN;AAAA,EACD;AACD;AAEO,MAAM,2BAAuF,aAAgB;AAAA,EACnH,QAA0B,UAAU,IAAY;AAAA,EAExC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,OACA,QACC;AACD,UAAM,OAAO,MAAM;AACnB,SAAK,UAAU,OAAO,iBAAiB,SAAS,OAAO,WAAW;AAClE,SAAK,QAAQ,OAAO,iBAAiB;AACrC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,gBAAgB,OAAO,iBAAiB;AAAA,EAC9C;AAAA,EAEA,aAAqB;AACpB,WAAO,KAAK;AAAA,EACb;AAAA,EAES,mBAAmB,OAAoC;AAC/D,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI;AAAA,EACnE;AAAA,EAEA,iBAAiB,OAA2B;AAC3C,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI,KAAK,mBAAmB,KAAK;AAAA,EAChG;AAAA,EAEA,qBAAqB,YAAiB,KAAwB;AAC7D,QAAI,OAAO,KAAK,kBAAkB;AAAY,aAAO,KAAK,cAAc,YAAY,GAAG;AAEvF,UAAM,UAAU,KAAK,WAAW,EAAE,YAAY;AAC9C,UAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,UAAM,OAAQ,WAAW,IAAK,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAE3D,YAAQ,MAAM;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AACd,eAAO,WAAW,UAAU;AAAA,MAC7B;AAAA,MACA,KAAK,QAAQ;AACZ,eAAO,UAAU,UAAU;AAAA,MAC5B;AAAA,MACA,SAAS;AACR,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EAES,iBAAiB,OAAoC;AAC7D,WAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D;AACD;AAoOO,SAAS,WACf,kBAoBD;AACC,SAAO,CACN,GACA,MAC8D;AAC9D,UAAM,EAAE,MAAM,OAAO,IAAI,uBAAoC,GAAG,CAAC;AACjE,WAAO,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/sqlite-core/columns/custom.ts"],"sourcesContent":["import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnConfig } from '~/column-builder.ts';\nimport type { ColumnBaseConfig } from '~/column.ts';\nimport { entityKind } from '~/entity.ts';\nimport type { SQL, SQLGenerator } from '~/sql/sql.ts';\nimport type { AnySQLiteTable } from '~/sqlite-core/table.ts';\nimport { type Equal, getColumnNameAndConfig } from '~/utils.ts';\nimport { SQLiteColumn, SQLiteColumnBuilder } from './common.ts';\n\nexport type ConvertCustomConfig<TName extends string, T extends Partial<CustomTypeValues>> =\n\t& {\n\t\tname: TName;\n\t\tdataType: 'custom';\n\t\tcolumnType: 'SQLiteCustomColumn';\n\t\tdata: T['data'];\n\t\tdriverParam: T['driverData'];\n\t\tenumValues: undefined;\n\t}\n\t& (T['notNull'] extends true ? { notNull: true } : {})\n\t& (T['default'] extends true ? { hasDefault: true } : {});\n\nexport interface SQLiteCustomColumnInnerConfig {\n\tcustomTypeValues: CustomTypeValues;\n}\n\nexport class SQLiteCustomColumnBuilder<T extends ColumnBuilderBaseConfig<'custom', 'SQLiteCustomColumn'>>\n\textends SQLiteColumnBuilder<\n\t\tT,\n\t\t{\n\t\t\tfieldConfig: CustomTypeValues['config'];\n\t\t\tcustomTypeParams: CustomTypeParams<any>;\n\t\t},\n\t\t{\n\t\t\tsqliteColumnBuilderBrand: 'SQLiteCustomColumnBuilderBrand';\n\t\t}\n\t>\n{\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumnBuilder';\n\n\tconstructor(\n\t\tname: T['name'],\n\t\tfieldConfig: CustomTypeValues['config'],\n\t\tcustomTypeParams: CustomTypeParams<any>,\n\t) {\n\t\tsuper(name, 'custom', 'SQLiteCustomColumn');\n\t\tthis.config.fieldConfig = fieldConfig;\n\t\tthis.config.customTypeParams = customTypeParams;\n\t}\n\n\t/** @internal */\n\tbuild<TTableName extends string>(\n\t\ttable: AnySQLiteTable<{ name: TTableName }>,\n\t): SQLiteCustomColumn<MakeColumnConfig<T, TTableName>> {\n\t\treturn new SQLiteCustomColumn<MakeColumnConfig<T, TTableName>>(\n\t\t\ttable,\n\t\t\tthis.config as ColumnBuilderRuntimeConfig<any, any>,\n\t\t);\n\t}\n}\n\nexport class SQLiteCustomColumn<T extends ColumnBaseConfig<'custom', 'SQLiteCustomColumn'>> extends SQLiteColumn<T> {\n\tstatic override readonly [entityKind]: string = 'SQLiteCustomColumn';\n\n\tprivate sqlName: string;\n\tprivate mapTo?: (value: T['data']) => T['driverParam'];\n\tprivate mapFrom?: (value: T['driverParam']) => T['data'];\n\tprivate mapJson?: (value: unknown) => T['data'];\n\tprivate forJsonSelect?: (name: SQL, sql: SQLGenerator) => SQL;\n\n\tconstructor(\n\t\ttable: AnySQLiteTable<{ name: T['tableName'] }>,\n\t\tconfig: SQLiteCustomColumnBuilder<T>['config'],\n\t) {\n\t\tsuper(table, config);\n\t\tthis.sqlName = config.customTypeParams.dataType(config.fieldConfig);\n\t\tthis.mapTo = config.customTypeParams.toDriver;\n\t\tthis.mapFrom = config.customTypeParams.fromDriver;\n\t\tthis.mapJson = config.customTypeParams.fromJson;\n\t\tthis.forJsonSelect = config.customTypeParams.forJsonSelect;\n\t}\n\n\tgetSQLType(): string {\n\t\treturn this.sqlName;\n\t}\n\n\toverride mapFromDriverValue(value: T['driverParam']): T['data'] {\n\t\treturn typeof this.mapFrom === 'function' ? this.mapFrom(value) : value as T['data'];\n\t}\n\n\tmapFromJsonValue(value: unknown): T['data'] {\n\t\treturn typeof this.mapJson === 'function' ? this.mapJson(value) : this.mapFromDriverValue(value) as T['data'];\n\t}\n\n\tjsonSelectIdentifier(identifier: SQL, sql: SQLGenerator): SQL {\n\t\tif (typeof this.forJsonSelect === 'function') return this.forJsonSelect(identifier, sql);\n\n\t\tconst rawType = this.getSQLType().toLowerCase();\n\t\tconst parenPos = rawType.indexOf('(');\n\t\tconst type = (parenPos + 1) ? rawType.slice(0, parenPos) : rawType;\n\n\t\tswitch (type) {\n\t\t\tcase 'numeric':\n\t\t\tcase 'decimal':\n\t\t\tcase 'bigint': {\n\t\t\t\treturn sql`cast(${identifier} as text)`;\n\t\t\t}\n\t\t\tcase 'blob': {\n\t\t\t\treturn sql`hex(${identifier})`;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn identifier;\n\t\t\t}\n\t\t}\n\t}\n\n\toverride mapToDriverValue(value: T['data']): T['driverParam'] {\n\t\treturn typeof this.mapTo === 'function' ? this.mapTo(value) : value as T['data'];\n\t}\n}\n\nexport interface CustomTypeValues {\n\t/**\n\t * Required type for custom column, that will infer proper type model\n\t *\n\t * Examples:\n\t *\n\t * If you want your column to be `string` type after selecting/or on inserting - use `data: string`. Like `text`, `varchar`\n\t *\n\t * If you want your column to be `number` type after selecting/or on inserting - use `data: number`. Like `integer`\n\t */\n\tdata: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is accepting for specific database data type\n\t */\n\tdriverData?: unknown;\n\n\t/**\n\t * Type helper, that represents what type database driver is returning for specific database data type\n\t *\n\t * Needed only in case driver's output and input for type differ\n\t *\n\t * Defaults to {@link driverData}\n\t */\n\tdriverOutput?: unknown;\n\n\t/**\n\t * Type helper, that represents what type field returns after being aggregated to JSON\n\t */\n\tjsonData?: unknown;\n\n\t/**\n\t * What config type should be used for {@link CustomTypeParams} `dataType` generation\n\t */\n\tconfig?: Record<string, any>;\n\n\t/**\n\t * Whether the config argument should be required or not\n\t * @default false\n\t */\n\tconfigRequired?: boolean;\n\n\t/**\n\t * If your custom data type should be notNull by default you can use `notNull: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tnotNull?: boolean;\n\n\t/**\n\t * If your custom data type has default you can use `default: true`\n\t *\n\t * @example\n\t * const customSerial = customType<{ data: number, notNull: true, default: true }>({\n\t * \t dataType() {\n\t * \t return 'serial';\n\t * },\n\t * });\n\t */\n\tdefault?: boolean;\n}\n\nexport interface CustomTypeParams<T extends CustomTypeValues> {\n\t/**\n\t * Database data type string representation, that is used for migrations\n\t * @example\n\t * ```\n\t * `jsonb`, `text`\n\t * ```\n\t *\n\t * If database data type needs additional params you can use them from `config` param\n\t * @example\n\t * ```\n\t * `varchar(256)`, `numeric(2,3)`\n\t * ```\n\t *\n\t * To make `config` be of specific type please use config generic in {@link CustomTypeValues}\n\t *\n\t * @example\n\t * Usage example\n\t * ```\n\t * dataType() {\n\t * return 'boolean';\n\t * },\n\t * ```\n\t * Or\n\t * ```\n\t * dataType(config) {\n\t * \t return typeof config.length !== 'undefined' ? `varchar(${config.length})` : `varchar`;\n\t * \t }\n\t * ```\n\t */\n\tdataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;\n\n\t/**\n\t * Optional mapping function, that is used to transform inputs from desired to be used in code format to one suitable for driver\n\t * @example\n\t * For example, when using jsonb we need to map JS/TS object to string before writing to database\n\t * ```\n\t * toDriver(value: TData): string {\n\t * \t return JSON.stringify(value);\n\t * }\n\t * ```\n\t */\n\ttoDriver?: (value: T['data']) => T['driverData'] | SQL;\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by driver to desired column's output format\n\t * @example\n\t * For example, when using timestamp we need to map string Date representation to JS Date\n\t * ```\n\t * fromDriver(value: string): Date {\n\t * \treturn new Date(value);\n\t * }\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"2025-04-07T03:25:16.635Z\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: new Date(\"2025-04-07T03:25:16.635Z\");\n\t * }\n\t * ```\n\t */\n\tfromDriver?: (value: 'driverOutput' extends keyof T ? T['driverOutput'] : T['driverData']) => T['data'];\n\n\t/**\n\t * Optional mapping function, that is used for transforming data returned by transofmed to JSON in database data to desired format\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)\n\t *\n\t * Defaults to {@link fromDriver} function\n\t * @example\n\t * For example, when querying blob column via [RQB](https://orm.drizzle.team/docs/rqb-v2) or [JSON functions](https://orm.drizzle.team/docs/json-functions), the result field will be returned as it's hex string representation, as opposed to Buffer from regular query\n\t * To handle that, we need a separate function to handle such field's mapping:\n\t * ```\n\t * fromJson(value: string): Buffer {\n\t * \treturn Buffer.from(value, 'hex');\n\t * },\n\t * ```\n\t *\n\t * It'll cause the returned data to change from:\n\t * ```\n\t * {\n\t * \tcustomField: \"04A8...\";\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tcustomField: Buffer([...]);\n\t * }\n\t * ```\n\t */\n\tfromJson?: (value: T['jsonData']) => T['data'];\n\n\t/**\n\t * Optional selection modifier function, that is used for modifying selection of column inside [JSON functions](https://orm.drizzle.team/docs/json-functions)\n\t *\n\t * Additional mapping that could be required for such scenarios can be handled using {@link fromJson} function\n\t *\n\t * Used by [relational queries](https://orm.drizzle.team/docs/rqb-v2)\n\t *\n\t * Following types are being casted to text by default: `numeric`, `decimal`, `bigint`, `blob` (via `hex()` function)\n\t * @example\n\t * For example, when using numeric field for bigint storage we need to cast field to text to preserve data integrity\n\t * ```\n\t * forJsonSelect(identifier: SQL, sql: SQLGenerator): SQL {\n\t * \treturn sql`cast(${identifier} as text)`\n\t * },\n\t * ```\n\t *\n\t * This will change query from:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\t`table`.`custom_bigint` AS \"bigint\"\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t * to:\n\t * ```\n\t * SELECT\n\t * \tjson_object('bigint', `t`.`bigint`)\n\t * \tFROM\n\t * \t(\n\t * \t\tSELECT\n\t * \t\tcast(`table`.`custom_bigint` as text) AS `bigint`\n\t * \t\tFROM\n\t * \t\t`table`\n\t * \t) AS `t`\n\t * ```\n\t *\n\t * Returned by query object will change from:\n\t * ```\n\t * {\n\t * \tbigint: 5044565289845416000; // Partial data loss due to direct conversion to JSON format\n\t * }\n\t * ```\n\t * to:\n\t * ```\n\t * {\n\t * \tbigint: \"5044565289845416380\"; // Data is preserved due to conversion of field to text before JSON-ification\n\t * }\n\t * ```\n\t */\n\tforJsonSelect?: (identifier: SQL, sql: SQLGenerator) => SQL;\n}\n\n/**\n * Custom sqlite database data type generator\n */\nexport function customType<T extends CustomTypeValues = CustomTypeValues>(\n\tcustomTypeParams: CustomTypeParams<T>,\n): Equal<T['configRequired'], true> extends true ? {\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n\t: {\n\t\t(): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TConfig extends Record<string, any> & T['config']>(\n\t\t\tfieldConfig?: TConfig,\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<'', T>>;\n\t\t<TName extends string>(\n\t\t\tdbName: TName,\n\t\t\tfieldConfig?: T['config'],\n\t\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>>;\n\t}\n{\n\treturn <TName extends string>(\n\t\ta?: TName | T['config'],\n\t\tb?: T['config'],\n\t): SQLiteCustomColumnBuilder<ConvertCustomConfig<TName, T>> => {\n\t\tconst { name, config } = getColumnNameAndConfig<T['config']>(a, b);\n\t\treturn new SQLiteCustomColumnBuilder(\n\t\t\tname as ConvertCustomConfig<TName, T>['name'],\n\t\t\tconfig,\n\t\t\tcustomTypeParams,\n\t\t);\n\t};\n}\n"],"mappings":"AAEA,SAAS,kBAAkB;AAG3B,SAAqB,8BAA8B;AACnD,SAAS,cAAc,2BAA2B;AAkB3C,MAAM,kCACJ,oBAUT;AAAA,EACC,QAA0B,UAAU,IAAY;AAAA,EAEhD,YACC,MACA,aACA,kBACC;AACD,UAAM,MAAM,UAAU,oBAAoB;AAC1C,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,mBAAmB;AAAA,EAChC;AAAA;AAAA,EAGA,MACC,OACsD;AACtD,WAAO,IAAI;AAAA,MACV;AAAA,MACA,KAAK;AAAA,IACN;AAAA,EACD;AACD;AAEO,MAAM,2BAAuF,aAAgB;AAAA,EACnH,QAA0B,UAAU,IAAY;AAAA,EAExC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,OACA,QACC;AACD,UAAM,OAAO,MAAM;AACnB,SAAK,UAAU,OAAO,iBAAiB,SAAS,OAAO,WAAW;AAClE,SAAK,QAAQ,OAAO,iBAAiB;AACrC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,UAAU,OAAO,iBAAiB;AACvC,SAAK,gBAAgB,OAAO,iBAAiB;AAAA,EAC9C;AAAA,EAEA,aAAqB;AACpB,WAAO,KAAK;AAAA,EACb;AAAA,EAES,mBAAmB,OAAoC;AAC/D,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI;AAAA,EACnE;AAAA,EAEA,iBAAiB,OAA2B;AAC3C,WAAO,OAAO,KAAK,YAAY,aAAa,KAAK,QAAQ,KAAK,IAAI,KAAK,mBAAmB,KAAK;AAAA,EAChG;AAAA,EAEA,qBAAqB,YAAiB,KAAwB;AAC7D,QAAI,OAAO,KAAK,kBAAkB;AAAY,aAAO,KAAK,cAAc,YAAY,GAAG;AAEvF,UAAM,UAAU,KAAK,WAAW,EAAE,YAAY;AAC9C,UAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,UAAM,OAAQ,WAAW,IAAK,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAE3D,YAAQ,MAAM;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AACd,eAAO,WAAW,UAAU;AAAA,MAC7B;AAAA,MACA,KAAK,QAAQ;AACZ,eAAO,UAAU,UAAU;AAAA,MAC5B;AAAA,MACA,SAAS;AACR,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EAES,iBAAiB,OAAoC;AAC7D,WAAO,OAAO,KAAK,UAAU,aAAa,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D;AACD;AAoOO,SAAS,WACf,kBAoBD;AACC,SAAO,CACN,GACA,MAC8D;AAC9D,UAAM,EAAE,MAAM,OAAO,IAAI,uBAAoC,GAAG,CAAC;AACjE,WAAO,IAAI;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
@@ -24,9 +24,9 @@ __export(expressions_exports, {
|
|
|
24
24
|
substring: () => substring
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(expressions_exports);
|
|
27
|
-
var import_expressions = require("../expressions.cjs");
|
|
27
|
+
var import_expressions = require("../sql/expressions/index.cjs");
|
|
28
28
|
var import_sql = require("../sql/sql.cjs");
|
|
29
|
-
__reExport(expressions_exports, require("../expressions.cjs"), module.exports);
|
|
29
|
+
__reExport(expressions_exports, require("../sql/expressions/index.cjs"), module.exports);
|
|
30
30
|
function concat(column, value) {
|
|
31
31
|
return import_sql.sql`${column} || ${(0, import_expressions.bindIfParam)(value, column)}`;
|
|
32
32
|
}
|
|
@@ -49,6 +49,6 @@ function rowId() {
|
|
|
49
49
|
concat,
|
|
50
50
|
rowId,
|
|
51
51
|
substring,
|
|
52
|
-
...require("../expressions.cjs")
|
|
52
|
+
...require("../sql/expressions/index.cjs")
|
|
53
53
|
});
|
|
54
54
|
//# sourceMappingURL=expressions.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sqlite-core/expressions.ts"],"sourcesContent":["import { bindIfParam } from '~/expressions.ts';\nimport type { SQL, SQLChunk, SQLWrapper } from '~/sql/sql.ts';\nimport { sql } from '~/sql/sql.ts';\nimport type { SQLiteColumn } from '~/sqlite-core/columns/index.ts';\n\nexport * from '~/expressions.ts';\n\nexport function concat(column: SQLiteColumn | SQL.Aliased, value: string | SQLWrapper): SQL {\n\treturn sql`${column} || ${bindIfParam(value, column)}`;\n}\n\nexport function substring(\n\tcolumn: SQLiteColumn | SQL.Aliased,\n\t{ from, for: _for }: { from?: number | SQLWrapper; for?: number | SQLWrapper },\n): SQL {\n\tconst chunks: SQLChunk[] = [sql`substring(`, column];\n\tif (from !== undefined) {\n\t\tchunks.push(sql` from `, bindIfParam(from, column));\n\t}\n\tif (_for !== undefined) {\n\t\tchunks.push(sql` for `, bindIfParam(_for, column));\n\t}\n\tchunks.push(sql`)`);\n\treturn sql.join(chunks);\n}\n\nexport function rowId(): SQL<number> {\n\treturn sql<number>`rowid`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA4B;AAE5B,iBAAoB;AAGpB,gCAAc,
|
|
1
|
+
{"version":3,"sources":["../../src/sqlite-core/expressions.ts"],"sourcesContent":["import { bindIfParam } from '~/sql/expressions/index.ts';\nimport type { SQL, SQLChunk, SQLWrapper } from '~/sql/sql.ts';\nimport { sql } from '~/sql/sql.ts';\nimport type { SQLiteColumn } from '~/sqlite-core/columns/index.ts';\n\nexport * from '~/sql/expressions/index.ts';\n\nexport function concat(column: SQLiteColumn | SQL.Aliased, value: string | SQLWrapper): SQL {\n\treturn sql`${column} || ${bindIfParam(value, column)}`;\n}\n\nexport function substring(\n\tcolumn: SQLiteColumn | SQL.Aliased,\n\t{ from, for: _for }: { from?: number | SQLWrapper; for?: number | SQLWrapper },\n): SQL {\n\tconst chunks: SQLChunk[] = [sql`substring(`, column];\n\tif (from !== undefined) {\n\t\tchunks.push(sql` from `, bindIfParam(from, column));\n\t}\n\tif (_for !== undefined) {\n\t\tchunks.push(sql` for `, bindIfParam(_for, column));\n\t}\n\tchunks.push(sql`)`);\n\treturn sql.join(chunks);\n}\n\nexport function rowId(): SQL<number> {\n\treturn sql<number>`rowid`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA4B;AAE5B,iBAAoB;AAGpB,gCAAc,uCALd;AAOO,SAAS,OAAO,QAAoC,OAAiC;AAC3F,SAAO,iBAAM,MAAM,WAAO,gCAAY,OAAO,MAAM,CAAC;AACrD;AAEO,SAAS,UACf,QACA,EAAE,MAAM,KAAK,KAAK,GACZ;AACN,QAAM,SAAqB,CAAC,4BAAiB,MAAM;AACnD,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK,4BAAa,gCAAY,MAAM,MAAM,CAAC;AAAA,EACnD;AACA,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK,2BAAY,gCAAY,MAAM,MAAM,CAAC;AAAA,EAClD;AACA,SAAO,KAAK,iBAAM;AAClB,SAAO,eAAI,KAAK,MAAM;AACvB;AAEO,SAAS,QAAqB;AACpC,SAAO;AACR;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SQL, SQLWrapper } from "../sql/sql.cjs";
|
|
2
2
|
import type { SQLiteColumn } from "./columns/index.cjs";
|
|
3
|
-
export * from "../expressions.cjs";
|
|
3
|
+
export * from "../sql/expressions/index.cjs";
|
|
4
4
|
export declare function concat(column: SQLiteColumn | SQL.Aliased, value: string | SQLWrapper): SQL;
|
|
5
5
|
export declare function substring(column: SQLiteColumn | SQL.Aliased, { from, for: _for }: {
|
|
6
6
|
from?: number | SQLWrapper;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SQL, SQLWrapper } from "../sql/sql.js";
|
|
2
2
|
import type { SQLiteColumn } from "./columns/index.js";
|
|
3
|
-
export * from "../expressions.js";
|
|
3
|
+
export * from "../sql/expressions/index.js";
|
|
4
4
|
export declare function concat(column: SQLiteColumn | SQL.Aliased, value: string | SQLWrapper): SQL;
|
|
5
5
|
export declare function substring(column: SQLiteColumn | SQL.Aliased, { from, for: _for }: {
|
|
6
6
|
from?: number | SQLWrapper;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { bindIfParam } from "../expressions.js";
|
|
1
|
+
import { bindIfParam } from "../sql/expressions/index.js";
|
|
2
2
|
import { sql } from "../sql/sql.js";
|
|
3
|
-
export * from "../expressions.js";
|
|
3
|
+
export * from "../sql/expressions/index.js";
|
|
4
4
|
function concat(column, value) {
|
|
5
5
|
return sql`${column} || ${bindIfParam(value, column)}`;
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sqlite-core/expressions.ts"],"sourcesContent":["import { bindIfParam } from '~/expressions.ts';\nimport type { SQL, SQLChunk, SQLWrapper } from '~/sql/sql.ts';\nimport { sql } from '~/sql/sql.ts';\nimport type { SQLiteColumn } from '~/sqlite-core/columns/index.ts';\n\nexport * from '~/expressions.ts';\n\nexport function concat(column: SQLiteColumn | SQL.Aliased, value: string | SQLWrapper): SQL {\n\treturn sql`${column} || ${bindIfParam(value, column)}`;\n}\n\nexport function substring(\n\tcolumn: SQLiteColumn | SQL.Aliased,\n\t{ from, for: _for }: { from?: number | SQLWrapper; for?: number | SQLWrapper },\n): SQL {\n\tconst chunks: SQLChunk[] = [sql`substring(`, column];\n\tif (from !== undefined) {\n\t\tchunks.push(sql` from `, bindIfParam(from, column));\n\t}\n\tif (_for !== undefined) {\n\t\tchunks.push(sql` for `, bindIfParam(_for, column));\n\t}\n\tchunks.push(sql`)`);\n\treturn sql.join(chunks);\n}\n\nexport function rowId(): SQL<number> {\n\treturn sql<number>`rowid`;\n}\n"],"mappings":"AAAA,SAAS,mBAAmB;AAE5B,SAAS,WAAW;AAGpB,cAAc;AAEP,SAAS,OAAO,QAAoC,OAAiC;AAC3F,SAAO,MAAM,MAAM,OAAO,YAAY,OAAO,MAAM,CAAC;AACrD;AAEO,SAAS,UACf,QACA,EAAE,MAAM,KAAK,KAAK,GACZ;AACN,QAAM,SAAqB,CAAC,iBAAiB,MAAM;AACnD,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK,aAAa,YAAY,MAAM,MAAM,CAAC;AAAA,EACnD;AACA,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK,YAAY,YAAY,MAAM,MAAM,CAAC;AAAA,EAClD;AACA,SAAO,KAAK,MAAM;AAClB,SAAO,IAAI,KAAK,MAAM;AACvB;AAEO,SAAS,QAAqB;AACpC,SAAO;AACR;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/sqlite-core/expressions.ts"],"sourcesContent":["import { bindIfParam } from '~/sql/expressions/index.ts';\nimport type { SQL, SQLChunk, SQLWrapper } from '~/sql/sql.ts';\nimport { sql } from '~/sql/sql.ts';\nimport type { SQLiteColumn } from '~/sqlite-core/columns/index.ts';\n\nexport * from '~/sql/expressions/index.ts';\n\nexport function concat(column: SQLiteColumn | SQL.Aliased, value: string | SQLWrapper): SQL {\n\treturn sql`${column} || ${bindIfParam(value, column)}`;\n}\n\nexport function substring(\n\tcolumn: SQLiteColumn | SQL.Aliased,\n\t{ from, for: _for }: { from?: number | SQLWrapper; for?: number | SQLWrapper },\n): SQL {\n\tconst chunks: SQLChunk[] = [sql`substring(`, column];\n\tif (from !== undefined) {\n\t\tchunks.push(sql` from `, bindIfParam(from, column));\n\t}\n\tif (_for !== undefined) {\n\t\tchunks.push(sql` for `, bindIfParam(_for, column));\n\t}\n\tchunks.push(sql`)`);\n\treturn sql.join(chunks);\n}\n\nexport function rowId(): SQL<number> {\n\treturn sql<number>`rowid`;\n}\n"],"mappings":"AAAA,SAAS,mBAAmB;AAE5B,SAAS,WAAW;AAGpB,cAAc;AAEP,SAAS,OAAO,QAAoC,OAAiC;AAC3F,SAAO,MAAM,MAAM,OAAO,YAAY,OAAO,MAAM,CAAC;AACrD;AAEO,SAAS,UACf,QACA,EAAE,MAAM,KAAK,KAAK,GACZ;AACN,QAAM,SAAqB,CAAC,iBAAiB,MAAM;AACnD,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK,aAAa,YAAY,MAAM,MAAM,CAAC;AAAA,EACnD;AACA,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK,YAAY,YAAY,MAAM,MAAM,CAAC;AAAA,EAClD;AACA,SAAO,KAAK,MAAM;AAClB,SAAO,IAAI,KAAK,MAAM;AACvB;AAEO,SAAS,QAAqB;AACpC,SAAO;AACR;","names":[]}
|
package/table.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/table.ts"],"sourcesContent":["import type { Column, GetColumnData } from './column.ts';\nimport { entityKind } from './entity.ts';\nimport type { OptionalKeyOnly, RequiredKeyOnly } from './operations.ts';\nimport type { SQLWrapper, View } from './sql/sql.ts';\nimport { TableName } from './table.utils.ts';\nimport type { Simplify, Update } from './utils.ts';\n\nexport interface TableConfig<TColumn extends Column = Column<any>> {\n\tname: string;\n\tschema: string | undefined;\n\tcolumns: Record<string, TColumn>;\n\tdialect: string;\n}\n\nexport type UpdateTableConfig<T extends TableConfig, TUpdate extends Partial<TableConfig>> = Required<\n\tUpdate<T, TUpdate>\n>;\n\n/** @internal */\nexport const Schema = Symbol.for('drizzle:Schema');\n\n/** @internal */\nexport const Columns = Symbol.for('drizzle:Columns');\n\n/** @internal */\nexport const ExtraConfigColumns = Symbol.for('drizzle:ExtraConfigColumns');\n\n/** @internal */\nexport const OriginalName = Symbol.for('drizzle:OriginalName');\n\n/** @internal */\nexport const BaseName = Symbol.for('drizzle:BaseName');\n\n/** @internal */\nexport const IsAlias = Symbol.for('drizzle:IsAlias');\n\n/** @internal */\nexport const ExtraConfigBuilder = Symbol.for('drizzle:ExtraConfigBuilder');\n\nconst IsDrizzleTable = Symbol.for('drizzle:IsDrizzleTable');\n\nexport interface Table<\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tT extends TableConfig = TableConfig,\n> extends SQLWrapper {\n\t// SQLWrapper runtime implementation is defined in 'sql/sql.ts'\n}\n\nexport class Table<T extends TableConfig = TableConfig> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Table';\n\n\tdeclare readonly _: {\n\t\treadonly brand: 'Table';\n\t\treadonly config: T;\n\t\treadonly name: T['name'];\n\t\treadonly schema: T['schema'];\n\t\treadonly columns: T['columns'];\n\t\treadonly inferSelect: InferSelectModel<Table<T>>;\n\t\treadonly inferInsert: InferInsertModel<Table<T>>;\n\t};\n\n\tdeclare readonly $inferSelect: InferSelectModel<Table<T>>;\n\tdeclare readonly $inferInsert: InferInsertModel<Table<T>>;\n\n\t/** @internal */\n\tstatic readonly Symbol = {\n\t\tName: TableName as typeof TableName,\n\t\tSchema: Schema as typeof Schema,\n\t\tOriginalName: OriginalName as typeof OriginalName,\n\t\tColumns: Columns as typeof Columns,\n\t\tExtraConfigColumns: ExtraConfigColumns as typeof ExtraConfigColumns,\n\t\tBaseName: BaseName as typeof BaseName,\n\t\tIsAlias: IsAlias as typeof IsAlias,\n\t\tExtraConfigBuilder: ExtraConfigBuilder as typeof ExtraConfigBuilder,\n\t};\n\n\t/**\n\t * @internal\n\t * Can be changed if the table is aliased.\n\t */\n\t[TableName]: string;\n\n\t/**\n\t * @internal\n\t * Used to store the original name of the table, before any aliasing.\n\t */\n\t[OriginalName]: string;\n\n\t/** @internal */\n\t[Schema]: string | undefined;\n\n\t/** @internal */\n\t[Columns]!: T['columns'];\n\n\t/** @internal */\n\t[ExtraConfigColumns]!: Record<string, unknown>;\n\n\t/**\n\t * @internal\n\t * Used to store the table name before the transformation via the `tableCreator` functions.\n\t */\n\t[BaseName]: string;\n\n\t/** @internal */\n\t[IsAlias] = false;\n\n\t/** @internal */\n\t[IsDrizzleTable] = true;\n\n\t/** @internal */\n\t[ExtraConfigBuilder]: ((self: any) => Record<string, unknown> | unknown[]) | undefined = undefined;\n\n\tconstructor(name: string, schema: string | undefined, baseName: string) {\n\t\tthis[TableName] = this[OriginalName] = name;\n\t\tthis[Schema] = schema;\n\t\tthis[BaseName] = baseName;\n\t}\n}\n\nexport function isTable(table: unknown): table is Table {\n\treturn typeof table === 'object' && table !== null && IsDrizzleTable in table;\n}\n\n/**\n * Any table with a specified boundary.\n *\n * @example\n\t```ts\n\t// Any table with a specific name\n\ttype AnyUsersTable = AnyTable<{ name: 'users' }>;\n\t```\n *\n * To describe any table with any config, simply use `Table` without any type arguments, like this:\n *\n\t```ts\n\tfunction needsTable(table: Table) {\n\t\t...\n\t}\n\t```\n */\nexport type AnyTable<TPartial extends Partial<TableConfig>> = Table<UpdateTableConfig<TableConfig, TPartial>>;\n\nexport function getTableName<T extends Table>(table: T): T['_']['name'] {\n\treturn table[TableName];\n}\n\nexport function getTableUniqueName<\n\tT extends Table | View,\n\tTResult extends string = T extends Table ? T['_']['schema'] extends undefined ? `public.${T['_']['name']}`\n\t\t: `${T['_']['schema']}.${T['_']['name']}`\n\t\t// Views don't have type-level schema names, to be added\n\t\t: `${string}.${T['_']['name']}`,\n>(\n\ttable: T,\n): TResult {\n\treturn `${table[Schema] ?? 'public'}.${table[TableName]}` as TResult;\n}\n\nexport type MapColumnName<TName extends string, TColumn extends Column, TDBColumNames extends boolean> =\n\tTDBColumNames extends true ? TColumn['_']['name']\n\t\t: TName;\n\nexport type InferModelFromColumns<\n\tTColumns extends Record<string, Column>,\n\tTInferMode extends 'select' | 'insert' = 'select',\n\tTConfig extends { dbColumnNames: boolean; override?: boolean } = { dbColumnNames: false; override: false },\n> = Simplify<\n\tTInferMode extends 'insert' ?\n\t\t\t& {\n\t\t\t\t[\n\t\t\t\t\tKey in keyof TColumns & string as RequiredKeyOnly<\n\t\t\t\t\t\tMapColumnName<Key, TColumns[Key], TConfig['dbColumnNames']>,\n\t\t\t\t\t\tTColumns[Key]\n\t\t\t\t\t>\n\t\t\t\t]: GetColumnData<TColumns[Key], 'query'>;\n\t\t\t}\n\t\t\t& {\n\t\t\t\t[\n\t\t\t\t\tKey in keyof TColumns & string as OptionalKeyOnly<\n\t\t\t\t\t\tMapColumnName<Key, TColumns[Key], TConfig['dbColumnNames']>,\n\t\t\t\t\t\tTColumns[Key],\n\t\t\t\t\t\tTConfig['override']\n\t\t\t\t\t>\n\t\t\t\t]?: GetColumnData<TColumns[Key], 'query'> | undefined;\n\t\t\t}\n\t\t: {\n\t\t\t[\n\t\t\t\tKey in keyof TColumns & string as MapColumnName<\n\t\t\t\t\tKey,\n\t\t\t\t\tTColumns[Key],\n\t\t\t\t\tTConfig['dbColumnNames']\n\t\t\t\t>\n\t\t\t]: GetColumnData<TColumns[Key], 'query'>;\n\t\t}\n>;\n\n/** @deprecated Use one of the alternatives: {@link InferSelectModel} / {@link InferInsertModel}, or `table.$inferSelect` / `table.$inferInsert`\n */\nexport type InferModel<\n\tTTable extends Table,\n\tTInferMode extends 'select' | 'insert' = 'select',\n\tTConfig extends { dbColumnNames: boolean } = { dbColumnNames: false },\n> = InferModelFromColumns<TTable['_']['columns'], TInferMode, TConfig>;\n\nexport type InferSelectModel<\n\tTTable extends Table,\n\tTConfig extends { dbColumnNames: boolean } = { dbColumnNames: false },\n> = InferModelFromColumns<TTable['_']['columns'], 'select', TConfig>;\n\nexport type InferInsertModel<\n\tTTable extends Table,\n\tTConfig extends { dbColumnNames: boolean; override?: boolean } = { dbColumnNames: false; override: false },\n> = InferModelFromColumns<TTable['_']['columns'], 'insert', TConfig>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA2B;AAG3B,yBAA0B;AAenB,MAAM,SAAS,OAAO,IAAI,gBAAgB;AAG1C,MAAM,UAAU,OAAO,IAAI,iBAAiB;AAG5C,MAAM,qBAAqB,OAAO,IAAI,4BAA4B;AAGlE,MAAM,eAAe,OAAO,IAAI,sBAAsB;AAGtD,MAAM,WAAW,OAAO,IAAI,kBAAkB;AAG9C,MAAM,UAAU,OAAO,IAAI,iBAAiB;AAG5C,MAAM,qBAAqB,OAAO,IAAI,4BAA4B;AAEzE,MAAM,iBAAiB,OAAO,IAAI,wBAAwB;AASnD,MAAM,MAAiE;AAAA,EAC7E,QAAiB,wBAAU,IAAY;AAAA;AAAA,EAgBvC,OAAgB,SAAS;AAAA,IACxB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,CAAC,4BAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,CAAC,YAAY;AAAA;AAAA,EAGb,CAAC,MAAM;AAAA;AAAA,EAGP,CAAC,OAAO;AAAA;AAAA,EAGR,CAAC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnB,CAAC,QAAQ;AAAA;AAAA,EAGT,CAAC,OAAO,IAAI;AAAA;AAAA,EAGZ,CAAC,cAAc,IAAI;AAAA;AAAA,EAGnB,CAAC,kBAAkB,IAAsE;AAAA,EAEzF,YAAY,MAAc,QAA4B,UAAkB;AACvE,SAAK,4BAAS,IAAI,KAAK,YAAY,IAAI;AACvC,SAAK,MAAM,IAAI;AACf,SAAK,QAAQ,IAAI;AAAA,EAClB;AACD;AAEO,SAAS,QAAQ,OAAgC;AACvD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,kBAAkB;AACzE;AAqBO,SAAS,aAA8B,OAA0B;AACvE,SAAO,MAAM,4BAAS;AACvB;AAEO,SAAS,mBAOf,OACU;AACV,SAAO,GAAG,MAAM,MAAM,KAAK,QAAQ,IAAI,MAAM,4BAAS,CAAC;AACxD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/table.ts"],"sourcesContent":["import type { Column, GetColumnData } from './column.ts';\nimport { entityKind } from './entity.ts';\nimport type { OptionalKeyOnly, RequiredKeyOnly } from './operations.ts';\nimport type { SQLWrapper, View } from './sql/sql.ts';\nimport { TableName } from './table.utils.ts';\nimport type { Simplify, Update } from './utils.ts';\n\nexport interface TableConfig<TColumn extends Column = Column<any>> {\n\tname: string;\n\tschema: string | undefined;\n\tcolumns: Record<string, TColumn>;\n\tdialect: string;\n}\n\nexport type UpdateTableConfig<T extends TableConfig, TUpdate extends Partial<TableConfig>> = Required<\n\tUpdate<T, TUpdate>\n>;\n\n/** @internal */\nexport const Schema = Symbol.for('drizzle:Schema');\n\n/** @internal */\nexport const Columns = Symbol.for('drizzle:Columns');\n\n/** @internal */\nexport const ExtraConfigColumns = Symbol.for('drizzle:ExtraConfigColumns');\n\n/** @internal */\nexport const OriginalName = Symbol.for('drizzle:OriginalName');\n\n/** @internal */\nexport const BaseName = Symbol.for('drizzle:BaseName');\n\n/** @internal */\nexport const IsAlias = Symbol.for('drizzle:IsAlias');\n\n/** @internal */\nexport const ExtraConfigBuilder = Symbol.for('drizzle:ExtraConfigBuilder');\n\nconst IsDrizzleTable = Symbol.for('drizzle:IsDrizzleTable');\n\nexport interface Table<\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tT extends TableConfig = TableConfig,\n> extends SQLWrapper {\n\t// SQLWrapper runtime implementation is defined in 'sql/sql.ts'\n}\n\nexport class Table<T extends TableConfig = TableConfig> implements SQLWrapper {\n\tstatic readonly [entityKind]: string = 'Table';\n\n\tdeclare readonly _: {\n\t\treadonly brand: 'Table';\n\t\treadonly config: T;\n\t\treadonly name: T['name'];\n\t\treadonly schema: T['schema'];\n\t\treadonly columns: T['columns'];\n\t\treadonly inferSelect: InferSelectModel<Table<T>>;\n\t\treadonly inferInsert: InferInsertModel<Table<T>>;\n\t};\n\n\tdeclare readonly $inferSelect: InferSelectModel<Table<T>>;\n\tdeclare readonly $inferInsert: InferInsertModel<Table<T>>;\n\n\t/** @internal */\n\tstatic readonly Symbol = {\n\t\tName: TableName as typeof TableName,\n\t\tSchema: Schema as typeof Schema,\n\t\tOriginalName: OriginalName as typeof OriginalName,\n\t\tColumns: Columns as typeof Columns,\n\t\tExtraConfigColumns: ExtraConfigColumns as typeof ExtraConfigColumns,\n\t\tBaseName: BaseName as typeof BaseName,\n\t\tIsAlias: IsAlias as typeof IsAlias,\n\t\tExtraConfigBuilder: ExtraConfigBuilder as typeof ExtraConfigBuilder,\n\t};\n\n\t/**\n\t * @internal\n\t * Can be changed if the table is aliased.\n\t */\n\t[TableName]: string;\n\n\t/**\n\t * @internal\n\t * Used to store the original name of the table, before any aliasing.\n\t */\n\t[OriginalName]: string;\n\n\t/** @internal */\n\t[Schema]: string | undefined;\n\n\t/** @internal */\n\t[Columns]!: T['columns'];\n\n\t/** @internal */\n\t[ExtraConfigColumns]!: Record<string, unknown>;\n\n\t/**\n\t * @internal\n\t * Used to store the table name before the transformation via the `tableCreator` functions.\n\t */\n\t[BaseName]: string;\n\n\t/** @internal */\n\t[IsAlias] = false;\n\n\t/** @internal */\n\t[IsDrizzleTable] = true;\n\n\t/** @internal */\n\t[ExtraConfigBuilder]: ((self: any) => Record<string, unknown> | unknown[]) | undefined = undefined;\n\n\tconstructor(name: string, schema: string | undefined, baseName: string) {\n\t\tthis[TableName] = this[OriginalName] = name;\n\t\tthis[Schema] = schema;\n\t\tthis[BaseName] = baseName;\n\t}\n}\n\nexport function isTable(table: unknown): table is Table {\n\treturn typeof table === 'object' && table !== null && IsDrizzleTable in table;\n}\n\n/**\n * Any table with a specified boundary.\n *\n * @example\n\t```ts\n\t// Any table with a specific name\n\ttype AnyUsersTable = AnyTable<{ name: 'users' }>;\n\t```\n *\n * To describe any table with any config, simply use `Table` without any type arguments, like this:\n *\n\t```ts\n\tfunction needsTable(table: Table) {\n\t\t...\n\t}\n\t```\n */\nexport type AnyTable<TPartial extends Partial<TableConfig>> = Table<UpdateTableConfig<TableConfig, TPartial>>;\n\nexport function getTableName<T extends Table>(table: T): T['_']['name'] {\n\treturn table[TableName];\n}\n\nexport function getTableUniqueName<\n\tT extends Table | View,\n\tTResult extends string = T extends Table ? T['_']['schema'] extends undefined ? `public.${T['_']['name']}`\n\t\t: `${T['_']['schema']}.${T['_']['name']}`\n\t\t// Views don't have type-level schema names, to be added\n\t\t: `${string}.${T['_']['name']}`,\n>(\n\ttable: T,\n): TResult {\n\treturn `${table[Schema] ?? 'public'}.${table[TableName]}` as TResult;\n}\n\nexport type MapColumnName<TName extends string, TColumn extends Column, TDBColumNames extends boolean> =\n\tTDBColumNames extends true ? TColumn['_']['name']\n\t\t: TName;\n\nexport type InferModelFromColumns<\n\tTColumns extends Record<string, Column>,\n\tTInferMode extends 'select' | 'insert' = 'select',\n\tTConfig extends { dbColumnNames: boolean; override?: boolean } = { dbColumnNames: false; override: false },\n> = Simplify<\n\tTInferMode extends 'insert' ?\n\t\t\t& {\n\t\t\t\t[\n\t\t\t\t\tKey in keyof TColumns & string as RequiredKeyOnly<\n\t\t\t\t\t\tMapColumnName<Key, TColumns[Key], TConfig['dbColumnNames']>,\n\t\t\t\t\t\tTColumns[Key]\n\t\t\t\t\t>\n\t\t\t\t]: GetColumnData<TColumns[Key], 'query'>;\n\t\t\t}\n\t\t\t& {\n\t\t\t\t[\n\t\t\t\t\tKey in keyof TColumns & string as OptionalKeyOnly<\n\t\t\t\t\t\tMapColumnName<Key, TColumns[Key], TConfig['dbColumnNames']>,\n\t\t\t\t\t\tTColumns[Key],\n\t\t\t\t\t\tTConfig['override']\n\t\t\t\t\t>\n\t\t\t\t]?: GetColumnData<TColumns[Key], 'query'> | undefined;\n\t\t\t}\n\t\t: {\n\t\t\t[\n\t\t\t\tKey in keyof TColumns & string as MapColumnName<\n\t\t\t\t\tKey,\n\t\t\t\t\tTColumns[Key],\n\t\t\t\t\tTConfig['dbColumnNames']\n\t\t\t\t>\n\t\t\t]: GetColumnData<TColumns[Key], 'query'>;\n\t\t}\n>;\n\n/** @deprecated Use one of the alternatives: {@link InferSelectModel} / {@link InferInsertModel}, or `table.$inferSelect` / `table.$inferInsert`\n */\nexport type InferModel<\n\tTTable extends Table,\n\tTInferMode extends 'select' | 'insert' = 'select',\n\tTConfig extends { dbColumnNames: boolean } = { dbColumnNames: false },\n> = InferModelFromColumns<TTable['_']['columns'], TInferMode, TConfig>;\n\nexport type InferSelectModel<\n\tTTable extends Table,\n\tTConfig extends { dbColumnNames: boolean } = { dbColumnNames: false },\n> = InferModelFromColumns<TTable['_']['columns'], 'select', TConfig>;\n\nexport type InferInsertModel<\n\tTTable extends Table,\n\tTConfig extends { dbColumnNames: boolean; override?: boolean } = { dbColumnNames: false; override: false },\n> = InferModelFromColumns<TTable['_']['columns'], 'insert', TConfig>;\n\nexport type InferEnum<T> = T extends { enumValues: readonly (infer U)[] } ? U\n\t: never;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAA2B;AAG3B,yBAA0B;AAenB,MAAM,SAAS,OAAO,IAAI,gBAAgB;AAG1C,MAAM,UAAU,OAAO,IAAI,iBAAiB;AAG5C,MAAM,qBAAqB,OAAO,IAAI,4BAA4B;AAGlE,MAAM,eAAe,OAAO,IAAI,sBAAsB;AAGtD,MAAM,WAAW,OAAO,IAAI,kBAAkB;AAG9C,MAAM,UAAU,OAAO,IAAI,iBAAiB;AAG5C,MAAM,qBAAqB,OAAO,IAAI,4BAA4B;AAEzE,MAAM,iBAAiB,OAAO,IAAI,wBAAwB;AASnD,MAAM,MAAiE;AAAA,EAC7E,QAAiB,wBAAU,IAAY;AAAA;AAAA,EAgBvC,OAAgB,SAAS;AAAA,IACxB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,CAAC,4BAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,CAAC,YAAY;AAAA;AAAA,EAGb,CAAC,MAAM;AAAA;AAAA,EAGP,CAAC,OAAO;AAAA;AAAA,EAGR,CAAC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnB,CAAC,QAAQ;AAAA;AAAA,EAGT,CAAC,OAAO,IAAI;AAAA;AAAA,EAGZ,CAAC,cAAc,IAAI;AAAA;AAAA,EAGnB,CAAC,kBAAkB,IAAsE;AAAA,EAEzF,YAAY,MAAc,QAA4B,UAAkB;AACvE,SAAK,4BAAS,IAAI,KAAK,YAAY,IAAI;AACvC,SAAK,MAAM,IAAI;AACf,SAAK,QAAQ,IAAI;AAAA,EAClB;AACD;AAEO,SAAS,QAAQ,OAAgC;AACvD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,kBAAkB;AACzE;AAqBO,SAAS,aAA8B,OAA0B;AACvE,SAAO,MAAM,4BAAS;AACvB;AAEO,SAAS,mBAOf,OACU;AACV,SAAO,GAAG,MAAM,MAAM,KAAK,QAAQ,IAAI,MAAM,4BAAS,CAAC;AACxD;","names":[]}
|