linkgress-orm 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +196 -0
  3. package/dist/database/database-client.interface.d.ts +45 -0
  4. package/dist/database/database-client.interface.d.ts.map +1 -0
  5. package/dist/database/database-client.interface.js +20 -0
  6. package/dist/database/database-client.interface.js.map +1 -0
  7. package/dist/database/index.d.ts +5 -0
  8. package/dist/database/index.d.ts.map +1 -0
  9. package/dist/database/index.js +10 -0
  10. package/dist/database/index.js.map +1 -0
  11. package/dist/database/pg-client.d.ts +30 -0
  12. package/dist/database/pg-client.d.ts.map +1 -0
  13. package/dist/database/pg-client.js +76 -0
  14. package/dist/database/pg-client.js.map +1 -0
  15. package/dist/database/postgres-client.d.ts +44 -0
  16. package/dist/database/postgres-client.d.ts.map +1 -0
  17. package/dist/database/postgres-client.js +111 -0
  18. package/dist/database/postgres-client.js.map +1 -0
  19. package/dist/database/types.d.ts +200 -0
  20. package/dist/database/types.d.ts.map +1 -0
  21. package/dist/database/types.js +8 -0
  22. package/dist/database/types.js.map +1 -0
  23. package/dist/entity/base-entity.d.ts +21 -0
  24. package/dist/entity/base-entity.d.ts.map +1 -0
  25. package/dist/entity/base-entity.js +27 -0
  26. package/dist/entity/base-entity.js.map +1 -0
  27. package/dist/entity/db-column.d.ts +61 -0
  28. package/dist/entity/db-column.d.ts.map +1 -0
  29. package/dist/entity/db-column.js +35 -0
  30. package/dist/entity/db-column.js.map +1 -0
  31. package/dist/entity/db-context.d.ts +665 -0
  32. package/dist/entity/db-context.d.ts.map +1 -0
  33. package/dist/entity/db-context.js +1463 -0
  34. package/dist/entity/db-context.js.map +1 -0
  35. package/dist/entity/entity-base.d.ts +76 -0
  36. package/dist/entity/entity-base.d.ts.map +1 -0
  37. package/dist/entity/entity-base.js +42 -0
  38. package/dist/entity/entity-base.js.map +1 -0
  39. package/dist/entity/entity-builder.d.ts +171 -0
  40. package/dist/entity/entity-builder.d.ts.map +1 -0
  41. package/dist/entity/entity-builder.js +376 -0
  42. package/dist/entity/entity-builder.js.map +1 -0
  43. package/dist/entity/model-config.d.ts +18 -0
  44. package/dist/entity/model-config.d.ts.map +1 -0
  45. package/dist/entity/model-config.js +157 -0
  46. package/dist/entity/model-config.js.map +1 -0
  47. package/dist/index.d.ts +27 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +142 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/migration/db-schema-manager.d.ts +228 -0
  52. package/dist/migration/db-schema-manager.d.ts.map +1 -0
  53. package/dist/migration/db-schema-manager.js +1055 -0
  54. package/dist/migration/db-schema-manager.js.map +1 -0
  55. package/dist/migration/enum-migrator.d.ts +29 -0
  56. package/dist/migration/enum-migrator.d.ts.map +1 -0
  57. package/dist/migration/enum-migrator.js +137 -0
  58. package/dist/migration/enum-migrator.js.map +1 -0
  59. package/dist/query/collection-strategy.factory.d.ts +16 -0
  60. package/dist/query/collection-strategy.factory.d.ts.map +1 -0
  61. package/dist/query/collection-strategy.factory.js +37 -0
  62. package/dist/query/collection-strategy.factory.js.map +1 -0
  63. package/dist/query/collection-strategy.interface.d.ts +146 -0
  64. package/dist/query/collection-strategy.interface.d.ts.map +1 -0
  65. package/dist/query/collection-strategy.interface.js +3 -0
  66. package/dist/query/collection-strategy.interface.js.map +1 -0
  67. package/dist/query/conditions.d.ts +222 -0
  68. package/dist/query/conditions.d.ts.map +1 -0
  69. package/dist/query/conditions.js +446 -0
  70. package/dist/query/conditions.js.map +1 -0
  71. package/dist/query/cte-builder.d.ts +95 -0
  72. package/dist/query/cte-builder.d.ts.map +1 -0
  73. package/dist/query/cte-builder.js +172 -0
  74. package/dist/query/cte-builder.js.map +1 -0
  75. package/dist/query/grouped-query.d.ts +186 -0
  76. package/dist/query/grouped-query.d.ts.map +1 -0
  77. package/dist/query/grouped-query.js +588 -0
  78. package/dist/query/grouped-query.js.map +1 -0
  79. package/dist/query/join-builder.d.ts +106 -0
  80. package/dist/query/join-builder.d.ts.map +1 -0
  81. package/dist/query/join-builder.js +275 -0
  82. package/dist/query/join-builder.js.map +1 -0
  83. package/dist/query/query-builder.d.ts +543 -0
  84. package/dist/query/query-builder.d.ts.map +1 -0
  85. package/dist/query/query-builder.js +2649 -0
  86. package/dist/query/query-builder.js.map +1 -0
  87. package/dist/query/strategies/jsonb-collection-strategy.d.ts +51 -0
  88. package/dist/query/strategies/jsonb-collection-strategy.d.ts.map +1 -0
  89. package/dist/query/strategies/jsonb-collection-strategy.js +210 -0
  90. package/dist/query/strategies/jsonb-collection-strategy.js.map +1 -0
  91. package/dist/query/strategies/temptable-collection-strategy.d.ts +95 -0
  92. package/dist/query/strategies/temptable-collection-strategy.d.ts.map +1 -0
  93. package/dist/query/strategies/temptable-collection-strategy.js +456 -0
  94. package/dist/query/strategies/temptable-collection-strategy.js.map +1 -0
  95. package/dist/query/subquery.d.ts +152 -0
  96. package/dist/query/subquery.d.ts.map +1 -0
  97. package/dist/query/subquery.js +206 -0
  98. package/dist/query/subquery.js.map +1 -0
  99. package/dist/schema/column-builder.d.ts +127 -0
  100. package/dist/schema/column-builder.d.ts.map +1 -0
  101. package/dist/schema/column-builder.js +184 -0
  102. package/dist/schema/column-builder.js.map +1 -0
  103. package/dist/schema/inference.d.ts +26 -0
  104. package/dist/schema/inference.d.ts.map +1 -0
  105. package/dist/schema/inference.js +3 -0
  106. package/dist/schema/inference.js.map +1 -0
  107. package/dist/schema/navigation.d.ts +215 -0
  108. package/dist/schema/navigation.d.ts.map +1 -0
  109. package/dist/schema/navigation.js +233 -0
  110. package/dist/schema/navigation.js.map +1 -0
  111. package/dist/schema/row-type.d.ts +26 -0
  112. package/dist/schema/row-type.d.ts.map +1 -0
  113. package/dist/schema/row-type.js +3 -0
  114. package/dist/schema/row-type.js.map +1 -0
  115. package/dist/schema/sequence-builder.d.ts +87 -0
  116. package/dist/schema/sequence-builder.d.ts.map +1 -0
  117. package/dist/schema/sequence-builder.js +123 -0
  118. package/dist/schema/sequence-builder.js.map +1 -0
  119. package/dist/schema/table-builder.d.ts +122 -0
  120. package/dist/schema/table-builder.d.ts.map +1 -0
  121. package/dist/schema/table-builder.js +132 -0
  122. package/dist/schema/table-builder.js.map +1 -0
  123. package/dist/schema/typed-schema.d.ts +22 -0
  124. package/dist/schema/typed-schema.d.ts.map +1 -0
  125. package/dist/schema/typed-schema.js +28 -0
  126. package/dist/schema/typed-schema.js.map +1 -0
  127. package/dist/types/column-types.d.ts +20 -0
  128. package/dist/types/column-types.d.ts.map +1 -0
  129. package/dist/types/column-types.js +14 -0
  130. package/dist/types/column-types.js.map +1 -0
  131. package/dist/types/custom-types.d.ts +85 -0
  132. package/dist/types/custom-types.d.ts.map +1 -0
  133. package/dist/types/custom-types.js +132 -0
  134. package/dist/types/custom-types.js.map +1 -0
  135. package/dist/types/enum-builder.d.ts +31 -0
  136. package/dist/types/enum-builder.d.ts.map +1 -0
  137. package/dist/types/enum-builder.js +46 -0
  138. package/dist/types/enum-builder.js.map +1 -0
  139. package/dist/types/metadata.d.ts +67 -0
  140. package/dist/types/metadata.d.ts.map +1 -0
  141. package/dist/types/metadata.js +57 -0
  142. package/dist/types/metadata.js.map +1 -0
  143. package/dist/types/type-mapper.d.ts +49 -0
  144. package/dist/types/type-mapper.d.ts.map +1 -0
  145. package/dist/types/type-mapper.js +49 -0
  146. package/dist/types/type-mapper.js.map +1 -0
  147. package/package.json +77 -0
