drizzle-orm 0.27.2 → 0.27.3-0ea6f8c
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/{alias-3e926a50.mjs → alias-340e2b86.mjs} +787 -317
- package/alias-340e2b86.mjs.map +1 -0
- package/{alias-72a4082c.cjs → alias-ac8392a9.cjs} +998 -519
- package/alias-ac8392a9.cjs.map +1 -0
- package/aws-data-api/pg/index.cjs +1 -1
- package/aws-data-api/pg/index.d.ts +4 -4
- package/aws-data-api/pg/index.mjs +2 -3
- package/aws-data-api/pg/index.mjs.map +1 -1
- package/aws-data-api/pg/migrator.d.ts +4 -4
- package/better-sqlite3/index.cjs +2 -2
- package/better-sqlite3/index.d.ts +5 -5
- package/better-sqlite3/index.mjs +2 -3
- package/better-sqlite3/index.mjs.map +1 -1
- package/better-sqlite3/migrator.d.ts +5 -5
- package/bun-sqlite/index.cjs +2 -2
- package/bun-sqlite/index.d.ts +5 -5
- package/bun-sqlite/index.mjs +2 -3
- package/bun-sqlite/index.mjs.map +1 -1
- package/bun-sqlite/migrator.d.ts +5 -5
- package/{column.d-aa4e525d.d.ts → column.d-9d74a4f3.d.ts} +26 -3
- package/d1/index.cjs +2 -2
- package/d1/index.d.ts +5 -5
- package/d1/index.mjs +2 -3
- package/d1/index.mjs.map +1 -1
- package/d1/migrator.d.ts +5 -5
- package/{db.d-b9835153.d.ts → db.d-3ed1a275.d.ts} +21 -10
- package/{db.d-b5fdf746.d.ts → db.d-62505c51.d.ts} +78 -68
- package/{driver.d-449d310e.d.ts → driver.d-017ff9a0.d.ts} +2 -2
- package/{driver.d-f4e534d3.d.ts → driver.d-0da678d1.d.ts} +2 -2
- package/{driver.d-a56977fa.d.ts → driver.d-59cd0f1f.d.ts} +2 -2
- package/{driver.d-1c9fcc75.d.ts → driver.d-78251db9.d.ts} +2 -2
- package/{driver.d-8cc7ee94.d.ts → driver.d-f762f8b3.d.ts} +2 -2
- package/{driver.d-72edf0bc.d.ts → driver.d-fb46a1a6.d.ts} +2 -2
- package/index.cjs +1 -1
- package/index.d.ts +4 -4
- package/index.mjs +2 -3
- package/index.mjs.map +1 -1
- package/knex/index.d.ts +1 -1
- package/kysely/index.d.ts +1 -1
- package/libsql/index.cjs +2 -2
- package/libsql/index.d.ts +5 -5
- package/libsql/index.mjs +2 -3
- package/libsql/index.mjs.map +1 -1
- package/libsql/migrator.d.ts +5 -5
- package/mysql-core/index.cjs +3 -2
- package/mysql-core/index.cjs.map +1 -1
- package/mysql-core/index.d.ts +5 -5
- package/mysql-core/index.mjs +3 -4
- package/mysql-core/index.mjs.map +1 -1
- package/mysql2/index.cjs +6 -5
- package/mysql2/index.cjs.map +1 -1
- package/mysql2/index.d.ts +11 -6
- package/mysql2/index.mjs +7 -6
- package/mysql2/index.mjs.map +1 -1
- package/mysql2/migrator.d.ts +4 -4
- package/neon-http/index.cjs +1 -1
- package/neon-http/index.d.ts +4 -4
- package/neon-http/index.mjs +2 -3
- package/neon-http/index.mjs.map +1 -1
- package/neon-http/migrator.cjs +1 -1
- package/neon-http/migrator.d.ts +4 -4
- package/neon-http/migrator.mjs +1 -1
- package/neon-serverless/index.cjs +1 -1
- package/neon-serverless/index.d.ts +4 -4
- package/neon-serverless/index.mjs +2 -3
- package/neon-serverless/index.mjs.map +1 -1
- package/neon-serverless/migrator.d.ts +4 -4
- package/node-postgres/index.cjs +1 -1
- package/node-postgres/index.d.ts +4 -4
- package/node-postgres/index.mjs +2 -3
- package/node-postgres/index.mjs.map +1 -1
- package/node-postgres/migrator.d.ts +4 -4
- package/package.json +1 -1
- package/pg-core/index.cjs +1 -1
- package/pg-core/index.d.ts +5 -5
- package/pg-core/index.mjs +3 -4
- package/pg-core/index.mjs.map +1 -1
- package/planetscale-serverless/index.cjs +6 -3
- package/planetscale-serverless/index.cjs.map +1 -1
- package/planetscale-serverless/index.d.ts +5 -4
- package/planetscale-serverless/index.mjs +6 -4
- package/planetscale-serverless/index.mjs.map +1 -1
- package/planetscale-serverless/migrator.d.ts +4 -4
- package/postgres-js/index.cjs +1 -1
- package/postgres-js/index.d.ts +4 -4
- package/postgres-js/index.mjs +2 -3
- package/postgres-js/index.mjs.map +1 -1
- package/postgres-js/migrator.d.ts +4 -4
- package/{query-promise.d-0dd411fc.d.ts → query-promise.d-b3e74091.d.ts} +10 -9
- package/{select.types.d-eff54486.d.ts → select.types.d-1ea8ee3b.d.ts} +1 -1
- package/{select.types.d-b947a018.d.ts → select.types.d-4b3b7da7.d.ts} +38 -13
- package/{session-5f9eaf6b.cjs → session-3188d735.cjs} +479 -278
- package/session-3188d735.cjs.map +1 -0
- package/{session-60cba450.cjs → session-4db53655.cjs} +1387 -1413
- package/session-4db53655.cjs.map +1 -0
- package/{session-2062e9e6.mjs → session-7085e47f.mjs} +31 -4
- package/session-7085e47f.mjs.map +1 -0
- package/{session-9628aea0.mjs → session-7e5d9b73.mjs} +481 -279
- package/session-7e5d9b73.mjs.map +1 -0
- package/{session-8302855c.mjs → session-adcd857f.mjs} +399 -269
- package/session-adcd857f.mjs.map +1 -0
- package/sql-js/index.cjs +2 -2
- package/sql-js/index.d.ts +5 -5
- package/sql-js/index.mjs +2 -3
- package/sql-js/index.mjs.map +1 -1
- package/sql-js/migrator.d.ts +5 -5
- package/sqlite-core/index.cjs +2 -2
- package/sqlite-core/index.d.ts +5 -5
- package/sqlite-core/index.mjs +36 -194
- package/sqlite-core/index.mjs.map +1 -1
- package/sqlite-proxy/index.cjs +2 -2
- package/sqlite-proxy/index.d.ts +6 -6
- package/sqlite-proxy/index.mjs +2 -3
- package/sqlite-proxy/index.mjs.map +1 -1
- package/sqlite-proxy/migrator.cjs +1 -1
- package/sqlite-proxy/migrator.d.ts +5 -5
- package/sqlite-proxy/migrator.mjs +1 -1
- package/vercel-postgres/index.cjs +1 -1
- package/vercel-postgres/index.d.ts +4 -4
- package/vercel-postgres/index.mjs +2 -3
- package/vercel-postgres/index.mjs.map +1 -1
- package/vercel-postgres/migrator.d.ts +4 -4
- package/version.cjs +1 -1
- package/version.d.ts +1 -1
- package/version.mjs +1 -1
- package/alias-3e926a50.mjs.map +0 -1
- package/alias-72a4082c.cjs.map +0 -1
- package/errors-fed11085.mjs +0 -23
- package/errors-fed11085.mjs.map +0 -1
- package/session-2062e9e6.mjs.map +0 -1
- package/session-5f9eaf6b.cjs.map +0 -1
- package/session-60cba450.cjs.map +0 -1
- package/session-8302855c.mjs.map +0 -1
- package/session-9628aea0.mjs.map +0 -1
|
@@ -646,6 +646,25 @@ const tracer = {
|
|
|
646
646
|
},
|
|
647
647
|
};
|
|
648
648
|
|
|
649
|
+
class DrizzleError extends Error {
|
|
650
|
+
static [entityKind] = 'DrizzleError';
|
|
651
|
+
constructor(message) {
|
|
652
|
+
super(message);
|
|
653
|
+
this.name = 'DrizzleError';
|
|
654
|
+
}
|
|
655
|
+
static wrap(error, message) {
|
|
656
|
+
return error instanceof Error // eslint-disable-line no-instanceof/no-instanceof
|
|
657
|
+
? new DrizzleError(message ? `${message}: ${error.message}` : error.message)
|
|
658
|
+
: new DrizzleError(message ?? String(error));
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
class TransactionRollbackError extends DrizzleError {
|
|
662
|
+
static [entityKind] = 'TransactionRollbackError';
|
|
663
|
+
constructor() {
|
|
664
|
+
super('Rollback');
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
649
668
|
class PgDialect {
|
|
650
669
|
static [entityKind] = 'PgDialect';
|
|
651
670
|
async migrate(migrations, session) {
|
|
@@ -691,10 +710,10 @@ class PgDialect {
|
|
|
691
710
|
buildUpdateSet(table, set) {
|
|
692
711
|
const setEntries = Object.entries(set);
|
|
693
712
|
const setSize = setEntries.length;
|
|
694
|
-
return sql.
|
|
713
|
+
return sql.join(setEntries
|
|
695
714
|
.flatMap(([colName, value], i) => {
|
|
696
715
|
const col = table[Table.Symbol.Columns][colName];
|
|
697
|
-
const res = sql `${
|
|
716
|
+
const res = sql `${sql.identifier(col.name)} = ${value}`;
|
|
698
717
|
if (i < setSize - 1) {
|
|
699
718
|
return [res, sql.raw(', ')];
|
|
700
719
|
}
|
|
@@ -733,7 +752,7 @@ class PgDialect {
|
|
|
733
752
|
if (isSingleTable) {
|
|
734
753
|
chunk.push(new SQL(query.queryChunks.map((c) => {
|
|
735
754
|
if (is(c, PgColumn)) {
|
|
736
|
-
return
|
|
755
|
+
return sql.identifier(c.name);
|
|
737
756
|
}
|
|
738
757
|
return c;
|
|
739
758
|
})));
|
|
@@ -758,7 +777,7 @@ class PgDialect {
|
|
|
758
777
|
}
|
|
759
778
|
return chunk;
|
|
760
779
|
});
|
|
761
|
-
return sql.
|
|
780
|
+
return sql.join(chunks);
|
|
762
781
|
}
|
|
763
782
|
buildSelectQuery({ withList, fields, fieldsFlat, where, having, table, joins, orderBy, groupBy, limit, offset, lockingClauses, distinct, }) {
|
|
764
783
|
const fieldsList = fieldsFlat ?? orderSelectedFields(fields);
|
|
@@ -772,23 +791,23 @@ class PgDialect {
|
|
|
772
791
|
: is(table, SQL)
|
|
773
792
|
? undefined
|
|
774
793
|
: getTableName(table))
|
|
775
|
-
&& !((table) => joins
|
|
794
|
+
&& !((table) => joins?.some(({ alias }) => alias === (table[Table.Symbol.IsAlias] ? getTableName(table) : table[Table.Symbol.BaseName])))(f.field.table)) {
|
|
776
795
|
const tableName = getTableName(f.field.table);
|
|
777
796
|
throw new Error(`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?`);
|
|
778
797
|
}
|
|
779
798
|
}
|
|
780
|
-
const isSingleTable = joins.length === 0;
|
|
799
|
+
const isSingleTable = !joins || joins.length === 0;
|
|
781
800
|
let withSql;
|
|
782
801
|
if (withList?.length) {
|
|
783
802
|
const withSqlChunks = [sql `with `];
|
|
784
803
|
for (const [i, w] of withList.entries()) {
|
|
785
|
-
withSqlChunks.push(sql `${
|
|
804
|
+
withSqlChunks.push(sql `${sql.identifier(w[SubqueryConfig].alias)} as (${w[SubqueryConfig].sql})`);
|
|
786
805
|
if (i < withList.length - 1) {
|
|
787
806
|
withSqlChunks.push(sql `, `);
|
|
788
807
|
}
|
|
789
808
|
}
|
|
790
809
|
withSqlChunks.push(sql ` `);
|
|
791
|
-
withSql = sql.
|
|
810
|
+
withSql = sql.join(withSqlChunks);
|
|
792
811
|
}
|
|
793
812
|
let distinctSql;
|
|
794
813
|
if (distinct) {
|
|
@@ -806,59 +825,63 @@ class PgDialect {
|
|
|
806
825
|
return table;
|
|
807
826
|
})();
|
|
808
827
|
const joinsArray = [];
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
828
|
+
if (joins) {
|
|
829
|
+
for (const [index, joinMeta] of joins.entries()) {
|
|
830
|
+
if (index === 0) {
|
|
831
|
+
joinsArray.push(sql ` `);
|
|
832
|
+
}
|
|
833
|
+
const table = joinMeta.table;
|
|
834
|
+
const lateralSql = joinMeta.lateral ? sql ` lateral` : undefined;
|
|
835
|
+
if (is(table, PgTable)) {
|
|
836
|
+
const tableName = table[PgTable.Symbol.Name];
|
|
837
|
+
const tableSchema = table[PgTable.Symbol.Schema];
|
|
838
|
+
const origTableName = table[PgTable.Symbol.OriginalName];
|
|
839
|
+
const alias = tableName === origTableName ? undefined : joinMeta.alias;
|
|
840
|
+
joinsArray.push(sql `${sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql `${sql.identifier(tableSchema)}.` : undefined}${sql.identifier(origTableName)}${alias && sql ` ${sql.identifier(alias)}`} on ${joinMeta.on}`);
|
|
841
|
+
}
|
|
842
|
+
else if (is(table, View)) {
|
|
843
|
+
const viewName = table[ViewBaseConfig].name;
|
|
844
|
+
const viewSchema = table[ViewBaseConfig].schema;
|
|
845
|
+
const origViewName = table[ViewBaseConfig].originalName;
|
|
846
|
+
const alias = viewName === origViewName ? undefined : joinMeta.alias;
|
|
847
|
+
joinsArray.push(sql `${sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql `${sql.identifier(viewSchema)}.` : undefined}${sql.identifier(origViewName)}${alias && sql ` ${sql.identifier(alias)}`} on ${joinMeta.on}`);
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
joinsArray.push(sql `${sql.raw(joinMeta.joinType)} join${lateralSql} ${table} on ${joinMeta.on}`);
|
|
851
|
+
}
|
|
852
|
+
if (index < joins.length - 1) {
|
|
853
|
+
joinsArray.push(sql ` `);
|
|
854
|
+
}
|
|
826
855
|
}
|
|
827
856
|
}
|
|
828
|
-
const joinsSql = sql.
|
|
857
|
+
const joinsSql = sql.join(joinsArray);
|
|
829
858
|
const whereSql = where ? sql ` where ${where}` : undefined;
|
|
830
859
|
const havingSql = having ? sql ` having ${having}` : undefined;
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
if (index < orderBy.length - 1) {
|
|
835
|
-
orderByList.push(sql `, `);
|
|
836
|
-
}
|
|
860
|
+
let orderBySql;
|
|
861
|
+
if (orderBy && orderBy.length > 0) {
|
|
862
|
+
orderBySql = sql ` order by ${sql.join(orderBy, sql `, `)}`;
|
|
837
863
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
groupByList.push(groupByValue);
|
|
842
|
-
if (index < groupBy.length - 1) {
|
|
843
|
-
groupByList.push(sql `, `);
|
|
844
|
-
}
|
|
864
|
+
let groupBySql;
|
|
865
|
+
if (groupBy && groupBy.length > 0) {
|
|
866
|
+
groupBySql = sql ` group by ${sql.join(groupBy, sql `, `)}`;
|
|
845
867
|
}
|
|
846
|
-
const groupBySql = groupByList.length > 0 ? sql ` group by ${sql.fromList(groupByList)}` : undefined;
|
|
847
868
|
const limitSql = limit ? sql ` limit ${limit}` : undefined;
|
|
848
869
|
const offsetSql = offset ? sql ` offset ${offset}` : undefined;
|
|
849
870
|
const lockingClausesSql = sql.empty();
|
|
850
|
-
|
|
851
|
-
const
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
871
|
+
if (lockingClauses) {
|
|
872
|
+
for (const { strength, config } of lockingClauses) {
|
|
873
|
+
const clauseSql = sql ` for ${sql.raw(strength)}`;
|
|
874
|
+
if (config.of) {
|
|
875
|
+
clauseSql.append(sql ` of ${config.of}`);
|
|
876
|
+
}
|
|
877
|
+
if (config.noWait) {
|
|
878
|
+
clauseSql.append(sql ` no wait`);
|
|
879
|
+
}
|
|
880
|
+
else if (config.skipLocked) {
|
|
881
|
+
clauseSql.append(sql ` skip locked`);
|
|
882
|
+
}
|
|
883
|
+
lockingClausesSql.append(clauseSql);
|
|
860
884
|
}
|
|
861
|
-
lockingClausesSql.append(clauseSql);
|
|
862
885
|
}
|
|
863
886
|
return sql `${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClausesSql}`;
|
|
864
887
|
}
|
|
@@ -869,7 +892,7 @@ class PgDialect {
|
|
|
869
892
|
const colEntries = isSingleValue
|
|
870
893
|
? Object.keys(values[0]).map((fieldName) => [fieldName, columns[fieldName]])
|
|
871
894
|
: Object.entries(columns);
|
|
872
|
-
const insertOrder = colEntries.map(([, column]) =>
|
|
895
|
+
const insertOrder = colEntries.map(([, column]) => sql.identifier(column.name));
|
|
873
896
|
for (const [valueIndex, value] of values.entries()) {
|
|
874
897
|
const valueList = [];
|
|
875
898
|
for (const [fieldName] of colEntries) {
|
|
@@ -886,7 +909,7 @@ class PgDialect {
|
|
|
886
909
|
valuesSqlList.push(sql `, `);
|
|
887
910
|
}
|
|
888
911
|
}
|
|
889
|
-
const valuesSql = sql.
|
|
912
|
+
const valuesSql = sql.join(valuesSqlList);
|
|
890
913
|
const returningSql = returning
|
|
891
914
|
? sql ` returning ${this.buildSelection(returning, { isSingleTable: true })}`
|
|
892
915
|
: undefined;
|
|
@@ -929,273 +952,702 @@ class PgDialect {
|
|
|
929
952
|
prepareTyping: this.prepareTyping,
|
|
930
953
|
});
|
|
931
954
|
}
|
|
932
|
-
|
|
955
|
+
// buildRelationalQueryWithPK({
|
|
956
|
+
// fullSchema,
|
|
957
|
+
// schema,
|
|
958
|
+
// tableNamesMap,
|
|
959
|
+
// table,
|
|
960
|
+
// tableConfig,
|
|
961
|
+
// queryConfig: config,
|
|
962
|
+
// tableAlias,
|
|
963
|
+
// isRoot = false,
|
|
964
|
+
// joinOn,
|
|
965
|
+
// }: {
|
|
966
|
+
// fullSchema: Record<string, unknown>;
|
|
967
|
+
// schema: TablesRelationalConfig;
|
|
968
|
+
// tableNamesMap: Record<string, string>;
|
|
969
|
+
// table: AnyPgTable;
|
|
970
|
+
// tableConfig: TableRelationalConfig;
|
|
971
|
+
// queryConfig: true | DBQueryConfig<'many', true>;
|
|
972
|
+
// tableAlias: string;
|
|
973
|
+
// isRoot?: boolean;
|
|
974
|
+
// joinOn?: SQL;
|
|
975
|
+
// }): BuildRelationalQueryResult<AnyPgTable, AnyPgColumn> {
|
|
976
|
+
// // For { "<relation>": true }, return a table with selection of all columns
|
|
977
|
+
// if (config === true) {
|
|
978
|
+
// const selectionEntries = Object.entries(tableConfig.columns);
|
|
979
|
+
// const selection: BuildRelationalQueryResult<AnyPgTable, AnyPgColumn>['selection'] = selectionEntries.map((
|
|
980
|
+
// [key, value],
|
|
981
|
+
// ) => ({
|
|
982
|
+
// dbKey: value.name,
|
|
983
|
+
// tsKey: key,
|
|
984
|
+
// field: value as AnyPgColumn,
|
|
985
|
+
// relationTableTsKey: undefined,
|
|
986
|
+
// isJson: false,
|
|
987
|
+
// selection: [],
|
|
988
|
+
// }));
|
|
989
|
+
// return {
|
|
990
|
+
// tableTsKey: tableConfig.tsName,
|
|
991
|
+
// sql: table,
|
|
992
|
+
// selection,
|
|
993
|
+
// };
|
|
994
|
+
// }
|
|
995
|
+
// // let selection: BuildRelationalQueryResult<AnyPgTable, AnyPgColumn>['selection'] = [];
|
|
996
|
+
// // let selectionForBuild = selection;
|
|
997
|
+
// const aliasedColumns = Object.fromEntries(
|
|
998
|
+
// Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]),
|
|
999
|
+
// );
|
|
1000
|
+
// const aliasedRelations = Object.fromEntries(
|
|
1001
|
+
// Object.entries(tableConfig.relations).map(([key, value]) => [key, aliasedRelation(value, tableAlias)]),
|
|
1002
|
+
// );
|
|
1003
|
+
// const aliasedFields = Object.assign({}, aliasedColumns, aliasedRelations);
|
|
1004
|
+
// let where, hasUserDefinedWhere;
|
|
1005
|
+
// if (config.where) {
|
|
1006
|
+
// const whereSql = typeof config.where === 'function' ? config.where(aliasedFields, operators) : config.where;
|
|
1007
|
+
// where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
|
|
1008
|
+
// hasUserDefinedWhere = !!where;
|
|
1009
|
+
// }
|
|
1010
|
+
// where = and(joinOn, where);
|
|
1011
|
+
// // const fieldsSelection: { tsKey: string; value: AnyPgColumn | SQL.Aliased; isExtra?: boolean }[] = [];
|
|
1012
|
+
// let joins: Join[] = [];
|
|
1013
|
+
// let selectedColumns: string[] = [];
|
|
1014
|
+
// // Figure out which columns to select
|
|
1015
|
+
// if (config.columns) {
|
|
1016
|
+
// let isIncludeMode = false;
|
|
1017
|
+
// for (const [field, value] of Object.entries(config.columns)) {
|
|
1018
|
+
// if (value === undefined) {
|
|
1019
|
+
// continue;
|
|
1020
|
+
// }
|
|
1021
|
+
// if (field in tableConfig.columns) {
|
|
1022
|
+
// if (!isIncludeMode && value === true) {
|
|
1023
|
+
// isIncludeMode = true;
|
|
1024
|
+
// }
|
|
1025
|
+
// selectedColumns.push(field);
|
|
1026
|
+
// }
|
|
1027
|
+
// }
|
|
1028
|
+
// if (selectedColumns.length > 0) {
|
|
1029
|
+
// selectedColumns = isIncludeMode
|
|
1030
|
+
// ? selectedColumns.filter((c) => config.columns?.[c] === true)
|
|
1031
|
+
// : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
|
|
1032
|
+
// }
|
|
1033
|
+
// } else {
|
|
1034
|
+
// // Select all columns if selection is not specified
|
|
1035
|
+
// selectedColumns = Object.keys(tableConfig.columns);
|
|
1036
|
+
// }
|
|
1037
|
+
// // for (const field of selectedColumns) {
|
|
1038
|
+
// // const column = tableConfig.columns[field]! as AnyPgColumn;
|
|
1039
|
+
// // fieldsSelection.push({ tsKey: field, value: column });
|
|
1040
|
+
// // }
|
|
1041
|
+
// let initiallySelectedRelations: {
|
|
1042
|
+
// tsKey: string;
|
|
1043
|
+
// queryConfig: true | DBQueryConfig<'many', false>;
|
|
1044
|
+
// relation: Relation;
|
|
1045
|
+
// }[] = [];
|
|
1046
|
+
// // let selectedRelations: BuildRelationalQueryResult<AnyPgTable, AnyPgColumn>['selection'] = [];
|
|
1047
|
+
// // Figure out which relations to select
|
|
1048
|
+
// if (config.with) {
|
|
1049
|
+
// initiallySelectedRelations = Object.entries(config.with)
|
|
1050
|
+
// .filter((entry): entry is [typeof entry[0], NonNullable<typeof entry[1]>] => !!entry[1])
|
|
1051
|
+
// .map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey]! }));
|
|
1052
|
+
// }
|
|
1053
|
+
// const manyRelations = initiallySelectedRelations.filter((r) =>
|
|
1054
|
+
// is(r.relation, Many)
|
|
1055
|
+
// && (schema[tableNamesMap[r.relation.referencedTable[Table.Symbol.Name]]!]?.primaryKey.length ?? 0) > 0
|
|
1056
|
+
// );
|
|
1057
|
+
// // If this is the last Many relation (or there are no Many relations), we are on the innermost subquery level
|
|
1058
|
+
// const isInnermostQuery = manyRelations.length < 2;
|
|
1059
|
+
// const selectedExtras: {
|
|
1060
|
+
// tsKey: string;
|
|
1061
|
+
// value: SQL.Aliased;
|
|
1062
|
+
// }[] = [];
|
|
1063
|
+
// // Figure out which extras to select
|
|
1064
|
+
// if (isInnermostQuery && config.extras) {
|
|
1065
|
+
// const extras = typeof config.extras === 'function'
|
|
1066
|
+
// ? config.extras(aliasedFields, { sql })
|
|
1067
|
+
// : config.extras;
|
|
1068
|
+
// for (const [tsKey, value] of Object.entries(extras)) {
|
|
1069
|
+
// selectedExtras.push({
|
|
1070
|
+
// tsKey,
|
|
1071
|
+
// value: mapColumnsInAliasedSQLToAlias(value, tableAlias),
|
|
1072
|
+
// });
|
|
1073
|
+
// }
|
|
1074
|
+
// }
|
|
1075
|
+
// // Transform `fieldsSelection` into `selection`
|
|
1076
|
+
// // `fieldsSelection` shouldn't be used after this point
|
|
1077
|
+
// // for (const { tsKey, value, isExtra } of fieldsSelection) {
|
|
1078
|
+
// // selection.push({
|
|
1079
|
+
// // dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey]!.name,
|
|
1080
|
+
// // tsKey,
|
|
1081
|
+
// // field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,
|
|
1082
|
+
// // relationTableTsKey: undefined,
|
|
1083
|
+
// // isJson: false,
|
|
1084
|
+
// // isExtra,
|
|
1085
|
+
// // selection: [],
|
|
1086
|
+
// // });
|
|
1087
|
+
// // }
|
|
1088
|
+
// let orderByOrig = typeof config.orderBy === 'function'
|
|
1089
|
+
// ? config.orderBy(aliasedFields, orderByOperators)
|
|
1090
|
+
// : config.orderBy ?? [];
|
|
1091
|
+
// if (!Array.isArray(orderByOrig)) {
|
|
1092
|
+
// orderByOrig = [orderByOrig];
|
|
1093
|
+
// }
|
|
1094
|
+
// const orderBy = orderByOrig.map((orderByValue) => {
|
|
1095
|
+
// if (is(orderByValue, Column)) {
|
|
1096
|
+
// return aliasedTableColumn(orderByValue, tableAlias) as AnyPgColumn;
|
|
1097
|
+
// }
|
|
1098
|
+
// return mapColumnsInSQLToAlias(orderByValue, tableAlias);
|
|
1099
|
+
// });
|
|
1100
|
+
// const limit = isInnermostQuery ? config.limit : undefined;
|
|
1101
|
+
// const offset = isInnermostQuery ? config.offset : undefined;
|
|
1102
|
+
// // For non-root queries without additional config except columns, return a table with selection
|
|
1103
|
+
// if (
|
|
1104
|
+
// !isRoot
|
|
1105
|
+
// && initiallySelectedRelations.length === 0
|
|
1106
|
+
// && selectedExtras.length === 0
|
|
1107
|
+
// && !where
|
|
1108
|
+
// && orderBy.length === 0
|
|
1109
|
+
// && limit === undefined
|
|
1110
|
+
// && offset === undefined
|
|
1111
|
+
// ) {
|
|
1112
|
+
// return {
|
|
1113
|
+
// tableTsKey: tableConfig.tsName,
|
|
1114
|
+
// sql: table,
|
|
1115
|
+
// selection: selectedColumns.map((key) => ({
|
|
1116
|
+
// dbKey: tableConfig.columns[key]!.name,
|
|
1117
|
+
// tsKey: key,
|
|
1118
|
+
// field: tableConfig.columns[key] as AnyPgColumn,
|
|
1119
|
+
// relationTableTsKey: undefined,
|
|
1120
|
+
// isJson: false,
|
|
1121
|
+
// selection: [],
|
|
1122
|
+
// })),
|
|
1123
|
+
// };
|
|
1124
|
+
// }
|
|
1125
|
+
// const selectedRelationsWithoutPK:
|
|
1126
|
+
// // Process all relations without primary keys, because they need to be joined differently and will all be on the same query level
|
|
1127
|
+
// for (
|
|
1128
|
+
// const {
|
|
1129
|
+
// tsKey: selectedRelationTsKey,
|
|
1130
|
+
// queryConfig: selectedRelationConfigValue,
|
|
1131
|
+
// relation,
|
|
1132
|
+
// } of initiallySelectedRelations
|
|
1133
|
+
// ) {
|
|
1134
|
+
// const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
|
|
1135
|
+
// const relationTableName = relation.referencedTable[Table.Symbol.Name];
|
|
1136
|
+
// const relationTableTsName = tableNamesMap[relationTableName]!;
|
|
1137
|
+
// const relationTable = schema[relationTableTsName]!;
|
|
1138
|
+
// if (relationTable.primaryKey.length > 0) {
|
|
1139
|
+
// continue;
|
|
1140
|
+
// }
|
|
1141
|
+
// const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
|
|
1142
|
+
// const joinOn = and(
|
|
1143
|
+
// ...normalizedRelation.fields.map((field, i) =>
|
|
1144
|
+
// eq(
|
|
1145
|
+
// aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
|
|
1146
|
+
// aliasedTableColumn(field, tableAlias),
|
|
1147
|
+
// )
|
|
1148
|
+
// ),
|
|
1149
|
+
// );
|
|
1150
|
+
// const builtRelation = this.buildRelationalQueryWithoutPK({
|
|
1151
|
+
// fullSchema,
|
|
1152
|
+
// schema,
|
|
1153
|
+
// tableNamesMap,
|
|
1154
|
+
// table: fullSchema[relationTableTsName] as AnyPgTable,
|
|
1155
|
+
// tableConfig: schema[relationTableTsName]!,
|
|
1156
|
+
// queryConfig: selectedRelationConfigValue,
|
|
1157
|
+
// tableAlias: relationTableAlias,
|
|
1158
|
+
// joinOn,
|
|
1159
|
+
// nestedQueryRelation: relation,
|
|
1160
|
+
// });
|
|
1161
|
+
// const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey);
|
|
1162
|
+
// joins.push({
|
|
1163
|
+
// on: sql`true`,
|
|
1164
|
+
// table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias),
|
|
1165
|
+
// alias: relationTableAlias,
|
|
1166
|
+
// joinType: 'left',
|
|
1167
|
+
// lateral: true,
|
|
1168
|
+
// });
|
|
1169
|
+
// selectedRelations.push({
|
|
1170
|
+
// dbKey: selectedRelationTsKey,
|
|
1171
|
+
// tsKey: selectedRelationTsKey,
|
|
1172
|
+
// field,
|
|
1173
|
+
// relationTableTsKey: relationTableTsName,
|
|
1174
|
+
// isJson: true,
|
|
1175
|
+
// selection: builtRelation.selection,
|
|
1176
|
+
// });
|
|
1177
|
+
// }
|
|
1178
|
+
// const oneRelations = initiallySelectedRelations.filter((r): r is typeof r & { relation: One } =>
|
|
1179
|
+
// is(r.relation, One)
|
|
1180
|
+
// );
|
|
1181
|
+
// // Process all One relations with PKs, because they can all be joined on the same level
|
|
1182
|
+
// for (
|
|
1183
|
+
// const {
|
|
1184
|
+
// tsKey: selectedRelationTsKey,
|
|
1185
|
+
// queryConfig: selectedRelationConfigValue,
|
|
1186
|
+
// relation,
|
|
1187
|
+
// } of oneRelations
|
|
1188
|
+
// ) {
|
|
1189
|
+
// const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
|
|
1190
|
+
// const relationTableName = relation.referencedTable[Table.Symbol.Name];
|
|
1191
|
+
// const relationTableTsName = tableNamesMap[relationTableName]!;
|
|
1192
|
+
// const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
|
|
1193
|
+
// const relationTable = schema[relationTableTsName]!;
|
|
1194
|
+
// if (relationTable.primaryKey.length === 0) {
|
|
1195
|
+
// continue;
|
|
1196
|
+
// }
|
|
1197
|
+
// const joinOn = and(
|
|
1198
|
+
// ...normalizedRelation.fields.map((field, i) =>
|
|
1199
|
+
// eq(
|
|
1200
|
+
// aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
|
|
1201
|
+
// aliasedTableColumn(field, tableAlias),
|
|
1202
|
+
// )
|
|
1203
|
+
// ),
|
|
1204
|
+
// );
|
|
1205
|
+
// const builtRelation = this.buildRelationalQueryWithPK({
|
|
1206
|
+
// fullSchema,
|
|
1207
|
+
// schema,
|
|
1208
|
+
// tableNamesMap,
|
|
1209
|
+
// table: fullSchema[relationTableTsName] as AnyPgTable,
|
|
1210
|
+
// tableConfig: schema[relationTableTsName]!,
|
|
1211
|
+
// queryConfig: selectedRelationConfigValue,
|
|
1212
|
+
// tableAlias: relationTableAlias,
|
|
1213
|
+
// joinOn,
|
|
1214
|
+
// });
|
|
1215
|
+
// const field = sql`case when ${sql.identifier(relationTableAlias)} is null then null else json_build_array(${
|
|
1216
|
+
// sql.join(
|
|
1217
|
+
// builtRelation.selection.map(({ field }) =>
|
|
1218
|
+
// is(field, SQL.Aliased)
|
|
1219
|
+
// ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`
|
|
1220
|
+
// : is(field, Column)
|
|
1221
|
+
// ? aliasedTableColumn(field, relationTableAlias)
|
|
1222
|
+
// : field
|
|
1223
|
+
// ),
|
|
1224
|
+
// sql`, `,
|
|
1225
|
+
// )
|
|
1226
|
+
// }) end`.as(selectedRelationTsKey);
|
|
1227
|
+
// const isLateralJoin = is(builtRelation.sql, SQL);
|
|
1228
|
+
// joins.push({
|
|
1229
|
+
// on: isLateralJoin ? sql`true` : joinOn,
|
|
1230
|
+
// table: is(builtRelation.sql, SQL)
|
|
1231
|
+
// ? new Subquery(builtRelation.sql, {}, relationTableAlias)
|
|
1232
|
+
// : aliasedTable(builtRelation.sql, relationTableAlias),
|
|
1233
|
+
// alias: relationTableAlias,
|
|
1234
|
+
// joinType: 'left',
|
|
1235
|
+
// lateral: is(builtRelation.sql, SQL),
|
|
1236
|
+
// });
|
|
1237
|
+
// selectedRelations.push({
|
|
1238
|
+
// dbKey: selectedRelationTsKey,
|
|
1239
|
+
// tsKey: selectedRelationTsKey,
|
|
1240
|
+
// field,
|
|
1241
|
+
// relationTableTsKey: relationTableTsName,
|
|
1242
|
+
// isJson: true,
|
|
1243
|
+
// selection: builtRelation.selection,
|
|
1244
|
+
// });
|
|
1245
|
+
// }
|
|
1246
|
+
// let distinct: PgSelectConfig['distinct'];
|
|
1247
|
+
// let tableFrom: AnyPgTable | Subquery = table;
|
|
1248
|
+
// // Process first Many relation - each one requires a nested subquery
|
|
1249
|
+
// const manyRelation = manyRelations[0];
|
|
1250
|
+
// if (manyRelation) {
|
|
1251
|
+
// const {
|
|
1252
|
+
// tsKey: selectedRelationTsKey,
|
|
1253
|
+
// queryConfig: selectedRelationQueryConfig,
|
|
1254
|
+
// relation,
|
|
1255
|
+
// } = manyRelation;
|
|
1256
|
+
// distinct = {
|
|
1257
|
+
// on: tableConfig.primaryKey.map((c) => aliasedTableColumn(c as AnyPgColumn, tableAlias)),
|
|
1258
|
+
// };
|
|
1259
|
+
// const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
|
|
1260
|
+
// const relationTableName = relation.referencedTable[Table.Symbol.Name];
|
|
1261
|
+
// const relationTableTsName = tableNamesMap[relationTableName]!;
|
|
1262
|
+
// const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
|
|
1263
|
+
// const joinOn = and(
|
|
1264
|
+
// ...normalizedRelation.fields.map((field, i) =>
|
|
1265
|
+
// eq(
|
|
1266
|
+
// aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
|
|
1267
|
+
// aliasedTableColumn(field, tableAlias),
|
|
1268
|
+
// )
|
|
1269
|
+
// ),
|
|
1270
|
+
// );
|
|
1271
|
+
// const builtRelationJoin = this.buildRelationalQueryWithPK({
|
|
1272
|
+
// fullSchema,
|
|
1273
|
+
// schema,
|
|
1274
|
+
// tableNamesMap,
|
|
1275
|
+
// table: fullSchema[relationTableTsName] as AnyPgTable,
|
|
1276
|
+
// tableConfig: schema[relationTableTsName]!,
|
|
1277
|
+
// queryConfig: selectedRelationQueryConfig,
|
|
1278
|
+
// tableAlias: relationTableAlias,
|
|
1279
|
+
// joinOn,
|
|
1280
|
+
// });
|
|
1281
|
+
// const builtRelationSelectionField = sql`case when ${
|
|
1282
|
+
// sql.identifier(relationTableAlias)
|
|
1283
|
+
// } is null then '[]' else json_agg(json_build_array(${
|
|
1284
|
+
// sql.join(
|
|
1285
|
+
// builtRelationJoin.selection.map(({ field }) =>
|
|
1286
|
+
// is(field, SQL.Aliased)
|
|
1287
|
+
// ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`
|
|
1288
|
+
// : is(field, Column)
|
|
1289
|
+
// ? aliasedTableColumn(field, relationTableAlias)
|
|
1290
|
+
// : field
|
|
1291
|
+
// ),
|
|
1292
|
+
// sql`, `,
|
|
1293
|
+
// )
|
|
1294
|
+
// })) over (partition by ${sql.join(distinct.on, sql`, `)}) end`.as(selectedRelationTsKey);
|
|
1295
|
+
// const isLateralJoin = is(builtRelationJoin.sql, SQL);
|
|
1296
|
+
// joins.push({
|
|
1297
|
+
// on: isLateralJoin ? sql`true` : joinOn,
|
|
1298
|
+
// table: isLateralJoin
|
|
1299
|
+
// ? new Subquery(builtRelationJoin.sql as SQL, {}, relationTableAlias)
|
|
1300
|
+
// : aliasedTable(builtRelationJoin.sql as AnyPgTable, relationTableAlias),
|
|
1301
|
+
// alias: relationTableAlias,
|
|
1302
|
+
// joinType: 'left',
|
|
1303
|
+
// lateral: isLateralJoin,
|
|
1304
|
+
// });
|
|
1305
|
+
// // Build the "from" subquery with the remaining Many relations
|
|
1306
|
+
// const builtTableFrom = this.buildRelationalQueryWithPK({
|
|
1307
|
+
// fullSchema,
|
|
1308
|
+
// schema,
|
|
1309
|
+
// tableNamesMap,
|
|
1310
|
+
// table,
|
|
1311
|
+
// tableConfig,
|
|
1312
|
+
// queryConfig: {
|
|
1313
|
+
// ...config,
|
|
1314
|
+
// where: undefined,
|
|
1315
|
+
// orderBy: undefined,
|
|
1316
|
+
// limit: undefined,
|
|
1317
|
+
// offset: undefined,
|
|
1318
|
+
// with: manyRelations.slice(1).reduce<NonNullable<typeof config['with']>>(
|
|
1319
|
+
// (result, { tsKey, queryConfig: configValue }) => {
|
|
1320
|
+
// result[tsKey] = configValue;
|
|
1321
|
+
// return result;
|
|
1322
|
+
// },
|
|
1323
|
+
// {},
|
|
1324
|
+
// ),
|
|
1325
|
+
// },
|
|
1326
|
+
// tableAlias,
|
|
1327
|
+
// });
|
|
1328
|
+
// selectedRelations.push({
|
|
1329
|
+
// dbKey: selectedRelationTsKey,
|
|
1330
|
+
// tsKey: selectedRelationTsKey,
|
|
1331
|
+
// field: builtRelationSelectionField,
|
|
1332
|
+
// relationTableTsKey: relationTableTsName,
|
|
1333
|
+
// isJson: true,
|
|
1334
|
+
// selection: builtRelationJoin.selection,
|
|
1335
|
+
// });
|
|
1336
|
+
// // selection = builtTableFrom.selection.map((item) =>
|
|
1337
|
+
// // is(item.field, SQL.Aliased)
|
|
1338
|
+
// // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }
|
|
1339
|
+
// // : item
|
|
1340
|
+
// // );
|
|
1341
|
+
// // selectionForBuild = [{
|
|
1342
|
+
// // dbKey: '*',
|
|
1343
|
+
// // tsKey: '*',
|
|
1344
|
+
// // field: sql`${sql.identifier(tableAlias)}.*`,
|
|
1345
|
+
// // selection: [],
|
|
1346
|
+
// // isJson: false,
|
|
1347
|
+
// // relationTableTsKey: undefined,
|
|
1348
|
+
// // }];
|
|
1349
|
+
// // const newSelectionItem: (typeof selection)[number] = {
|
|
1350
|
+
// // dbKey: selectedRelationTsKey,
|
|
1351
|
+
// // tsKey: selectedRelationTsKey,
|
|
1352
|
+
// // field,
|
|
1353
|
+
// // relationTableTsKey: relationTableTsName,
|
|
1354
|
+
// // isJson: true,
|
|
1355
|
+
// // selection: builtRelationJoin.selection,
|
|
1356
|
+
// // };
|
|
1357
|
+
// // selection.push(newSelectionItem);
|
|
1358
|
+
// // selectionForBuild.push(newSelectionItem);
|
|
1359
|
+
// tableFrom = is(builtTableFrom.sql, PgTable)
|
|
1360
|
+
// ? builtTableFrom.sql
|
|
1361
|
+
// : new Subquery(builtTableFrom.sql, {}, tableAlias);
|
|
1362
|
+
// }
|
|
1363
|
+
// if (selectedColumns.length === 0 && selectedRelations.length === 0 && selectedExtras.length === 0) {
|
|
1364
|
+
// throw new DrizzleError(`No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")`);
|
|
1365
|
+
// }
|
|
1366
|
+
// let selection: BuildRelationalQueryResult<AnyPgTable, AnyPgColumn>['selection'];
|
|
1367
|
+
// function prepareSelectedColumns() {
|
|
1368
|
+
// return selectedColumns.map((key) => ({
|
|
1369
|
+
// dbKey: tableConfig.columns[key]!.name,
|
|
1370
|
+
// tsKey: key,
|
|
1371
|
+
// field: tableConfig.columns[key] as AnyPgColumn,
|
|
1372
|
+
// relationTableTsKey: undefined,
|
|
1373
|
+
// isJson: false,
|
|
1374
|
+
// selection: [],
|
|
1375
|
+
// }));
|
|
1376
|
+
// }
|
|
1377
|
+
// function prepareSelectedExtras() {
|
|
1378
|
+
// return selectedExtras.map((item) => ({
|
|
1379
|
+
// dbKey: item.value.fieldAlias,
|
|
1380
|
+
// tsKey: item.tsKey,
|
|
1381
|
+
// field: item.value,
|
|
1382
|
+
// relationTableTsKey: undefined,
|
|
1383
|
+
// isJson: false,
|
|
1384
|
+
// selection: [],
|
|
1385
|
+
// }));
|
|
1386
|
+
// }
|
|
1387
|
+
// if (isRoot) {
|
|
1388
|
+
// selection = [
|
|
1389
|
+
// ...prepareSelectedColumns(),
|
|
1390
|
+
// ...prepareSelectedExtras(),
|
|
1391
|
+
// ];
|
|
1392
|
+
// }
|
|
1393
|
+
// if (hasUserDefinedWhere || orderBy.length > 0) {
|
|
1394
|
+
// tableFrom = new Subquery(
|
|
1395
|
+
// this.buildSelectQuery({
|
|
1396
|
+
// table: is(tableFrom, PgTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,
|
|
1397
|
+
// fields: {},
|
|
1398
|
+
// fieldsFlat: selectionForBuild.map(({ field }) => ({
|
|
1399
|
+
// path: [],
|
|
1400
|
+
// field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
|
|
1401
|
+
// })),
|
|
1402
|
+
// joins,
|
|
1403
|
+
// distinct,
|
|
1404
|
+
// }),
|
|
1405
|
+
// {},
|
|
1406
|
+
// tableAlias,
|
|
1407
|
+
// );
|
|
1408
|
+
// selectionForBuild = selection.map((item) =>
|
|
1409
|
+
// is(item.field, SQL.Aliased)
|
|
1410
|
+
// ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }
|
|
1411
|
+
// : item
|
|
1412
|
+
// );
|
|
1413
|
+
// joins = [];
|
|
1414
|
+
// distinct = undefined;
|
|
1415
|
+
// }
|
|
1416
|
+
// const result = this.buildSelectQuery({
|
|
1417
|
+
// table: is(tableFrom, PgTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,
|
|
1418
|
+
// fields: {},
|
|
1419
|
+
// fieldsFlat: selectionForBuild.map(({ field }) => ({
|
|
1420
|
+
// path: [],
|
|
1421
|
+
// field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
|
|
1422
|
+
// })),
|
|
1423
|
+
// where,
|
|
1424
|
+
// limit,
|
|
1425
|
+
// offset,
|
|
1426
|
+
// joins,
|
|
1427
|
+
// orderBy,
|
|
1428
|
+
// distinct,
|
|
1429
|
+
// });
|
|
1430
|
+
// return {
|
|
1431
|
+
// tableTsKey: tableConfig.tsName,
|
|
1432
|
+
// sql: result,
|
|
1433
|
+
// selection,
|
|
1434
|
+
// };
|
|
1435
|
+
// }
|
|
1436
|
+
buildRelationalQueryWithoutPK({ fullSchema, schema, tableNamesMap, table, tableConfig, queryConfig: config, tableAlias, nestedQueryRelation, joinOn, }) {
|
|
1437
|
+
let selection = [];
|
|
1438
|
+
let limit, offset, orderBy = [], where;
|
|
1439
|
+
const joins = [];
|
|
933
1440
|
if (config === true) {
|
|
934
1441
|
const selectionEntries = Object.entries(tableConfig.columns);
|
|
935
|
-
|
|
1442
|
+
selection = selectionEntries.map(([key, value]) => ({
|
|
936
1443
|
dbKey: value.name,
|
|
937
1444
|
tsKey: key,
|
|
938
|
-
field: value,
|
|
939
|
-
|
|
1445
|
+
field: aliasedTableColumn(value, tableAlias),
|
|
1446
|
+
relationTableTsKey: undefined,
|
|
940
1447
|
isJson: false,
|
|
941
1448
|
selection: [],
|
|
942
1449
|
}));
|
|
943
|
-
return {
|
|
944
|
-
tableTsKey: tableConfig.tsName,
|
|
945
|
-
sql: table,
|
|
946
|
-
selection,
|
|
947
|
-
};
|
|
948
1450
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1451
|
+
else {
|
|
1452
|
+
const aliasedColumns = Object.fromEntries(Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]));
|
|
1453
|
+
if (config.where) {
|
|
1454
|
+
const whereSql = typeof config.where === 'function' ? config.where(aliasedColumns, operators) : config.where;
|
|
1455
|
+
where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
|
|
1456
|
+
}
|
|
1457
|
+
const fieldsSelection = [];
|
|
1458
|
+
let selectedColumns = [];
|
|
1459
|
+
// Figure out which columns to select
|
|
1460
|
+
if (config.columns) {
|
|
1461
|
+
let isIncludeMode = false;
|
|
1462
|
+
for (const [field, value] of Object.entries(config.columns)) {
|
|
1463
|
+
if (value === undefined) {
|
|
1464
|
+
continue;
|
|
1465
|
+
}
|
|
1466
|
+
if (field in tableConfig.columns) {
|
|
1467
|
+
if (!isIncludeMode && value === true) {
|
|
1468
|
+
isIncludeMode = true;
|
|
1469
|
+
}
|
|
1470
|
+
selectedColumns.push(field);
|
|
965
1471
|
}
|
|
966
|
-
|
|
1472
|
+
}
|
|
1473
|
+
if (selectedColumns.length > 0) {
|
|
1474
|
+
selectedColumns = isIncludeMode
|
|
1475
|
+
? selectedColumns.filter((c) => config.columns?.[c] === true)
|
|
1476
|
+
: Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
|
|
967
1477
|
}
|
|
968
1478
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1479
|
+
else {
|
|
1480
|
+
// Select all columns if selection is not specified
|
|
1481
|
+
selectedColumns = Object.keys(tableConfig.columns);
|
|
1482
|
+
}
|
|
1483
|
+
for (const field of selectedColumns) {
|
|
1484
|
+
const column = tableConfig.columns[field];
|
|
1485
|
+
fieldsSelection.push({ tsKey: field, value: column });
|
|
1486
|
+
}
|
|
1487
|
+
let selectedRelations = [];
|
|
1488
|
+
// Figure out which relations to select
|
|
1489
|
+
if (config.with) {
|
|
1490
|
+
selectedRelations = Object.entries(config.with)
|
|
1491
|
+
.filter((entry) => !!entry[1])
|
|
1492
|
+
.map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey] }));
|
|
1493
|
+
}
|
|
1494
|
+
let extras;
|
|
1495
|
+
// Figure out which extras to select
|
|
1496
|
+
if (config.extras) {
|
|
1497
|
+
extras = typeof config.extras === 'function'
|
|
1498
|
+
? config.extras(aliasedColumns, { sql })
|
|
1499
|
+
: config.extras;
|
|
1500
|
+
for (const [tsKey, value] of Object.entries(extras)) {
|
|
1501
|
+
fieldsSelection.push({
|
|
1502
|
+
tsKey,
|
|
1503
|
+
value: mapColumnsInAliasedSQLToAlias(value, tableAlias),
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
973
1506
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
.
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
? config.extras(aliasedFields, { sql })
|
|
986
|
-
: config.extras;
|
|
987
|
-
selectedExtras = Object.entries(extrasOrig).map(([key, value]) => ({
|
|
988
|
-
key,
|
|
989
|
-
value: mapColumnsInAliasedSQLToAlias(value, tableAlias),
|
|
990
|
-
}));
|
|
991
|
-
}
|
|
992
|
-
for (const field of selectedColumns) {
|
|
993
|
-
const column = tableConfig.columns[field];
|
|
994
|
-
fieldsSelection[field] = column;
|
|
995
|
-
}
|
|
996
|
-
for (const { key, value } of selectedExtras) {
|
|
997
|
-
fieldsSelection[key] = value;
|
|
998
|
-
}
|
|
999
|
-
let where;
|
|
1000
|
-
if (config.where) {
|
|
1001
|
-
const whereSql = typeof config.where === 'function' ? config.where(aliasedFields, operators) : config.where;
|
|
1002
|
-
where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
|
|
1003
|
-
}
|
|
1004
|
-
const groupBy = ((tableConfig.primaryKey.length > 0 && selectedRelations.length < 2)
|
|
1005
|
-
? tableConfig.primaryKey
|
|
1006
|
-
: Object.values(tableConfig.columns)).map((c) => aliasedTableColumn(c, tableAlias));
|
|
1007
|
-
let orderByOrig = typeof config.orderBy === 'function'
|
|
1008
|
-
? config.orderBy(aliasedFields, orderByOperators)
|
|
1009
|
-
: config.orderBy ?? [];
|
|
1010
|
-
if (!Array.isArray(orderByOrig)) {
|
|
1011
|
-
orderByOrig = [orderByOrig];
|
|
1012
|
-
}
|
|
1013
|
-
const orderBy = orderByOrig.map((orderByValue) => {
|
|
1014
|
-
if (is(orderByValue, Column)) {
|
|
1015
|
-
return aliasedTableColumn(orderByValue, tableAlias);
|
|
1507
|
+
// Transform `fieldsSelection` into `selection`
|
|
1508
|
+
// `fieldsSelection` shouldn't be used after this point
|
|
1509
|
+
for (const { tsKey, value } of fieldsSelection) {
|
|
1510
|
+
selection.push({
|
|
1511
|
+
dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey].name,
|
|
1512
|
+
tsKey,
|
|
1513
|
+
field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,
|
|
1514
|
+
relationTableTsKey: undefined,
|
|
1515
|
+
isJson: false,
|
|
1516
|
+
selection: [],
|
|
1517
|
+
});
|
|
1016
1518
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
let selectedRelationIndex = 0;
|
|
1023
|
-
for (const { key: selectedRelationKey, value: selectedRelationValue } of selectedRelations) {
|
|
1024
|
-
let relation;
|
|
1025
|
-
for (const [relationKey, relationValue] of Object.entries(tableConfig.relations)) {
|
|
1026
|
-
if (is(relationValue, Relation) && relationKey === selectedRelationKey) {
|
|
1027
|
-
relation = relationValue;
|
|
1028
|
-
break;
|
|
1029
|
-
}
|
|
1519
|
+
let orderByOrig = typeof config.orderBy === 'function'
|
|
1520
|
+
? config.orderBy(aliasedColumns, orderByOperators)
|
|
1521
|
+
: config.orderBy ?? [];
|
|
1522
|
+
if (!Array.isArray(orderByOrig)) {
|
|
1523
|
+
orderByOrig = [orderByOrig];
|
|
1030
1524
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
|
|
1035
|
-
const relationAlias = `${tableAlias}_${selectedRelationKey}`;
|
|
1036
|
-
const relationConfig = schema[tableNamesMap[relation.referencedTable[Table.Symbol.Name]]];
|
|
1037
|
-
const builtRelation = this.buildRelationalQuery(fullSchema, schema, tableNamesMap, fullSchema[tableNamesMap[relation.referencedTable[Table.Symbol.Name]]], schema[tableNamesMap[relation.referencedTable[Table.Symbol.Name]]], selectedRelationValue, relationAlias, normalizedRelation.references);
|
|
1038
|
-
builtRelations.push({ key: selectedRelationKey, value: builtRelation });
|
|
1039
|
-
let relationWhere;
|
|
1040
|
-
if (typeof selectedRelationValue === 'object' && selectedRelationValue.limit) {
|
|
1041
|
-
const field = sql `${sql.identifier(relationAlias)}.${sql.identifier('__drizzle_row_number')}`;
|
|
1042
|
-
relationWhere = and(relationWhere, or(and(sql `${field} <= ${selectedRelationValue.limit}`), sql `(${field} is null)`));
|
|
1043
|
-
}
|
|
1044
|
-
const join = {
|
|
1045
|
-
table: is(builtRelation.sql, Table)
|
|
1046
|
-
? aliasedTable(builtRelation.sql, relationAlias)
|
|
1047
|
-
: new Subquery(builtRelation.sql, {}, relationAlias),
|
|
1048
|
-
alias: relationAlias,
|
|
1049
|
-
on: and(...normalizedRelation.fields.map((field, i) => eq(aliasedTableColumn(field, tableAlias), aliasedTableColumn(normalizedRelation.references[i], relationAlias)))),
|
|
1050
|
-
joinType: 'left',
|
|
1051
|
-
};
|
|
1052
|
-
const relationAliasedColumns = Object.fromEntries(Object.entries(relationConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]));
|
|
1053
|
-
const relationAliasedRelations = Object.fromEntries(Object.entries(relationConfig.relations).map(([key, value]) => [key, aliasedRelation(value, tableAlias)]));
|
|
1054
|
-
const relationAliasedFields = Object.assign({}, relationAliasedColumns, relationAliasedRelations);
|
|
1055
|
-
let relationOrderBy;
|
|
1056
|
-
if (typeof selectedRelationValue === 'object') {
|
|
1057
|
-
let orderByOrig = typeof selectedRelationValue.orderBy === 'function'
|
|
1058
|
-
? selectedRelationValue.orderBy(relationAliasedFields, orderByOperators)
|
|
1059
|
-
: selectedRelationValue.orderBy ?? [];
|
|
1060
|
-
if (!Array.isArray(orderByOrig)) {
|
|
1061
|
-
orderByOrig = [orderByOrig];
|
|
1525
|
+
orderBy = orderByOrig.map((orderByValue) => {
|
|
1526
|
+
if (is(orderByValue, Column)) {
|
|
1527
|
+
return aliasedTableColumn(orderByValue, tableAlias);
|
|
1062
1528
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1529
|
+
return mapColumnsInSQLToAlias(orderByValue, tableAlias);
|
|
1530
|
+
});
|
|
1531
|
+
limit = config.limit;
|
|
1532
|
+
offset = config.offset;
|
|
1533
|
+
// Process all relations
|
|
1534
|
+
for (const { tsKey: selectedRelationTsKey, queryConfig: selectedRelationConfigValue, relation, } of selectedRelations) {
|
|
1535
|
+
const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
|
|
1536
|
+
const relationTableName = relation.referencedTable[Table.Symbol.Name];
|
|
1537
|
+
const relationTableTsName = tableNamesMap[relationTableName];
|
|
1538
|
+
const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
|
|
1539
|
+
const joinOn = and(...normalizedRelation.fields.map((field, i) => eq(aliasedTableColumn(normalizedRelation.references[i], relationTableAlias), aliasedTableColumn(field, tableAlias))));
|
|
1540
|
+
const builtRelation = this.buildRelationalQueryWithoutPK({
|
|
1541
|
+
fullSchema,
|
|
1542
|
+
schema,
|
|
1543
|
+
tableNamesMap,
|
|
1544
|
+
table: fullSchema[relationTableTsName],
|
|
1545
|
+
tableConfig: schema[relationTableTsName],
|
|
1546
|
+
queryConfig: is(relation, One)
|
|
1547
|
+
? (selectedRelationConfigValue === true
|
|
1548
|
+
? { limit: 1 }
|
|
1549
|
+
: { ...selectedRelationConfigValue, limit: 1 })
|
|
1550
|
+
: selectedRelationConfigValue,
|
|
1551
|
+
tableAlias: relationTableAlias,
|
|
1552
|
+
joinOn,
|
|
1553
|
+
nestedQueryRelation: relation,
|
|
1554
|
+
});
|
|
1555
|
+
const field = sql `${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey);
|
|
1556
|
+
joins.push({
|
|
1557
|
+
on: sql `true`,
|
|
1558
|
+
table: new Subquery(builtRelation.sql, {}, relationTableAlias),
|
|
1559
|
+
alias: relationTableAlias,
|
|
1560
|
+
joinType: 'left',
|
|
1561
|
+
lateral: true,
|
|
1562
|
+
});
|
|
1563
|
+
selection.push({
|
|
1564
|
+
dbKey: selectedRelationTsKey,
|
|
1565
|
+
tsKey: selectedRelationTsKey,
|
|
1566
|
+
field,
|
|
1567
|
+
relationTableTsKey: relationTableTsName,
|
|
1568
|
+
isJson: true,
|
|
1569
|
+
selection: builtRelation.selection,
|
|
1068
1570
|
});
|
|
1069
1571
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1572
|
+
}
|
|
1573
|
+
if (selection.length === 0) {
|
|
1574
|
+
throw new DrizzleError(`No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")`);
|
|
1575
|
+
}
|
|
1576
|
+
let result;
|
|
1577
|
+
where = and(joinOn, where);
|
|
1578
|
+
if (nestedQueryRelation) {
|
|
1579
|
+
let field = sql `json_build_array(${sql.join(selection.map(({ field, tsKey, isJson }) => isJson
|
|
1580
|
+
? sql `${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier('data')}`
|
|
1581
|
+
: is(field, SQL.Aliased)
|
|
1582
|
+
? field.sql
|
|
1583
|
+
: field), sql `, `)})`;
|
|
1584
|
+
if (is(nestedQueryRelation, Many)) {
|
|
1585
|
+
field = sql `coalesce(json_agg(${field}${orderBy.length > 0 ? sql ` order by ${sql.join(orderBy, sql `, `)}` : undefined}), '[]'::json)`;
|
|
1586
|
+
// orderBy = [];
|
|
1587
|
+
}
|
|
1588
|
+
const nestedSelection = [{
|
|
1589
|
+
dbKey: 'data',
|
|
1590
|
+
tsKey: 'data',
|
|
1591
|
+
field: field.as('data'),
|
|
1592
|
+
isJson: true,
|
|
1593
|
+
relationTableTsKey: tableConfig.tsName,
|
|
1594
|
+
selection,
|
|
1595
|
+
}];
|
|
1596
|
+
const needsSubquery = limit !== undefined || offset !== undefined || orderBy.length > 0;
|
|
1597
|
+
if (needsSubquery) {
|
|
1598
|
+
result = this.buildSelectQuery({
|
|
1599
|
+
table: aliasedTable(table, tableAlias),
|
|
1600
|
+
fields: {},
|
|
1601
|
+
fieldsFlat: [{
|
|
1602
|
+
path: [],
|
|
1603
|
+
field: sql.raw('*'),
|
|
1604
|
+
}],
|
|
1605
|
+
where,
|
|
1606
|
+
limit,
|
|
1607
|
+
offset,
|
|
1608
|
+
orderBy,
|
|
1609
|
+
});
|
|
1610
|
+
where = undefined;
|
|
1611
|
+
limit = undefined;
|
|
1612
|
+
offset = undefined;
|
|
1613
|
+
orderBy = [];
|
|
1614
|
+
}
|
|
1615
|
+
else {
|
|
1616
|
+
result = aliasedTable(table, tableAlias);
|
|
1617
|
+
}
|
|
1095
1618
|
result = this.buildSelectQuery({
|
|
1096
|
-
table: result ? new Subquery(result, {}, tableAlias)
|
|
1619
|
+
table: is(result, PgTable) ? result : new Subquery(result, {}, tableAlias),
|
|
1097
1620
|
fields: {},
|
|
1098
|
-
fieldsFlat:
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
}))
|
|
1108
|
-
: []),
|
|
1109
|
-
builtRelationField,
|
|
1110
|
-
],
|
|
1111
|
-
where: relationWhere,
|
|
1112
|
-
groupBy: [
|
|
1113
|
-
...groupBy,
|
|
1114
|
-
...builtRelationFields.map(({ field }) => sql `${sql.identifier(tableAlias)}.${sql.identifier(field.fieldAlias)}`),
|
|
1115
|
-
],
|
|
1116
|
-
orderBy: selectedRelationIndex === selectedRelations.length - 1 ? orderBy : [],
|
|
1117
|
-
joins: [join],
|
|
1118
|
-
lockingClauses: [],
|
|
1621
|
+
fieldsFlat: nestedSelection.map(({ field }) => ({
|
|
1622
|
+
path: [],
|
|
1623
|
+
field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
|
|
1624
|
+
})),
|
|
1625
|
+
joins,
|
|
1626
|
+
where,
|
|
1627
|
+
limit,
|
|
1628
|
+
offset,
|
|
1629
|
+
orderBy,
|
|
1119
1630
|
});
|
|
1120
|
-
builtRelationFields.push(builtRelationField);
|
|
1121
|
-
selectedRelationIndex++;
|
|
1122
1631
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
});
|
|
1129
|
-
const finalFieldsFlat = isRoot
|
|
1130
|
-
? [
|
|
1131
|
-
...finalFieldsSelection.map(({ path, field }) => ({
|
|
1132
|
-
path,
|
|
1133
|
-
field: is(field, SQL.Aliased) ? sql `${sql.identifier(field.fieldAlias)}` : field,
|
|
1134
|
-
})),
|
|
1135
|
-
...builtRelationFields.map(({ path, field }) => ({
|
|
1136
|
-
path,
|
|
1137
|
-
field: sql `${sql.identifier(field.fieldAlias)}${selectedRelations.length > 1 ? sql.raw('::json') : undefined}`,
|
|
1138
|
-
})),
|
|
1139
|
-
]
|
|
1140
|
-
: [
|
|
1141
|
-
{
|
|
1632
|
+
else {
|
|
1633
|
+
result = this.buildSelectQuery({
|
|
1634
|
+
table: aliasedTable(table, tableAlias),
|
|
1635
|
+
fields: {},
|
|
1636
|
+
fieldsFlat: selection.map(({ field }) => ({
|
|
1142
1637
|
path: [],
|
|
1143
|
-
field:
|
|
1144
|
-
},
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
];
|
|
1152
|
-
let limit, offset;
|
|
1153
|
-
if (config.limit !== undefined || config.offset !== undefined) {
|
|
1154
|
-
if (isRoot) {
|
|
1155
|
-
limit = config.limit;
|
|
1156
|
-
offset = config.offset;
|
|
1157
|
-
}
|
|
1158
|
-
else {
|
|
1159
|
-
finalFieldsFlat.push({
|
|
1160
|
-
path: ['__drizzle_row_number'],
|
|
1161
|
-
field: sql `row_number() over(partition by ${relationColumns.map((c) => aliasedTableColumn(c, tableAlias))}${orderBy.length ? sql ` order by ${sql.join(orderBy, sql `, `)}` : undefined})`
|
|
1162
|
-
.as('__drizzle_row_number'),
|
|
1163
|
-
});
|
|
1164
|
-
}
|
|
1638
|
+
field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
|
|
1639
|
+
})),
|
|
1640
|
+
joins,
|
|
1641
|
+
where,
|
|
1642
|
+
limit,
|
|
1643
|
+
offset,
|
|
1644
|
+
orderBy,
|
|
1645
|
+
});
|
|
1165
1646
|
}
|
|
1166
|
-
result = this.buildSelectQuery({
|
|
1167
|
-
table: result ? new Subquery(result, {}, tableAlias) : aliasedTable(table, tableAlias),
|
|
1168
|
-
fields: {},
|
|
1169
|
-
fieldsFlat: finalFieldsFlat,
|
|
1170
|
-
where,
|
|
1171
|
-
groupBy: [],
|
|
1172
|
-
orderBy: orderBy ?? [],
|
|
1173
|
-
joins: [],
|
|
1174
|
-
lockingClauses: [],
|
|
1175
|
-
limit,
|
|
1176
|
-
offset: offset,
|
|
1177
|
-
});
|
|
1178
1647
|
return {
|
|
1179
1648
|
tableTsKey: tableConfig.tsName,
|
|
1180
1649
|
sql: result,
|
|
1181
|
-
selection
|
|
1182
|
-
...finalFieldsSelection.map(({ path, field }) => ({
|
|
1183
|
-
dbKey: is(field, SQL.Aliased) ? field.fieldAlias : tableConfig.columns[path[0]].name,
|
|
1184
|
-
tsKey: path[0],
|
|
1185
|
-
field,
|
|
1186
|
-
tableTsKey: undefined,
|
|
1187
|
-
isJson: false,
|
|
1188
|
-
selection: [],
|
|
1189
|
-
})),
|
|
1190
|
-
...builtRelations.map(({ key, value }) => ({
|
|
1191
|
-
dbKey: key,
|
|
1192
|
-
tsKey: key,
|
|
1193
|
-
field: undefined,
|
|
1194
|
-
tableTsKey: value.tableTsKey,
|
|
1195
|
-
isJson: true,
|
|
1196
|
-
selection: value.selection,
|
|
1197
|
-
})),
|
|
1198
|
-
],
|
|
1650
|
+
selection,
|
|
1199
1651
|
};
|
|
1200
1652
|
}
|
|
1201
1653
|
}
|
|
@@ -1275,10 +1727,6 @@ class PgSelectQueryBuilder extends TypedQueryBuilder {
|
|
|
1275
1727
|
withList,
|
|
1276
1728
|
table,
|
|
1277
1729
|
fields: { ...fields },
|
|
1278
|
-
joins: [],
|
|
1279
|
-
orderBy: [],
|
|
1280
|
-
groupBy: [],
|
|
1281
|
-
lockingClauses: [],
|
|
1282
1730
|
distinct,
|
|
1283
1731
|
};
|
|
1284
1732
|
this.isPartialSelect = isPartialSelect;
|
|
@@ -1294,7 +1742,7 @@ class PgSelectQueryBuilder extends TypedQueryBuilder {
|
|
|
1294
1742
|
return (table, on) => {
|
|
1295
1743
|
const baseTableName = this.tableName;
|
|
1296
1744
|
const tableName = getTableLikeName(table);
|
|
1297
|
-
if (typeof tableName === 'string' && this.config.joins
|
|
1745
|
+
if (typeof tableName === 'string' && this.config.joins?.some((join) => join.alias === tableName)) {
|
|
1298
1746
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
1299
1747
|
}
|
|
1300
1748
|
if (!this.isPartialSelect) {
|
|
@@ -1316,6 +1764,9 @@ class PgSelectQueryBuilder extends TypedQueryBuilder {
|
|
|
1316
1764
|
if (typeof on === 'function') {
|
|
1317
1765
|
on = on(new Proxy(this.config.fields, new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' })));
|
|
1318
1766
|
}
|
|
1767
|
+
if (!this.config.joins) {
|
|
1768
|
+
this.config.joins = [];
|
|
1769
|
+
}
|
|
1319
1770
|
this.config.joins.push({ on, table, joinType, alias: tableName });
|
|
1320
1771
|
if (typeof tableName === 'string') {
|
|
1321
1772
|
switch (joinType) {
|
|
@@ -1464,6 +1915,9 @@ class PgSelectQueryBuilder extends TypedQueryBuilder {
|
|
|
1464
1915
|
* {@link https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE|Postgres locking clause documentation}
|
|
1465
1916
|
*/
|
|
1466
1917
|
for(strength, config = {}) {
|
|
1918
|
+
if (!this.config.lockingClauses) {
|
|
1919
|
+
this.config.lockingClauses = [];
|
|
1920
|
+
}
|
|
1467
1921
|
this.config.lockingClauses.push({ strength, config });
|
|
1468
1922
|
return this;
|
|
1469
1923
|
}
|
|
@@ -2526,14 +2980,10 @@ function mapRelationalRow(tablesConfig, tableConfig, row, buildQueryResultSelect
|
|
|
2526
2980
|
const relation = tableConfig.relations[selectionItem.tsKey];
|
|
2527
2981
|
const rawSubRows = row[selectionItemIndex];
|
|
2528
2982
|
const subRows = typeof rawSubRows === 'string' ? JSON.parse(rawSubRows) : rawSubRows;
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
}
|
|
2534
|
-
else {
|
|
2535
|
-
result[selectionItem.tsKey] = subRows.map((subRow) => mapRelationalRow(tablesConfig, tablesConfig[selectionItem.tableTsKey], subRow, selectionItem.selection, mapColumnValue));
|
|
2536
|
-
}
|
|
2983
|
+
result[selectionItem.tsKey] = is(relation, One)
|
|
2984
|
+
? subRows
|
|
2985
|
+
&& mapRelationalRow(tablesConfig, tablesConfig[selectionItem.relationTableTsKey], subRows, selectionItem.selection, mapColumnValue)
|
|
2986
|
+
: subRows.map((subRow) => mapRelationalRow(tablesConfig, tablesConfig[selectionItem.relationTableTsKey], subRow, selectionItem.selection, mapColumnValue));
|
|
2537
2987
|
}
|
|
2538
2988
|
else {
|
|
2539
2989
|
const value = mapColumnValue(row[selectionItemIndex]);
|
|
@@ -2585,7 +3035,7 @@ function and(...unfilteredConditions) {
|
|
|
2585
3035
|
}
|
|
2586
3036
|
}
|
|
2587
3037
|
chunks.push(sql `)`);
|
|
2588
|
-
return sql.
|
|
3038
|
+
return sql.join(chunks);
|
|
2589
3039
|
}
|
|
2590
3040
|
function or(...unfilteredConditions) {
|
|
2591
3041
|
const conditions = unfilteredConditions.filter((c) => c !== undefined);
|
|
@@ -2605,7 +3055,7 @@ function or(...unfilteredConditions) {
|
|
|
2605
3055
|
}
|
|
2606
3056
|
}
|
|
2607
3057
|
chunks.push(sql `)`);
|
|
2608
|
-
return sql.
|
|
3058
|
+
return sql.join(chunks);
|
|
2609
3059
|
}
|
|
2610
3060
|
/**
|
|
2611
3061
|
* Negate the meaning of an expression using the `not` keyword.
|
|
@@ -3138,6 +3588,7 @@ function sql(strings, ...params) {
|
|
|
3138
3588
|
return new SQL([]);
|
|
3139
3589
|
}
|
|
3140
3590
|
sql.empty = empty;
|
|
3591
|
+
/** @deprecated - use `sql.join()` */
|
|
3141
3592
|
function fromList(list) {
|
|
3142
3593
|
return new SQL(list);
|
|
3143
3594
|
}
|
|
@@ -3151,24 +3602,43 @@ function sql(strings, ...params) {
|
|
|
3151
3602
|
}
|
|
3152
3603
|
sql.raw = raw;
|
|
3153
3604
|
/**
|
|
3154
|
-
*
|
|
3605
|
+
* Join a list of SQL chunks with a separator.
|
|
3606
|
+
* @example
|
|
3607
|
+
* ```ts
|
|
3608
|
+
* const query = sql.join([sql`a`, sql`b`, sql`c`]);
|
|
3609
|
+
* // sql`abc`
|
|
3610
|
+
* ```
|
|
3611
|
+
* @example
|
|
3612
|
+
* ```ts
|
|
3613
|
+
* const query = sql.join([sql`a`, sql`b`, sql`c`], sql`, `);
|
|
3614
|
+
* // sql`a, b, c`
|
|
3615
|
+
* ```
|
|
3155
3616
|
*/
|
|
3156
3617
|
function join(chunks, separator) {
|
|
3157
3618
|
const result = [];
|
|
3158
3619
|
for (const [i, chunk] of chunks.entries()) {
|
|
3159
|
-
if (i > 0) {
|
|
3620
|
+
if (i > 0 && separator !== undefined) {
|
|
3160
3621
|
result.push(separator);
|
|
3161
3622
|
}
|
|
3162
3623
|
result.push(chunk);
|
|
3163
3624
|
}
|
|
3164
|
-
return
|
|
3625
|
+
return new SQL(result);
|
|
3165
3626
|
}
|
|
3166
3627
|
sql.join = join;
|
|
3167
3628
|
/**
|
|
3168
|
-
*
|
|
3629
|
+
* Create a SQL chunk that represents a DB identifier (table, column, index etc.).
|
|
3630
|
+
* When used in a query, the identifier will be escaped based on the DB engine.
|
|
3631
|
+
* For example, in PostgreSQL, identifiers are escaped with double quotes.
|
|
3632
|
+
*
|
|
3633
|
+
* **WARNING: This function does not offer any protection against SQL injections, so you must validate any user input beforehand.**
|
|
3634
|
+
*
|
|
3635
|
+
* @example ```ts
|
|
3636
|
+
* const query = sql`SELECT * FROM ${sql.identifier('my-table')}`;
|
|
3637
|
+
* // 'SELECT * FROM "my-table"'
|
|
3638
|
+
* ```
|
|
3169
3639
|
*/
|
|
3170
3640
|
function identifier(value) {
|
|
3171
|
-
return
|
|
3641
|
+
return new Name(value);
|
|
3172
3642
|
}
|
|
3173
3643
|
sql.identifier = identifier;
|
|
3174
3644
|
})(sql || (sql = {}));
|
|
@@ -3297,7 +3767,7 @@ function mapColumnsInAliasedSQLToAlias(query, alias) {
|
|
|
3297
3767
|
return new SQL.Aliased(mapColumnsInSQLToAlias(query.sql, alias), query.fieldAlias);
|
|
3298
3768
|
}
|
|
3299
3769
|
function mapColumnsInSQLToAlias(query, alias) {
|
|
3300
|
-
return sql.
|
|
3770
|
+
return sql.join(query.queryChunks.map((c) => {
|
|
3301
3771
|
if (is(c, Column)) {
|
|
3302
3772
|
return aliasedTableColumn(c, alias);
|
|
3303
3773
|
}
|
|
@@ -3311,5 +3781,5 @@ function mapColumnsInSQLToAlias(query, alias) {
|
|
|
3311
3781
|
}));
|
|
3312
3782
|
}
|
|
3313
3783
|
|
|
3314
|
-
export { check as $,
|
|
3315
|
-
//# sourceMappingURL=alias-
|
|
3784
|
+
export { check as $, mapColumnsInAliasedSQLToAlias as A, orderByOperators as B, ColumnBuilder as C, normalizeRelation as D, and as E, eq as F, DrizzleError as G, aliasedTable as H, applyMixins as I, TypedQueryBuilder as J, getTableLikeName as K, param as L, Many as M, PgColumnBuilder as N, One as O, PgDialect as P, QueryPromise as Q, PgColumn as R, SQL as S, Table as T, pgTableWithSchema as U, ViewBaseConfig as V, WithSubquery as W, pgViewWithSchema as X, pgMaterializedViewWithSchema as Y, CheckBuilder as Z, Check as _, extractTablesRelationalConfig as a, PgViewConfig as a$, PgArrayBuilder as a0, PgArray as a1, PgDateBuilder as a2, PgDate as a3, PgDateStringBuilder as a4, PgDateString as a5, date as a6, PgJsonBuilder as a7, PgJson as a8, json as a9, primaryKey as aA, PrimaryKeyBuilder as aB, PrimaryKey as aC, unique as aD, uniqueKeyName as aE, UniqueConstraintBuilder as aF, UniqueOnConstraintBuilder as aG, UniqueConstraint as aH, PgSelectQueryBuilder as aI, PgSelect as aJ, InlineForeignKeys as aK, PgTable as aL, pgTable as aM, pgTableCreator as aN, getTableConfig as aO, getViewConfig as aP, getMaterializedViewConfig as aQ, parsePgNestedArray as aR, parsePgArray as aS, makePgArray as aT, DefaultViewBuilderCore as aU, ViewBuilder as aV, ManualViewBuilder as aW, MaterializedViewBuilderCore as aX, MaterializedViewBuilder as aY, ManualMaterializedViewBuilder as aZ, PgViewBase as a_, PgJsonbBuilder as aa, PgJsonb as ab, jsonb as ac, PgNumericBuilder as ad, PgNumeric as ae, numeric as af, decimal as ag, PgTimeBuilder as ah, PgTime as ai, time as aj, PgTimestampBuilder as ak, PgTimestamp as al, PgTimestampStringBuilder as am, PgTimestampString as an, timestamp as ao, PgUUIDBuilder as ap, PgUUID as aq, uuid as ar, ForeignKeyBuilder as as, ForeignKey as at, foreignKey as au, IndexBuilderOn as av, IndexBuilder as aw, Index as ax, index as ay, uniqueIndex as az, Param as b, PgView as b0, PgMaterializedViewConfig as b1, PgMaterializedView as b2, pgView as b3, pgMaterializedView as b4, ColumnAliasProxyHandler as b5, RelationTableAliasProxyHandler as b6, aliasedRelation as b7, hasOwnEntityKind as b8, bindIfParam as b9, FakePrimitiveParam as bA, isSQLWrapper as bB, StringChunk as bC, Name as bD, name as bE, isDriverValueEncoder as bF, noopDecoder as bG, noopEncoder as bH, noopMapper as bI, Placeholder as bJ, placeholder as bK, TableName as bL, Schema as bM, Columns as bN, OriginalName as bO, BaseName as bP, IsAlias as bQ, ExtraConfigBuilder as bR, isTable as bS, iife as bT, ne as ba, or as bb, not as bc, gt as bd, gte as be, lt as bf, lte as bg, inArray as bh, notInArray as bi, isNull as bj, isNotNull as bk, exists as bl, notExists as bm, between as bn, notBetween as bo, like as bp, notLike as bq, ilike as br, notIlike as bs, asc as bt, desc as bu, Relation as bv, Relations as bw, relations as bx, createOne as by, createMany as bz, createTableRelationsHelpers as c, mapUpdateSet as d, entityKind as e, fillPlaceholders as f, mapRelationalRow as g, QueryBuilder as h, is as i, SelectionProxyHandler as j, PgSelectBuilder as k, TransactionRollbackError as l, mapResultRow as m, TableAliasProxyHandler as n, orderSelectedFields as o, Column as p, getTableColumns as q, View as r, sql as s, tracer as t, getTableName as u, Subquery as v, SubqueryConfig as w, aliasedTableColumn as x, operators as y, mapColumnsInSQLToAlias as z };
|
|
3785
|
+
//# sourceMappingURL=alias-340e2b86.mjs.map
|