linkgress-orm 0.0.2 → 0.1.0

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.
Files changed (72) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +196 -196
  3. package/dist/entity/db-column.d.ts +38 -1
  4. package/dist/entity/db-column.d.ts.map +1 -1
  5. package/dist/entity/db-column.js.map +1 -1
  6. package/dist/entity/db-context.d.ts +429 -50
  7. package/dist/entity/db-context.d.ts.map +1 -1
  8. package/dist/entity/db-context.js +884 -203
  9. package/dist/entity/db-context.js.map +1 -1
  10. package/dist/entity/entity-base.d.ts +8 -0
  11. package/dist/entity/entity-base.d.ts.map +1 -1
  12. package/dist/entity/entity-base.js.map +1 -1
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +5 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/migration/db-schema-manager.js +77 -77
  18. package/dist/migration/enum-migrator.js +6 -6
  19. package/dist/query/collection-strategy.factory.d.ts.map +1 -1
  20. package/dist/query/collection-strategy.factory.js +7 -3
  21. package/dist/query/collection-strategy.factory.js.map +1 -1
  22. package/dist/query/collection-strategy.interface.d.ts +12 -6
  23. package/dist/query/collection-strategy.interface.d.ts.map +1 -1
  24. package/dist/query/conditions.d.ts +178 -24
  25. package/dist/query/conditions.d.ts.map +1 -1
  26. package/dist/query/conditions.js +165 -4
  27. package/dist/query/conditions.js.map +1 -1
  28. package/dist/query/cte-builder.d.ts +21 -5
  29. package/dist/query/cte-builder.d.ts.map +1 -1
  30. package/dist/query/cte-builder.js +31 -7
  31. package/dist/query/cte-builder.js.map +1 -1
  32. package/dist/query/grouped-query.d.ts +185 -8
  33. package/dist/query/grouped-query.d.ts.map +1 -1
  34. package/dist/query/grouped-query.js +516 -30
  35. package/dist/query/grouped-query.js.map +1 -1
  36. package/dist/query/join-builder.d.ts +5 -4
  37. package/dist/query/join-builder.d.ts.map +1 -1
  38. package/dist/query/join-builder.js +11 -33
  39. package/dist/query/join-builder.js.map +1 -1
  40. package/dist/query/query-builder.d.ts +89 -20
  41. package/dist/query/query-builder.d.ts.map +1 -1
  42. package/dist/query/query-builder.js +317 -168
  43. package/dist/query/query-builder.js.map +1 -1
  44. package/dist/query/query-utils.d.ts +45 -0
  45. package/dist/query/query-utils.d.ts.map +1 -0
  46. package/dist/query/query-utils.js +103 -0
  47. package/dist/query/query-utils.js.map +1 -0
  48. package/dist/query/sql-utils.d.ts +83 -0
  49. package/dist/query/sql-utils.d.ts.map +1 -0
  50. package/dist/query/sql-utils.js +218 -0
  51. package/dist/query/sql-utils.js.map +1 -0
  52. package/dist/query/strategies/cte-collection-strategy.d.ts +85 -0
  53. package/dist/query/strategies/cte-collection-strategy.d.ts.map +1 -0
  54. package/dist/query/strategies/cte-collection-strategy.js +338 -0
  55. package/dist/query/strategies/cte-collection-strategy.js.map +1 -0
  56. package/dist/query/strategies/lateral-collection-strategy.d.ts +59 -0
  57. package/dist/query/strategies/lateral-collection-strategy.d.ts.map +1 -0
  58. package/dist/query/strategies/lateral-collection-strategy.js +243 -0
  59. package/dist/query/strategies/lateral-collection-strategy.js.map +1 -0
  60. package/dist/query/strategies/temptable-collection-strategy.d.ts +21 -0
  61. package/dist/query/strategies/temptable-collection-strategy.d.ts.map +1 -1
  62. package/dist/query/strategies/temptable-collection-strategy.js +216 -94
  63. package/dist/query/strategies/temptable-collection-strategy.js.map +1 -1
  64. package/dist/query/subquery.d.ts +24 -1
  65. package/dist/query/subquery.d.ts.map +1 -1
  66. package/dist/query/subquery.js +38 -2
  67. package/dist/query/subquery.js.map +1 -1
  68. package/package.json +1 -1
  69. package/dist/query/strategies/jsonb-collection-strategy.d.ts +0 -51
  70. package/dist/query/strategies/jsonb-collection-strategy.d.ts.map +0 -1
  71. package/dist/query/strategies/jsonb-collection-strategy.js +0 -210
  72. package/dist/query/strategies/jsonb-collection-strategy.js.map +0 -1
