linkgress-orm 0.4.35 → 0.4.37

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 (41) hide show
  1. package/README.md +1 -0
  2. package/dist/entity/db-context.d.ts +37 -0
  3. package/dist/entity/db-context.d.ts.map +1 -1
  4. package/dist/entity/db-context.js +39 -0
  5. package/dist/entity/db-context.js.map +1 -1
  6. package/dist/entity/entity-base.d.ts +3 -1
  7. package/dist/entity/entity-base.d.ts.map +1 -1
  8. package/dist/entity/entity-base.js.map +1 -1
  9. package/dist/entity/entity-builder.d.ts +34 -0
  10. package/dist/entity/entity-builder.d.ts.map +1 -1
  11. package/dist/entity/entity-builder.js +50 -0
  12. package/dist/entity/entity-builder.js.map +1 -1
  13. package/dist/entity/model-config.d.ts.map +1 -1
  14. package/dist/entity/model-config.js +7 -0
  15. package/dist/entity/model-config.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +7 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/migration/db-schema-manager.d.ts.map +1 -1
  21. package/dist/migration/db-schema-manager.js +11 -1
  22. package/dist/migration/db-schema-manager.js.map +1 -1
  23. package/dist/migration/migration-scaffold.d.ts.map +1 -1
  24. package/dist/migration/migration-scaffold.js +18 -0
  25. package/dist/migration/migration-scaffold.js.map +1 -1
  26. package/dist/migration/partition-sql.d.ts +21 -0
  27. package/dist/migration/partition-sql.d.ts.map +1 -0
  28. package/dist/migration/partition-sql.js +46 -0
  29. package/dist/migration/partition-sql.js.map +1 -0
  30. package/dist/query/cte-builder.d.ts.map +1 -1
  31. package/dist/query/cte-builder.js +30 -6
  32. package/dist/query/cte-builder.js.map +1 -1
  33. package/dist/query/cte-root-query.d.ts +164 -0
  34. package/dist/query/cte-root-query.d.ts.map +1 -0
  35. package/dist/query/cte-root-query.js +398 -0
  36. package/dist/query/cte-root-query.js.map +1 -0
  37. package/dist/schema/table-builder.d.ts +40 -0
  38. package/dist/schema/table-builder.d.ts.map +1 -1
  39. package/dist/schema/table-builder.js +11 -0
  40. package/dist/schema/table-builder.js.map +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,164 @@