@@ -0,0 +1,456 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TempTableCollectionStrategy = void 0;
4
+ /**
5
+ * Temp table-based collection strategy
6
+ *
7
+ * This strategy uses PostgreSQL temporary tables to store parent IDs,
8
+ * then JOINs against them to aggregate related records.
9
+ *
10
+ * Benefits:
11
+ * - Better performance for large datasets
12
+ * - Indexed temp table JOIN can be faster than CTE
13
+ * - More control over query plan
14
+ *
15
+ * Trade-offs:
16
+ * - Requires two round trips (get parent IDs, then aggregate)
17
+ * - Needs temp table management
18
+ * - Transaction-scoped temp tables
19
+ *
20
+ * SQL Pattern:
21
+ * ```sql
22
+ * CREATE TEMP TABLE tmp_parent_ids_0 (
23
+ * id integer PRIMARY KEY
24
+ * ) ON COMMIT DROP;
25
+ *
26
+ * INSERT INTO tmp_parent_ids_0 VALUES (1),(2),(3);
27
+ *
28
+ * SELECT
29
+ * t.id as parent_id,
30
+ * jsonb_agg(
31
+ * jsonb_build_object('id', p.id, 'title', p.title)
32
+ * ORDER BY p.views DESC
33
+ * ) as data
34
+ * FROM tmp_parent_ids_0 t
35
+ * LEFT JOIN posts p ON p.user_id = t.id AND p.views > $1
36
+ * GROUP BY t.id;
37
+ * ```
38
+ */
39
+ class TempTableCollectionStrategy {
40
+ getType() {
41
+ return 'temptable';
42
+ }
43
+ requiresParentIds() {
44
+ // Temp table strategy requires parent IDs to be fetched first
45
+ return true;
46
+ }
47
+ async buildAggregation(config, context, client) {
48
+ if (!config.parentIds || config.parentIds.length === 0) {
49
+ // No parent IDs means we'll return empty results
50
+ // We can still create an empty temp table for consistency
51
+ return this.buildEmptyAggregation(config, context);
52
+ }
53
+ // Check if client supports multi-statement queries for optimization
54
+ if (client.supportsMultiStatementQueries()) {
55
+ return this.buildAggregationMultiStatement(config, context, client);
56
+ }
57
+ else {
58
+ return this.buildAggregationLegacy(config, context, client);
59
+ }
60
+ }
61
+ /**
62
+ * Build aggregation using multi-statement query (single round trip)
63
+ * Supported by postgres.js using .simple() mode
64
+ *
65
+ * For JSONB/array collections: fetches raw rows and groups in JavaScript (fast!)
66
+ * For scalar aggregations: uses database aggregation (necessary)
67
+ */
68
+ async buildAggregationMultiStatement(config, context, client) {
69
+ const tempTableName = `tmp_parent_ids_${config.counter}`;
70
+ // Build aggregation SQL with WHERE parameters interpolated
71
+ const aggregationSQL = this.buildAggregationSQLWithInterpolatedParams(config, tempTableName);
72
+ // Build the value placeholders for INSERT (interpolate integer parent IDs - safe)
73
+ const valuePlaceholders = config.parentIds.map(id => `(${id})`).join(',');
74
+ // Determine if we're doing client-side grouping (JSONB/array) or server-side (scalar)
75
+ const isClientSideGrouping = config.aggregationType === 'jsonb' || config.aggregationType === 'array';
76
+ // Combine everything into a single multi-statement query
77
+ const multiStatementSQL = `
78
+ -- Create temporary table for parent IDs
79
+ CREATE TEMP TABLE ${tempTableName} (
80
+ id integer PRIMARY KEY
81
+ ) ON COMMIT DROP;
82
+
83
+ -- Insert parent IDs
84
+ INSERT INTO ${tempTableName} VALUES ${valuePlaceholders};
85
+
86
+ -- Query and return the data
87
+ ${aggregationSQL};
88
+
89
+ -- Cleanup
90
+ DROP TABLE IF EXISTS ${tempTableName};
91
+ `.trim();
92
+ // Execute multi-statement query using querySimple (no parameters)
93
+ const executor = context.executor || client;
94
+ // Use querySimple if available (for proper logging)
95
+ let result;
96
+ if ('querySimple' in executor && typeof executor.querySimple === 'function') {
97
+ // Use querySimple for true single round-trip execution with logging
98
+ result = await executor.querySimple(multiStatementSQL);
99
+ }
100
+ else if ('querySimple' in client && typeof client.querySimple === 'function') {
101
+ // Fallback: call client directly (no logging)
102
+ result = await client.querySimple(multiStatementSQL);
103
+ }
104
+ else {
105
+ // Final fallback: regular query
106
+ result = await executor.query(multiStatementSQL, []);
107
+ }
108
+ // Group results by parent_id
109
+ const dataMap = new Map();
110
+ if (isClientSideGrouping) {
111
+ // Client-side grouping for JSONB/array - much faster than jsonb_agg!
112
+ if (config.aggregationType === 'jsonb') {
113
+ // Group rows by parent_id and build objects
114
+ for (const row of result.rows) {
115
+ const parentId = row.parent_id;
116
+ if (!dataMap.has(parentId)) {
117
+ dataMap.set(parentId, []);
118
+ }
119
+ // Extract the actual data (everything except parent_id)
120
+ const { parent_id, ...rowData } = row;
121
+ dataMap.get(parentId).push(rowData);
122
+ }
123
+ }
124
+ else if (config.aggregationType === 'array') {
125
+ // Group rows by parent_id and extract array field
126
+ const arrayField = config.arrayField;
127
+ for (const row of result.rows) {
128
+ const parentId = row.parent_id;
129
+ if (!dataMap.has(parentId)) {
130
+ dataMap.set(parentId, []);
131
+ }
132
+ dataMap.get(parentId).push(row[arrayField]);
133
+ }
134
+ }
135
+ }
136
+ else {
137
+ // Server-side aggregation (scalar) - data already aggregated
138
+ for (const row of result.rows) {
139
+ dataMap.set(row.parent_id, row.data);
140
+ }
141
+ }
142
+ // Return result with fetched data
143
+ return {
144
+ sql: aggregationSQL,
145
+ params: [], // Params already used in execution
146
+ tableName: `${tempTableName}_result`,
147
+ joinClause: '', // Not needed - data already fetched
148
+ selectExpression: '', // Not needed - data already fetched
149
+ isCTE: false,
150
+ dataFetched: true,
151
+ data: dataMap,
152
+ };
153
+ }
154
+ /**
155
+ * Build aggregation using legacy approach (multiple queries)
156
+ * Used for clients that don't support multi-statement queries
157
+ */
158
+ async buildAggregationLegacy(config, context, client) {
159
+ const tempTableName = `tmp_parent_ids_${config.counter}`;
160
+ // Create temp table (without ON COMMIT DROP to persist across queries in the same session)
161
+ const createTableSQL = `
162
+ CREATE TEMP TABLE IF NOT EXISTS ${tempTableName} (
163
+ id integer PRIMARY KEY
164
+ )
165
+ `.trim();
166
+ // Use executor from context if available for query logging
167
+ if (context.executor) {
168
+ await context.executor.query(createTableSQL);
169
+ }
170
+ else {
171
+ await client.query(createTableSQL);
172
+ }
173
+ // Insert parent IDs
174
+ const valuePlaceholders = config.parentIds.map((_, idx) => `($${idx + 1})`).join(',');
175
+ const insertSQL = `INSERT INTO ${tempTableName} VALUES ${valuePlaceholders}`;
176
+ // Use executor from context if available for query logging
177
+ if (context.executor) {
178
+ await context.executor.query(insertSQL, config.parentIds);
179
+ }
180
+ else {
181
+ await client.query(insertSQL, config.parentIds);
182
+ }
183
+ // Build aggregation query based on type
184
+ const aggregationSQL = this.buildAggregationSQLByType(config, tempTableName);
185
+ const aggregationParams = config.whereParams || [];
186
+ const selectExpression = `"${tempTableName}_agg".data`;
187
+ // Execute aggregation query and store results in another temp table
188
+ const aggTempTableName = `${tempTableName}_agg`;
189
+ const createAggTableSQL = `
190
+ CREATE TEMP TABLE ${aggTempTableName} AS
191
+ ${aggregationSQL}
192
+ `.trim();
193
+ // Use executor from context if available for query logging
194
+ if (context.executor) {
195
+ await context.executor.query(createAggTableSQL, aggregationParams);
196
+ }
197
+ else {
198
+ await client.query(createAggTableSQL, aggregationParams);
199
+ }
200
+ // Cleanup SQL
201
+ const cleanupSQL = `DROP TABLE IF EXISTS ${tempTableName}, ${aggTempTableName}`;
202
+ return {
203
+ sql: aggregationSQL,
204
+ params: [], // Params already used in execution
205
+ tableName: aggTempTableName,
206
+ joinClause: `LEFT JOIN "${aggTempTableName}" ON "${config.sourceTable}"."id" = "${aggTempTableName}".parent_id`,
207
+ selectExpression: `COALESCE(${selectExpression}, ${config.defaultValue})`,
208
+ isCTE: false, // Not a CTE - already executed
209
+ cleanupSql: cleanupSQL,
210
+ };
211
+ }
212
+ /**
213
+ * Build aggregation SQL based on aggregation type
214
+ */
215
+ buildAggregationSQLByType(config, tempTableName) {
216
+ switch (config.aggregationType) {
217
+ case 'jsonb':
218
+ return this.buildJsonbAggregationSQL(config, tempTableName);
219
+ case 'array':
220
+ return this.buildArrayAggregationSQL(config, tempTableName);
221
+ case 'count':
222
+ case 'min':
223
+ case 'max':
224
+ case 'sum':
225
+ return this.buildScalarAggregationSQL(config, tempTableName);
226
+ default:
227
+ throw new Error(`Unknown aggregation type: ${config.aggregationType}`);
228
+ }
229
+ }
230
+ /**
231
+ * Build aggregation SQL with WHERE parameters interpolated
232
+ * Used for multi-statement queries with .simple() mode
233
+ *
234
+ * For JSONB/array aggregations, this returns a simple SELECT without aggregation
235
+ * so we can group in JavaScript (much faster than jsonb_agg)
236
+ */
237
+ buildAggregationSQLWithInterpolatedParams(config, tempTableName) {
238
+ // Clone config and interpolate WHERE parameters
239
+ const configWithInterpolatedParams = { ...config };
240
+ if (config.whereClause && config.whereParams && config.whereParams.length > 0) {
241
+ // Replace $1, $2, etc. with actual values
242
+ let interpolatedWhere = config.whereClause;
243
+ config.whereParams.forEach((param, idx) => {
244
+ const placeholder = `$${idx + 1}`;
245
+ const value = this.escapeValue(param);
246
+ interpolatedWhere = interpolatedWhere.replace(placeholder, value);
247
+ });
248
+ configWithInterpolatedParams.whereClause = interpolatedWhere;
249
+ configWithInterpolatedParams.whereParams = []; // Clear params since they're now interpolated
250
+ }
251
+ // For multi-statement optimization: use simple SELECT instead of aggregation
252
+ // This allows us to group in JavaScript which is much faster than jsonb_agg
253
+ switch (config.aggregationType) {
254
+ case 'jsonb':
255
+ case 'array':
256
+ return this.buildSimpleSelectSQL(configWithInterpolatedParams, tempTableName);
257
+ case 'count':
258
+ case 'min':
259
+ case 'max':
260
+ case 'sum':
261
+ // Scalar aggregations still need database aggregation
262
+ return this.buildScalarAggregationSQL(configWithInterpolatedParams, tempTableName);
263
+ default:
264
+ throw new Error(`Unknown aggregation type: ${config.aggregationType}`);
265
+ }
266
+ }
267
+ /**
268
+ * Build a simple SELECT query without aggregation
269
+ * Results will be grouped in JavaScript for better performance
270
+ */
271
+ buildSimpleSelectSQL(config, tempTableName) {
272
+ const { selectedFields, targetTable, foreignKey, whereClause, orderByClause, limitValue, offsetValue } = config;
273
+ // Build SELECT fields
274
+ const selectFields = selectedFields
275
+ .map(f => `${f.expression} as "${f.alias}"`)
276
+ .join(', ');
277
+ // Build WHERE clause
278
+ const additionalWhere = whereClause ? ` AND ${whereClause}` : '';
279
+ // Build ORDER BY clause
280
+ const orderBySQL = orderByClause ? ` ORDER BY ${orderByClause}` : ` ORDER BY "id" DESC`;
281
+ // Build LIMIT/OFFSET
282
+ let limitOffsetClause = '';
283
+ if (limitValue !== undefined) {
284
+ limitOffsetClause = ` LIMIT ${limitValue}`;
285
+ }
286
+ if (offsetValue !== undefined) {
287
+ limitOffsetClause += ` OFFSET ${offsetValue}`;
288
+ }
289
+ // Simple SELECT with foreign key for grouping
290
+ const sql = `
291
+ SELECT
292
+ "${foreignKey}" as parent_id,
293
+ ${selectFields}
294
+ FROM "${targetTable}"
295
+ WHERE "${foreignKey}" IN (SELECT id FROM ${tempTableName})${additionalWhere}
296
+ ${orderBySQL}
297
+ ${limitOffsetClause}
298
+ `.trim();
299
+ return sql;
300
+ }
301
+ /**
302
+ * Safely escape a value for SQL interpolation
303
+ * Used only in multi-statement queries with .simple() mode
304
+ */
305
+ escapeValue(value) {
306
+ if (value === null || value === undefined) {
307
+ return 'NULL';
308
+ }
309
+ if (typeof value === 'number') {
310
+ return String(value);
311
+ }
312
+ if (typeof value === 'boolean') {
313
+ return value ? 'TRUE' : 'FALSE';
314
+ }
315
+ if (typeof value === 'string') {
316
+ // Escape single quotes by doubling them (PostgreSQL standard)
317
+ return `'${value.replace(/'/g, "''")}'`;
318
+ }
319
+ if (value instanceof Date) {
320
+ return `'${value.toISOString()}'`;
321
+ }
322
+ // For arrays, objects, etc., convert to JSON string
323
+ return `'${JSON.stringify(value).replace(/'/g, "''")}'`;
324
+ }
325
+ /**
326
+ * Build aggregation for when there are no parent IDs
327
+ */
328
+ buildEmptyAggregation(config, context) {
329
+ // Return a result that will always give empty/default values
330
+ const dummyTableName = `empty_agg_${config.counter}`;
331
+ return {
332
+ sql: '',
333
+ params: [],
334
+ tableName: dummyTableName,
335
+ joinClause: '', // No join needed
336
+ selectExpression: config.defaultValue, // Just use default value
337
+ isCTE: false,
338
+ };
339
+ }
340
+ /**
341
+ * Build JSONB aggregation using temp table
342
+ */
343
+ buildJsonbAggregationSQL(config, tempTableName) {
344
+ const { selectedFields, targetTable, foreignKey, whereClause, orderByClause, limitValue, offsetValue, isDistinct } = config;
345
+ // Build the JSONB fields for jsonb_build_object
346
+ const jsonbFields = selectedFields
347
+ .map(f => `'${f.alias}', t.${f.expression}`)
348
+ .join(', ');
349
+ // Build WHERE clause (combine temp table join with additional filters)
350
+ const additionalWhere = whereClause ? ` AND ${whereClause}` : '';
351
+ // Build ORDER BY clause (use primary key DESC as default for consistent ordering matching JSONB)
352
+ const orderBySQL = orderByClause ? ` ORDER BY ${orderByClause}` : ` ORDER BY "id" DESC`;
353
+ // Build LIMIT/OFFSET (applied globally to match JSONB strategy behavior)
354
+ let limitOffsetClause = '';
355
+ if (limitValue !== undefined) {
356
+ limitOffsetClause = ` LIMIT ${limitValue}`;
357
+ }
358
+ if (offsetValue !== undefined) {
359
+ limitOffsetClause += ` OFFSET ${offsetValue}`;
360
+ }
361
+ // Build jsonb_agg ORDER BY clause
362
+ const jsonbAggOrderBy = orderByClause ? ` ORDER BY ${orderByClause}` : '';
363
+ // Build the SQL - matching JSONB strategy approach
364
+ const sql = `
365
+ SELECT
366
+ t."${foreignKey}" as parent_id,
367
+ jsonb_agg(
368
+ jsonb_build_object(${jsonbFields})${jsonbAggOrderBy}
369
+ ) as data
370
+ FROM (
371
+ SELECT *
372
+ FROM "${targetTable}"
373
+ WHERE "${foreignKey}" IN (SELECT id FROM ${tempTableName})${additionalWhere}
374
+ ${orderBySQL}
375
+ ${limitOffsetClause}
376
+ ) t
377
+ GROUP BY t."${foreignKey}"
378
+ `.trim();
379
+ return sql;
380
+ }
381
+ /**
382
+ * Build array aggregation using temp table
383
+ */
384
+ buildArrayAggregationSQL(config, tempTableName) {
385
+ const { arrayField, targetTable, foreignKey, whereClause, orderByClause, limitValue, offsetValue } = config;
386
+ if (!arrayField) {
387
+ throw new Error('arrayField is required for array aggregation');
388
+ }
389
+ // Build WHERE clause
390
+ const additionalWhere = whereClause ? ` AND ${whereClause}` : '';
391
+ // Build ORDER BY clause (use primary key DESC as default for consistent ordering matching JSONB)
392
+ const orderBySQL = orderByClause ? ` ORDER BY ${orderByClause}` : ` ORDER BY "id" DESC`;
393
+ // Build LIMIT/OFFSET (applied globally to match JSONB strategy behavior)
394
+ let limitOffsetClause = '';
395
+ if (limitValue !== undefined) {
396
+ limitOffsetClause = ` LIMIT ${limitValue}`;
397
+ }
398
+ if (offsetValue !== undefined) {
399
+ limitOffsetClause += ` OFFSET ${offsetValue}`;
400
+ }
401
+ // Build array_agg ORDER BY clause
402
+ const arrayAggOrderBy = orderByClause ? ` ORDER BY ${orderByClause}` : '';
403
+ // Build the SQL - matching JSONB strategy approach
404
+ const sql = `
405
+ SELECT
406
+ t."${foreignKey}" as parent_id,
407
+ array_agg(t."${arrayField}"${arrayAggOrderBy}) as data
408
+ FROM (
409
+ SELECT "${foreignKey}", "${arrayField}"
410
+ FROM "${targetTable}"
411
+ WHERE "${foreignKey}" IN (SELECT id FROM ${tempTableName})${additionalWhere}
412
+ ${orderBySQL}
413
+ ${limitOffsetClause}
414
+ ) t
415
+ GROUP BY t."${foreignKey}"
416
+ `.trim();
417
+ return sql;
418
+ }
419
+ /**
420
+ * Build scalar aggregation using temp table
421
+ */
422
+ buildScalarAggregationSQL(config, tempTableName) {
423
+ const { aggregationType, aggregateField, targetTable, foreignKey, whereClause } = config;
424
+ // Build WHERE clause
425
+ const additionalWhere = whereClause ? ` AND ${whereClause}` : '';
426
+ // Build aggregation expression
427
+ let aggregateExpression;
428
+ switch (aggregationType) {
429
+ case 'count':
430
+ // Count only rows where there's an actual join match (not the temp table row)
431
+ aggregateExpression = `COUNT(t."${foreignKey}")`;
432
+ break;
433
+ case 'min':
434
+ case 'max':
435
+ case 'sum':
436
+ if (!aggregateField) {
437
+ throw new Error(`${aggregationType.toUpperCase()} requires an aggregate field`);
438
+ }
439
+ aggregateExpression = `${aggregationType.toUpperCase()}(t."${aggregateField}")`;
440
+ break;
441
+ default:
442
+ throw new Error(`Unknown aggregation type: ${aggregationType}`);
443
+ }
444
+ const sql = `
445
+ SELECT
446
+ tmp.id as parent_id,
447
+ COALESCE(${aggregateExpression}, ${config.defaultValue}) as data
448
+ FROM ${tempTableName} tmp
449
+ LEFT JOIN "${targetTable}" t ON t."${foreignKey}" = tmp.id${additionalWhere}
450
+ GROUP BY tmp.id
451
+ `.trim();
452
+ return sql;
453
+ }
454
+ }
455
+ exports.TempTableCollectionStrategy = TempTableCollectionStrategy;
456
+ //# sourceMappingURL=temptable-collection-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temptable-collection-strategy.js","sourceRoot":"","sources":["../../../src/query/strategies/temptable-collection-strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import { WhereConditionBase, SqlBuildContext, FieldRef } from './conditions';
2
+ /**
3
+ * Represents a subquery that can be used in various contexts
4
+ * TResult: The type of data the subquery returns
5
+ * TMode: 'scalar' | 'array' | 'table' - determines how the subquery can be used
6
+ */
7
+ export declare class Subquery<TResult = any, TMode extends 'scalar' | 'array' | 'table' = 'table'> {
8
+ /**
9
+ * The SQL generator function - called with context to build SQL
10
+ */
11
+ private sqlBuilder;
12
+ /**
13
+ * Optional alias for the subquery when used as a table source
14
+ */
15
+ private alias?;
16
+ /**
17
+ * Selection metadata - preserves SqlFragments with mappers for table subqueries
18
+ */
19
+ private selectionMetadata?;
20
+ /**
21
+ * Phantom type marker for type checking
22
+ */
23
+ private __resultType?;
24
+ private __mode?;
25
+ constructor(sqlBuilder: (context: SqlBuildContext & {
26
+ tableAlias?: string;
27
+ }) => string, mode?: TMode, selectionMetadata?: Record<string, any>);
28
+ /**
29
+ * Set an alias for this subquery (used when subquery is a table source)
30
+ */
31
+ as(alias: string): Subquery<TResult, TMode>;
32
+ /**
33
+ * Build the SQL for this subquery
34
+ */
35
+ buildSql(context: SqlBuildContext & {
36
+ tableAlias?: string;
37
+ }): string;
38
+ /**
39
+ * Get the alias for this subquery
40
+ */
41
+ getAlias(): string | undefined;
42
+ /**
43
+ * Get the selection metadata (preserves SqlFragments with mappers)
44
+ */
45
+ getSelectionMetadata(): Record<string, any> | undefined;
46
+ /**
47
+ * Check if this is a scalar subquery
48
+ */
49
+ isScalar(): this is Subquery<TResult, 'scalar'>;
50
+ /**
51
+ * Check if this is an array subquery
52
+ */
53
+ isArray(): this is Subquery<TResult, 'array'>;
54
+ /**
55
+ * Check if this is a table subquery
56
+ */
57
+ isTable(): this is Subquery<TResult, 'table'>;
58
+ }
59
+ /**
60
+ * Subquery reference - used to reference columns from a subquery in a FROM clause
61
+ * This is similar to FieldRef but for subquery columns
62
+ */
63
+ export interface SubqueryFieldRef<TName extends string = string, TValueType = any> extends FieldRef<TName, TValueType> {
64
+ readonly __isSubqueryField: true;
65
+ }
66
+ /**
67
+ * Helper to check if something is a Subquery
68
+ */
69
+ export declare function isSubquery(value: any): value is Subquery;
70
+ /**
71
+ * Condition: EXISTS (subquery)
72
+ */
73
+ export declare class ExistsCondition extends WhereConditionBase {
74
+ private subquery;
75
+ constructor(subquery: Subquery);
76
+ buildSql(context: SqlBuildContext): string;
77
+ }
78
+ /**
79
+ * Condition: NOT EXISTS (subquery)
80
+ */
81
+ export declare class NotExistsCondition extends WhereConditionBase {
82
+ private subquery;
83
+ constructor(subquery: Subquery);
84
+ buildSql(context: SqlBuildContext): string;
85
+ }
86
+ /**
87
+ * Condition: field IN (subquery)
88
+ * The subquery must return a single column
89
+ */
90
+ export declare class InSubqueryCondition<T> extends WhereConditionBase {
91
+ private field;
92
+ private subquery;
93
+ constructor(field: FieldRef<any, T>, subquery: Subquery<T[], 'array'>);
94
+ buildSql(context: SqlBuildContext): string;
95
+ }
96
+ /**
97
+ * Condition: field NOT IN (subquery)
98
+ */
99
+ export declare class NotInSubqueryCondition<T> extends WhereConditionBase {
100
+ private field;
101
+ private subquery;
102
+ constructor(field: FieldRef<any, T>, subquery: Subquery<T[], 'array'>);
103
+ buildSql(context: SqlBuildContext): string;
104
+ }
105
+ /**
106
+ * Comparison with scalar subquery
107
+ * Example: field = (SELECT ...)
108
+ */
109
+ export declare class ScalarSubqueryComparison<T> extends WhereConditionBase {
110
+ private field;
111
+ private operator;
112
+ private subquery;
113
+ constructor(field: FieldRef<any, T>, operator: '=' | '!=' | '>' | '>=' | '<' | '<=', subquery: Subquery<T, 'scalar'>);
114
+ buildSql(context: SqlBuildContext): string;
115
+ }
116
+ /**
117
+ * Helper functions to create subquery conditions
118
+ */
119
+ /**
120
+ * EXISTS condition
121
+ */
122
+ export declare function exists(subquery: Subquery): ExistsCondition;
123
+ /**
124
+ * NOT EXISTS condition
125
+ */
126
+ export declare function notExists(subquery: Subquery): NotExistsCondition;
127
+ /**
128
+ * IN subquery condition
129
+ */
130
+ export declare function inSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T[], 'array'>): InSubqueryCondition<T>;
131
+ /**
132
+ * NOT IN subquery condition
133
+ */
134
+ export declare function notInSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T[], 'array'>): NotInSubqueryCondition<T>;
135
+ /**
136
+ * Scalar subquery comparison helpers
137
+ */
138
+ export declare function eqSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T, 'scalar'>): ScalarSubqueryComparison<T>;
139
+ export declare function neSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T, 'scalar'>): ScalarSubqueryComparison<T>;
140
+ export declare function gtSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T, 'scalar'>): ScalarSubqueryComparison<T>;
141
+ export declare function gteSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T, 'scalar'>): ScalarSubqueryComparison<T>;
142
+ export declare function ltSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T, 'scalar'>): ScalarSubqueryComparison<T>;
143
+ export declare function lteSubquery<T>(field: FieldRef<any, T>, subquery: Subquery<T, 'scalar'>): ScalarSubqueryComparison<T>;
144
+ /**
145
+ * Type helper: Extract result type from a subquery
146
+ */
147
+ export type SubqueryResult<T> = T extends Subquery<infer R, any> ? R : never;
148
+ /**
149
+ * Type helper: Extract mode from a subquery
150
+ */
151
+ export type SubqueryMode<T> = T extends Subquery<any, infer M> ? M : never;
152
+ //# sourceMappingURL=subquery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subquery.d.ts","sourceRoot":"","sources":["../../src/query/subquery.ts"],"names":[],"mappings":"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"}