AK-21/Graphite-Industrial-Intelligence
0
1"use strict";2var __defProp = Object.defineProperty;3var __getOwnPropDesc = Object.getOwnPropertyDescriptor;4var __getOwnPropNames = Object.getOwnPropertyNames;5var __hasOwnProp = Object.prototype.hasOwnProperty;6var __export = (target, all) => {7 for (var name in all)8 __defProp(target, name, { get: all[name], enumerable: true });9};10var __copyProps = (to, from, except, desc) => {11 if (from && typeof from === "object" || typeof from === "function") {12 for (let key of __getOwnPropNames(from))13 if (!__hasOwnProp.call(to, key) && key !== except)14 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });15 }16 return to;17};18var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);19var dialect_exports = {};20__export(dialect_exports, {21 GelDialect: () => GelDialect22});23module.exports = __toCommonJS(dialect_exports);24var import_alias = require("../alias.cjs");25var import_casing = require("../casing.cjs");26var import_column = require("../column.cjs");27var import_entity = require("../entity.cjs");28var import_errors = require("../errors.cjs");29var import_columns = require("./columns/index.cjs");30var import_table = require("./table.cjs");31var import_relations = require("../relations.cjs");32var import_sql = require("../sql/index.cjs");33var import_sql2 = require("../sql/sql.cjs");34var import_subquery = require("../subquery.cjs");35var import_table2 = require("../table.cjs");36var import_utils = require("../utils.cjs");37var import_view_common = require("../view-common.cjs");38var import_timestamp = require("./columns/timestamp.cjs");39var import_view_base = require("./view-base.cjs");40class GelDialect {41 static [import_entity.entityKind] = "GelDialect";42 /** @internal */43 casing;44 constructor(config) {45 this.casing = new import_casing.CasingCache(config?.casing);46 }47 // TODO can not migrate gel with drizzle48 // async migrate(migrations: MigrationMeta[], session: GelSession, config: string | MigrationConfig): Promise<void> {49 // const migrationsTable = typeof config === 'string'50 // ? '__drizzle_migrations'51 // : config.migrationsTable ?? '__drizzle_migrations';52 // const migrationsSchema = typeof config === 'string' ? 'drizzle' : config.migrationsSchema ?? 'drizzle';53 // const migrationTableCreate = sql`54 // CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} (55 // id SERIAL PRIMARY KEY,56 // hash text NOT NULL,57 // created_at bigint58 // )59 // `;60 // await session.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);61 // await session.execute(migrationTableCreate);62 // const dbMigrations = await session.all<{ id: number; hash: string; created_at: string }>(63 // sql`select id, hash, created_at from ${sql.identifier(migrationsSchema)}.${64 // sql.identifier(migrationsTable)65 // } order by created_at desc limit 1`,66 // );67 // const lastDbMigration = dbMigrations[0];68 // await session.transaction(async (tx) => {69 // for await (const migration of migrations) {70 // if (71 // !lastDbMigration72 // || Number(lastDbMigration.created_at) < migration.folderMillis73 // ) {74 // for (const stmt of migration.sql) {75 // await tx.execute(sql.raw(stmt));76 // }77 // await tx.execute(78 // sql`insert into ${sql.identifier(migrationsSchema)}.${79 // sql.identifier(migrationsTable)80 // } ("hash", "created_at") values(${migration.hash}, ${migration.folderMillis})`,81 // );82 // }83 // }84 // });85 // }86 escapeName(name) {87 return `"${name}"`;88 }89 escapeParam(num) {90 return `$${num + 1}`;91 }92 escapeString(str) {93 return `'${str.replace(/'/g, "''")}'`;94 }95 buildWithCTE(queries) {96 if (!queries?.length) return void 0;97 const withSqlChunks = [import_sql2.sql`with `];98 for (const [i, w] of queries.entries()) {99 withSqlChunks.push(import_sql2.sql`${import_sql2.sql.identifier(w._.alias)} as (${w._.sql})`);100 if (i < queries.length - 1) {101 withSqlChunks.push(import_sql2.sql`, `);102 }103 }104 withSqlChunks.push(import_sql2.sql` `);105 return import_sql2.sql.join(withSqlChunks);106 }107 buildDeleteQuery({ table, where, returning, withList }) {108 const withSql = this.buildWithCTE(withList);109 const returningSql = returning ? import_sql2.sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;110 const whereSql = where ? import_sql2.sql` where ${where}` : void 0;111 return import_sql2.sql`${withSql}delete from ${table}${whereSql}${returningSql}`;112 }113 buildUpdateSet(table, set) {114 const tableColumns = table[import_table2.Table.Symbol.Columns];115 const columnNames = Object.keys(tableColumns).filter(116 (colName) => set[colName] !== void 0 || tableColumns[colName]?.onUpdateFn !== void 0117 );118 const setSize = columnNames.length;119 return import_sql2.sql.join(columnNames.flatMap((colName, i) => {120 const col = tableColumns[colName];121 const onUpdateFnResult = col.onUpdateFn?.();122 const value = set[colName] ?? ((0, import_entity.is)(onUpdateFnResult, import_sql2.SQL) ? onUpdateFnResult : import_sql2.sql.param(onUpdateFnResult, col));123 const res = import_sql2.sql`${import_sql2.sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;124 if (i < setSize - 1) {125 return [res, import_sql2.sql.raw(", ")];126 }127 return [res];128 }));129 }130 buildUpdateQuery({ table, set, where, returning, withList, from, joins }) {131 const withSql = this.buildWithCTE(withList);132 const tableName = table[import_table.GelTable.Symbol.Name];133 const tableSchema = table[import_table.GelTable.Symbol.Schema];134 const origTableName = table[import_table.GelTable.Symbol.OriginalName];135 const alias = tableName === origTableName ? void 0 : tableName;136 const tableSql = import_sql2.sql`${tableSchema ? import_sql2.sql`${import_sql2.sql.identifier(tableSchema)}.` : void 0}${import_sql2.sql.identifier(origTableName)}${alias && import_sql2.sql` ${import_sql2.sql.identifier(alias)}`}`;137 const setSql = this.buildUpdateSet(table, set);138 const fromSql = from && import_sql2.sql.join([import_sql2.sql.raw(" from "), this.buildFromTable(from)]);139 const joinsSql = this.buildJoins(joins);140 const returningSql = returning ? import_sql2.sql` returning ${this.buildSelection(returning, { isSingleTable: !from })}` : void 0;141 const whereSql = where ? import_sql2.sql` where ${where}` : void 0;142 return import_sql2.sql`${withSql}update ${tableSql} set ${setSql}${fromSql}${joinsSql}${whereSql}${returningSql}`;143 }144 /**145 * Builds selection SQL with provided fields/expressions146 *147 * Examples:148 *149 * `select <selection> from`150 *151 * `insert ... returning <selection>`152 *153 * If `isSingleTable` is true, then columns won't be prefixed with table name154 * ^ Temporarily disabled behaviour, see comments within method for a reasoning155 */156 buildSelection(fields, { isSingleTable = false } = {}) {157 const columnsLen = fields.length;158 const chunks = fields.flatMap(({ field }, i) => {159 const chunk = [];160 if ((0, import_entity.is)(field, import_sql2.SQL.Aliased) && field.isSelectionField) {161 chunk.push(import_sql2.sql.identifier(field.fieldAlias));162 } else if ((0, import_entity.is)(field, import_sql2.SQL.Aliased) || (0, import_entity.is)(field, import_sql2.SQL)) {163 const query = (0, import_entity.is)(field, import_sql2.SQL.Aliased) ? field.sql : field;164 chunk.push(query);165 if ((0, import_entity.is)(field, import_sql2.SQL.Aliased)) {166 chunk.push(import_sql2.sql` as ${import_sql2.sql.identifier(field.fieldAlias)}`);167 }168 } else if ((0, import_entity.is)(field, import_column.Column)) {169 chunk.push(field);170 } else if ((0, import_entity.is)(field, import_subquery.Subquery)) {171 const entries = Object.entries(field._.selectedFields);172 if (entries.length === 1) {173 const entry = entries[0][1];174 const fieldDecoder = (0, import_entity.is)(entry, import_sql2.SQL) ? entry.decoder : (0, import_entity.is)(entry, import_column.Column) ? { mapFromDriverValue: (v) => entry.mapFromDriverValue(v) } : entry.sql.decoder;175 if (fieldDecoder) {176 field._.sql.decoder = fieldDecoder;177 }178 }179 chunk.push(field);180 }181 if (i < columnsLen - 1) {182 chunk.push(import_sql2.sql`, `);183 }184 return chunk;185 });186 return import_sql2.sql.join(chunks);187 }188 buildJoins(joins) {189 if (!joins || joins.length === 0) {190 return void 0;191 }192 const joinsArray = [];193 for (const [index, joinMeta] of joins.entries()) {194 if (index === 0) {195 joinsArray.push(import_sql2.sql` `);196 }197 const table = joinMeta.table;198 const lateralSql = joinMeta.lateral ? import_sql2.sql` lateral` : void 0;199 const onSql = joinMeta.on ? import_sql2.sql` on ${joinMeta.on}` : void 0;200 if ((0, import_entity.is)(table, import_table.GelTable)) {201 const tableName = table[import_table.GelTable.Symbol.Name];202 const tableSchema = table[import_table.GelTable.Symbol.Schema];203 const origTableName = table[import_table.GelTable.Symbol.OriginalName];204 const alias = tableName === origTableName ? void 0 : joinMeta.alias;205 joinsArray.push(206 import_sql2.sql`${import_sql2.sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? import_sql2.sql`${import_sql2.sql.identifier(tableSchema)}.` : void 0}${import_sql2.sql.identifier(origTableName)}${alias && import_sql2.sql` ${import_sql2.sql.identifier(alias)}`}${onSql}`207 );208 } else if ((0, import_entity.is)(table, import_sql.View)) {209 const viewName = table[import_view_common.ViewBaseConfig].name;210 const viewSchema = table[import_view_common.ViewBaseConfig].schema;211 const origViewName = table[import_view_common.ViewBaseConfig].originalName;212 const alias = viewName === origViewName ? void 0 : joinMeta.alias;213 joinsArray.push(214 import_sql2.sql`${import_sql2.sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? import_sql2.sql`${import_sql2.sql.identifier(viewSchema)}.` : void 0}${import_sql2.sql.identifier(origViewName)}${alias && import_sql2.sql` ${import_sql2.sql.identifier(alias)}`}${onSql}`215 );216 } else {217 joinsArray.push(218 import_sql2.sql`${import_sql2.sql.raw(joinMeta.joinType)} join${lateralSql} ${table}${onSql}`219 );220 }221 if (index < joins.length - 1) {222 joinsArray.push(import_sql2.sql` `);223 }224 }225 return import_sql2.sql.join(joinsArray);226 }227 buildFromTable(table) {228 if ((0, import_entity.is)(table, import_table2.Table) && table[import_table2.Table.Symbol.OriginalName] !== table[import_table2.Table.Symbol.Name]) {229 let fullName = import_sql2.sql`${import_sql2.sql.identifier(table[import_table2.Table.Symbol.OriginalName])}`;230 if (table[import_table2.Table.Symbol.Schema]) {231 fullName = import_sql2.sql`${import_sql2.sql.identifier(table[import_table2.Table.Symbol.Schema])}.${fullName}`;232 }233 return import_sql2.sql`${fullName} ${import_sql2.sql.identifier(table[import_table2.Table.Symbol.Name])}`;234 }235 return table;236 }237 buildSelectQuery({238 withList,239 fields,240 fieldsFlat,241 where,242 having,243 table,244 joins,245 orderBy,246 groupBy,247 limit,248 offset,249 lockingClause,250 distinct,251 setOperators252 }) {253 const fieldsList = fieldsFlat ?? (0, import_utils.orderSelectedFields)(fields);254 for (const f of fieldsList) {255 if ((0, import_entity.is)(f.field, import_column.Column) && (0, import_table2.getTableName)(f.field.table) !== ((0, import_entity.is)(table, import_subquery.Subquery) ? table._.alias : (0, import_entity.is)(table, import_view_base.GelViewBase) ? table[import_view_common.ViewBaseConfig].name : (0, import_entity.is)(table, import_sql2.SQL) ? void 0 : (0, import_table2.getTableName)(table)) && !((table2) => joins?.some(256 ({ alias }) => alias === (table2[import_table2.Table.Symbol.IsAlias] ? (0, import_table2.getTableName)(table2) : table2[import_table2.Table.Symbol.BaseName])257 ))(f.field.table)) {258 const tableName = (0, import_table2.getTableName)(f.field.table);259 throw new Error(260 `Your "${f.path.join("->")}" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`261 );262 }263 }264 const isSingleTable = !joins || joins.length === 0;265 const withSql = this.buildWithCTE(withList);266 let distinctSql;267 if (distinct) {268 distinctSql = distinct === true ? import_sql2.sql` distinct` : import_sql2.sql` distinct on (${import_sql2.sql.join(distinct.on, import_sql2.sql`, `)})`;269 }270 const selection = this.buildSelection(fieldsList, { isSingleTable });271 const tableSql = this.buildFromTable(table);272 const joinsSql = this.buildJoins(joins);273 const whereSql = where ? import_sql2.sql` where ${where}` : void 0;274 const havingSql = having ? import_sql2.sql` having ${having}` : void 0;275 let orderBySql;276 if (orderBy && orderBy.length > 0) {277 orderBySql = import_sql2.sql` order by ${import_sql2.sql.join(orderBy, import_sql2.sql`, `)}`;278 }279 let groupBySql;280 if (groupBy && groupBy.length > 0) {281 groupBySql = import_sql2.sql` group by ${import_sql2.sql.join(groupBy, import_sql2.sql`, `)}`;282 }283 const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? import_sql2.sql` limit ${limit}` : void 0;284 const offsetSql = offset ? import_sql2.sql` offset ${offset}` : void 0;285 const lockingClauseSql = import_sql2.sql.empty();286 if (lockingClause) {287 const clauseSql = import_sql2.sql` for ${import_sql2.sql.raw(lockingClause.strength)}`;288 if (lockingClause.config.of) {289 clauseSql.append(290 import_sql2.sql` of ${import_sql2.sql.join(291 Array.isArray(lockingClause.config.of) ? lockingClause.config.of : [lockingClause.config.of],292 import_sql2.sql`, `293 )}`294 );295 }296 if (lockingClause.config.noWait) {297 clauseSql.append(import_sql2.sql` nowait`);298 } else if (lockingClause.config.skipLocked) {299 clauseSql.append(import_sql2.sql` skip locked`);300 }301 lockingClauseSql.append(clauseSql);302 }303 const finalQuery = import_sql2.sql`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClauseSql}`;304 if (setOperators.length > 0) {305 return this.buildSetOperations(finalQuery, setOperators);306 }307 return finalQuery;308 }309 buildSetOperations(leftSelect, setOperators) {310 const [setOperator, ...rest] = setOperators;311 if (!setOperator) {312 throw new Error("Cannot pass undefined values to any set operator");313 }314 if (rest.length === 0) {315 return this.buildSetOperationQuery({ leftSelect, setOperator });316 }317 return this.buildSetOperations(318 this.buildSetOperationQuery({ leftSelect, setOperator }),319 rest320 );321 }322 buildSetOperationQuery({323 leftSelect,324 setOperator: { type, isAll, rightSelect, limit, orderBy, offset }325 }) {326 const leftChunk = import_sql2.sql`(${leftSelect.getSQL()}) `;327 const rightChunk = import_sql2.sql`(${rightSelect.getSQL()})`;328 let orderBySql;329 if (orderBy && orderBy.length > 0) {330 const orderByValues = [];331 for (const singleOrderBy of orderBy) {332 if ((0, import_entity.is)(singleOrderBy, import_columns.GelColumn)) {333 orderByValues.push(import_sql2.sql.identifier(singleOrderBy.name));334 } else if ((0, import_entity.is)(singleOrderBy, import_sql2.SQL)) {335 for (let i = 0; i < singleOrderBy.queryChunks.length; i++) {336 const chunk = singleOrderBy.queryChunks[i];337 if ((0, import_entity.is)(chunk, import_columns.GelColumn)) {338 singleOrderBy.queryChunks[i] = import_sql2.sql.identifier(chunk.name);339 }340 }341 orderByValues.push(import_sql2.sql`${singleOrderBy}`);342 } else {343 orderByValues.push(import_sql2.sql`${singleOrderBy}`);344 }345 }346 orderBySql = import_sql2.sql` order by ${import_sql2.sql.join(orderByValues, import_sql2.sql`, `)} `;347 }348 const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? import_sql2.sql` limit ${limit}` : void 0;349 const operatorChunk = import_sql2.sql.raw(`${type} ${isAll ? "all " : ""}`);350 const offsetSql = offset ? import_sql2.sql` offset ${offset}` : void 0;351 return import_sql2.sql`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`;352 }353 buildInsertQuery({ table, values: valuesOrSelect, onConflict, returning, withList, select, overridingSystemValue_ }) {354 const valuesSqlList = [];355 const columns = table[import_table2.Table.Symbol.Columns];356 const colEntries = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert());357 const insertOrder = colEntries.map(358 ([, column]) => import_sql2.sql.identifier(this.casing.getColumnCasing(column))359 );360 if (select) {361 const select2 = valuesOrSelect;362 if ((0, import_entity.is)(select2, import_sql2.SQL)) {363 valuesSqlList.push(select2);364 } else {365 valuesSqlList.push(select2.getSQL());366 }367 } else {368 const values = valuesOrSelect;369 valuesSqlList.push(import_sql2.sql.raw("values "));370 for (const [valueIndex, value] of values.entries()) {371 const valueList = [];372 for (const [fieldName, col] of colEntries) {373 const colValue = value[fieldName];374 if (colValue === void 0 || (0, import_entity.is)(colValue, import_sql2.Param) && colValue.value === void 0) {375 if (col.defaultFn !== void 0) {376 const defaultFnResult = col.defaultFn();377 const defaultValue = (0, import_entity.is)(defaultFnResult, import_sql2.SQL) ? defaultFnResult : import_sql2.sql.param(defaultFnResult, col);378 valueList.push(defaultValue);379 } else if (!col.default && col.onUpdateFn !== void 0) {380 const onUpdateFnResult = col.onUpdateFn();381 const newValue = (0, import_entity.is)(onUpdateFnResult, import_sql2.SQL) ? onUpdateFnResult : import_sql2.sql.param(onUpdateFnResult, col);382 valueList.push(newValue);383 } else {384 valueList.push(import_sql2.sql`default`);385 }386 } else {387 valueList.push(colValue);388 }389 }390 valuesSqlList.push(valueList);391 if (valueIndex < values.length - 1) {392 valuesSqlList.push(import_sql2.sql`, `);393 }394 }395 }396 const withSql = this.buildWithCTE(withList);397 const valuesSql = import_sql2.sql.join(valuesSqlList);398 const returningSql = returning ? import_sql2.sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;399 const onConflictSql = onConflict ? import_sql2.sql` on conflict ${onConflict}` : void 0;400 const overridingSql = overridingSystemValue_ === true ? import_sql2.sql`overriding system value ` : void 0;401 return import_sql2.sql`${withSql}insert into ${table} ${insertOrder} ${overridingSql}${valuesSql}${onConflictSql}${returningSql}`;402 }403 buildRefreshMaterializedViewQuery({ view, concurrently, withNoData }) {404 const concurrentlySql = concurrently ? import_sql2.sql` concurrently` : void 0;405 const withNoDataSql = withNoData ? import_sql2.sql` with no data` : void 0;406 return import_sql2.sql`refresh materialized view${concurrentlySql} ${view}${withNoDataSql}`;407 }408 prepareTyping(encoder) {409 if ((0, import_entity.is)(encoder, import_columns.GelJson)) {410 return "json";411 } else if ((0, import_entity.is)(encoder, import_columns.GelDecimal)) {412 return "decimal";413 } else if ((0, import_entity.is)(encoder, import_timestamp.GelTimestamp)) {414 return "timestamp";415 } else if ((0, import_entity.is)(encoder, import_columns.GelUUID)) {416 return "uuid";417 } else {418 return "none";419 }420 }421 sqlToQuery(sql2, invokeSource) {422 return sql2.toQuery({423 casing: this.casing,424 escapeName: this.escapeName,425 escapeParam: this.escapeParam,426 escapeString: this.escapeString,427 prepareTyping: this.prepareTyping,428 invokeSource429 });430 }431 // buildRelationalQueryWithPK({432 // fullSchema,433 // schema,434 // tableNamesMap,435 // table,436 // tableConfig,437 // queryConfig: config,438 // tableAlias,439 // isRoot = false,440 // joinOn,441 // }: {442 // fullSchema: Record<string, unknown>;443 // schema: TablesRelationalConfig;444 // tableNamesMap: Record<string, string>;445 // table: GelTable;446 // tableConfig: TableRelationalConfig;447 // queryConfig: true | DBQueryConfig<'many', true>;448 // tableAlias: string;449 // isRoot?: boolean;450 // joinOn?: SQL;451 // }): BuildRelationalQueryResult<GelTable, GelColumn> {452 // // For { "<relation>": true }, return a table with selection of all columns453 // if (config === true) {454 // const selectionEntries = Object.entries(tableConfig.columns);455 // const selection: BuildRelationalQueryResult<GelTable, GelColumn>['selection'] = selectionEntries.map((456 // [key, value],457 // ) => ({458 // dbKey: value.name,459 // tsKey: key,460 // field: value as GelColumn,461 // relationTableTsKey: undefined,462 // isJson: false,463 // selection: [],464 // }));465 // return {466 // tableTsKey: tableConfig.tsName,467 // sql: table,468 // selection,469 // };470 // }471 // // let selection: BuildRelationalQueryResult<GelTable, GelColumn>['selection'] = [];472 // // let selectionForBuild = selection;473 // const aliasedColumns = Object.fromEntries(474 // Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]),475 // );476 // const aliasedRelations = Object.fromEntries(477 // Object.entries(tableConfig.relations).map(([key, value]) => [key, aliasedRelation(value, tableAlias)]),478 // );479 // const aliasedFields = Object.assign({}, aliasedColumns, aliasedRelations);480 // let where, hasUserDefinedWhere;481 // if (config.where) {482 // const whereSql = typeof config.where === 'function' ? config.where(aliasedFields, operators) : config.where;483 // where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);484 // hasUserDefinedWhere = !!where;485 // }486 // where = and(joinOn, where);487 // // const fieldsSelection: { tsKey: string; value: GelColumn | SQL.Aliased; isExtra?: boolean }[] = [];488 // let joins: Join[] = [];489 // let selectedColumns: string[] = [];490 // // Figure out which columns to select491 // if (config.columns) {492 // let isIncludeMode = false;493 // for (const [field, value] of Object.entries(config.columns)) {494 // if (value === undefined) {495 // continue;496 // }497 // if (field in tableConfig.columns) {498 // if (!isIncludeMode && value === true) {499 // isIncludeMode = true;500 // }501 // selectedColumns.push(field);502 // }503 // }504 // if (selectedColumns.length > 0) {505 // selectedColumns = isIncludeMode506 // ? selectedColumns.filter((c) => config.columns?.[c] === true)507 // : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));508 // }509 // } else {510 // // Select all columns if selection is not specified511 // selectedColumns = Object.keys(tableConfig.columns);512 // }513 // // for (const field of selectedColumns) {514 // // const column = tableConfig.columns[field]! as GelColumn;515 // // fieldsSelection.push({ tsKey: field, value: column });516 // // }517 // let initiallySelectedRelations: {518 // tsKey: string;519 // queryConfig: true | DBQueryConfig<'many', false>;520 // relation: Relation;521 // }[] = [];522 // // let selectedRelations: BuildRelationalQueryResult<GelTable, GelColumn>['selection'] = [];523 // // Figure out which relations to select524 // if (config.with) {525 // initiallySelectedRelations = Object.entries(config.with)526 // .filter((entry): entry is [typeof entry[0], NonNullable<typeof entry[1]>] => !!entry[1])527 // .map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey]! }));528 // }529 // const manyRelations = initiallySelectedRelations.filter((r) =>530 // is(r.relation, Many)531 // && (schema[tableNamesMap[r.relation.referencedTable[Table.Symbol.Name]]!]?.primaryKey.length ?? 0) > 0532 // );533 // // If this is the last Many relation (or there are no Many relations), we are on the innermost subquery level534 // const isInnermostQuery = manyRelations.length < 2;535 // const selectedExtras: {536 // tsKey: string;537 // value: SQL.Aliased;538 // }[] = [];539 // // Figure out which extras to select540 // if (isInnermostQuery && config.extras) {541 // const extras = typeof config.extras === 'function'542 // ? config.extras(aliasedFields, { sql })543 // : config.extras;544 // for (const [tsKey, value] of Object.entries(extras)) {545 // selectedExtras.push({546 // tsKey,547 // value: mapColumnsInAliasedSQLToAlias(value, tableAlias),548 // });549 // }550 // }551 // // Transform `fieldsSelection` into `selection`552 // // `fieldsSelection` shouldn't be used after this point553 // // for (const { tsKey, value, isExtra } of fieldsSelection) {554 // // selection.push({555 // // dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey]!.name,556 // // tsKey,557 // // field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,558 // // relationTableTsKey: undefined,559 // // isJson: false,560 // // isExtra,561 // // selection: [],562 // // });563 // // }564 // let orderByOrig = typeof config.orderBy === 'function'565 // ? config.orderBy(aliasedFields, orderByOperators)566 // : config.orderBy ?? [];567 // if (!Array.isArray(orderByOrig)) {568 // orderByOrig = [orderByOrig];569 // }570 // const orderBy = orderByOrig.map((orderByValue) => {571 // if (is(orderByValue, Column)) {572 // return aliasedTableColumn(orderByValue, tableAlias) as GelColumn;573 // }574 // return mapColumnsInSQLToAlias(orderByValue, tableAlias);575 // });576 // const limit = isInnermostQuery ? config.limit : undefined;577 // const offset = isInnermostQuery ? config.offset : undefined;578 // // For non-root queries without additional config except columns, return a table with selection579 // if (580 // !isRoot581 // && initiallySelectedRelations.length === 0582 // && selectedExtras.length === 0583 // && !where584 // && orderBy.length === 0585 // && limit === undefined586 // && offset === undefined587 // ) {588 // return {589 // tableTsKey: tableConfig.tsName,590 // sql: table,591 // selection: selectedColumns.map((key) => ({592 // dbKey: tableConfig.columns[key]!.name,593 // tsKey: key,594 // field: tableConfig.columns[key] as GelColumn,595 // relationTableTsKey: undefined,596 // isJson: false,597 // selection: [],598 // })),599 // };600 // }601 // const selectedRelationsWithoutPK:602 // // Process all relations without primary keys, because they need to be joined differently and will all be on the same query level603 // for (604 // const {605 // tsKey: selectedRelationTsKey,606 // queryConfig: selectedRelationConfigValue,607 // relation,608 // } of initiallySelectedRelations609 // ) {610 // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);611 // const relationTableName = relation.referencedTable[Table.Symbol.Name];612 // const relationTableTsName = tableNamesMap[relationTableName]!;613 // const relationTable = schema[relationTableTsName]!;614 // if (relationTable.primaryKey.length > 0) {615 // continue;616 // }617 // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;618 // const joinOn = and(619 // ...normalizedRelation.fields.map((field, i) =>620 // eq(621 // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),622 // aliasedTableColumn(field, tableAlias),623 // )624 // ),625 // );626 // const builtRelation = this.buildRelationalQueryWithoutPK({627 // fullSchema,628 // schema,629 // tableNamesMap,630 // table: fullSchema[relationTableTsName] as GelTable,631 // tableConfig: schema[relationTableTsName]!,632 // queryConfig: selectedRelationConfigValue,633 // tableAlias: relationTableAlias,634 // joinOn,635 // nestedQueryRelation: relation,636 // });637 // const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey);638 // joins.push({639 // on: sql`true`,640 // table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias),641 // alias: relationTableAlias,642 // joinType: 'left',643 // lateral: true,644 // });645 // selectedRelations.push({646 // dbKey: selectedRelationTsKey,647 // tsKey: selectedRelationTsKey,648 // field,649 // relationTableTsKey: relationTableTsName,650 // isJson: true,651 // selection: builtRelation.selection,652 // });653 // }654 // const oneRelations = initiallySelectedRelations.filter((r): r is typeof r & { relation: One } =>655 // is(r.relation, One)656 // );657 // // Process all One relations with PKs, because they can all be joined on the same level658 // for (659 // const {660 // tsKey: selectedRelationTsKey,661 // queryConfig: selectedRelationConfigValue,662 // relation,663 // } of oneRelations664 // ) {665 // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);666 // const relationTableName = relation.referencedTable[Table.Symbol.Name];667 // const relationTableTsName = tableNamesMap[relationTableName]!;668 // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;669 // const relationTable = schema[relationTableTsName]!;670 // if (relationTable.primaryKey.length === 0) {671 // continue;672 // }673 // const joinOn = and(674 // ...normalizedRelation.fields.map((field, i) =>675 // eq(676 // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),677 // aliasedTableColumn(field, tableAlias),678 // )679 // ),680 // );681 // const builtRelation = this.buildRelationalQueryWithPK({682 // fullSchema,683 // schema,684 // tableNamesMap,685 // table: fullSchema[relationTableTsName] as GelTable,686 // tableConfig: schema[relationTableTsName]!,687 // queryConfig: selectedRelationConfigValue,688 // tableAlias: relationTableAlias,689 // joinOn,690 // });691 // const field = sql`case when ${sql.identifier(relationTableAlias)} is null then null else json_build_array(${692 // sql.join(693 // builtRelation.selection.map(({ field }) =>694 // is(field, SQL.Aliased)695 // ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`696 // : is(field, Column)697 // ? aliasedTableColumn(field, relationTableAlias)698 // : field699 // ),700 // sql`, `,701 // )702 // }) end`.as(selectedRelationTsKey);703 // const isLateralJoin = is(builtRelation.sql, SQL);704 // joins.push({705 // on: isLateralJoin ? sql`true` : joinOn,706 // table: is(builtRelation.sql, SQL)707 // ? new Subquery(builtRelation.sql, {}, relationTableAlias)708 // : aliasedTable(builtRelation.sql, relationTableAlias),709 // alias: relationTableAlias,710 // joinType: 'left',711 // lateral: is(builtRelation.sql, SQL),712 // });713 // selectedRelations.push({714 // dbKey: selectedRelationTsKey,715 // tsKey: selectedRelationTsKey,716 // field,717 // relationTableTsKey: relationTableTsName,718 // isJson: true,719 // selection: builtRelation.selection,720 // });721 // }722 // let distinct: GelSelectConfig['distinct'];723 // let tableFrom: GelTable | Subquery = table;724 // // Process first Many relation - each one requires a nested subquery725 // const manyRelation = manyRelations[0];726 // if (manyRelation) {727 // const {728 // tsKey: selectedRelationTsKey,729 // queryConfig: selectedRelationQueryConfig,730 // relation,731 // } = manyRelation;732 // distinct = {733 // on: tableConfig.primaryKey.map((c) => aliasedTableColumn(c as GelColumn, tableAlias)),734 // };735 // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);736 // const relationTableName = relation.referencedTable[Table.Symbol.Name];737 // const relationTableTsName = tableNamesMap[relationTableName]!;738 // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;739 // const joinOn = and(740 // ...normalizedRelation.fields.map((field, i) =>741 // eq(742 // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),743 // aliasedTableColumn(field, tableAlias),744 // )745 // ),746 // );747 // const builtRelationJoin = this.buildRelationalQueryWithPK({748 // fullSchema,749 // schema,750 // tableNamesMap,751 // table: fullSchema[relationTableTsName] as GelTable,752 // tableConfig: schema[relationTableTsName]!,753 // queryConfig: selectedRelationQueryConfig,754 // tableAlias: relationTableAlias,755 // joinOn,756 // });757 // const builtRelationSelectionField = sql`case when ${758 // sql.identifier(relationTableAlias)759 // } is null then '[]' else json_agg(json_build_array(${760 // sql.join(761 // builtRelationJoin.selection.map(({ field }) =>762 // is(field, SQL.Aliased)763 // ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`764 // : is(field, Column)765 // ? aliasedTableColumn(field, relationTableAlias)766 // : field767 // ),768 // sql`, `,769 // )770 // })) over (partition by ${sql.join(distinct.on, sql`, `)}) end`.as(selectedRelationTsKey);771 // const isLateralJoin = is(builtRelationJoin.sql, SQL);772 // joins.push({773 // on: isLateralJoin ? sql`true` : joinOn,774 // table: isLateralJoin775 // ? new Subquery(builtRelationJoin.sql as SQL, {}, relationTableAlias)776 // : aliasedTable(builtRelationJoin.sql as GelTable, relationTableAlias),777 // alias: relationTableAlias,778 // joinType: 'left',779 // lateral: isLateralJoin,780 // });781 // // Build the "from" subquery with the remaining Many relations782 // const builtTableFrom = this.buildRelationalQueryWithPK({783 // fullSchema,784 // schema,785 // tableNamesMap,786 // table,787 // tableConfig,788 // queryConfig: {789 // ...config,790 // where: undefined,791 // orderBy: undefined,792 // limit: undefined,793 // offset: undefined,794 // with: manyRelations.slice(1).reduce<NonNullable<typeof config['with']>>(795 // (result, { tsKey, queryConfig: configValue }) => {796 // result[tsKey] = configValue;797 // return result;798 // },799 // {},800 // ),801 // },802 // tableAlias,803 // });804 // selectedRelations.push({805 // dbKey: selectedRelationTsKey,806 // tsKey: selectedRelationTsKey,807 // field: builtRelationSelectionField,808 // relationTableTsKey: relationTableTsName,809 // isJson: true,810 // selection: builtRelationJoin.selection,811 // });812 // // selection = builtTableFrom.selection.map((item) =>813 // // is(item.field, SQL.Aliased)814 // // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }815 // // : item816 // // );817 // // selectionForBuild = [{818 // // dbKey: '*',819 // // tsKey: '*',820 // // field: sql`${sql.identifier(tableAlias)}.*`,821 // // selection: [],822 // // isJson: false,823 // // relationTableTsKey: undefined,824 // // }];825 // // const newSelectionItem: (typeof selection)[number] = {826 // // dbKey: selectedRelationTsKey,827 // // tsKey: selectedRelationTsKey,828 // // field,829 // // relationTableTsKey: relationTableTsName,830 // // isJson: true,831 // // selection: builtRelationJoin.selection,832 // // };833 // // selection.push(newSelectionItem);834 // // selectionForBuild.push(newSelectionItem);835 // tableFrom = is(builtTableFrom.sql, GelTable)836 // ? builtTableFrom.sql837 // : new Subquery(builtTableFrom.sql, {}, tableAlias);838 // }839 // if (selectedColumns.length === 0 && selectedRelations.length === 0 && selectedExtras.length === 0) {840 // throw new DrizzleError(`No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")`);841 // }842 // let selection: BuildRelationalQueryResult<GelTable, GelColumn>['selection'];843 // function prepareSelectedColumns() {844 // return selectedColumns.map((key) => ({845 // dbKey: tableConfig.columns[key]!.name,846 // tsKey: key,847 // field: tableConfig.columns[key] as GelColumn,848 // relationTableTsKey: undefined,849 // isJson: false,850 // selection: [],851 // }));852 // }853 // function prepareSelectedExtras() {854 // return selectedExtras.map((item) => ({855 // dbKey: item.value.fieldAlias,856 // tsKey: item.tsKey,857 // field: item.value,858 // relationTableTsKey: undefined,859 // isJson: false,860 // selection: [],861 // }));862 // }863 // if (isRoot) {864 // selection = [865 // ...prepareSelectedColumns(),866 // ...prepareSelectedExtras(),867 // ];868 // }869 // if (hasUserDefinedWhere || orderBy.length > 0) {870 // tableFrom = new Subquery(871 // this.buildSelectQuery({872 // table: is(tableFrom, GelTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,873 // fields: {},874 // fieldsFlat: selectionForBuild.map(({ field }) => ({875 // path: [],876 // field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,877 // })),878 // joins,879 // distinct,880 // }),881 // {},882 // tableAlias,883 // );884 // selectionForBuild = selection.map((item) =>885 // is(item.field, SQL.Aliased)886 // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }887 // : item888 // );889 // joins = [];890 // distinct = undefined;891 // }892 // const result = this.buildSelectQuery({893 // table: is(tableFrom, GelTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,894 // fields: {},895 // fieldsFlat: selectionForBuild.map(({ field }) => ({896 // path: [],897 // field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,898 // })),899 // where,900 // limit,901 // offset,902 // joins,903 // orderBy,904 // distinct,905 // });906 // return {907 // tableTsKey: tableConfig.tsName,908 // sql: result,909 // selection,910 // };911 // }912 buildRelationalQueryWithoutPK({913 fullSchema,914 schema,915 tableNamesMap,916 table,917 tableConfig,918 queryConfig: config,919 tableAlias,920 nestedQueryRelation,921 joinOn922 }) {923 let selection = [];924 let limit, offset, orderBy = [], where;925 const joins = [];926 if (config === true) {927 const selectionEntries = Object.entries(tableConfig.columns);928 selection = selectionEntries.map(([key, value]) => ({929 dbKey: value.name,930 tsKey: key,931 field: (0, import_alias.aliasedTableColumn)(value, tableAlias),932 relationTableTsKey: void 0,933 isJson: false,934 selection: []935 }));936 } else {937 const aliasedColumns = Object.fromEntries(938 Object.entries(tableConfig.columns).map(([key, value]) => [key, (0, import_alias.aliasedTableColumn)(value, tableAlias)])939 );940 if (config.where) {941 const whereSql = typeof config.where === "function" ? config.where(aliasedColumns, (0, import_relations.getOperators)()) : config.where;942 where = whereSql && (0, import_alias.mapColumnsInSQLToAlias)(whereSql, tableAlias);943 }944 const fieldsSelection = [];945 let selectedColumns = [];946 if (config.columns) {947 let isIncludeMode = false;948 for (const [field, value] of Object.entries(config.columns)) {949 if (value === void 0) {950 continue;951 }952 if (field in tableConfig.columns) {953 if (!isIncludeMode && value === true) {954 isIncludeMode = true;955 }956 selectedColumns.push(field);957 }958 }959 if (selectedColumns.length > 0) {960 selectedColumns = isIncludeMode ? selectedColumns.filter((c) => config.columns?.[c] === true) : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));961 }962 } else {963 selectedColumns = Object.keys(tableConfig.columns);964 }965 for (const field of selectedColumns) {966 const column = tableConfig.columns[field];967 fieldsSelection.push({ tsKey: field, value: column });968 }969 let selectedRelations = [];970 if (config.with) {971 selectedRelations = Object.entries(config.with).filter((entry) => !!entry[1]).map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey] }));972 }973 let extras;974 if (config.extras) {975 extras = typeof config.extras === "function" ? config.extras(aliasedColumns, { sql: import_sql2.sql }) : config.extras;976 for (const [tsKey, value] of Object.entries(extras)) {977 fieldsSelection.push({978 tsKey,979 value: (0, import_alias.mapColumnsInAliasedSQLToAlias)(value, tableAlias)980 });981 }982 }983 for (const { tsKey, value } of fieldsSelection) {984 selection.push({985 dbKey: (0, import_entity.is)(value, import_sql2.SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey].name,986 tsKey,987 field: (0, import_entity.is)(value, import_column.Column) ? (0, import_alias.aliasedTableColumn)(value, tableAlias) : value,988 relationTableTsKey: void 0,989 isJson: false,990 selection: []991 });992 }993 let orderByOrig = typeof config.orderBy === "function" ? config.orderBy(aliasedColumns, (0, import_relations.getOrderByOperators)()) : config.orderBy ?? [];994 if (!Array.isArray(orderByOrig)) {995 orderByOrig = [orderByOrig];996 }997 orderBy = orderByOrig.map((orderByValue) => {998 if ((0, import_entity.is)(orderByValue, import_column.Column)) {999 return (0, import_alias.aliasedTableColumn)(orderByValue, tableAlias);1000 }1001 return (0, import_alias.mapColumnsInSQLToAlias)(orderByValue, tableAlias);1002 });1003 limit = config.limit;1004 offset = config.offset;1005 for (const {1006 tsKey: selectedRelationTsKey,1007 queryConfig: selectedRelationConfigValue,1008 relation1009 } of selectedRelations) {1010 const normalizedRelation = (0, import_relations.normalizeRelation)(schema, tableNamesMap, relation);1011 const relationTableName = (0, import_table2.getTableUniqueName)(relation.referencedTable);1012 const relationTableTsName = tableNamesMap[relationTableName];1013 const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;1014 const joinOn2 = (0, import_sql.and)(1015 ...normalizedRelation.fields.map(1016 (field2, i) => (0, import_sql.eq)(1017 (0, import_alias.aliasedTableColumn)(normalizedRelation.references[i], relationTableAlias),1018 (0, import_alias.aliasedTableColumn)(field2, tableAlias)1019 )1020 )1021 );1022 const builtRelation = this.buildRelationalQueryWithoutPK({1023 fullSchema,1024 schema,1025 tableNamesMap,1026 table: fullSchema[relationTableTsName],1027 tableConfig: schema[relationTableTsName],1028 queryConfig: (0, import_entity.is)(relation, import_relations.One) ? selectedRelationConfigValue === true ? { limit: 1 } : { ...selectedRelationConfigValue, limit: 1 } : selectedRelationConfigValue,1029 tableAlias: relationTableAlias,1030 joinOn: joinOn2,1031 nestedQueryRelation: relation1032 });1033 const field = import_sql2.sql`${import_sql2.sql.identifier(relationTableAlias)}.${import_sql2.sql.identifier("data")}`.as(selectedRelationTsKey);1034 joins.push({1035 on: import_sql2.sql`true`,1036 table: new import_subquery.Subquery(builtRelation.sql, {}, relationTableAlias),1037 alias: relationTableAlias,1038 joinType: "left",1039 lateral: true1040 });1041 selection.push({1042 dbKey: selectedRelationTsKey,1043 tsKey: selectedRelationTsKey,1044 field,1045 relationTableTsKey: relationTableTsName,1046 isJson: true,1047 selection: builtRelation.selection1048 });1049 }1050 }1051 if (selection.length === 0) {1052 throw new import_errors.DrizzleError({ message: `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")` });1053 }1054 let result;1055 where = (0, import_sql.and)(joinOn, where);1056 if (nestedQueryRelation) {1057 let field = import_sql2.sql`json_build_array(${import_sql2.sql.join(1058 selection.map(1059 ({ field: field2, tsKey, isJson }) => isJson ? import_sql2.sql`${import_sql2.sql.identifier(`${tableAlias}_${tsKey}`)}.${import_sql2.sql.identifier("data")}` : (0, import_entity.is)(field2, import_sql2.SQL.Aliased) ? field2.sql : field21060 ),1061 import_sql2.sql`, `1062 )})`;1063 if ((0, import_entity.is)(nestedQueryRelation, import_relations.Many)) {1064 field = import_sql2.sql`coalesce(json_agg(${field}${orderBy.length > 0 ? import_sql2.sql` order by ${import_sql2.sql.join(orderBy, import_sql2.sql`, `)}` : void 0}), '[]'::json)`;1065 }1066 const nestedSelection = [{1067 dbKey: "data",1068 tsKey: "data",1069 field: field.as("data"),1070 isJson: true,1071 relationTableTsKey: tableConfig.tsName,1072 selection1073 }];1074 const needsSubquery = limit !== void 0 || offset !== void 0 || orderBy.length > 0;1075 if (needsSubquery) {1076 result = this.buildSelectQuery({1077 table: (0, import_alias.aliasedTable)(table, tableAlias),1078 fields: {},1079 fieldsFlat: [{1080 path: [],1081 field: import_sql2.sql.raw("*")1082 }],1083 where,1084 limit,1085 offset,1086 orderBy,1087 setOperators: []1088 });1089 where = void 0;1090 limit = void 0;1091 offset = void 0;1092 orderBy = [];1093 } else {1094 result = (0, import_alias.aliasedTable)(table, tableAlias);1095 }1096 result = this.buildSelectQuery({1097 table: (0, import_entity.is)(result, import_table.GelTable) ? result : new import_subquery.Subquery(result, {}, tableAlias),1098 fields: {},1099 fieldsFlat: nestedSelection.map(({ field: field2 }) => ({1100 path: [],1101 field: (0, import_entity.is)(field2, import_column.Column) ? (0, import_alias.aliasedTableColumn)(field2, tableAlias) : field21102 })),1103 joins,1104 where,1105 limit,1106 offset,1107 orderBy,1108 setOperators: []1109 });1110 } else {1111 result = this.buildSelectQuery({1112 table: (0, import_alias.aliasedTable)(table, tableAlias),1113 fields: {},1114 fieldsFlat: selection.map(({ field }) => ({1115 path: [],1116 field: (0, import_entity.is)(field, import_column.Column) ? (0, import_alias.aliasedTableColumn)(field, tableAlias) : field1117 })),1118 joins,1119 where,1120 limit,1121 offset,1122 orderBy,1123 setOperators: []1124 });1125 }1126 return {1127 tableTsKey: tableConfig.tsName,1128 sql: result,1129 selection1130 };1131 }1132}1133// Annotate the CommonJS export names for ESM import in node:11340 && (module.exports = {1135 GelDialect1136});1137//# sourceMappingURL=dialect.cjs.map