1
+ import type { DatabaseClient } from '../database/database-client.interface';
2
+ import { QueryExecutor } from '../entity/db-context';
3
+ import type { OrderDirection } from '../entity/db-context';
4
+ import { Condition, UnwrapSelection } from './conditions';
5
+ import { DbCte } from './cte-builder';
6
+ /**
7
+ * Join types supported when a CTE is the FROM root.
8
+ *
9
+ * Unlike the entity-anchored {@link JoinQueryBuilder} (which only models
10
+ * `INNER`/`LEFT`), a CTE-rooted query can express the full set of SQL join
11
+ * flavours — including `FULL OUTER` and `CROSS` — because both sides are
12
+ * already materialized, independent relations (the CTE bodies). This is what
13
+ * makes a `spend FULL OUTER JOIN current_tier ON TRUE` shape expressible.
14
+ */
15
+ export type CteJoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'FULL OUTER' | 'CROSS';
16
+ /**
17
+ * A constant `TRUE` join predicate, for cross-product joins written as
18
+ * `… JOIN … ON TRUE`. Equivalent to a `CROSS JOIN` but keeps the `ON`
19
+ * keyword, which Postgres requires for `FULL OUTER JOIN` (a bare
20
+ * `FULL OUTER JOIN` with no `ON`/`USING` is a syntax error).
21
+ *
22
+ * @example
23
+ * cteBuilder
24
+ * .selectFromCte(spendCte)
25
+ * .fullOuterJoin(currentTierCte, onTrue(), (s, t) => ({ ... }))
26
+ */
27
+ export declare function onTrue(): Condition;
28
+ /**
29
+ * A single joined CTE step (the right-hand relation + how it is attached).
30
+ */
31
+ interface CteJoinStep {
32
+ type: CteJoinType;
33
+ cte: DbCte<any>;
34
+ /** ON predicate. Always undefined for `CROSS` joins. */
35
+ condition?: Condition;
36
+ }
37
+ /**
38
+ * A query whose FROM root is a {@link DbCte} (rather than an entity table),
39
+ * joined to one or more further CTEs with any SQL join flavour.
40
+ *
41
+ * This complements the entity-anchored `db.<table>.with(...).leftJoin(cte, …)`
42
+ * path: there the FROM root must be a real table and joins are `INNER`/`LEFT`
43
+ * only. Here the FROM root is itself a CTE and `FULL OUTER` / `RIGHT` / `CROSS`
44
+ * joins (and `ON TRUE` predicates) are available — exactly what a
45
+ * `WITH a AS (…), b AS (…) SELECT … FROM a FULL OUTER JOIN b ON TRUE` shape
46
+ * needs.
47
+ *
48
+ * Parameter ordering: every CTE body's parameters are emitted first, in `WITH`
49
+ * declaration order (root CTE, then each joined CTE), followed by any `ON`
50
+ * predicate parameters — so the whole statement keeps a single, sequential
51
+ * `$1..$n` numbering, matching how the entity-rooted CTE path orders params.
52
+ *
53
+ * @typeParam TRootColumns - the column shape of the root CTE
54
+ * @typeParam TSelection - the projected output row shape (after `.select(...)`)
55
+ */
56
+ export declare class CteRootQueryBuilder<TRootColumns extends Record<string, any>, TSelection = TRootColumns> {
57
+ protected rootCte: DbCte<TRootColumns>;
58
+ protected client: DatabaseClient;
59
+ protected executor?: QueryExecutor | undefined;
60
+ private joinSteps;
61
+ private selector?;
62
+ private orderByFields;
63
+ private limitValue?;
64
+ private offsetValue?;
65
+ constructor(rootCte: DbCte<TRootColumns>, client: DatabaseClient, executor?: QueryExecutor | undefined);
66
+ /** Override the per-query timeout (ms). Pass `0` to disable. */
67
+ withTimeout(timeoutMs: number): this;
68
+ /** Flag this query as expected to finish within `expectedMs` (ms). */
69
+ expectedExecutionTime(expectedMs: number): this;
70
+ /**
71
+ * `INNER JOIN` another CTE.
72
+ */
73
+ innerJoin<TRight extends Record<string, any>>(cte: DbCte<TRight>, condition: Condition): CteJoinedQueryBuilder<TRootColumns, TRight>;
74
+ /**
75
+ * `LEFT JOIN` another CTE.
76
+ */
77
+ leftJoin<TRight extends Record<string, any>>(cte: DbCte<TRight>, condition: Condition): CteJoinedQueryBuilder<TRootColumns, TRight>;
78
+ /**
79
+ * `RIGHT JOIN` another CTE.
80
+ */
81
+ rightJoin<TRight extends Record<string, any>>(cte: DbCte<TRight>, condition: Condition): CteJoinedQueryBuilder<TRootColumns, TRight>;
82
+ /**
83
+ * `FULL OUTER JOIN` another CTE.
84
+ *
85
+ * Postgres requires an `ON`/`USING` clause on a `FULL OUTER JOIN`, so pass a
86
+ * predicate — use {@link onTrue} for the cross-product (`ON TRUE`) form that
87
+ * keeps every row of both sides while pairing them up.
88
+ */
89
+ fullOuterJoin<TRight extends Record<string, any>>(cte: DbCte<TRight>, condition: Condition): CteJoinedQueryBuilder<TRootColumns, TRight>;
90
+ /**
91
+ * `CROSS JOIN` another CTE (cartesian product, no `ON`).
92
+ */
93
+ crossJoin<TRight extends Record<string, any>>(cte: DbCte<TRight>): CteJoinedQueryBuilder<TRootColumns, TRight>;
94
+ /**
95
+ * Project the root CTE's columns directly (no join).
96
+ */
97
+ select<TNewSelection>(selector: (root: TRootColumns) => TNewSelection): CteRootQueryBuilder<TRootColumns, UnwrapSelection<TNewSelection>>;
98
+ /**
99
+ * Order the result. Selector returns one or more projected columns (by their
100
+ * output alias) — `ORDER BY "alias"` — supporting the same shapes as the
101
+ * other builders (`r => r.col`, `r => [a, b]`, `r => [[a, 'DESC']]`).
102
+ */
103
+ orderBy<T>(selector: (row: TSelection) => T): this;
104
+ orderBy<T>(selector: (row: TSelection) => T[]): this;
105
+ orderBy<T>(selector: (row: TSelection) => Array<[T, OrderDirection]>): this;
106
+ /** Limit the result set. */
107
+ limit(count: number): this;
108
+ /** Offset the result set. */
109
+ offset(count: number): this;
110
+ private addJoin;
111
+ /** @internal — used by the joined builder to share the build machinery. */
112
+ _getRootCte(): DbCte<TRootColumns>;
113
+ /** @internal */
114
+ _setState(joinSteps: CteJoinStep[], selector: ((...sources: any[]) => any) | undefined, orderByFields: Array<{
115
+ table: string;
116
+ field: string;
117
+ direction: 'ASC' | 'DESC';
118
+ }>, limitValue: number | undefined, offsetValue: number | undefined): void;
119
+ /**
120
+ * Build the SQL + ordered parameter array for this CTE-rooted query.
121
+ * @internal
122
+ */
123
+ buildQuery(): {
124
+ sql: string;
125
+ params: any[];
126
+ };
127
+ /** Generate the SQL string (for debugging / assertions). */
128
+ toSql(): string;
129
+ /** Execute and return all rows. */
130
+ toList(): Promise<TSelection[]>;
131
+ /** Execute and return the first row, or null. */
132
+ first(): Promise<TSelection | null>;
133
+ /** Evaluate the user selector against fresh CTE FieldRef proxies. */
134
+ protected evaluateSelection(): Record<string, any>;
135
+ }
136
+ /**
137
+ * The result of joining a CTE onto a CTE-rooted query. Carries the same build
138
+ * machinery as {@link CteRootQueryBuilder} but its `.select(...)` selector
139
+ * receives a FieldRef proxy per source (root first, then each joined CTE in
140
+ * order), and further joins can still be chained.
141
+ */
142
+ export declare class CteJoinedQueryBuilder<TRootColumns extends Record<string, any>, TRight extends Record<string, any>, TSelection = TRootColumns & TRight> extends CteRootQueryBuilder<TRootColumns, TSelection> {
143
+ private _joinSteps;
144
+ /** @internal */
145
+ _inheritJoins(steps: CteJoinStep[]): void;
146
+ /**
147
+ * Project columns from the root CTE plus every joined CTE. The selector is
148
+ * called with `(root, ...joined)` FieldRef proxies in FROM declaration order.
149
+ *
150
+ * The common single-join case is fully typed: `(root, right)` where `right`
151
+ * is the joined CTE ({@link TRight}). For 3+ way joins, the additional joined
152
+ * sources arrive (in FROM order) as loosely-typed rest arguments.
153
+ */
154
+ select<TNewSelection>(selector: (root: TRootColumns, right: TRight) => TNewSelection): CteRootQueryBuilder<TRootColumns, UnwrapSelection<TNewSelection>>;
155
+ select<TNewSelection>(selector: (root: TRootColumns, ...joined: any[]) => TNewSelection): CteRootQueryBuilder<TRootColumns, UnwrapSelection<TNewSelection>>;
156
+ /**
157
+ * Typed `fullOuterJoin` that exposes both already-joined sources (root +
158
+ * first right) to the predicate. (Re-declared so the chained right side keeps
159
+ * a useful element type rather than collapsing to the base signature.)
160
+ */
161
+ fullOuterJoin<TThird extends Record<string, any>>(cte: DbCte<TThird>, condition: Condition): CteJoinedQueryBuilder<TRootColumns, TThird>;
162
+ }
163
+ export {};
164
+ //# sourceMappingURL=cte-root-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cte-root-query.d.ts","sourceRoot":"","sources":["../../src/query/cte-root-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,398 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CteJoinedQueryBuilder = exports.CteRootQueryBuilder = void 0;
4
+ exports.onTrue = onTrue;
5
+ const db_context_1 = require("../entity/db-context");
6
+ const conditions_1 = require("./conditions");
7
+ const query_utils_1 = require("./query-utils");
8
+ /** SQL keyword emitted for each {@link CteJoinType}. */
9
+ const CTE_JOIN_SQL = {
10
+ INNER: 'INNER JOIN',
11
+ LEFT: 'LEFT JOIN',
12
+ RIGHT: 'RIGHT JOIN',
13
+ 'FULL OUTER': 'FULL OUTER JOIN',
14
+ CROSS: 'CROSS JOIN',
15
+ };
16
+ /**
17
+ * A constant `TRUE` join predicate, for cross-product joins written as
18
+ * `… JOIN … ON TRUE`. Equivalent to a `CROSS JOIN` but keeps the `ON`
19
+ * keyword, which Postgres requires for `FULL OUTER JOIN` (a bare
20
+ * `FULL OUTER JOIN` with no `ON`/`USING` is a syntax error).
21
+ *
22
+ * @example
23
+ * cteBuilder
24
+ * .selectFromCte(spendCte)
25
+ * .fullOuterJoin(currentTierCte, onTrue(), (s, t) => ({ ... }))
26
+ */
27
+ function onTrue() {
28
+ return (0, conditions_1.sql) `TRUE`;
29
+ }
30
+ /**
31
+ * Build a mock row that yields {@link FieldRef}s for a CTE's columns, qualified
32
+ * with the CTE's own name as the table alias. Mirrors
33
+ * `SelectQueryBuilder.createMockRowForCte` so column mappers / aggregation-array
34
+ * markers carried on the CTE's `selectionMetadata` survive into the projection.
35
+ */
36
+ function createCteFieldRefProxy(cte) {
37
+ return new Proxy({}, {
38
+ get(_target, prop) {
39
+ if (typeof prop === 'symbol') {
40
+ return undefined;
41
+ }
42
+ if (cte.selectionMetadata && prop in cte.selectionMetadata) {
43
+ const value = cte.selectionMetadata[prop];
44
+ // SqlFragment / column with a fromDriver mapper — preserve it so the
45
+ // projection re-applies the mapper to the joined column.
46
+ if (typeof value === 'object' && value !== null && typeof value.getMapper === 'function') {
47
+ return {
48
+ __fieldName: prop,
49
+ __dbColumnName: prop,
50
+ __tableAlias: cte.name,
51
+ getMapper: () => value.getMapper(),
52
+ };
53
+ }
54
+ // CTE aggregation-array marker (json_agg column) — preserve the inner
55
+ // metadata so nested items can be mapped.
56
+ if (typeof value === 'object' && value !== null && '__isAggregationArray' in value && value.__isAggregationArray) {
57
+ return {
58
+ __fieldName: prop,
59
+ __dbColumnName: prop,
60
+ __tableAlias: cte.name,
61
+ __isAggregationArray: true,
62
+ __innerSelectionMetadata: value.__innerSelectionMetadata,
63
+ };
64
+ }
65
+ }
66
+ return {
67
+ __fieldName: prop,
68
+ __dbColumnName: prop,
69
+ __tableAlias: cte.name,
70
+ };
71
+ },
72
+ has() {
73
+ return true;
74
+ },
75
+ ownKeys() {
76
+ return cte.columnDefs ? Object.keys(cte.columnDefs) : [];
77
+ },
78
+ getOwnPropertyDescriptor() {
79
+ return { enumerable: true, configurable: true };
80
+ },
81
+ });
82
+ }
83
+ const NUMERIC_REGEX = /^-?\d+(\.\d+)?$/;
84
+ /**
85
+ * A query whose FROM root is a {@link DbCte} (rather than an entity table),
86
+ * joined to one or more further CTEs with any SQL join flavour.
87
+ *
88
+ * This complements the entity-anchored `db.<table>.with(...).leftJoin(cte, …)`
89
+ * path: there the FROM root must be a real table and joins are `INNER`/`LEFT`
90
+ * only. Here the FROM root is itself a CTE and `FULL OUTER` / `RIGHT` / `CROSS`
91
+ * joins (and `ON TRUE` predicates) are available — exactly what a
92
+ * `WITH a AS (…), b AS (…) SELECT … FROM a FULL OUTER JOIN b ON TRUE` shape
93
+ * needs.
94
+ *
95
+ * Parameter ordering: every CTE body's parameters are emitted first, in `WITH`
96
+ * declaration order (root CTE, then each joined CTE), followed by any `ON`
97
+ * predicate parameters — so the whole statement keeps a single, sequential
98
+ * `$1..$n` numbering, matching how the entity-rooted CTE path orders params.
99
+ *
100
+ * @typeParam TRootColumns - the column shape of the root CTE
101
+ * @typeParam TSelection - the projected output row shape (after `.select(...)`)
102
+ */
103
+ class CteRootQueryBuilder {
104
+ constructor(rootCte, client, executor) {
105
+ this.rootCte = rootCte;
106
+ this.client = client;
107
+ this.executor = executor;
108
+ this.joinSteps = [];
109
+ this.orderByFields = [];
110
+ }
111
+ /** Override the per-query timeout (ms). Pass `0` to disable. */
112
+ withTimeout(timeoutMs) {
113
+ this.executor = this.executor
114
+ ? this.executor.withTimeout(timeoutMs)
115
+ : new db_context_1.QueryExecutor(this.client, undefined, timeoutMs);
116
+ return this;
117
+ }
118
+ /** Flag this query as expected to finish within `expectedMs` (ms). */
119
+ expectedExecutionTime(expectedMs) {
120
+ this.executor = this.executor
121
+ ? this.executor.withExpectedExecutionTime(expectedMs)
122
+ : new db_context_1.QueryExecutor(this.client, undefined, undefined, expectedMs);
123
+ return this;
124
+ }
125
+ /**
126
+ * `INNER JOIN` another CTE.
127
+ */
128
+ innerJoin(cte, condition) {
129
+ return this.addJoin('INNER', cte, condition);
130
+ }
131
+ /**
132
+ * `LEFT JOIN` another CTE.
133
+ */
134
+ leftJoin(cte, condition) {
135
+ return this.addJoin('LEFT', cte, condition);
136
+ }
137
+ /**
138
+ * `RIGHT JOIN` another CTE.
139
+ */
140
+ rightJoin(cte, condition) {
141
+ return this.addJoin('RIGHT', cte, condition);
142
+ }
143
+ /**
144
+ * `FULL OUTER JOIN` another CTE.
145
+ *
146
+ * Postgres requires an `ON`/`USING` clause on a `FULL OUTER JOIN`, so pass a
147
+ * predicate — use {@link onTrue} for the cross-product (`ON TRUE`) form that
148
+ * keeps every row of both sides while pairing them up.
149
+ */
150
+ fullOuterJoin(cte, condition) {
151
+ return this.addJoin('FULL OUTER', cte, condition);
152
+ }
153
+ /**
154
+ * `CROSS JOIN` another CTE (cartesian product, no `ON`).
155
+ */
156
+ crossJoin(cte) {
157
+ return this.addJoin('CROSS', cte, undefined);
158
+ }
159
+ /**
160
+ * Project the root CTE's columns directly (no join).
161
+ */
162
+ select(selector) {
163
+ const next = new CteRootQueryBuilder(this.rootCte, this.client, this.executor);
164
+ next.joinSteps = this.joinSteps;
165
+ next.selector = selector;
166
+ next.orderByFields = this.orderByFields;
167
+ next.limitValue = this.limitValue;
168
+ next.offsetValue = this.offsetValue;
169
+ return next;
170
+ }
171
+ orderBy(selector) {
172
+ const mockRow = new Proxy({}, {
173
+ get: (_t, prop) => {
174
+ if (typeof prop === 'symbol') {
175
+ return undefined;
176
+ }
177
+ return { __fieldName: prop, __dbColumnName: prop };
178
+ },
179
+ has: () => true,
180
+ });
181
+ const result = selector(mockRow);
182
+ this.orderByFields = [];
183
+ (0, query_utils_1.parseOrderBy)(result, this.orderByFields, undefined, () => '');
184
+ return this;
185
+ }
186
+ /** Limit the result set. */
187
+ limit(count) {
188
+ this.limitValue = count;
189
+ return this;
190
+ }
191
+ /** Offset the result set. */
192
+ offset(count) {
193
+ this.offsetValue = count;
194
+ return this;
195
+ }
196
+ addJoin(type, cte, condition) {
197
+ const next = new CteJoinedQueryBuilder(this.rootCte, this.client, this.executor);
198
+ next._inheritJoins([...this.joinSteps, { type, cte, condition }]);
199
+ return next;
200
+ }
201
+ /** @internal — used by the joined builder to share the build machinery. */
202
+ _getRootCte() {
203
+ return this.rootCte;
204
+ }
205
+ /** @internal */
206
+ _setState(joinSteps, selector, orderByFields, limitValue, offsetValue) {
207
+ this.joinSteps = joinSteps;
208
+ this.selector = selector;
209
+ this.orderByFields = orderByFields;
210
+ this.limitValue = limitValue;
211
+ this.offsetValue = offsetValue;
212
+ }
213
+ /**
214
+ * Build the SQL + ordered parameter array for this CTE-rooted query.
215
+ * @internal
216
+ */
217
+ buildQuery() {
218
+ if (!this.selector) {
219
+ throw new Error('A selection is required. Call .select(...) before executing a CTE-rooted query.');
220
+ }
221
+ const params = [];
222
+ // Parameters of every CTE body come first, in WITH declaration order
223
+ // (root, then each join). The bodies already carry sequential `$N`
224
+ // placeholders assigned by DbCteBuilder, so just concatenate their params.
225
+ params.push(...this.rootCte.params);
226
+ for (const step of this.joinSteps) {
227
+ params.push(...step.cte.params);
228
+ }
229
+ // The ON predicates are appended after all CTE-body params. Their next free
230
+ // placeholder index is therefore (paramsSoFar + 1).
231
+ const ctx = {
232
+ paramCounter: params.length + 1,
233
+ params,
234
+ };
235
+ // FROM root
236
+ let fromClause = `FROM "${this.rootCte.name}"`;
237
+ for (const step of this.joinSteps) {
238
+ const keyword = CTE_JOIN_SQL[step.type];
239
+ if (step.type === 'CROSS') {
240
+ fromClause += `\n${keyword} "${step.cte.name}"`;
241
+ }
242
+ else {
243
+ const condBuilder = new conditions_1.ConditionBuilder();
244
+ const { sql: condSql, params: condParams, paramCounter } = condBuilder.build(step.condition, ctx.paramCounter);
245
+ ctx.paramCounter = paramCounter;
246
+ ctx.params.push(...condParams);
247
+ fromClause += `\n${keyword} "${step.cte.name}" ON ${condSql}`;
248
+ }
249
+ }
250
+ // Build the WITH clause from every referenced CTE, in declaration order.
251
+ const cteDecls = [`"${this.rootCte.name}" AS (${this.rootCte.query})`];
252
+ for (const step of this.joinSteps) {
253
+ cteDecls.push(`"${step.cte.name}" AS (${step.cte.query})`);
254
+ }
255
+ // Build SELECT from the projection (root + joined CTE FieldRefs).
256
+ const selection = this.evaluateSelection();
257
+ const selectParts = buildSelectParts(selection, ctx, this.rootCte.name);
258
+ let orderByClause = '';
259
+ if (this.orderByFields.length > 0) {
260
+ const orderParts = this.orderByFields.map(({ field, direction }) => `"${field}" ${direction}`);
261
+ orderByClause = `\nORDER BY ${orderParts.join(', ')}`;
262
+ }
263
+ let limitClause = '';
264
+ if (this.limitValue !== undefined) {
265
+ limitClause = `\nLIMIT ${this.limitValue}`;
266
+ }
267
+ if (this.offsetValue !== undefined) {
268
+ limitClause += `\nOFFSET ${this.offsetValue}`;
269
+ }
270
+ const sqlText = `WITH ${cteDecls.join(', ')}\n` +
271
+ `SELECT ${selectParts.join(', ')}\n${fromClause}${orderByClause}${limitClause}`;
272
+ return { sql: sqlText, params: ctx.params };
273
+ }
274
+ /** Generate the SQL string (for debugging / assertions). */
275
+ toSql() {
276
+ return this.buildQuery().sql;
277
+ }
278
+ /** Execute and return all rows. */
279
+ async toList() {
280
+ const { sql: sqlText, params } = this.buildQuery();
281
+ const result = this.executor
282
+ ? await this.executor.query(sqlText, params)
283
+ : await this.client.query(sqlText, params);
284
+ const selection = this.evaluateSelection();
285
+ return transformRows(result.rows, selection);
286
+ }
287
+ /** Execute and return the first row, or null. */
288
+ async first() {
289
+ const results = await this.limit(1).toList();
290
+ return results.length > 0 ? results[0] : null;
291
+ }
292
+ /** Evaluate the user selector against fresh CTE FieldRef proxies. */
293
+ evaluateSelection() {
294
+ const rootMock = createCteFieldRefProxy(this.rootCte);
295
+ const joinMocks = this.joinSteps.map(step => createCteFieldRefProxy(step.cte));
296
+ return this.selector(rootMock, ...joinMocks);
297
+ }
298
+ }
299
+ exports.CteRootQueryBuilder = CteRootQueryBuilder;
300
+ /**
301
+ * The result of joining a CTE onto a CTE-rooted query. Carries the same build
302
+ * machinery as {@link CteRootQueryBuilder} but its `.select(...)` selector
303
+ * receives a FieldRef proxy per source (root first, then each joined CTE in
304
+ * order), and further joins can still be chained.
305
+ */
306
+ class CteJoinedQueryBuilder extends CteRootQueryBuilder {
307
+ constructor() {
308
+ super(...arguments);
309
+ this._joinSteps = [];
310
+ }
311
+ /** @internal */
312
+ _inheritJoins(steps) {
313
+ this._joinSteps = steps;
314
+ this._setState(steps, undefined, [], undefined, undefined);
315
+ }
316
+ select(selector) {
317
+ const next = new CteRootQueryBuilder(this._getRootCte(), this.client, this.executor);
318
+ next._setState(this._joinSteps, selector, [], undefined, undefined);
319
+ return next;
320
+ }
321
+ /**
322
+ * Typed `fullOuterJoin` that exposes both already-joined sources (root +
323
+ * first right) to the predicate. (Re-declared so the chained right side keeps
324
+ * a useful element type rather than collapsing to the base signature.)
325
+ */
326
+ fullOuterJoin(cte, condition) {
327
+ return super.fullOuterJoin(cte, condition);
328
+ }
329
+ }
330
+ exports.CteJoinedQueryBuilder = CteJoinedQueryBuilder;
331
+ /**
332
+ * Build SELECT list fragments from a projection object whose leaves are
333
+ * FieldRefs (qualified with their CTE/table alias), SqlFragments, or literals.
334
+ */
335
+ function buildSelectParts(selection, ctx, defaultAlias) {
336
+ const parts = [];
337
+ for (const [key, value] of Object.entries(selection)) {
338
+ if (value instanceof conditions_1.SqlFragment) {
339
+ const fragmentSql = value.buildSql(ctx);
340
+ parts.push(`${fragmentSql} as "${key}"`);
341
+ }
342
+ else if (typeof value === 'object' && value !== null && '__dbColumnName' in value) {
343
+ const alias = value.__tableAlias || defaultAlias;
344
+ parts.push(`"${alias}"."${value.__dbColumnName}" as "${key}"`);
345
+ }
346
+ else if (typeof value === 'string') {
347
+ // Bare column name string — qualify with the root alias.
348
+ parts.push(`"${defaultAlias}"."${value}" as "${key}"`);
349
+ }
350
+ else {
351
+ // Literal value
352
+ ctx.params.push(value);
353
+ parts.push(`$${ctx.paramCounter++} as "${key}"`);
354
+ }
355
+ }
356
+ return parts;
357
+ }
358
+ /**
359
+ * Transform driver rows into the projected shape, re-applying any column /
360
+ * SqlFragment fromDriver mappers and coercing Postgres numeric strings to
361
+ * numbers. NULLs are preserved as `null` (faithful to the SQL — a CTE-rooted
362
+ * projection mirrors raw column output, unlike the entity path which maps
363
+ * absent columns to `undefined`).
364
+ */
365
+ function transformRows(rows, selection) {
366
+ // Pre-analyze each selected field once.
367
+ const fields = [];
368
+ for (const [key, value] of Object.entries(selection)) {
369
+ let mapper;
370
+ if (value && typeof value === 'object' && typeof value.getMapper === 'function') {
371
+ let m = value.getMapper();
372
+ if (m && typeof m.getType === 'function') {
373
+ m = m.getType();
374
+ }
375
+ if (m && typeof m.fromDriver === 'function') {
376
+ mapper = m;
377
+ }
378
+ }
379
+ fields.push({ key, mapper });
380
+ }
381
+ return rows.map(row => {
382
+ const out = {};
383
+ for (const { key, mapper } of fields) {
384
+ const raw = row[key];
385
+ if (mapper) {
386
+ out[key] = mapper.fromDriver(raw);
387
+ }
388
+ else if (typeof raw === 'string' && NUMERIC_REGEX.test(raw)) {
389
+ out[key] = +raw;
390
+ }
391
+ else {
392
+ out[key] = raw;
393
+ }
394
+ }
395
+ return out;
396
+ });
397
+ }
398
+ //# sourceMappingURL=cte-root-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cte-root-query.js","sourceRoot":"","sources":["../../src/query/cte-root-query.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,37 @@ export interface IndexDefinition {
49
49
  */