@@ -0,0 +1,83 @@
1
+ import type { TableSchema } from '../schema/table-builder';
2
+ /**
3
+ * Column configuration extracted from schema
4
+ */
5
+ export interface ColumnConfig {
6
+ propName: string;
7
+ dbName: string;
8
+ mapper?: {
9
+ toDriver: (value: any) => any;
10
+ fromDriver: (value: any) => any;
11
+ };
12
+ primaryKey?: boolean;
13
+ autoIncrement?: boolean;
14
+ }
15
+ /**
16
+ * Result from building VALUES clause
17
+ */
18
+ export interface ValuesClauseResult {
19
+ valueClauses: string[];
20
+ params: any[];
21
+ nextParamIndex: number;
22
+ }
23
+ /**
24
+ * Get qualified table name with schema prefix if specified
25
+ */
26
+ export declare function getQualifiedTableName(schema: TableSchema): string;
27
+ /**
28
+ * Build RETURNING column list from schema
29
+ */
30
+ export declare function buildReturningColumnList(schema: TableSchema): string;
31
+ /**
32
+ * Build column names list from property keys
33
+ */
34
+ export declare function buildColumnNamesList(schema: TableSchema, columnKeys: string[]): string[];
35
+ /**
36
+ * Apply mapper and get value for database
37
+ */
38
+ export declare function applyToDriverMapper(value: any, config: ColumnConfig): any;
39
+ /**
40
+ * Apply fromDriver mapper on query result
41
+ */
42
+ export declare function applyFromDriverMapper(value: any, config: ColumnConfig): any;
43
+ /**
44
+ * Detect primary keys from schema
45
+ */
46
+ export declare function detectPrimaryKeys(schema: TableSchema): string[];
47
+ /**
48
+ * Check if schema has auto-increment primary key with provided data
49
+ */
50
+ export declare function hasAutoIncrementPrimaryKey(schema: TableSchema, dataKeys: string[]): boolean;
51
+ /**
52
+ * PostgreSQL maximum parameter limit
53
+ */
54
+ export declare const POSTGRES_MAX_PARAMS = 65535;
55
+ /**
56
+ * Calculate optimal chunk size for bulk operations
57
+ */
58
+ export declare function calculateOptimalChunkSize(columnCount: number, configChunkSize?: number): number;
59
+ /**
60
+ * Build column configs from schema for given data keys
61
+ */
62
+ export declare function buildColumnConfigs(schema: TableSchema, dataKeys: string[], includeAutoIncrement?: boolean): ColumnConfig[];
63
+ /**
64
+ * Extract unique column keys from array of data objects
65
+ */
66
+ export declare function extractUniqueColumnKeys(dataArray: Record<string, any>[], schema: TableSchema, includeAutoIncrement?: boolean): string[];
67
+ /**
68
+ * Build VALUES clause with parameter placeholders
69
+ */
70
+ export declare function buildValuesClause(dataArray: Record<string, any>[], columnConfigs: ColumnConfig[], startParamIndex?: number): ValuesClauseResult;
71
+ /**
72
+ * Build ON CONFLICT clause for upserts
73
+ */
74
+ export declare function buildConflictClause(conflictColumns: string[], updateColumns: string[], schema: TableSchema, targetWhere?: string, setWhere?: string): string;
75
+ /**
76
+ * Build column name to DB name mapping
77
+ */
78
+ export declare function buildColumnNameMap(schema: TableSchema): Map<string, string>;
79
+ /**
80
+ * Get database column name from property name
81
+ */
82
+ export declare function getDbColumnName(schema: TableSchema, propName: string): string;
83
+ //# sourceMappingURL=sql-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-utils.d.ts","sourceRoot":"","sources":["../../src/query/sql-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE;QACP,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;QAC9B,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;KACjC,CAAC;IACF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAIjE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAIpE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAMxF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,GAAG,GAAG,CAKzE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,GAAG,GAAG,CAI3E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAS/D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAW3F;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CAMR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,oBAAoB,GAAE,OAAe,GACpC,YAAY,EAAE,CAoBhB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAChC,MAAM,EAAE,WAAW,EACnB,oBAAoB,GAAE,OAAe,GACpC,MAAM,EAAE,CAgBV;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAChC,aAAa,EAAE,YAAY,EAAE,EAC7B,eAAe,GAAE,MAAU,GAC1B,kBAAkB,CAuBpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,MAAM,EAAE,EACzB,aAAa,EAAE,MAAM,EAAE,EACvB,MAAM,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAgCR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO7E"}
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POSTGRES_MAX_PARAMS = void 0;
4
+ exports.getQualifiedTableName = getQualifiedTableName;
5
+ exports.buildReturningColumnList = buildReturningColumnList;
6
+ exports.buildColumnNamesList = buildColumnNamesList;
7
+ exports.applyToDriverMapper = applyToDriverMapper;
8
+ exports.applyFromDriverMapper = applyFromDriverMapper;
9
+ exports.detectPrimaryKeys = detectPrimaryKeys;
10
+ exports.hasAutoIncrementPrimaryKey = hasAutoIncrementPrimaryKey;
11
+ exports.calculateOptimalChunkSize = calculateOptimalChunkSize;
12
+ exports.buildColumnConfigs = buildColumnConfigs;
13
+ exports.extractUniqueColumnKeys = extractUniqueColumnKeys;
14
+ exports.buildValuesClause = buildValuesClause;
15
+ exports.buildConflictClause = buildConflictClause;
16
+ exports.buildColumnNameMap = buildColumnNameMap;
17
+ exports.getDbColumnName = getDbColumnName;
18
+ /**
19
+ * Get qualified table name with schema prefix if specified
20
+ */
21
+ function getQualifiedTableName(schema) {
22
+ return schema.schema
23
+ ? `"${schema.schema}"."${schema.name}"`
24
+ : `"${schema.name}"`;
25
+ }
26
+ /**
27
+ * Build RETURNING column list from schema
28
+ */
29
+ function buildReturningColumnList(schema) {
30
+ return Object.entries(schema.columns)
31
+ .map(([_, col]) => `"${col.build().name}"`)
32
+ .join(', ');
33
+ }
34
+ /**
35
+ * Build column names list from property keys
36
+ */
37
+ function buildColumnNamesList(schema, columnKeys) {
38
+ return columnKeys.map(key => {
39
+ const column = schema.columns[key];
40
+ const config = column.build();
41
+ return `"${config.name}"`;
42
+ });
43
+ }
44
+ /**
45
+ * Apply mapper and get value for database
46
+ */
47
+ function applyToDriverMapper(value, config) {
48
+ const normalizedValue = value !== undefined ? value : null;
49
+ return config.mapper
50
+ ? config.mapper.toDriver(normalizedValue)
51
+ : normalizedValue;
52
+ }
53
+ /**
54
+ * Apply fromDriver mapper on query result
55
+ */
56
+ function applyFromDriverMapper(value, config) {
57
+ return config.mapper
58
+ ? config.mapper.fromDriver(value)
59
+ : value;
60
+ }
61
+ /**
62
+ * Detect primary keys from schema
63
+ */
64
+ function detectPrimaryKeys(schema) {
65
+ const primaryKeys = [];
66
+ for (const [key, colBuilder] of Object.entries(schema.columns)) {
67
+ const colConfig = colBuilder.build();
68
+ if (colConfig.primaryKey) {
69
+ primaryKeys.push(key);
70
+ }
71
+ }
72
+ return primaryKeys;
73
+ }
74
+ /**
75
+ * Check if schema has auto-increment primary key with provided data
76
+ */
77
+ function hasAutoIncrementPrimaryKey(schema, dataKeys) {
78
+ for (const key of dataKeys) {
79
+ const column = schema.columns[key];
80
+ if (column) {
81
+ const colConfig = column.build();
82
+ if (colConfig.primaryKey && colConfig.autoIncrement) {
83
+ return true;
84
+ }
85
+ }
86
+ }
87
+ return false;
88
+ }
89
+ /**
90
+ * PostgreSQL maximum parameter limit
91
+ */
92
+ exports.POSTGRES_MAX_PARAMS = 65535;
93
+ /**
94
+ * Calculate optimal chunk size for bulk operations
95
+ */
96
+ function calculateOptimalChunkSize(columnCount, configChunkSize) {
97
+ if (configChunkSize != null) {
98
+ return configChunkSize;
99
+ }
100
+ const maxRowsPerBatch = Math.floor(exports.POSTGRES_MAX_PARAMS / columnCount);
101
+ return Math.floor(maxRowsPerBatch * 0.6); // Use 60% of max to be safe
102
+ }
103
+ /**
104
+ * Build column configs from schema for given data keys
105
+ */
106
+ function buildColumnConfigs(schema, dataKeys, includeAutoIncrement = false) {
107
+ const configs = [];
108
+ for (const propName of dataKeys) {
109
+ const column = schema.columns[propName];
110
+ if (column) {
111
+ const config = column.build();
112
+ if (!config.autoIncrement || includeAutoIncrement) {
113
+ configs.push({
114
+ propName,
115
+ dbName: config.name,
116
+ mapper: config.mapper,
117
+ primaryKey: config.primaryKey,
118
+ autoIncrement: config.autoIncrement,
119
+ });
120
+ }
121
+ }
122
+ }
123
+ return configs;
124
+ }
125
+ /**
126
+ * Extract unique column keys from array of data objects
127
+ */
128
+ function extractUniqueColumnKeys(dataArray, schema, includeAutoIncrement = false) {
129
+ const columnSet = new Set();
130
+ for (const data of dataArray) {
131
+ for (const key of Object.keys(data)) {
132
+ const column = schema.columns[key];
133
+ if (column) {
134
+ const config = column.build();
135
+ if (!config.autoIncrement || includeAutoIncrement) {
136
+ columnSet.add(key);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ return Array.from(columnSet);
142
+ }
143
+ /**
144
+ * Build VALUES clause with parameter placeholders
145
+ */
146
+ function buildValuesClause(dataArray, columnConfigs, startParamIndex = 1) {
147
+ const valueClauses = [];
148
+ const params = [];
149
+ let paramIndex = startParamIndex;
150
+ for (const data of dataArray) {
151
+ const rowPlaceholders = [];
152
+ for (const config of columnConfigs) {
153
+ const value = data[config.propName];
154
+ const mappedValue = applyToDriverMapper(value, config);
155
+ params.push(mappedValue);
156
+ rowPlaceholders.push(`$${paramIndex++}`);
157
+ }
158
+ valueClauses.push(`(${rowPlaceholders.join(', ')})`);
159
+ }
160
+ return {
161
+ valueClauses,
162
+ params,
163
+ nextParamIndex: paramIndex,
164
+ };
165
+ }
166
+ /**
167
+ * Build ON CONFLICT clause for upserts
168
+ */
169
+ function buildConflictClause(conflictColumns, updateColumns, schema, targetWhere, setWhere) {
170
+ let sql = ' ON CONFLICT';
171
+ // Conflict target columns
172
+ const conflictCols = conflictColumns.map(c => {
173
+ const column = schema.columns[c];
174
+ const config = column?.build();
175
+ return `"${config?.name || c}"`;
176
+ }).join(', ');
177
+ sql += ` (${conflictCols})`;
178
+ // Target WHERE clause
179
+ if (targetWhere) {
180
+ sql += ` WHERE ${targetWhere}`;
181
+ }
182
+ // DO UPDATE SET
183
+ sql += ' DO UPDATE SET ';
184
+ const updateParts = updateColumns.map(col => {
185
+ const column = schema.columns[col];
186
+ const config = column.build();
187
+ return `"${config.name}" = EXCLUDED."${config.name}"`;
188
+ });
189
+ sql += updateParts.join(', ');
190
+ // SET WHERE clause
191
+ if (setWhere) {
192
+ sql += ` WHERE ${setWhere}`;
193
+ }
194
+ return sql;
195
+ }
196
+ /**
197
+ * Build column name to DB name mapping
198
+ */
199
+ function buildColumnNameMap(schema) {
200
+ const map = new Map();
201
+ for (const [propName, colBuilder] of Object.entries(schema.columns)) {
202
+ const config = colBuilder.build();
203
+ map.set(propName, config.name);
204
+ }
205
+ return map;
206
+ }
207
+ /**
208
+ * Get database column name from property name
209
+ */
210
+ function getDbColumnName(schema, propName) {
211
+ const column = schema.columns[propName];
212
+ if (column) {
213
+ const config = column.build();
214
+ return config.name;
215
+ }
216
+ return propName;
217
+ }
218
+ //# sourceMappingURL=sql-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-utils.js","sourceRoot":"","sources":["../../src/query/sql-utils.ts"],"names":[],"mappings":";;;AA4BA,sDAIC;AAKD,4DAIC;AAKD,oDAMC;AAKD,kDAKC;AAKD,sDAIC;AAKD,8CASC;AAKD,gEAWC;AAUD,8DASC;AAKD,gDAwBC;AAKD,0DAoBC;AAKD,8CA2BC;AAKD,kDAsCC;AAKD,gDAOC;AAKD,0CAOC;AAxPD;;GAEG;AACH,SAAgB,qBAAqB,CAAC,MAAmB;IACvD,OAAO,MAAM,CAAC,MAAM;QAClB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,MAAM,MAAM,CAAC,IAAI,GAAG;QACvC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,SAAgB,wBAAwB,CAAC,MAAmB;IAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAK,GAAW,CAAC,KAAK,EAAE,CAAC,IAAI,GAAG,CAAC;SACnD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,MAAmB,EAAE,UAAoB;IAC5E,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9B,OAAO,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,KAAU,EAAE,MAAoB;IAClE,MAAM,eAAe,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,OAAO,MAAM,CAAC,MAAM;QAClB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QACzC,CAAC,CAAC,eAAe,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,KAAU,EAAE,MAAoB;IACpE,OAAO,MAAM,CAAC,MAAM;QAClB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;QACjC,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,MAAmB;IACnD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/D,MAAM,SAAS,GAAI,UAAkB,CAAC,KAAK,EAAE,CAAC;QAC9C,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YACzB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CAAC,MAAmB,EAAE,QAAkB;IAChF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,SAAS,GAAI,MAAc,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;gBACpD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACU,QAAA,mBAAmB,GAAG,KAAK,CAAC;AAEzC;;GAEG;AACH,SAAgB,yBAAyB,CACvC,WAAmB,EACnB,eAAwB;IAExB,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;QAC5B,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,2BAAmB,GAAG,WAAW,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,CAAC,CAAC,4BAA4B;AACxE,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAChC,MAAmB,EACnB,QAAkB,EAClB,uBAAgC,KAAK;IAErC,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,oBAAoB,EAAE,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC;oBACX,QAAQ;oBACR,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;iBACpC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CACrC,SAAgC,EAChC,MAAmB,EACnB,uBAAgC,KAAK;IAErC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,oBAAoB,EAAE,CAAC;oBAClD,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,SAAgC,EAChC,aAA6B,EAC7B,kBAA0B,CAAC;IAE3B,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,IAAI,UAAU,GAAG,eAAe,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,eAAe,GAAa,EAAE,CAAC;QAErC,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzB,eAAe,CAAC,IAAI,CAAC,IAAI,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,OAAO;QACL,YAAY;QACZ,MAAM;QACN,cAAc,EAAE,UAAU;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,eAAyB,EACzB,aAAuB,EACvB,MAAmB,EACnB,WAAoB,EACpB,QAAiB;IAEjB,IAAI,GAAG,GAAG,cAAc,CAAC;IAEzB,0BAA0B;IAC1B,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC;QAC/B,OAAO,IAAI,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC;IAClC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,GAAG,IAAI,KAAK,YAAY,GAAG,CAAC;IAE5B,sBAAsB;IACtB,IAAI,WAAW,EAAE,CAAC;QAChB,GAAG,IAAI,UAAU,WAAW,EAAE,CAAC;IACjC,CAAC;IAED,gBAAgB;IAChB,GAAG,IAAI,iBAAiB,CAAC;IAEzB,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9B,OAAO,IAAI,MAAM,CAAC,IAAI,iBAAiB,MAAM,CAAC,IAAI,GAAG,CAAC;IACxD,CAAC,CAAC,CAAC;IACH,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE9B,mBAAmB;IACnB,IAAI,QAAQ,EAAE,CAAC;QACb,GAAG,IAAI,UAAU,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,MAAmB;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACpE,MAAM,MAAM,GAAI,UAAkB,CAAC,KAAK,EAAE,CAAC;QAC3C,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAAmB,EAAE,QAAgB;IACnE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,85 @@
1
+ import { ICollectionStrategy, CollectionStrategyType, CollectionAggregationConfig, CollectionAggregationResult } from '../collection-strategy.interface';
2
+ import { QueryContext } from '../query-builder';
3
+ /**
4
+ * CTE-based collection strategy
5
+ *
6
+ * This is the current/default strategy that uses PostgreSQL CTEs with jsonb_agg
7
+ * to aggregate related records into JSONB arrays.
8
+ *
9
+ * Benefits:
10
+ * - Single query execution
11
+ * - No temp table management
12
+ * - Works well for moderate data sizes
13
+ *
14
+ * SQL Pattern:
15
+ * ```sql
16
+ * WITH "cte_0" AS (
17
+ * SELECT
18
+ * "user_id" as parent_id,
19
+ * jsonb_agg(
20
+ * jsonb_build_object('id', "id", 'title', "title")
21
+ * ORDER BY "views" DESC
22
+ * ) as data
23
+ * FROM (
24
+ * SELECT "user_id", "id", "title", "views"
25
+ * FROM "posts"
26
+ * WHERE "views" > $1
27
+ * ORDER BY "views" DESC
28
+ * ) sub
29
+ * GROUP BY "user_id"
30
+ * )
31
+ * SELECT ... COALESCE("cte_0".data, '[]'::jsonb) as "posts" ...
32
+ * ```
33
+ */
34
+ export declare class CteCollectionStrategy implements ICollectionStrategy {
35
+ getType(): CollectionStrategyType;
36
+ requiresParentIds(): boolean;
37
+ buildAggregation(config: CollectionAggregationConfig, context: QueryContext): CollectionAggregationResult;
38
+ /**
39
+ * Helper to collect all leaf fields from a potentially nested structure
40
+ * Returns array of { alias, expression } for SELECT clause (flattened with unique aliases)
41
+ */
42
+ private collectLeafFields;
43
+ /**
44
+ * Helper to build jsonb_build_object expression (handles nested structures)
45
+ */
46
+ private buildJsonbObject;
47
+ /**
48
+ * Build JSONB aggregation CTE
49
+ *
50
+ * When LIMIT/OFFSET is specified, uses ROW_NUMBER() window function to correctly
51
+ * apply pagination per parent row (not globally).
52
+ */
53
+ private buildJsonbAggregation;
54
+ /**
55
+ * Build JSONB aggregation with ROW_NUMBER() for per-parent LIMIT/OFFSET
56
+ *
57
+ * SQL Pattern:
58
+ * ```sql
59
+ * SELECT parent_id, jsonb_agg(jsonb_build_object(...)) as data
60
+ * FROM (
61
+ * SELECT *, ROW_NUMBER() OVER (PARTITION BY foreign_key ORDER BY ...) as __rn
62
+ * FROM (SELECT ... FROM table WHERE ...) inner_sub
63
+ * ) sub
64
+ * WHERE __rn > offset AND __rn <= offset + limit
65
+ * GROUP BY parent_id
66
+ * ```
67
+ */
68
+ private buildJsonbAggregationWithRowNumber;
69
+ /**
70
+ * Build array aggregation CTE (for toNumberList/toStringList)
71
+ *
72
+ * When LIMIT/OFFSET is specified, uses ROW_NUMBER() window function to correctly
73
+ * apply pagination per parent row (not globally).
74
+ */
75
+ private buildArrayAggregation;
76
+ /**
77
+ * Build array aggregation with ROW_NUMBER() for per-parent LIMIT/OFFSET
78
+ */
79
+ private buildArrayAggregationWithRowNumber;
80
+ /**
81
+ * Build scalar aggregation CTE (COUNT, MIN, MAX, SUM)
82
+ */
83
+ private buildScalarAggregation;
84
+ }
85
+ //# sourceMappingURL=cte-collection-strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cte-collection-strategy.d.ts","sourceRoot":"","sources":["../../../src/query/strategies/cte-collection-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAE5B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,OAAO,IAAI,sBAAsB;IAIjC,iBAAiB,IAAI,OAAO;IAK5B,gBAAgB,CACd,MAAM,EAAE,2BAA2B,EACnC,OAAO,EAAE,YAAY,GACpB,2BAA2B;IA0C9B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IA8D7B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,kCAAkC;IAuD1C;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAkD7B;;OAEG;IACH,OAAO,CAAC,kCAAkC;IAwC1C;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAuC/B"}