@rocicorp/zero 0.25.13 → 0.25.14-canary.1
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/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +6 -25
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts +0 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +17 -14
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.json.js +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-server/src/custom.js +1 -7
- package/out/zero-server/src/custom.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAQ7C,OAAO,EAAC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAQ7C,OAAO,EAAC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EACV,GAAG,EAEH,kBAAkB,EAElB,WAAW,EAEX,QAAQ,EACR,eAAe,EAEhB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAC3D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,uCAAuC,CAAC;AACxE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AAUtD,KAAK,KAAK,GAAG;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,YAAY,CAAC;IAErB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAQF,wBAAgB,OAAO,CACrB,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,GAAG,EACR,MAAM,CAAC,EAAE,MAAM,GACd,QAAQ,CAgBV;AA4CD,wBAAgB,KAAK,CACnB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAC5B,QAAQ,CAWV;AAUD,wBAAgB,OAAO,CACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,QAAQ,GAAG,SAAS,EAC7B,KAAK,EAAE,KAAK,GACX,QAAQ,CAoBV;AAyJD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,SAAS,eAAe,EAAE,EACxC,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,CAAC,UAAU,EAAE,KAAK,KAAK,QAAQ,CAiBjC;AAED,wBAAgB,MAAM,CACpB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,KAAK,GACX,QAAQ,CAgCV;AAED,wBAAgB,GAAG,CACjB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,KAAK,GACX,QAAQ,CAMV;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,KAAK,GACX,QAAQ,CAIV;AAgGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,kBAAkB,GAC/B;IACD,IAAI,EAAE,QAAQ,CAAC;IACf,mBAAmB,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;CAC/D,CA2BA;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,kBAAkB,GAC/B;IACD;QACE,KAAK,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,WAAW,CAAC;QACzB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;KAC3B;IACD;QAAC,KAAK,EAAE,KAAK,CAAC;QAAC,WAAW,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;KAAC;CACpE,CAmBA;AAiDD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAMhE"}
|
package/out/z2s/src/compiler.js
CHANGED
|
@@ -4,10 +4,9 @@ import { parse } from "../../shared/src/bigint-json.js";
|
|
|
4
4
|
import { hasOwn } from "../../shared/src/has-own.js";
|
|
5
5
|
import "../../shared/src/config.js";
|
|
6
6
|
import { must } from "../../shared/src/must.js";
|
|
7
|
-
import { pgToZqlStringTypeMap } from "../../zero-cache/src/types/pg-data-type.js";
|
|
8
7
|
import { clientToServer } from "../../zero-schema/src/name-mapper.js";
|
|
9
8
|
import { completeOrdering } from "../../zql/src/query/complete-ordering.js";
|
|
10
|
-
import { sql, sqlConvertSingularLiteralArg,
|
|
9
|
+
import { sql, sqlConvertSingularLiteralArg, sqlConvertPluralLiteralArg, sqlConvertColumnArg } from "./sql.js";
|
|
11
10
|
const ZQL_RESULT_KEY = "zql_result";
|
|
12
11
|
const ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);
|
|
13
12
|
const ZQL_RESULT_TABLE_KEY = "zql_root";
|
|
@@ -86,32 +85,22 @@ function orderBy(spec, orderBy2, table) {
|
|
|
86
85
|
return sql``;
|
|
87
86
|
}
|
|
88
87
|
return sql`ORDER BY ${sql.join(
|
|
89
|
-
orderBy2.map(
|
|
90
|
-
|
|
91
|
-
return dir === "asc" ? (
|
|
88
|
+
orderBy2.map(
|
|
89
|
+
([col, dir]) => dir === "asc" ? (
|
|
92
90
|
// Oh postgres. The table must be referred to by client name but the column by server name.
|
|
93
91
|
// E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`
|
|
94
92
|
sql`${colIdent(spec.server, {
|
|
95
93
|
table,
|
|
96
94
|
zql: col
|
|
97
|
-
})}
|
|
95
|
+
})} ASC NULLS FIRST`
|
|
98
96
|
) : sql`${colIdent(spec.server, {
|
|
99
97
|
table,
|
|
100
98
|
zql: col
|
|
101
|
-
})}
|
|
102
|
-
|
|
99
|
+
})} DESC NULLS LAST`
|
|
100
|
+
),
|
|
103
101
|
", "
|
|
104
102
|
)}`;
|
|
105
103
|
}
|
|
106
|
-
function maybeCollate(serverColumnSchema) {
|
|
107
|
-
if (serverColumnSchema.type === "uuid" || serverColumnSchema.isEnum) {
|
|
108
|
-
return sql`::text COLLATE ${sql.ident(Z2S_COLLATION)}`;
|
|
109
|
-
}
|
|
110
|
-
if (Object.hasOwn(pgToZqlStringTypeMap, serverColumnSchema.type)) {
|
|
111
|
-
return sql` COLLATE ${sql.ident(Z2S_COLLATION)}`;
|
|
112
|
-
}
|
|
113
|
-
return sql``;
|
|
114
|
-
}
|
|
115
104
|
function related(spec, relationships, format, parentTable) {
|
|
116
105
|
return relationships.map(
|
|
117
106
|
(relationship) => relationshipSubquery(
|
|
@@ -297,18 +286,10 @@ function valueComparison(spec, valuePos, table, otherValuePos, plural) {
|
|
|
297
286
|
const valuePosType = valuePos.type;
|
|
298
287
|
switch (valuePosType) {
|
|
299
288
|
case "column": {
|
|
300
|
-
const serverColumnSchema = getServerColumn(
|
|
301
|
-
spec.server,
|
|
302
|
-
table,
|
|
303
|
-
valuePos.name
|
|
304
|
-
);
|
|
305
289
|
const qualified = {
|
|
306
290
|
table,
|
|
307
291
|
zql: valuePos.name
|
|
308
292
|
};
|
|
309
|
-
if (serverColumnSchema.type === "uuid" || serverColumnSchema.isEnum) {
|
|
310
|
-
return sql`${colIdent(spec.server, qualified)}::text`;
|
|
311
|
-
}
|
|
312
293
|
return colIdent(spec.server, qualified);
|
|
313
294
|
}
|
|
314
295
|
case "literal":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","sources":["../../../../z2s/src/compiler.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {last, zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n parse as parseBigIntJson,\n type JSONValue as BigIntJSONValue,\n} from '../../shared/src/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport {pgToZqlStringTypeMap} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {\n AST,\n Condition,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Correlation,\n LiteralReference,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n clientToServer,\n type NameMapper,\n} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {\n ServerColumnSchema,\n ServerSchema,\n} from '../../zero-types/src/server-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {completeOrdering} from '../../zql/src/query/complete-ordering.ts';\nimport {\n sql,\n sqlConvertColumnArg,\n sqlConvertPluralLiteralArg,\n sqlConvertSingularLiteralArg,\n Z2S_COLLATION,\n type PluralLiteralType,\n} from './sql.ts';\n\ntype Table = {\n zql: string;\n alias: string;\n};\n\ntype QualifiedColumn = {\n table: Table;\n zql: string;\n};\n\ntype ServerSpec = {\n schema: ServerSchema;\n // maps zql names to server names\n mapper: NameMapper;\n};\n\nexport type Spec = {\n server: ServerSpec;\n zql: Schema['tables'];\n aliasCount: number;\n};\n\nconst ZQL_RESULT_KEY = 'zql_result';\nconst ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);\n\nconst ZQL_RESULT_TABLE_KEY = 'zql_root';\nconst ZQL_RESULT_TABLE_IDENT = sql.ident(ZQL_RESULT_TABLE_KEY);\n\nexport function compile(\n serverSchema: ServerSchema,\n zqlSchema: Schema,\n ast: AST,\n format?: Format,\n): SQLQuery {\n ast = completeOrdering(\n ast,\n tableName => zqlSchema.tables[tableName].primaryKey,\n );\n const spec: Spec = {\n aliasCount: 0,\n server: {\n schema: serverSchema,\n mapper: clientToServer(zqlSchema.tables),\n },\n zql: zqlSchema.tables,\n };\n return sql`SELECT \n ${toJSON(ZQL_RESULT_TABLE_KEY, format?.singular)}::text AS ${ZQL_RESULT_KEY_IDENT}\n FROM (${select(spec, ast, format)}) ${ZQL_RESULT_TABLE_IDENT}`;\n}\n\nfunction select(\n spec: Spec,\n ast: AST,\n format: Format | undefined,\n correlate?: (childTable: Table) => SQLQuery,\n): SQLQuery {\n const table = makeTable(spec, ast.table);\n const selectionSet = related(spec, ast.related ?? [], format, table);\n const tableSchema = spec.zql[ast.table];\n const usedAliases = new Set<string>(\n ast.related?.map(r => r.subquery.alias ?? ''),\n );\n for (const column of Object.keys(tableSchema.columns)) {\n if (!usedAliases.has(column)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table,\n zql: column,\n }),\n );\n }\n }\n\n let appliedWhere = false;\n function maybeWhere(test: unknown | undefined) {\n if (!test) {\n return sql``;\n }\n\n const ret = appliedWhere ? sql`AND` : sql`WHERE`;\n appliedWhere = true;\n return ret;\n }\n\n return sql`SELECT ${sql.join(selectionSet, ',')}\n FROM ${fromIdent(spec.server, table)}\n ${maybeWhere(ast.where)} ${where(spec, ast.where, table)}\n ${maybeWhere(correlate)} ${correlate ? correlate(table) : sql``}\n ${orderBy(spec, ast.orderBy, table)}\n ${limit(ast.limit, format?.singular)}`;\n}\n\nexport function limit(\n limit: number | undefined,\n singular: boolean | undefined,\n): SQLQuery {\n if (limit === 0) {\n return sql`LIMIT 0`;\n }\n if (singular) {\n return sql`LIMIT 1`;\n }\n if (limit === undefined) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertSingularLiteralArg(limit)}`;\n}\n\nfunction makeTable(spec: Spec, zql: string, alias?: string): Table {\n alias = alias ?? zql + '_' + spec.aliasCount++;\n return {\n zql,\n alias,\n };\n}\n\nexport function orderBy(\n spec: Spec,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!orderBy) {\n return sql``;\n }\n return sql`ORDER BY ${sql.join(\n orderBy.map(([col, dir]) => {\n const serverColumnSchema = getServerColumn(spec.server, table, col);\n return dir === 'asc'\n ? // Oh postgres. The table must be referred to by client name but the column by server name.\n // E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`\n sql`${colIdent(spec.server, {\n table,\n zql: col,\n })}${maybeCollate(serverColumnSchema)} ASC NULLS FIRST`\n : sql`${colIdent(spec.server, {\n table,\n zql: col,\n })}${maybeCollate(serverColumnSchema)} DESC NULLS LAST`;\n }),\n ', ',\n )}`;\n}\n\nfunction maybeCollate(serverColumnSchema: ServerColumnSchema): SQLQuery {\n if (serverColumnSchema.type === 'uuid' || serverColumnSchema.isEnum) {\n return sql`::text COLLATE ${sql.ident(Z2S_COLLATION)}`;\n }\n if (Object.hasOwn(pgToZqlStringTypeMap, serverColumnSchema.type)) {\n return sql` COLLATE ${sql.ident(Z2S_COLLATION)}`;\n }\n\n return sql``;\n}\n\nfunction related(\n spec: Spec,\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery[] {\n return relationships.map(relationship =>\n relationshipSubquery(\n spec,\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n}\n\nfunction relationshipSubquery(\n spec: Spec,\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery {\n const innerAlias = `inner_${relationship.subquery.alias}`;\n if (relationship.hidden) {\n const {join, participatingTables} = makeJunctionJoin(spec, relationship);\n const lastTable = must(last(participatingTables)).table;\n\n assert(\n relationship.subquery.related,\n 'hidden relationship must be a junction',\n );\n const nestedAst = relationship.subquery.related[0].subquery;\n const selectionSet = related(\n spec,\n nestedAst.related ?? [],\n format,\n lastTable,\n );\n const tableSchema = spec.zql[nestedAst.table];\n for (const column of Object.keys(tableSchema.columns)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table: lastTable,\n zql: column,\n }),\n );\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (SELECT ${sql.join(\n selectionSet,\n ',',\n )} FROM ${join} WHERE (${makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n )(participatingTables[0].table)}) ${\n nestedAst.where\n ? sql`AND ${where(spec, nestedAst.where, lastTable)}`\n : sql``\n } ${orderBy(spec, nestedAst.orderBy, lastTable)} ${limit(\n last(participatingTables)?.limit,\n format?.singular,\n )} ) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (${select(\n spec,\n relationship.subquery,\n format,\n makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n}\n\nfunction where(\n spec: Spec,\n condition: Condition | undefined,\n table: Table,\n): SQLQuery {\n if (!condition) {\n return sql``;\n }\n\n switch (condition.type) {\n case 'and':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n return exists(spec, condition, table);\n case 'simple':\n return simple(spec, condition, table);\n }\n}\n\nfunction exists(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n }\n}\n\nexport function makeCorrelator(\n spec: Spec,\n parentFields: readonly QualifiedColumn[],\n childZqlFields: readonly string[],\n): (childTable: Table) => SQLQuery {\n return (childTable: Table) => {\n const childFields = childZqlFields.map(zqlField => ({\n table: childTable,\n zql: zqlField,\n }));\n return sql.join(\n zip(parentFields, childFields).map(\n ([parentColumn, childColumn]) =>\n sql`${colIdent(spec.server, parentColumn)} = ${colIdent(\n spec.server,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n };\n}\n\nexport function simple(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n switch (condition.op) {\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE':\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n condition.right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(\n spec,\n condition.right,\n table,\n condition.left,\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return any(spec, condition, table);\n case 'IS':\n case 'IS NOT':\n return distinctFrom(spec, condition, table);\n }\n}\n\nexport function any(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${condition.op === 'NOT IN' ? sql`NOT` : sql``}\n (\n ${valueComparison(spec, condition.left, table, condition.right, false)} = ANY \n (${valueComparison(spec, condition.right, table, condition.left, true)})\n )`;\n}\n\nexport function distinctFrom(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${valueComparison(spec, condition.right, table, condition.left, false)}`;\n}\n\nfunction valueComparison(\n spec: Spec,\n valuePos: ValuePosition,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const valuePosType = valuePos.type;\n switch (valuePosType) {\n case 'column': {\n const serverColumnSchema = getServerColumn(\n spec.server,\n table,\n valuePos.name,\n );\n const qualified: QualifiedColumn = {\n table,\n zql: valuePos.name,\n };\n if (serverColumnSchema.type === 'uuid' || serverColumnSchema.isEnum) {\n return sql`${colIdent(spec.server, qualified)}::text`;\n }\n return colIdent(spec.server, qualified);\n }\n case 'literal':\n return literalValueComparison(\n spec,\n valuePos,\n table,\n otherValuePos,\n plural,\n );\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(valuePosType);\n break;\n }\n}\n\nfunction literalValueComparison(\n spec: Spec,\n valuePos: LiteralReference,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const otherType = otherValuePos.type;\n switch (otherType) {\n case 'column':\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, otherValuePos.name),\n valuePos.value,\n plural,\n true,\n );\n case 'literal': {\n assert(plural === Array.isArray(valuePos.value));\n if (Array.isArray(valuePos.value)) {\n if (valuePos.value.length > 0) {\n // If the array is non-empty base its type on its first\n // element\n return sqlConvertPluralLiteralArg(\n typeof valuePos.value[0] as PluralLiteralType,\n valuePos.value as PluralLiteralType[],\n );\n }\n // If the array is empty, base its type on the other value\n // position's type (as long as the other value position is non-null,\n // cannot have a null[]).\n if (otherValuePos.value !== null) {\n return sqlConvertPluralLiteralArg(\n typeof otherValuePos.value as PluralLiteralType,\n [],\n );\n }\n // If the other value position is null, it can be compared to any\n // type of empty array, chose 'string' arbitrarily.\n return sqlConvertPluralLiteralArg('string', []);\n }\n if (\n typeof valuePos.value === 'string' ||\n typeof valuePos.value === 'number' ||\n typeof valuePos.value === 'boolean'\n ) {\n return sqlConvertSingularLiteralArg(valuePos.value);\n }\n throw new Error(\n `Literal of unexpected type. ${valuePos.value} of type ${typeof valuePos.value}`,\n );\n }\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(otherType);\n }\n}\n\nexport function makeJunctionJoin(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): {\n join: SQLQuery;\n participatingTables: ReturnType<typeof pullTablesForJunction>;\n} {\n const participatingTables = pullTablesForJunction(spec, relationship);\n const joins: SQLQuery[] = [];\n\n for (const {table} of participatingTables) {\n if (joins.length === 0) {\n joins.push(fromIdent(spec.server, table));\n continue;\n }\n joins.push(\n sql` JOIN ${fromIdent(spec.server, table)} ON ${makeCorrelator(\n spec,\n participatingTables[joins.length].correlation.parentField.map(f => ({\n table: participatingTables[joins.length - 1].table,\n zql: f,\n })),\n participatingTables[joins.length].correlation.childField,\n )(participatingTables[joins.length].table)}`,\n );\n }\n\n return {\n join: sql`${sql.join(joins, '')}`,\n participatingTables,\n // lastTable: participatingTables[participatingTables.length - 1].table,\n // lastLimit: participatingTables[participatingTables.length - 1].limit,\n };\n}\n\nexport function pullTablesForJunction(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): [\n {\n table: Table;\n correlation: Correlation;\n limit: number | undefined;\n },\n {table: Table; correlation: Correlation; limit: number | undefined},\n] {\n assert(\n relationship.subquery.related?.length === 1,\n 'Too many related tables for a junction edge',\n );\n const otherRelationship = relationship.subquery.related[0];\n assert(!otherRelationship.hidden);\n return [\n {\n table: makeTable(spec, relationship.subquery.table),\n correlation: relationship.correlation,\n limit: relationship.subquery.limit,\n },\n {\n table: makeTable(spec, otherRelationship.subquery.table),\n correlation: otherRelationship.correlation,\n limit: otherRelationship.subquery.limit,\n },\n ];\n}\n\nfunction toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)}))${singular ? sql`` : sql`, '[]'::json)`}`;\n}\n\nfunction selectIdent(server: ServerSpec, column: QualifiedColumn): SQLQuery {\n const serverColumnSchema =\n server.schema[server.mapper.tableName(column.table.zql)][\n server.mapper.columnName(column.table.zql, column.zql)\n ];\n const serverType = serverColumnSchema.type;\n if (\n !serverColumnSchema.isEnum &&\n (serverType === 'date' ||\n serverType === 'timestamp' ||\n serverType === 'timestamp without time zone' ||\n serverType === 'timestamptz' ||\n serverType === 'timestamp with time zone')\n ) {\n if (serverColumnSchema.isArray) {\n // Map EXTRACT(EPOCH FROM ...) * 1000 over array elements\n return sql`ARRAY(SELECT EXTRACT(EPOCH FROM unnest(${colIdent(server, column)})) * 1000) as ${sql.ident(column.zql)}`;\n }\n return sql`EXTRACT(EPOCH FROM ${colIdent(server, column)}) * 1000 as ${sql.ident(column.zql)}`;\n }\n return sql`${colIdent(server, column)} as ${sql.ident(column.zql)}`;\n}\n\nfunction colIdent(server: ServerSpec, column: QualifiedColumn) {\n return sql.ident(\n column.table.alias,\n server.mapper.columnName(column.table.zql, column.zql),\n );\n}\n\nfunction fromIdent(server: ServerSpec, table: Table) {\n return sql`${sql.ident(server.mapper.tableName(table.zql))} AS ${sql.ident(table.alias)}`;\n}\n\nfunction getServerColumn(spec: ServerSpec, table: Table, zqlColumn: string) {\n return spec.schema[spec.mapper.tableName(table.zql)][\n spec.mapper.columnName(table.zql, zqlColumn)\n ];\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: Array<any>): JSONValue {\n const bigIntJson: BigIntJSONValue = parseBigIntJson(\n pgResult[0][ZQL_RESULT_KEY],\n );\n assertJSONValue(bigIntJson);\n return bigIntJson;\n}\n\nfunction assertJSONValue(v: BigIntJSONValue): asserts v is JSONValue {\n const path = findPathToBigInt(v);\n if (path) {\n throw new Error(`Value exceeds safe Number range. ${path}`);\n }\n}\n\nfunction findPathToBigInt(v: BigIntJSONValue): string | undefined {\n const typeOfV = typeof v;\n switch (typeOfV) {\n case 'bigint':\n return ` = ${v}`;\n case 'object': {\n if (v === null) {\n return;\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const path = findPathToBigInt(v[i]);\n if (path) {\n return `[${i}]${path}`;\n }\n }\n return undefined;\n }\n\n const o = v as Record<string, BigIntJSONValue>;\n for (const k in o) {\n if (hasOwn(o, k)) {\n const path = findPathToBigInt(o[k]);\n if (path) {\n return `['${k}']${path}`;\n }\n }\n }\n return undefined;\n }\n case 'number':\n return undefined;\n case 'boolean':\n return undefined;\n default:\n return undefined;\n }\n}\n"],"names":["limit","orderBy","parseBigIntJson"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compiler.js","sources":["../../../../z2s/src/compiler.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {last, zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n parse as parseBigIntJson,\n type JSONValue as BigIntJSONValue,\n} from '../../shared/src/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Condition,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Correlation,\n LiteralReference,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n clientToServer,\n type NameMapper,\n} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../zero-types/src/server-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {completeOrdering} from '../../zql/src/query/complete-ordering.ts';\nimport {\n sql,\n sqlConvertColumnArg,\n sqlConvertPluralLiteralArg,\n sqlConvertSingularLiteralArg,\n type PluralLiteralType,\n} from './sql.ts';\n\ntype Table = {\n zql: string;\n alias: string;\n};\n\ntype QualifiedColumn = {\n table: Table;\n zql: string;\n};\n\ntype ServerSpec = {\n schema: ServerSchema;\n // maps zql names to server names\n mapper: NameMapper;\n};\n\nexport type Spec = {\n server: ServerSpec;\n zql: Schema['tables'];\n aliasCount: number;\n};\n\nconst ZQL_RESULT_KEY = 'zql_result';\nconst ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);\n\nconst ZQL_RESULT_TABLE_KEY = 'zql_root';\nconst ZQL_RESULT_TABLE_IDENT = sql.ident(ZQL_RESULT_TABLE_KEY);\n\nexport function compile(\n serverSchema: ServerSchema,\n zqlSchema: Schema,\n ast: AST,\n format?: Format,\n): SQLQuery {\n ast = completeOrdering(\n ast,\n tableName => zqlSchema.tables[tableName].primaryKey,\n );\n const spec: Spec = {\n aliasCount: 0,\n server: {\n schema: serverSchema,\n mapper: clientToServer(zqlSchema.tables),\n },\n zql: zqlSchema.tables,\n };\n return sql`SELECT \n ${toJSON(ZQL_RESULT_TABLE_KEY, format?.singular)}::text AS ${ZQL_RESULT_KEY_IDENT}\n FROM (${select(spec, ast, format)}) ${ZQL_RESULT_TABLE_IDENT}`;\n}\n\nfunction select(\n spec: Spec,\n ast: AST,\n format: Format | undefined,\n correlate?: (childTable: Table) => SQLQuery,\n): SQLQuery {\n const table = makeTable(spec, ast.table);\n const selectionSet = related(spec, ast.related ?? [], format, table);\n const tableSchema = spec.zql[ast.table];\n const usedAliases = new Set<string>(\n ast.related?.map(r => r.subquery.alias ?? ''),\n );\n for (const column of Object.keys(tableSchema.columns)) {\n if (!usedAliases.has(column)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table,\n zql: column,\n }),\n );\n }\n }\n\n let appliedWhere = false;\n function maybeWhere(test: unknown | undefined) {\n if (!test) {\n return sql``;\n }\n\n const ret = appliedWhere ? sql`AND` : sql`WHERE`;\n appliedWhere = true;\n return ret;\n }\n\n return sql`SELECT ${sql.join(selectionSet, ',')}\n FROM ${fromIdent(spec.server, table)}\n ${maybeWhere(ast.where)} ${where(spec, ast.where, table)}\n ${maybeWhere(correlate)} ${correlate ? correlate(table) : sql``}\n ${orderBy(spec, ast.orderBy, table)}\n ${limit(ast.limit, format?.singular)}`;\n}\n\nexport function limit(\n limit: number | undefined,\n singular: boolean | undefined,\n): SQLQuery {\n if (limit === 0) {\n return sql`LIMIT 0`;\n }\n if (singular) {\n return sql`LIMIT 1`;\n }\n if (limit === undefined) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertSingularLiteralArg(limit)}`;\n}\n\nfunction makeTable(spec: Spec, zql: string, alias?: string): Table {\n alias = alias ?? zql + '_' + spec.aliasCount++;\n return {\n zql,\n alias,\n };\n}\n\nexport function orderBy(\n spec: Spec,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!orderBy) {\n return sql``;\n }\n return sql`ORDER BY ${sql.join(\n orderBy.map(([col, dir]) =>\n dir === 'asc'\n ? // Oh postgres. The table must be referred to by client name but the column by server name.\n // E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`\n sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} ASC NULLS FIRST`\n : sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} DESC NULLS LAST`,\n ),\n ', ',\n )}`;\n}\n\nfunction related(\n spec: Spec,\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery[] {\n return relationships.map(relationship =>\n relationshipSubquery(\n spec,\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n}\n\nfunction relationshipSubquery(\n spec: Spec,\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery {\n const innerAlias = `inner_${relationship.subquery.alias}`;\n if (relationship.hidden) {\n const {join, participatingTables} = makeJunctionJoin(spec, relationship);\n const lastTable = must(last(participatingTables)).table;\n\n assert(\n relationship.subquery.related,\n 'hidden relationship must be a junction',\n );\n const nestedAst = relationship.subquery.related[0].subquery;\n const selectionSet = related(\n spec,\n nestedAst.related ?? [],\n format,\n lastTable,\n );\n const tableSchema = spec.zql[nestedAst.table];\n for (const column of Object.keys(tableSchema.columns)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table: lastTable,\n zql: column,\n }),\n );\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (SELECT ${sql.join(\n selectionSet,\n ',',\n )} FROM ${join} WHERE (${makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n )(participatingTables[0].table)}) ${\n nestedAst.where\n ? sql`AND ${where(spec, nestedAst.where, lastTable)}`\n : sql``\n } ${orderBy(spec, nestedAst.orderBy, lastTable)} ${limit(\n last(participatingTables)?.limit,\n format?.singular,\n )} ) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (${select(\n spec,\n relationship.subquery,\n format,\n makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n}\n\nfunction where(\n spec: Spec,\n condition: Condition | undefined,\n table: Table,\n): SQLQuery {\n if (!condition) {\n return sql``;\n }\n\n switch (condition.type) {\n case 'and':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n return exists(spec, condition, table);\n case 'simple':\n return simple(spec, condition, table);\n }\n}\n\nfunction exists(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n }\n}\n\nexport function makeCorrelator(\n spec: Spec,\n parentFields: readonly QualifiedColumn[],\n childZqlFields: readonly string[],\n): (childTable: Table) => SQLQuery {\n return (childTable: Table) => {\n const childFields = childZqlFields.map(zqlField => ({\n table: childTable,\n zql: zqlField,\n }));\n return sql.join(\n zip(parentFields, childFields).map(\n ([parentColumn, childColumn]) =>\n sql`${colIdent(spec.server, parentColumn)} = ${colIdent(\n spec.server,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n };\n}\n\nexport function simple(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n switch (condition.op) {\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE':\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n condition.right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(\n spec,\n condition.right,\n table,\n condition.left,\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return any(spec, condition, table);\n case 'IS':\n case 'IS NOT':\n return distinctFrom(spec, condition, table);\n }\n}\n\nexport function any(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${condition.op === 'NOT IN' ? sql`NOT` : sql``}\n (\n ${valueComparison(spec, condition.left, table, condition.right, false)} = ANY \n (${valueComparison(spec, condition.right, table, condition.left, true)})\n )`;\n}\n\nexport function distinctFrom(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${valueComparison(spec, condition.right, table, condition.left, false)}`;\n}\n\nfunction valueComparison(\n spec: Spec,\n valuePos: ValuePosition,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const valuePosType = valuePos.type;\n switch (valuePosType) {\n case 'column': {\n const qualified: QualifiedColumn = {\n table,\n zql: valuePos.name,\n };\n return colIdent(spec.server, qualified);\n }\n case 'literal':\n return literalValueComparison(\n spec,\n valuePos,\n table,\n otherValuePos,\n plural,\n );\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(valuePosType);\n break;\n }\n}\n\nfunction literalValueComparison(\n spec: Spec,\n valuePos: LiteralReference,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const otherType = otherValuePos.type;\n switch (otherType) {\n case 'column':\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, otherValuePos.name),\n valuePos.value,\n plural,\n true,\n );\n case 'literal': {\n assert(plural === Array.isArray(valuePos.value));\n if (Array.isArray(valuePos.value)) {\n if (valuePos.value.length > 0) {\n // If the array is non-empty base its type on its first\n // element\n return sqlConvertPluralLiteralArg(\n typeof valuePos.value[0] as PluralLiteralType,\n valuePos.value as PluralLiteralType[],\n );\n }\n // If the array is empty, base its type on the other value\n // position's type (as long as the other value position is non-null,\n // cannot have a null[]).\n if (otherValuePos.value !== null) {\n return sqlConvertPluralLiteralArg(\n typeof otherValuePos.value as PluralLiteralType,\n [],\n );\n }\n // If the other value position is null, it can be compared to any\n // type of empty array, chose 'string' arbitrarily.\n return sqlConvertPluralLiteralArg('string', []);\n }\n if (\n typeof valuePos.value === 'string' ||\n typeof valuePos.value === 'number' ||\n typeof valuePos.value === 'boolean'\n ) {\n return sqlConvertSingularLiteralArg(valuePos.value);\n }\n throw new Error(\n `Literal of unexpected type. ${valuePos.value} of type ${typeof valuePos.value}`,\n );\n }\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(otherType);\n }\n}\n\nexport function makeJunctionJoin(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): {\n join: SQLQuery;\n participatingTables: ReturnType<typeof pullTablesForJunction>;\n} {\n const participatingTables = pullTablesForJunction(spec, relationship);\n const joins: SQLQuery[] = [];\n\n for (const {table} of participatingTables) {\n if (joins.length === 0) {\n joins.push(fromIdent(spec.server, table));\n continue;\n }\n joins.push(\n sql` JOIN ${fromIdent(spec.server, table)} ON ${makeCorrelator(\n spec,\n participatingTables[joins.length].correlation.parentField.map(f => ({\n table: participatingTables[joins.length - 1].table,\n zql: f,\n })),\n participatingTables[joins.length].correlation.childField,\n )(participatingTables[joins.length].table)}`,\n );\n }\n\n return {\n join: sql`${sql.join(joins, '')}`,\n participatingTables,\n // lastTable: participatingTables[participatingTables.length - 1].table,\n // lastLimit: participatingTables[participatingTables.length - 1].limit,\n };\n}\n\nexport function pullTablesForJunction(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): [\n {\n table: Table;\n correlation: Correlation;\n limit: number | undefined;\n },\n {table: Table; correlation: Correlation; limit: number | undefined},\n] {\n assert(\n relationship.subquery.related?.length === 1,\n 'Too many related tables for a junction edge',\n );\n const otherRelationship = relationship.subquery.related[0];\n assert(!otherRelationship.hidden);\n return [\n {\n table: makeTable(spec, relationship.subquery.table),\n correlation: relationship.correlation,\n limit: relationship.subquery.limit,\n },\n {\n table: makeTable(spec, otherRelationship.subquery.table),\n correlation: otherRelationship.correlation,\n limit: otherRelationship.subquery.limit,\n },\n ];\n}\n\nfunction toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)}))${singular ? sql`` : sql`, '[]'::json)`}`;\n}\n\nfunction selectIdent(server: ServerSpec, column: QualifiedColumn): SQLQuery {\n const serverColumnSchema =\n server.schema[server.mapper.tableName(column.table.zql)][\n server.mapper.columnName(column.table.zql, column.zql)\n ];\n const serverType = serverColumnSchema.type;\n if (\n !serverColumnSchema.isEnum &&\n (serverType === 'date' ||\n serverType === 'timestamp' ||\n serverType === 'timestamp without time zone' ||\n serverType === 'timestamptz' ||\n serverType === 'timestamp with time zone')\n ) {\n if (serverColumnSchema.isArray) {\n // Map EXTRACT(EPOCH FROM ...) * 1000 over array elements\n return sql`ARRAY(SELECT EXTRACT(EPOCH FROM unnest(${colIdent(server, column)})) * 1000) as ${sql.ident(column.zql)}`;\n }\n return sql`EXTRACT(EPOCH FROM ${colIdent(server, column)}) * 1000 as ${sql.ident(column.zql)}`;\n }\n return sql`${colIdent(server, column)} as ${sql.ident(column.zql)}`;\n}\n\nfunction colIdent(server: ServerSpec, column: QualifiedColumn) {\n return sql.ident(\n column.table.alias,\n server.mapper.columnName(column.table.zql, column.zql),\n );\n}\n\nfunction fromIdent(server: ServerSpec, table: Table) {\n return sql`${sql.ident(server.mapper.tableName(table.zql))} AS ${sql.ident(table.alias)}`;\n}\n\nfunction getServerColumn(spec: ServerSpec, table: Table, zqlColumn: string) {\n return spec.schema[spec.mapper.tableName(table.zql)][\n spec.mapper.columnName(table.zql, zqlColumn)\n ];\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: Array<any>): JSONValue {\n const bigIntJson: BigIntJSONValue = parseBigIntJson(\n pgResult[0][ZQL_RESULT_KEY],\n );\n assertJSONValue(bigIntJson);\n return bigIntJson;\n}\n\nfunction assertJSONValue(v: BigIntJSONValue): asserts v is JSONValue {\n const path = findPathToBigInt(v);\n if (path) {\n throw new Error(`Value exceeds safe Number range. ${path}`);\n }\n}\n\nfunction findPathToBigInt(v: BigIntJSONValue): string | undefined {\n const typeOfV = typeof v;\n switch (typeOfV) {\n case 'bigint':\n return ` = ${v}`;\n case 'object': {\n if (v === null) {\n return;\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const path = findPathToBigInt(v[i]);\n if (path) {\n return `[${i}]${path}`;\n }\n }\n return undefined;\n }\n\n const o = v as Record<string, BigIntJSONValue>;\n for (const k in o) {\n if (hasOwn(o, k)) {\n const path = findPathToBigInt(o[k]);\n if (path) {\n return `['${k}']${path}`;\n }\n }\n }\n return undefined;\n }\n case 'number':\n return undefined;\n case 'boolean':\n return undefined;\n default:\n return undefined;\n }\n}\n"],"names":["limit","orderBy","parseBigIntJson"],"mappings":"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"}
|
package/out/z2s/src/sql.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { SQLQuery } from '@databases/sql';
|
|
2
2
|
import baseSql from '@databases/sql';
|
|
3
3
|
import type { ServerColumnSchema } from '../../zero-types/src/server-schema.ts';
|
|
4
|
-
export declare const Z2S_COLLATION = "ucs_basic";
|
|
5
4
|
export declare function formatPg(sql: SQLQuery): {
|
|
6
5
|
text: string;
|
|
7
6
|
values: unknown[];
|
package/out/z2s/src/sql.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../../z2s/src/sql.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAwB,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AACpE,OAAO,OAAsB,MAAM,gBAAgB,CAAC;AAOpD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAE9E,
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../../z2s/src/sql.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAwB,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AACpE,OAAO,OAAsB,MAAM,gBAAgB,CAAC;AAOpD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAE9E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ;UA2P9B,MAAM;YACJ,OAAO,EAAE;EAzPlB;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,QAAQ;UAsP7C,MAAM;YACJ,OAAO,EAAE;EApPlB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ;UAiPlC,MAAM;YACJ,OAAO,EAAE;EA/OlB;AAID,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACnE,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAwB7D,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GACtC,QAAQ,CAQV;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,EAAE,GACzB,QAAQ,CAQV;AAED,wBAAgB,mBAAmB,CACjC,kBAAkB,EAAE,kBAAkB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,OAAO,GACpB,QAAQ,CASV;AAkKD,eAAO,MAAM,GAAG,aAAkB,CAAC"}
|
package/out/z2s/src/sql.js
CHANGED
|
@@ -2,7 +2,6 @@ import { escapePostgresIdentifier } from "@databases/escape-identifier";
|
|
|
2
2
|
import baseSql, { SQLItemType } from "@databases/sql";
|
|
3
3
|
import { assert, unreachable } from "../../shared/src/asserts.js";
|
|
4
4
|
import { isPgStringType, isPgNumberType } from "../../zero-cache/src/types/pg-data-type.js";
|
|
5
|
-
const Z2S_COLLATION = "ucs_basic";
|
|
6
5
|
function formatPg(sql2) {
|
|
7
6
|
const format = new ReusingFormat(escapePostgresIdentifier);
|
|
8
7
|
return sql2.format((items) => formatFn(items, format));
|
|
@@ -77,22 +76,28 @@ function stringify(arg) {
|
|
|
77
76
|
}
|
|
78
77
|
class SQLConvertFormat {
|
|
79
78
|
#seen = /* @__PURE__ */ new Map();
|
|
79
|
+
#size = 0;
|
|
80
80
|
escapeIdentifier;
|
|
81
81
|
constructor(escapeIdentifier) {
|
|
82
82
|
this.escapeIdentifier = escapeIdentifier;
|
|
83
83
|
}
|
|
84
84
|
formatValue = (value) => {
|
|
85
85
|
assert(isSqlConvert(value), "JsonPackedFormat can only take JsonPackArgs.");
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
86
|
+
const byType = this.#seen.get(value.value);
|
|
87
|
+
if (byType?.has(value.type)) {
|
|
88
88
|
return {
|
|
89
|
-
placeholder: createPlaceholder(
|
|
89
|
+
placeholder: createPlaceholder(byType.get(value.type), value),
|
|
90
90
|
value: PREVIOUSLY_SEEN_VALUE
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
|
-
this.#
|
|
93
|
+
this.#size++;
|
|
94
|
+
if (byType) {
|
|
95
|
+
byType.set(value.type, this.#size);
|
|
96
|
+
} else {
|
|
97
|
+
this.#seen.set(value.value, /* @__PURE__ */ new Map([[value.type, this.#size]]));
|
|
98
|
+
}
|
|
94
99
|
return {
|
|
95
|
-
placeholder: createPlaceholder(this.#
|
|
100
|
+
placeholder: createPlaceholder(this.#size, value),
|
|
96
101
|
value: stringify(value)
|
|
97
102
|
};
|
|
98
103
|
};
|
|
@@ -104,13 +109,12 @@ function createPlaceholder(index, arg) {
|
|
|
104
109
|
return `$${index}`;
|
|
105
110
|
}
|
|
106
111
|
if (arg[sqlConvert] === "literal") {
|
|
107
|
-
const collate = arg.type === "string" ? ` COLLATE "${Z2S_COLLATION}"` : "";
|
|
108
112
|
const { value } = arg;
|
|
109
113
|
if (Array.isArray(value)) {
|
|
110
114
|
const elType = pgTypeForLiteralType(arg.type);
|
|
111
|
-
return formatPlural(index, `value::${elType}
|
|
115
|
+
return formatPlural(index, `value::${elType}`);
|
|
112
116
|
}
|
|
113
|
-
return `$${index}::text::${pgTypeForLiteralType(arg.type)}
|
|
117
|
+
return `$${index}::text::${pgTypeForLiteralType(arg.type)}`;
|
|
114
118
|
}
|
|
115
119
|
const common = formatCommonToSingularAndPlural(index, arg);
|
|
116
120
|
return arg.plural ? formatPlural(index, common) : common;
|
|
@@ -125,15 +129,15 @@ function formatCommonToSingularAndPlural(index, arg) {
|
|
|
125
129
|
case "timestamptz":
|
|
126
130
|
case "timestamp with time zone":
|
|
127
131
|
return `to_timestamp(${valuePlaceholder}::text::bigint / 1000.0)`;
|
|
128
|
-
// uuid
|
|
132
|
+
// uuid: cast to native uuid type for proper comparison and index usage
|
|
129
133
|
case "uuid":
|
|
130
|
-
return
|
|
134
|
+
return `${valuePlaceholder}::text::uuid`;
|
|
131
135
|
}
|
|
132
136
|
if (arg.isEnum) {
|
|
133
|
-
return
|
|
137
|
+
return `${valuePlaceholder}::text::"${arg.type}"`;
|
|
134
138
|
}
|
|
135
139
|
if (isPgStringType(arg.type)) {
|
|
136
|
-
return arg.isComparison ? `${valuePlaceholder}::text
|
|
140
|
+
return arg.isComparison ? `${valuePlaceholder}::text` : `${valuePlaceholder}::text::${arg.type}`;
|
|
137
141
|
}
|
|
138
142
|
if (isPgNumberType(arg.type)) {
|
|
139
143
|
return arg.isComparison ? `${valuePlaceholder}::text::double precision` : `${valuePlaceholder}::text::${arg.type}`;
|
|
@@ -209,7 +213,6 @@ function formatFn(items, { escapeIdentifier, formatValue }) {
|
|
|
209
213
|
};
|
|
210
214
|
}
|
|
211
215
|
export {
|
|
212
|
-
Z2S_COLLATION,
|
|
213
216
|
formatPg,
|
|
214
217
|
formatPgInternalConvert,
|
|
215
218
|
sql,
|
package/out/z2s/src/sql.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.js","sources":["../../../../z2s/src/sql.ts"],"sourcesContent":["import {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {FormatConfig, SQLItem, SQLQuery} from '@databases/sql';\nimport baseSql, {SQLItemType} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n isPgNumberType,\n isPgStringType,\n} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {LiteralValue} from '../../zero-protocol/src/ast.ts';\nimport type {ServerColumnSchema} from '../../zero-types/src/server-schema.ts';\n\nexport const Z2S_COLLATION = 'ucs_basic';\n\nexport function formatPg(sql: SQLQuery) {\n const format = new ReusingFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatPgInternalConvert(sql: SQLQuery) {\n const format = new SQLConvertFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatSqlite(sql: SQLQuery) {\n const format = new ReusingFormat(escapeSQLiteIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nconst sqlConvert = Symbol('fromJson');\n\nexport type LiteralType = 'boolean' | 'number' | 'string' | 'null';\nexport type PluralLiteralType = Exclude<LiteralType, 'null'>;\n\ntype ColumnSqlConvertArg = {\n [sqlConvert]: 'column';\n type: string;\n value: unknown;\n plural: boolean;\n isEnum: boolean;\n isComparison: boolean;\n};\n\ntype SqlConvertArg =\n | ColumnSqlConvertArg\n | {\n [sqlConvert]: 'literal';\n type: LiteralType;\n value: LiteralValue;\n plural: boolean;\n };\n\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertSingularLiteralArg(\n value: string | boolean | number | null,\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type: value === null ? 'null' : (typeof value as LiteralType),\n value,\n plural: false,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertPluralLiteralArg(\n type: PluralLiteralType,\n value: PluralLiteralType[],\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type,\n value,\n plural: true,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertColumnArg(\n serverColumnSchema: ServerColumnSchema,\n value: unknown,\n plural: boolean,\n isComparison: boolean,\n): SQLQuery {\n return sql.value({\n [sqlConvert]: 'column',\n type: serverColumnSchema.type,\n isEnum: serverColumnSchema.isEnum,\n value,\n plural: plural || serverColumnSchema.isArray,\n isComparison,\n });\n}\n\nclass ReusingFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n if (this.#seen.has(value)) {\n return {\n placeholder: `$${this.#seen.get(value)}`,\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(value, this.#seen.size + 1);\n return {placeholder: `$${this.#seen.size}`, value};\n };\n}\n\nfunction stringify(arg: SqlConvertArg): string | null {\n if (arg.value === null) {\n return null;\n }\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n if (arg[sqlConvert] === 'literal' && arg.type === 'string') {\n return arg.value as unknown as string;\n }\n if (\n arg[sqlConvert] === 'column' &&\n (arg.isEnum || isPgStringType(arg.type))\n ) {\n return arg.value as string;\n }\n return JSON.stringify(arg.value);\n}\n\nclass SQLConvertFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const key = value.value;\n if (this.#seen.has(key)) {\n return {\n placeholder: createPlaceholder(this.#seen.get(key)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(key, this.#seen.size + 1);\n return {\n placeholder: createPlaceholder(this.#seen.size, value),\n value: stringify(value),\n };\n };\n}\n\nfunction createPlaceholder(index: number, arg: SqlConvertArg) {\n if (arg.type === 'null') {\n assert(arg.value === null, \"Args of type 'null' must have value null\");\n assert(!arg.plural, \"Args of type 'null' must not be plural\");\n return `$${index}`;\n }\n\n if (arg[sqlConvert] === 'literal') {\n const collate = arg.type === 'string' ? ` COLLATE \"${Z2S_COLLATION}\"` : '';\n const {value} = arg;\n if (Array.isArray(value)) {\n const elType = pgTypeForLiteralType(arg.type);\n return formatPlural(index, `value::${elType}${collate}`);\n }\n return `$${index}::text::${pgTypeForLiteralType(arg.type)}${collate}`;\n }\n\n const common = formatCommonToSingularAndPlural(index, arg);\n return arg.plural ? formatPlural(index, common) : common;\n}\n\nfunction formatCommonToSingularAndPlural(\n index: number,\n arg: ColumnSqlConvertArg,\n) {\n // Ok, so what is with all the `::text` casts\n // before the final cast?\n // This is to force the statement to describe its arguments\n // as being text. Without the text cast the args are described as\n // being bool/json/numeric/whatever and the bindings try to coerce\n // the inputs to those types.\n const valuePlaceholder = arg.plural ? 'value' : `$${index}`;\n switch (arg.type) {\n case 'date':\n case 'timestamp':\n case 'timestamp without time zone':\n return `to_timestamp(${valuePlaceholder}::text::bigint / 1000.0) AT TIME ZONE 'UTC'`;\n case 'timestamptz':\n case 'timestamp with time zone':\n return `to_timestamp(${valuePlaceholder}::text::bigint / 1000.0)`;\n // uuid doesn't support collation, so we compare as text\n case 'uuid':\n return arg.isComparison\n ? `${valuePlaceholder}::text COLLATE \"${Z2S_COLLATION}\"`\n : `${valuePlaceholder}::text::uuid`;\n }\n if (arg.isEnum) {\n return arg.isComparison\n ? `${valuePlaceholder}::text COLLATE \"${Z2S_COLLATION}\"`\n : `${valuePlaceholder}::text::\"${arg.type}\"`;\n }\n if (isPgStringType(arg.type)) {\n // For comparison cast to the general `text` type, not the\n // specific column type (i.e. `arg.type`), because we don't want to\n // force the value being compared to the size/max-size of the column\n // type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text COLLATE \"${Z2S_COLLATION}\"`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgNumberType(arg.type)) {\n // For comparison cast to `double precision` which uses IEEE 754 (the same\n // representation as JavaScript numbers which will accurately\n // represent any number value from zql) not the specific column type\n // (i.e. `arg.type`), because we don't want to force the value being\n // compared to the range and precision of the column type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text::double precision`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n return `${valuePlaceholder}::text::${arg.type}`;\n}\n\nfunction formatPlural(index: number, select: string) {\n return `ARRAY(\n SELECT ${select} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n}\n\nfunction pgTypeForLiteralType(type: Exclude<LiteralType, 'null'>) {\n switch (type) {\n case 'boolean':\n return 'boolean';\n case 'number':\n // `double precision` uses IEEE 754, the same representation as JavaScript\n // numbers, and so this will accurately represent any number value\n // from zql\n return 'double precision';\n case 'string':\n return 'text';\n default:\n unreachable(type);\n }\n}\n\nexport const sql = baseSql.default;\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\n\nfunction formatFn(\n items: readonly SQLItem[],\n {escapeIdentifier, formatValue}: FormatConfig,\n): {\n text: string;\n values: unknown[];\n} {\n // Create an empty query object.\n let text = '';\n const values = [];\n\n const localIdentifiers = new Map<unknown, string>();\n\n for (const item of items) {\n switch (item.type) {\n // If this is just raw text, we add it directly to the query text.\n case SQLItemType.RAW: {\n text += item.text;\n break;\n }\n\n // If we got a value SQL item, add a placeholder and add the value to our\n // placeholder values array.\n case SQLItemType.VALUE: {\n const {placeholder, value} = formatValue(item.value, values.length);\n text += placeholder;\n if (value !== PREVIOUSLY_SEEN_VALUE) {\n values.push(value);\n }\n\n break;\n }\n\n // If we got an identifier type, escape the strings and get a local\n // identifier for non-string identifiers.\n case SQLItemType.IDENTIFIER: {\n // This is a specific addition for Zero as Zero\n // does not support dots in identifiers.\n // If a dot is found, we assume it is a namespace\n // and split the identifier into its parts.\n const names =\n item.names.length === 1 &&\n typeof item.names[0] === 'string' &&\n item.names[0].includes('.')\n ? item.names[0].split('.')\n : item.names;\n\n text += names\n .map((name): string => {\n if (typeof name === 'string') return escapeIdentifier(name);\n\n if (!localIdentifiers.has(name))\n localIdentifiers.set(name, `__local_${localIdentifiers.size}__`);\n\n return escapeIdentifier(localIdentifiers.get(name)!);\n })\n .join('.');\n break;\n }\n }\n }\n\n if (text.trim()) {\n const lines = text.split('\\n');\n const min = Math.min(\n ...lines.filter(l => l.trim() !== '').map(l => /^\\s*/.exec(l)![0].length),\n );\n if (min) {\n text = lines.map(line => line.substr(min)).join('\\n');\n }\n }\n return {\n text: text.trim(),\n values,\n };\n}\n"],"names":["sql"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sql.js","sources":["../../../../z2s/src/sql.ts"],"sourcesContent":["import {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {FormatConfig, SQLItem, SQLQuery} from '@databases/sql';\nimport baseSql, {SQLItemType} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n isPgNumberType,\n isPgStringType,\n} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {LiteralValue} from '../../zero-protocol/src/ast.ts';\nimport type {ServerColumnSchema} from '../../zero-types/src/server-schema.ts';\n\nexport function formatPg(sql: SQLQuery) {\n const format = new ReusingFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatPgInternalConvert(sql: SQLQuery) {\n const format = new SQLConvertFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatSqlite(sql: SQLQuery) {\n const format = new ReusingFormat(escapeSQLiteIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nconst sqlConvert = Symbol('fromJson');\n\nexport type LiteralType = 'boolean' | 'number' | 'string' | 'null';\nexport type PluralLiteralType = Exclude<LiteralType, 'null'>;\n\ntype ColumnSqlConvertArg = {\n [sqlConvert]: 'column';\n type: string;\n value: unknown;\n plural: boolean;\n isEnum: boolean;\n isComparison: boolean;\n};\n\ntype SqlConvertArg =\n | ColumnSqlConvertArg\n | {\n [sqlConvert]: 'literal';\n type: LiteralType;\n value: LiteralValue;\n plural: boolean;\n };\n\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertSingularLiteralArg(\n value: string | boolean | number | null,\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type: value === null ? 'null' : (typeof value as LiteralType),\n value,\n plural: false,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertPluralLiteralArg(\n type: PluralLiteralType,\n value: PluralLiteralType[],\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type,\n value,\n plural: true,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertColumnArg(\n serverColumnSchema: ServerColumnSchema,\n value: unknown,\n plural: boolean,\n isComparison: boolean,\n): SQLQuery {\n return sql.value({\n [sqlConvert]: 'column',\n type: serverColumnSchema.type,\n isEnum: serverColumnSchema.isEnum,\n value,\n plural: plural || serverColumnSchema.isArray,\n isComparison,\n });\n}\n\nclass ReusingFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n if (this.#seen.has(value)) {\n return {\n placeholder: `$${this.#seen.get(value)}`,\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(value, this.#seen.size + 1);\n return {placeholder: `$${this.#seen.size}`, value};\n };\n}\n\nfunction stringify(arg: SqlConvertArg): string | null {\n if (arg.value === null) {\n return null;\n }\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n if (arg[sqlConvert] === 'literal' && arg.type === 'string') {\n return arg.value as unknown as string;\n }\n if (\n arg[sqlConvert] === 'column' &&\n (arg.isEnum || isPgStringType(arg.type))\n ) {\n return arg.value as string;\n }\n return JSON.stringify(arg.value);\n}\n\nclass SQLConvertFormat implements FormatConfig {\n readonly #seen: Map<unknown, Map<string, number>> = new Map();\n #size = 0;\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const byType = this.#seen.get(value.value);\n if (byType?.has(value.type)) {\n return {\n placeholder: createPlaceholder(byType.get(value.type)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#size++;\n if (byType) {\n byType.set(value.type, this.#size);\n } else {\n this.#seen.set(value.value, new Map([[value.type, this.#size]]));\n }\n return {\n placeholder: createPlaceholder(this.#size, value),\n value: stringify(value),\n };\n };\n}\n\nfunction createPlaceholder(index: number, arg: SqlConvertArg) {\n if (arg.type === 'null') {\n assert(arg.value === null, \"Args of type 'null' must have value null\");\n assert(!arg.plural, \"Args of type 'null' must not be plural\");\n return `$${index}`;\n }\n\n if (arg[sqlConvert] === 'literal') {\n const {value} = arg;\n if (Array.isArray(value)) {\n const elType = pgTypeForLiteralType(arg.type);\n return formatPlural(index, `value::${elType}`);\n }\n return `$${index}::text::${pgTypeForLiteralType(arg.type)}`;\n }\n\n const common = formatCommonToSingularAndPlural(index, arg);\n return arg.plural ? formatPlural(index, common) : common;\n}\n\nfunction formatCommonToSingularAndPlural(\n index: number,\n arg: ColumnSqlConvertArg,\n) {\n // Ok, so what is with all the `::text` casts\n // before the final cast?\n // This is to force the statement to describe its arguments\n // as being text. Without the text cast the args are described as\n // being bool/json/numeric/whatever and the bindings try to coerce\n // the inputs to those types.\n const valuePlaceholder = arg.plural ? 'value' : `$${index}`;\n switch (arg.type) {\n case 'date':\n case 'timestamp':\n case 'timestamp without time zone':\n return `to_timestamp(${valuePlaceholder}::text::bigint / 1000.0) AT TIME ZONE 'UTC'`;\n case 'timestamptz':\n case 'timestamp with time zone':\n return `to_timestamp(${valuePlaceholder}::text::bigint / 1000.0)`;\n // uuid: cast to native uuid type for proper comparison and index usage\n case 'uuid':\n return `${valuePlaceholder}::text::uuid`;\n }\n if (arg.isEnum) {\n return `${valuePlaceholder}::text::\"${arg.type}\"`;\n }\n if (isPgStringType(arg.type)) {\n // For comparison cast to the general `text` type, not the\n // specific column type (i.e. `arg.type`), because we don't want to\n // force the value being compared to the size/max-size of the column\n // type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgNumberType(arg.type)) {\n // For comparison cast to `double precision` which uses IEEE 754 (the same\n // representation as JavaScript numbers which will accurately\n // represent any number value from zql) not the specific column type\n // (i.e. `arg.type`), because we don't want to force the value being\n // compared to the range and precision of the column type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text::double precision`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n return `${valuePlaceholder}::text::${arg.type}`;\n}\n\nfunction formatPlural(index: number, select: string) {\n return `ARRAY(\n SELECT ${select} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n}\n\nfunction pgTypeForLiteralType(type: Exclude<LiteralType, 'null'>) {\n switch (type) {\n case 'boolean':\n return 'boolean';\n case 'number':\n // `double precision` uses IEEE 754, the same representation as JavaScript\n // numbers, and so this will accurately represent any number value\n // from zql\n return 'double precision';\n case 'string':\n return 'text';\n default:\n unreachable(type);\n }\n}\n\nexport const sql = baseSql.default;\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\n\nfunction formatFn(\n items: readonly SQLItem[],\n {escapeIdentifier, formatValue}: FormatConfig,\n): {\n text: string;\n values: unknown[];\n} {\n // Create an empty query object.\n let text = '';\n const values = [];\n\n const localIdentifiers = new Map<unknown, string>();\n\n for (const item of items) {\n switch (item.type) {\n // If this is just raw text, we add it directly to the query text.\n case SQLItemType.RAW: {\n text += item.text;\n break;\n }\n\n // If we got a value SQL item, add a placeholder and add the value to our\n // placeholder values array.\n case SQLItemType.VALUE: {\n const {placeholder, value} = formatValue(item.value, values.length);\n text += placeholder;\n if (value !== PREVIOUSLY_SEEN_VALUE) {\n values.push(value);\n }\n\n break;\n }\n\n // If we got an identifier type, escape the strings and get a local\n // identifier for non-string identifiers.\n case SQLItemType.IDENTIFIER: {\n // This is a specific addition for Zero as Zero\n // does not support dots in identifiers.\n // If a dot is found, we assume it is a namespace\n // and split the identifier into its parts.\n const names =\n item.names.length === 1 &&\n typeof item.names[0] === 'string' &&\n item.names[0].includes('.')\n ? item.names[0].split('.')\n : item.names;\n\n text += names\n .map((name): string => {\n if (typeof name === 'string') return escapeIdentifier(name);\n\n if (!localIdentifiers.has(name))\n localIdentifiers.set(name, `__local_${localIdentifiers.size}__`);\n\n return escapeIdentifier(localIdentifiers.get(name)!);\n })\n .join('.');\n break;\n }\n }\n }\n\n if (text.trim()) {\n const lines = text.split('\\n');\n const min = Math.min(\n ...lines.filter(l => l.trim() !== '').map(l => /^\\s*/.exec(l)![0].length),\n );\n if (min) {\n text = lines.map(line => line.substr(min)).join('\\n');\n }\n }\n return {\n text: text.trim(),\n values,\n };\n}\n"],"names":["sql"],"mappings":"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"}
|
package/out/zero/package.json.js
CHANGED
|
@@ -253,17 +253,11 @@ function primaryKeyClause(schema, serverTableSchema, row) {
|
|
|
253
253
|
const primaryKey = origAndServerNamesFor(schema.primaryKey, schema);
|
|
254
254
|
return sql`${sql.join(
|
|
255
255
|
primaryKey.map(
|
|
256
|
-
([origName, serverName2]) => sql`${sql.ident(serverName2)}
|
|
256
|
+
([origName, serverName2]) => sql`${sql.ident(serverName2)} = ${sqlValue(row[origName], serverTableSchema[serverName2])}`
|
|
257
257
|
),
|
|
258
258
|
" AND "
|
|
259
259
|
)}`;
|
|
260
260
|
}
|
|
261
|
-
function maybeCastColumn(col) {
|
|
262
|
-
if (col.type === "uuid" || col.isEnum) {
|
|
263
|
-
return sql`::text`;
|
|
264
|
-
}
|
|
265
|
-
return sql``;
|
|
266
|
-
}
|
|
267
261
|
function origAndServerNamesFor(originalNames, schema) {
|
|
268
262
|
return originalNames.map(
|
|
269
263
|
(name) => [name, serverNameFor(name, schema)]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.js","sources":["../../../../zero-server/src/custom.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\nimport {mapValues} from '../../shared/src/objects.ts';\nimport {recordProxy} from '../../shared/src/record-proxy.ts';\nimport {\n formatPgInternalConvert,\n sql,\n sqlConvertColumnArg,\n} from '../../z2s/src/sql.ts';\nimport type {TableSchema} from '../../zero-schema/src/table-schema.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {\n ServerColumnSchema,\n ServerSchema,\n ServerTableSchema,\n} from '../../zero-types/src/server-schema.ts';\nimport {\n type CRUDExecutor,\n type CRUDKind,\n makeCRUDMutate,\n makeTransactionMutate,\n type SchemaCRUD,\n type TableCRUD,\n type TransactionMutate,\n} from '../../zql/src/mutate/crud.ts';\nimport type {\n DBTransaction,\n MutateCRUD,\n ServerTransaction,\n} from '../../zql/src/mutate/custom.ts';\nimport {createRunnableBuilder} from '../../zql/src/query/create-builder.ts';\nimport {QueryDelegateBase} from '../../zql/src/query/query-delegate-base.ts';\nimport {asQueryInternals} from '../../zql/src/query/query-internals.ts';\nimport type {\n HumanReadable,\n Query,\n RunOptions,\n} from '../../zql/src/query/query.ts';\nimport type {ConditionalSchemaQuery} from '../../zql/src/query/schema-query.ts';\nimport {getServerSchema} from './schema.ts';\n\nexport type CustomMutatorDefs<TDBTransaction> = {\n [namespaceOrKey: string]:\n | CustomMutatorImpl<TDBTransaction>\n | CustomMutatorDefs<TDBTransaction>;\n};\n\nexport type CustomMutatorImpl<\n TDBTransaction,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n TArgs = any,\n Context = unknown,\n> = (tx: TDBTransaction, args: TArgs, ctx: Context) => Promise<void>;\n\n/**\n * QueryDelegate implementation for server-side transactions.\n * Extends QueryDelegateBase to satisfy the QueryDelegate interface,\n * but overrides run() to execute against Postgres and throws on\n * preload()/materialize() which don't make sense server-side.\n */\nclass ServerTransactionQueryDelegate extends QueryDelegateBase {\n readonly #dbTransaction: DBTransaction<unknown>;\n readonly #schema: Schema;\n readonly #serverSchema: ServerSchema;\n\n readonly defaultQueryComplete = true;\n\n constructor(\n dbTransaction: DBTransaction<unknown>,\n schema: Schema,\n serverSchema: ServerSchema,\n ) {\n super();\n this.#dbTransaction = dbTransaction;\n this.#schema = schema;\n this.#serverSchema = serverSchema;\n }\n\n getSource(): never {\n throw new Error('not implemented');\n }\n\n override run<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n _options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n const queryInternals = asQueryInternals(query);\n return this.#dbTransaction.runQuery<TReturn>(\n queryInternals.ast,\n queryInternals.format,\n this.#schema,\n this.#serverSchema,\n );\n }\n\n override preload(): never {\n throw new Error('preload() is not supported in server transactions');\n }\n\n override materialize(): never {\n throw new Error('materialize() is not supported in server transactions');\n }\n}\n\nexport class TransactionImpl<TSchema extends Schema, TWrappedTransaction>\n implements ServerTransaction<TSchema, TWrappedTransaction>\n{\n readonly location = 'server';\n readonly reason = 'authoritative';\n readonly dbTransaction: DBTransaction<TWrappedTransaction>;\n readonly clientID: string;\n readonly mutationID: number;\n readonly mutate: TransactionMutate<TSchema>;\n /**\n * @deprecated Use {@linkcode createBuilder} with `tx.run(zql.table.where(...))` instead.\n */\n readonly query: ConditionalSchemaQuery<TSchema>;\n\n readonly #schema: TSchema;\n readonly #serverSchema: ServerSchema;\n\n constructor(\n dbTransaction: DBTransaction<TWrappedTransaction>,\n clientID: string,\n mutationID: number,\n mutate: TransactionMutate<TSchema>,\n schema: TSchema,\n serverSchema: ServerSchema,\n ) {\n this.dbTransaction = dbTransaction;\n this.clientID = clientID;\n this.mutationID = mutationID;\n this.mutate = mutate;\n this.#schema = schema;\n this.#serverSchema = serverSchema;\n\n const delegate = new ServerTransactionQueryDelegate(\n dbTransaction,\n schema,\n serverSchema,\n );\n this.query = createRunnableBuilder(delegate, schema);\n }\n\n run<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n _options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n const queryInternals = asQueryInternals(query);\n\n // Execute the query using the database-specific executor\n return this.dbTransaction.runQuery<TReturn>(\n queryInternals.ast,\n queryInternals.format,\n this.#schema,\n this.#serverSchema,\n );\n }\n}\n\nconst dbTxSymbol = Symbol();\n\nconst serverSchemaSymbol = Symbol();\n\ntype WithHiddenTxAndSchema = {\n [dbTxSymbol]: DBTransaction<unknown>;\n [serverSchemaSymbol]: ServerSchema;\n};\n\n/**\n * Factory for creating MutateCRUD instances efficiently.\n *\n * Pre-creates the SQL-generating TableCRUD methods once from the schema,\n * caches the serverSchema after first fetch, and only binds the transaction\n * at transaction time.\n *\n * Use this when you need to create many transactions and want to avoid\n * the overhead of re-creating CRUD methods for each one.\n */\nexport class CRUDMutatorFactory<S extends Schema> {\n readonly #schema: S;\n readonly #tableCRUDs: Record<string, TableCRUD<TableSchema>>;\n #serverSchema: ServerSchema | undefined;\n\n constructor(schema: S) {\n this.#schema = schema;\n // Pre-create TableCRUD methods for each table once\n this.#tableCRUDs = {};\n for (const tableSchema of Object.values(schema.tables)) {\n this.#tableCRUDs[tableSchema.name] = makeServerTableCRUD(tableSchema);\n }\n }\n\n /**\n * Gets the cached serverSchema, or fetches and caches it on first call.\n */\n async #getOrFetchServerSchema(\n dbTransaction: DBTransaction<unknown>,\n ): Promise<ServerSchema> {\n if (!this.#serverSchema) {\n this.#serverSchema = await getServerSchema(dbTransaction, this.#schema);\n }\n return this.#serverSchema;\n }\n\n /**\n * Creates a CRUDExecutor bound to the given transaction and serverSchema.\n * Uses the pre-created TableCRUD methods from construction time.\n */\n createExecutor(\n dbTransaction: DBTransaction<unknown>,\n serverSchema: ServerSchema,\n ): CRUDExecutor {\n const txHolder: WithHiddenTxAndSchema = {\n [dbTxSymbol]: dbTransaction,\n [serverSchemaSymbol]: serverSchema,\n };\n const boundCRUDs = recordProxy(this.#tableCRUDs, tableCRUD =>\n mapValues(tableCRUD, method => method.bind(txHolder)),\n ) as unknown as SchemaCRUD<S>;\n\n return (table: string, kind: CRUDKind, args: unknown) => {\n const tableCRUD = boundCRUDs[table as keyof S['tables']];\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return (tableCRUD as any)[kind](args);\n };\n }\n\n /**\n * Creates a full ServerTransaction.\n * Fetches/caches serverSchema automatically.\n */\n async createTransaction<TWrappedTransaction>(\n dbTransaction: DBTransaction<TWrappedTransaction>,\n clientID: string,\n mutationID: number,\n ): Promise<TransactionImpl<S, TWrappedTransaction>> {\n const serverSchema = await this.#getOrFetchServerSchema(dbTransaction);\n const executor = this.createExecutor(dbTransaction, serverSchema);\n const mutate = makeTransactionMutate(this.#schema, executor);\n return new TransactionImpl(\n dbTransaction,\n clientID,\n mutationID,\n mutate,\n this.#schema,\n serverSchema,\n );\n }\n}\n\nexport async function makeServerTransaction<\n TSchema extends Schema,\n TWrappedTransaction,\n>(\n dbTransaction: DBTransaction<TWrappedTransaction>,\n clientID: string,\n mutationID: number,\n schema: TSchema,\n) {\n const serverSchema = await getServerSchema(dbTransaction, schema);\n // Use the internal executor and shared function directly,\n // bypassing the validation in makeMutateCRUD/makeSchemaCRUD\n const executor = makeServerCRUDExecutor(schema, dbTransaction, serverSchema);\n const mutate = makeTransactionMutate(schema, executor);\n return new TransactionImpl(\n dbTransaction,\n clientID,\n mutationID,\n mutate,\n schema,\n serverSchema,\n );\n}\n\n/**\n * @deprecated Use transactions instead.\n *\n * Returns a curried function for backwards compatibility.\n */\nexport function makeSchemaCRUD<S extends Schema>(\n schema: S,\n): (\n dbTransaction: DBTransaction<unknown>,\n serverSchema: ServerSchema,\n) => MutateCRUD<S, true> {\n return (dbTransaction: DBTransaction<unknown>, serverSchema: ServerSchema) =>\n makeCRUDMutate(\n schema,\n true,\n makeServerCRUDExecutor(schema, dbTransaction, serverSchema),\n );\n}\n\nfunction removeUndefined<T extends Record<string, unknown>>(value: T): T {\n const valueWithoutUndefined: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val !== undefined) {\n valueWithoutUndefined[key] = val;\n }\n }\n return valueWithoutUndefined as T;\n}\n\n/**\n * Creates a CRUDExecutor for server-side SQL execution.\n *\n * For users with very large schemas it is expensive to re-create\n * all the CRUD mutators for each transaction. Instead, we create\n * the SQL-generating methods once up-front and then bind them to\n * the transaction as requested.\n */\nfunction makeServerCRUDExecutor<S extends Schema>(\n schema: S,\n dbTransaction: DBTransaction<unknown>,\n serverSchema: ServerSchema,\n): CRUDExecutor {\n // Pre-create TableCRUD methods for each table (optimization for large schemas)\n const tableCRUDs: Record<string, TableCRUD<TableSchema>> = {};\n for (const tableSchema of Object.values(schema.tables)) {\n tableCRUDs[tableSchema.name] = makeServerTableCRUD(tableSchema);\n }\n\n // Bind transaction context to the methods\n const txHolder: WithHiddenTxAndSchema = {\n [dbTxSymbol]: dbTransaction,\n [serverSchemaSymbol]: serverSchema,\n };\n const boundCRUDs = recordProxy(tableCRUDs, tableCRUD =>\n mapValues(tableCRUD, method => method.bind(txHolder)),\n ) as unknown as SchemaCRUD<S>;\n\n // Return executor that dispatches to bound methods\n return (table: string, kind: CRUDKind, args: unknown) => {\n const tableCRUD = boundCRUDs[table as keyof S['tables']];\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return (tableCRUD as any)[kind](args);\n };\n}\n\n/**\n * Creates SQL-generating TableCRUD methods for a table.\n * Methods use `this` context to access transaction and server schema.\n */\nfunction makeServerTableCRUD(schema: TableSchema): TableCRUD<TableSchema> {\n return {\n async insert(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n\n const targetedColumns = origAndServerNamesFor(Object.keys(value), schema);\n const stmt = formatPgInternalConvert(\n sql`INSERT INTO ${sql.ident(serverName(schema))} (${sql.join(\n targetedColumns.map(([, serverName]) => sql.ident(serverName)),\n ',',\n )}) VALUES (${sql.join(\n Object.entries(value).map(([col, v]) =>\n sqlInsertValue(v, serverTableSchema[serverNameFor(col, schema)]),\n ),\n ', ',\n )})`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n async upsert(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n const targetedColumns = origAndServerNamesFor(Object.keys(value), schema);\n const primaryKeyColumns = origAndServerNamesFor(\n schema.primaryKey,\n schema,\n );\n const stmt = formatPgInternalConvert(\n sql`INSERT INTO ${sql.ident(serverName(schema))} (${sql.join(\n targetedColumns.map(([, serverName]) => sql.ident(serverName)),\n ',',\n )}) VALUES (${sql.join(\n Object.entries(value).map(([col, val]) =>\n sqlInsertValue(val, serverTableSchema[serverNameFor(col, schema)]),\n ),\n ', ',\n )}) ON CONFLICT (${sql.join(\n primaryKeyColumns.map(([, serverName]) => sql.ident(serverName)),\n ', ',\n )}) DO UPDATE SET ${sql.join(\n Object.entries(value).map(\n ([col, val]) =>\n sql`${sql.ident(\n schema.columns[col].serverName ?? col,\n )} = ${sqlInsertValue(val, serverTableSchema[serverNameFor(col, schema)])}`,\n ),\n ', ',\n )}`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n async update(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n const targetedColumns = origAndServerNamesFor(Object.keys(value), schema);\n const stmt = formatPgInternalConvert(\n sql`UPDATE ${sql.ident(serverName(schema))} SET ${sql.join(\n targetedColumns.map(\n ([origName, serverName]) =>\n sql`${sql.ident(serverName)} = ${sqlInsertValue(value[origName], serverTableSchema[serverName])}`,\n ),\n ', ',\n )} WHERE ${primaryKeyClause(schema, serverTableSchema, value)}`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n async delete(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n const stmt = formatPgInternalConvert(\n sql`DELETE FROM ${sql.ident(\n serverName(schema),\n )} WHERE ${primaryKeyClause(schema, serverTableSchema, value)}`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n };\n}\n\nfunction serverName(x: {name: string; serverName?: string | undefined}) {\n return x.serverName ?? x.name;\n}\n\nfunction primaryKeyClause(\n schema: TableSchema,\n serverTableSchema: ServerTableSchema,\n row: Record<string, unknown>,\n) {\n const primaryKey = origAndServerNamesFor(schema.primaryKey, schema);\n return sql`${sql.join(\n primaryKey.map(\n ([origName, serverName]) =>\n sql`${sql.ident(serverName)}${maybeCastColumn(serverTableSchema[serverName])} = ${sqlValue(row[origName], serverTableSchema[serverName])}`,\n ),\n ' AND ',\n )}`;\n}\n\nfunction maybeCastColumn(col: ServerColumnSchema) {\n if (col.type === 'uuid' || col.isEnum) {\n return sql`::text`;\n }\n return sql``;\n}\n\nfunction origAndServerNamesFor(\n originalNames: readonly string[],\n schema: TableSchema,\n): [origName: string, serverName: string][] {\n return originalNames.map(\n name => [name, serverNameFor(name, schema)] as const,\n );\n}\n\nfunction serverNameFor(originalName: string, schema: TableSchema): string {\n const col = schema.columns[originalName];\n assert(\n col,\n `Column ${originalName} was not found in the Zero schema for the table ${schema.name}`,\n );\n return col.serverName ?? originalName;\n}\n\nfunction sqlValue(value: unknown, serverColumnSchema: ServerColumnSchema) {\n return sqlConvertColumnArg(serverColumnSchema, value, false, true);\n}\n\nfunction sqlInsertValue(\n value: unknown,\n serverColumnSchema: ServerColumnSchema,\n) {\n return sqlConvertColumnArg(serverColumnSchema, value, false, false);\n}\n"],"names":["serverName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"custom.js","sources":["../../../../zero-server/src/custom.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\nimport {mapValues} from '../../shared/src/objects.ts';\nimport {recordProxy} from '../../shared/src/record-proxy.ts';\nimport {\n formatPgInternalConvert,\n sql,\n sqlConvertColumnArg,\n} from '../../z2s/src/sql.ts';\nimport type {TableSchema} from '../../zero-schema/src/table-schema.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {\n ServerColumnSchema,\n ServerSchema,\n ServerTableSchema,\n} from '../../zero-types/src/server-schema.ts';\nimport {\n type CRUDExecutor,\n type CRUDKind,\n makeCRUDMutate,\n makeTransactionMutate,\n type SchemaCRUD,\n type TableCRUD,\n type TransactionMutate,\n} from '../../zql/src/mutate/crud.ts';\nimport type {\n DBTransaction,\n MutateCRUD,\n ServerTransaction,\n} from '../../zql/src/mutate/custom.ts';\nimport {createRunnableBuilder} from '../../zql/src/query/create-builder.ts';\nimport {QueryDelegateBase} from '../../zql/src/query/query-delegate-base.ts';\nimport {asQueryInternals} from '../../zql/src/query/query-internals.ts';\nimport type {\n HumanReadable,\n Query,\n RunOptions,\n} from '../../zql/src/query/query.ts';\nimport type {ConditionalSchemaQuery} from '../../zql/src/query/schema-query.ts';\nimport {getServerSchema} from './schema.ts';\n\nexport type CustomMutatorDefs<TDBTransaction> = {\n [namespaceOrKey: string]:\n | CustomMutatorImpl<TDBTransaction>\n | CustomMutatorDefs<TDBTransaction>;\n};\n\nexport type CustomMutatorImpl<\n TDBTransaction,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n TArgs = any,\n Context = unknown,\n> = (tx: TDBTransaction, args: TArgs, ctx: Context) => Promise<void>;\n\n/**\n * QueryDelegate implementation for server-side transactions.\n * Extends QueryDelegateBase to satisfy the QueryDelegate interface,\n * but overrides run() to execute against Postgres and throws on\n * preload()/materialize() which don't make sense server-side.\n */\nclass ServerTransactionQueryDelegate extends QueryDelegateBase {\n readonly #dbTransaction: DBTransaction<unknown>;\n readonly #schema: Schema;\n readonly #serverSchema: ServerSchema;\n\n readonly defaultQueryComplete = true;\n\n constructor(\n dbTransaction: DBTransaction<unknown>,\n schema: Schema,\n serverSchema: ServerSchema,\n ) {\n super();\n this.#dbTransaction = dbTransaction;\n this.#schema = schema;\n this.#serverSchema = serverSchema;\n }\n\n getSource(): never {\n throw new Error('not implemented');\n }\n\n override run<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n _options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n const queryInternals = asQueryInternals(query);\n return this.#dbTransaction.runQuery<TReturn>(\n queryInternals.ast,\n queryInternals.format,\n this.#schema,\n this.#serverSchema,\n );\n }\n\n override preload(): never {\n throw new Error('preload() is not supported in server transactions');\n }\n\n override materialize(): never {\n throw new Error('materialize() is not supported in server transactions');\n }\n}\n\nexport class TransactionImpl<TSchema extends Schema, TWrappedTransaction>\n implements ServerTransaction<TSchema, TWrappedTransaction>\n{\n readonly location = 'server';\n readonly reason = 'authoritative';\n readonly dbTransaction: DBTransaction<TWrappedTransaction>;\n readonly clientID: string;\n readonly mutationID: number;\n readonly mutate: TransactionMutate<TSchema>;\n /**\n * @deprecated Use {@linkcode createBuilder} with `tx.run(zql.table.where(...))` instead.\n */\n readonly query: ConditionalSchemaQuery<TSchema>;\n\n readonly #schema: TSchema;\n readonly #serverSchema: ServerSchema;\n\n constructor(\n dbTransaction: DBTransaction<TWrappedTransaction>,\n clientID: string,\n mutationID: number,\n mutate: TransactionMutate<TSchema>,\n schema: TSchema,\n serverSchema: ServerSchema,\n ) {\n this.dbTransaction = dbTransaction;\n this.clientID = clientID;\n this.mutationID = mutationID;\n this.mutate = mutate;\n this.#schema = schema;\n this.#serverSchema = serverSchema;\n\n const delegate = new ServerTransactionQueryDelegate(\n dbTransaction,\n schema,\n serverSchema,\n );\n this.query = createRunnableBuilder(delegate, schema);\n }\n\n run<TTable extends keyof TSchema['tables'] & string, TReturn>(\n query: Query<TTable, TSchema, TReturn>,\n _options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n const queryInternals = asQueryInternals(query);\n\n // Execute the query using the database-specific executor\n return this.dbTransaction.runQuery<TReturn>(\n queryInternals.ast,\n queryInternals.format,\n this.#schema,\n this.#serverSchema,\n );\n }\n}\n\nconst dbTxSymbol = Symbol();\n\nconst serverSchemaSymbol = Symbol();\n\ntype WithHiddenTxAndSchema = {\n [dbTxSymbol]: DBTransaction<unknown>;\n [serverSchemaSymbol]: ServerSchema;\n};\n\n/**\n * Factory for creating MutateCRUD instances efficiently.\n *\n * Pre-creates the SQL-generating TableCRUD methods once from the schema,\n * caches the serverSchema after first fetch, and only binds the transaction\n * at transaction time.\n *\n * Use this when you need to create many transactions and want to avoid\n * the overhead of re-creating CRUD methods for each one.\n */\nexport class CRUDMutatorFactory<S extends Schema> {\n readonly #schema: S;\n readonly #tableCRUDs: Record<string, TableCRUD<TableSchema>>;\n #serverSchema: ServerSchema | undefined;\n\n constructor(schema: S) {\n this.#schema = schema;\n // Pre-create TableCRUD methods for each table once\n this.#tableCRUDs = {};\n for (const tableSchema of Object.values(schema.tables)) {\n this.#tableCRUDs[tableSchema.name] = makeServerTableCRUD(tableSchema);\n }\n }\n\n /**\n * Gets the cached serverSchema, or fetches and caches it on first call.\n */\n async #getOrFetchServerSchema(\n dbTransaction: DBTransaction<unknown>,\n ): Promise<ServerSchema> {\n if (!this.#serverSchema) {\n this.#serverSchema = await getServerSchema(dbTransaction, this.#schema);\n }\n return this.#serverSchema;\n }\n\n /**\n * Creates a CRUDExecutor bound to the given transaction and serverSchema.\n * Uses the pre-created TableCRUD methods from construction time.\n */\n createExecutor(\n dbTransaction: DBTransaction<unknown>,\n serverSchema: ServerSchema,\n ): CRUDExecutor {\n const txHolder: WithHiddenTxAndSchema = {\n [dbTxSymbol]: dbTransaction,\n [serverSchemaSymbol]: serverSchema,\n };\n const boundCRUDs = recordProxy(this.#tableCRUDs, tableCRUD =>\n mapValues(tableCRUD, method => method.bind(txHolder)),\n ) as unknown as SchemaCRUD<S>;\n\n return (table: string, kind: CRUDKind, args: unknown) => {\n const tableCRUD = boundCRUDs[table as keyof S['tables']];\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return (tableCRUD as any)[kind](args);\n };\n }\n\n /**\n * Creates a full ServerTransaction.\n * Fetches/caches serverSchema automatically.\n */\n async createTransaction<TWrappedTransaction>(\n dbTransaction: DBTransaction<TWrappedTransaction>,\n clientID: string,\n mutationID: number,\n ): Promise<TransactionImpl<S, TWrappedTransaction>> {\n const serverSchema = await this.#getOrFetchServerSchema(dbTransaction);\n const executor = this.createExecutor(dbTransaction, serverSchema);\n const mutate = makeTransactionMutate(this.#schema, executor);\n return new TransactionImpl(\n dbTransaction,\n clientID,\n mutationID,\n mutate,\n this.#schema,\n serverSchema,\n );\n }\n}\n\nexport async function makeServerTransaction<\n TSchema extends Schema,\n TWrappedTransaction,\n>(\n dbTransaction: DBTransaction<TWrappedTransaction>,\n clientID: string,\n mutationID: number,\n schema: TSchema,\n) {\n const serverSchema = await getServerSchema(dbTransaction, schema);\n // Use the internal executor and shared function directly,\n // bypassing the validation in makeMutateCRUD/makeSchemaCRUD\n const executor = makeServerCRUDExecutor(schema, dbTransaction, serverSchema);\n const mutate = makeTransactionMutate(schema, executor);\n return new TransactionImpl(\n dbTransaction,\n clientID,\n mutationID,\n mutate,\n schema,\n serverSchema,\n );\n}\n\n/**\n * @deprecated Use transactions instead.\n *\n * Returns a curried function for backwards compatibility.\n */\nexport function makeSchemaCRUD<S extends Schema>(\n schema: S,\n): (\n dbTransaction: DBTransaction<unknown>,\n serverSchema: ServerSchema,\n) => MutateCRUD<S, true> {\n return (dbTransaction: DBTransaction<unknown>, serverSchema: ServerSchema) =>\n makeCRUDMutate(\n schema,\n true,\n makeServerCRUDExecutor(schema, dbTransaction, serverSchema),\n );\n}\n\nfunction removeUndefined<T extends Record<string, unknown>>(value: T): T {\n const valueWithoutUndefined: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val !== undefined) {\n valueWithoutUndefined[key] = val;\n }\n }\n return valueWithoutUndefined as T;\n}\n\n/**\n * Creates a CRUDExecutor for server-side SQL execution.\n *\n * For users with very large schemas it is expensive to re-create\n * all the CRUD mutators for each transaction. Instead, we create\n * the SQL-generating methods once up-front and then bind them to\n * the transaction as requested.\n */\nfunction makeServerCRUDExecutor<S extends Schema>(\n schema: S,\n dbTransaction: DBTransaction<unknown>,\n serverSchema: ServerSchema,\n): CRUDExecutor {\n // Pre-create TableCRUD methods for each table (optimization for large schemas)\n const tableCRUDs: Record<string, TableCRUD<TableSchema>> = {};\n for (const tableSchema of Object.values(schema.tables)) {\n tableCRUDs[tableSchema.name] = makeServerTableCRUD(tableSchema);\n }\n\n // Bind transaction context to the methods\n const txHolder: WithHiddenTxAndSchema = {\n [dbTxSymbol]: dbTransaction,\n [serverSchemaSymbol]: serverSchema,\n };\n const boundCRUDs = recordProxy(tableCRUDs, tableCRUD =>\n mapValues(tableCRUD, method => method.bind(txHolder)),\n ) as unknown as SchemaCRUD<S>;\n\n // Return executor that dispatches to bound methods\n return (table: string, kind: CRUDKind, args: unknown) => {\n const tableCRUD = boundCRUDs[table as keyof S['tables']];\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return (tableCRUD as any)[kind](args);\n };\n}\n\n/**\n * Creates SQL-generating TableCRUD methods for a table.\n * Methods use `this` context to access transaction and server schema.\n */\nfunction makeServerTableCRUD(schema: TableSchema): TableCRUD<TableSchema> {\n return {\n async insert(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n\n const targetedColumns = origAndServerNamesFor(Object.keys(value), schema);\n const stmt = formatPgInternalConvert(\n sql`INSERT INTO ${sql.ident(serverName(schema))} (${sql.join(\n targetedColumns.map(([, serverName]) => sql.ident(serverName)),\n ',',\n )}) VALUES (${sql.join(\n Object.entries(value).map(([col, v]) =>\n sqlInsertValue(v, serverTableSchema[serverNameFor(col, schema)]),\n ),\n ', ',\n )})`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n async upsert(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n const targetedColumns = origAndServerNamesFor(Object.keys(value), schema);\n const primaryKeyColumns = origAndServerNamesFor(\n schema.primaryKey,\n schema,\n );\n const stmt = formatPgInternalConvert(\n sql`INSERT INTO ${sql.ident(serverName(schema))} (${sql.join(\n targetedColumns.map(([, serverName]) => sql.ident(serverName)),\n ',',\n )}) VALUES (${sql.join(\n Object.entries(value).map(([col, val]) =>\n sqlInsertValue(val, serverTableSchema[serverNameFor(col, schema)]),\n ),\n ', ',\n )}) ON CONFLICT (${sql.join(\n primaryKeyColumns.map(([, serverName]) => sql.ident(serverName)),\n ', ',\n )}) DO UPDATE SET ${sql.join(\n Object.entries(value).map(\n ([col, val]) =>\n sql`${sql.ident(\n schema.columns[col].serverName ?? col,\n )} = ${sqlInsertValue(val, serverTableSchema[serverNameFor(col, schema)])}`,\n ),\n ', ',\n )}`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n async update(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n const targetedColumns = origAndServerNamesFor(Object.keys(value), schema);\n const stmt = formatPgInternalConvert(\n sql`UPDATE ${sql.ident(serverName(schema))} SET ${sql.join(\n targetedColumns.map(\n ([origName, serverName]) =>\n sql`${sql.ident(serverName)} = ${sqlInsertValue(value[origName], serverTableSchema[serverName])}`,\n ),\n ', ',\n )} WHERE ${primaryKeyClause(schema, serverTableSchema, value)}`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n async delete(this: WithHiddenTxAndSchema, value) {\n value = removeUndefined(value);\n const serverTableSchema = this[serverSchemaSymbol][serverName(schema)];\n const stmt = formatPgInternalConvert(\n sql`DELETE FROM ${sql.ident(\n serverName(schema),\n )} WHERE ${primaryKeyClause(schema, serverTableSchema, value)}`,\n );\n const tx = this[dbTxSymbol];\n await tx.query(stmt.text, stmt.values);\n },\n };\n}\n\nfunction serverName(x: {name: string; serverName?: string | undefined}) {\n return x.serverName ?? x.name;\n}\n\nfunction primaryKeyClause(\n schema: TableSchema,\n serverTableSchema: ServerTableSchema,\n row: Record<string, unknown>,\n) {\n const primaryKey = origAndServerNamesFor(schema.primaryKey, schema);\n return sql`${sql.join(\n primaryKey.map(\n ([origName, serverName]) =>\n sql`${sql.ident(serverName)} = ${sqlValue(row[origName], serverTableSchema[serverName])}`,\n ),\n ' AND ',\n )}`;\n}\n\nfunction origAndServerNamesFor(\n originalNames: readonly string[],\n schema: TableSchema,\n): [origName: string, serverName: string][] {\n return originalNames.map(\n name => [name, serverNameFor(name, schema)] as const,\n );\n}\n\nfunction serverNameFor(originalName: string, schema: TableSchema): string {\n const col = schema.columns[originalName];\n assert(\n col,\n `Column ${originalName} was not found in the Zero schema for the table ${schema.name}`,\n );\n return col.serverName ?? originalName;\n}\n\nfunction sqlValue(value: unknown, serverColumnSchema: ServerColumnSchema) {\n return sqlConvertColumnArg(serverColumnSchema, value, false, true);\n}\n\nfunction sqlInsertValue(\n value: unknown,\n serverColumnSchema: ServerColumnSchema,\n) {\n return sqlConvertColumnArg(serverColumnSchema, value, false, false);\n}\n"],"names":["serverName"],"mappings":"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"}
|