50
50
  requiresSearchNormalize?: boolean;
51
51
  }
52
+ /**
53
+ * PostgreSQL declarative-partitioning strategy.
54
+ * - `'range'` — partition by ranges of the key (e.g. dates).
55
+ * - `'list'` — partition by an explicit list of key values.
56
+ * - `'hash'` — partition by hash of the key (even distribution).
57
+ */
58
+ export type PartitionStrategy = 'range' | 'list' | 'hash';
59
+ /**
60
+ * Declarative table-partitioning configuration — describes the parent table's
61
+ * `PARTITION BY <strategy> (<key>)` clause. Child partitions (`PARTITION OF ...
62
+ * FOR VALUES ...`) are managed separately (they are typically created/rotated at
63
+ * runtime), so they are not part of this declaration.
64
+ *
65
+ * PostgreSQL requires every partition-key column to be included in the table's
66
+ * PRIMARY KEY / UNIQUE constraints.
67
+ */
68
+ export interface PartitioningConfig {
69
+ /** Partitioning strategy: RANGE, LIST, or HASH. */
70
+ strategy: PartitionStrategy;
71
+ /**
72
+ * Partition-key columns (database column names). Mutually exclusive with
73
+ * {@link expression}.
74
+ */
75
+ columns?: string[];
76
+ /**
77
+ * Raw partition-key expression — the contents of the `PARTITION BY <strategy>
78
+ * (...)` parentheses, e.g. `date_trunc('month', created_at)`. Mutually
79
+ * exclusive with {@link columns}.
80
+ */
81
+ expression?: string;
82
+ }
52
83
  /**
53
84
  * Foreign key action type
54
85
  */
@@ -87,6 +118,8 @@ export interface TableSchema<TColumns extends Record<string, ColumnBuilder> = an
87
118
  relations: Record<string, RelationConfig>;
88
119
  indexes: IndexDefinition[];
89
120
  foreignKeys: ForeignKeyConstraint[];
121
+ /** Declarative partitioning config for this table (parent `PARTITION BY`). */
122
+ partitioning?: PartitioningConfig;
90
123
  /**
91
124
  * Performance optimization: Pre-computed map of property names to database column names
92
125
  * Avoids repeated .build().name calls during query building
@@ -146,8 +179,15 @@ export declare class TableBuilder<TSchema extends SchemaDefinition = any> {
146
179
  private relationDefs;
147
180
  private indexDefs;
148
181
  private foreignKeyDefs;
182
+ private partitioningDef?;
149
183
  constructor(name: string, schema: TSchema, indexes?: IndexDefinition[], foreignKeys?: ForeignKeyConstraint[], schemaName?: string);
150
184
  private _cachedSchema?;
185
+ /**
186
+ * Configure declarative table partitioning (the parent `PARTITION BY` clause).
187
+ * @example
188
+ * builder.partitionBy({ strategy: 'range', columns: ['created_at'] });
189
+ */
190
+ partitionBy(config: PartitioningConfig): this;
151
191
  /**
152
192
  * Build the final table schema
153
193
  */