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.
- package/LICENSE +21 -21
- package/README.md +196 -196
- package/dist/entity/db-column.d.ts +38 -1
- package/dist/entity/db-column.d.ts.map +1 -1
- package/dist/entity/db-column.js.map +1 -1
- package/dist/entity/db-context.d.ts +429 -50
- package/dist/entity/db-context.d.ts.map +1 -1
- package/dist/entity/db-context.js +884 -203
- package/dist/entity/db-context.js.map +1 -1
- package/dist/entity/entity-base.d.ts +8 -0
- package/dist/entity/entity-base.d.ts.map +1 -1
- package/dist/entity/entity-base.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/migration/db-schema-manager.js +77 -77
- package/dist/migration/enum-migrator.js +6 -6
- package/dist/query/collection-strategy.factory.d.ts.map +1 -1
- package/dist/query/collection-strategy.factory.js +7 -3
- package/dist/query/collection-strategy.factory.js.map +1 -1
- package/dist/query/collection-strategy.interface.d.ts +12 -6
- package/dist/query/collection-strategy.interface.d.ts.map +1 -1
- package/dist/query/conditions.d.ts +178 -24
- package/dist/query/conditions.d.ts.map +1 -1
- package/dist/query/conditions.js +165 -4
- package/dist/query/conditions.js.map +1 -1
- package/dist/query/cte-builder.d.ts +21 -5
- package/dist/query/cte-builder.d.ts.map +1 -1
- package/dist/query/cte-builder.js +31 -7
- package/dist/query/cte-builder.js.map +1 -1
- package/dist/query/grouped-query.d.ts +185 -8
- package/dist/query/grouped-query.d.ts.map +1 -1
- package/dist/query/grouped-query.js +516 -30
- package/dist/query/grouped-query.js.map +1 -1
- package/dist/query/join-builder.d.ts +5 -4
- package/dist/query/join-builder.d.ts.map +1 -1
- package/dist/query/join-builder.js +11 -33
- package/dist/query/join-builder.js.map +1 -1
- package/dist/query/query-builder.d.ts +89 -20
- package/dist/query/query-builder.d.ts.map +1 -1
- package/dist/query/query-builder.js +317 -168
- package/dist/query/query-builder.js.map +1 -1
- package/dist/query/query-utils.d.ts +45 -0
- package/dist/query/query-utils.d.ts.map +1 -0
- package/dist/query/query-utils.js +103 -0
- package/dist/query/query-utils.js.map +1 -0
- package/dist/query/sql-utils.d.ts +83 -0
- package/dist/query/sql-utils.d.ts.map +1 -0
- package/dist/query/sql-utils.js +218 -0
- package/dist/query/sql-utils.js.map +1 -0
- package/dist/query/strategies/cte-collection-strategy.d.ts +85 -0
- package/dist/query/strategies/cte-collection-strategy.d.ts.map +1 -0
- package/dist/query/strategies/cte-collection-strategy.js +338 -0
- package/dist/query/strategies/cte-collection-strategy.js.map +1 -0
- package/dist/query/strategies/lateral-collection-strategy.d.ts +59 -0
- package/dist/query/strategies/lateral-collection-strategy.d.ts.map +1 -0
- package/dist/query/strategies/lateral-collection-strategy.js +243 -0
- package/dist/query/strategies/lateral-collection-strategy.js.map +1 -0
- package/dist/query/strategies/temptable-collection-strategy.d.ts +21 -0
- package/dist/query/strategies/temptable-collection-strategy.d.ts.map +1 -1
- package/dist/query/strategies/temptable-collection-strategy.js +216 -94
- package/dist/query/strategies/temptable-collection-strategy.js.map +1 -1
- package/dist/query/subquery.d.ts +24 -1
- package/dist/query/subquery.d.ts.map +1 -1
- package/dist/query/subquery.js +38 -2
- package/dist/query/subquery.js.map +1 -1
- package/package.json +1 -1
- package/dist/query/strategies/jsonb-collection-strategy.d.ts +0 -51
- package/dist/query/strategies/jsonb-collection-strategy.d.ts.map +0 -1
- package/dist/query/strategies/jsonb-collection-strategy.js +0 -210
- package/dist/query/strategies/jsonb-collection-strategy.js.map +0 -1
package/dist/query/subquery.js
CHANGED
|
@@ -19,16 +19,22 @@ const conditions_1 = require("./conditions");
|
|
|
19
19
|
* TMode: 'scalar' | 'array' | 'table' - determines how the subquery can be used
|
|
20
20
|
*/
|
|
21
21
|
class Subquery {
|
|
22
|
-
constructor(sqlBuilder, mode = 'table', selectionMetadata) {
|
|
22
|
+
constructor(sqlBuilder, mode = 'table', selectionMetadata, outerFieldRefs) {
|
|
23
|
+
/**
|
|
24
|
+
* Field refs from outer queries used inside this subquery's WHERE condition.
|
|
25
|
+
* These need to be propagated to the outer query so it can add necessary JOINs.
|
|
26
|
+
*/
|
|
27
|
+
this.outerFieldRefs = [];
|
|
23
28
|
this.sqlBuilder = sqlBuilder;
|
|
24
29
|
this.__mode = mode;
|
|
25
30
|
this.selectionMetadata = selectionMetadata;
|
|
31
|
+
this.outerFieldRefs = outerFieldRefs || [];
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* Set an alias for this subquery (used when subquery is a table source)
|
|
29
35
|
*/
|
|
30
36
|
as(alias) {
|
|
31
|
-
const clone = new Subquery(this.sqlBuilder, this.__mode, this.selectionMetadata);
|
|
37
|
+
const clone = new Subquery(this.sqlBuilder, this.__mode, this.selectionMetadata, this.outerFieldRefs);
|
|
32
38
|
clone.alias = alias;
|
|
33
39
|
return clone;
|
|
34
40
|
}
|
|
@@ -50,6 +56,13 @@ class Subquery {
|
|
|
50
56
|
getSelectionMetadata() {
|
|
51
57
|
return this.selectionMetadata;
|
|
52
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Get field refs from outer queries used inside this subquery.
|
|
61
|
+
* These need to be propagated to the outer query for JOIN detection.
|
|
62
|
+
*/
|
|
63
|
+
getOuterFieldRefs() {
|
|
64
|
+
return this.outerFieldRefs;
|
|
65
|
+
}
|
|
53
66
|
/**
|
|
54
67
|
* Check if this is a scalar subquery
|
|
55
68
|
*/
|
|
@@ -84,6 +97,13 @@ class ExistsCondition extends conditions_1.WhereConditionBase {
|
|
|
84
97
|
super();
|
|
85
98
|
this.subquery = subquery;
|
|
86
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Get field refs from outer queries used inside this subquery.
|
|
102
|
+
* These are propagated to enable JOIN detection in the outer query.
|
|
103
|
+
*/
|
|
104
|
+
getFieldRefs() {
|
|
105
|
+
return this.subquery.getOuterFieldRefs();
|
|
106
|
+
}
|
|
87
107
|
buildSql(context) {
|
|
88
108
|
const subquerySql = this.subquery.buildSql(context);
|
|
89
109
|
return `EXISTS (${subquerySql})`;
|
|
@@ -98,6 +118,13 @@ class NotExistsCondition extends conditions_1.WhereConditionBase {
|
|
|
98
118
|
super();
|
|
99
119
|
this.subquery = subquery;
|
|
100
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Get field refs from outer queries used inside this subquery.
|
|
123
|
+
* These are propagated to enable JOIN detection in the outer query.
|
|
124
|
+
*/
|
|
125
|
+
getFieldRefs() {
|
|
126
|
+
return this.subquery.getOuterFieldRefs();
|
|
127
|
+
}
|
|
101
128
|
buildSql(context) {
|
|
102
129
|
const subquerySql = this.subquery.buildSql(context);
|
|
103
130
|
return `NOT EXISTS (${subquerySql})`;
|
|
@@ -114,6 +141,9 @@ class InSubqueryCondition extends conditions_1.WhereConditionBase {
|
|
|
114
141
|
this.field = field;
|
|
115
142
|
this.subquery = subquery;
|
|
116
143
|
}
|
|
144
|
+
getFieldRefs() {
|
|
145
|
+
return [this.field];
|
|
146
|
+
}
|
|
117
147
|
buildSql(context) {
|
|
118
148
|
const fieldName = this.getDbColumnName(this.field);
|
|
119
149
|
const subquerySql = this.subquery.buildSql(context);
|
|
@@ -130,6 +160,9 @@ class NotInSubqueryCondition extends conditions_1.WhereConditionBase {
|
|
|
130
160
|
this.field = field;
|
|
131
161
|
this.subquery = subquery;
|
|
132
162
|
}
|
|
163
|
+
getFieldRefs() {
|
|
164
|
+
return [this.field];
|
|
165
|
+
}
|
|
133
166
|
buildSql(context) {
|
|
134
167
|
const fieldName = this.getDbColumnName(this.field);
|
|
135
168
|
const subquerySql = this.subquery.buildSql(context);
|
|
@@ -148,6 +181,9 @@ class ScalarSubqueryComparison extends conditions_1.WhereConditionBase {
|
|
|
148
181
|
this.operator = operator;
|
|
149
182
|
this.subquery = subquery;
|
|
150
183
|
}
|
|
184
|
+
getFieldRefs() {
|
|
185
|
+
return [this.field];
|
|
186
|
+
}
|
|
151
187
|
buildSql(context) {
|
|
152
188
|
const fieldName = this.getDbColumnName(this.field);
|
|
153
189
|
const subquerySql = this.subquery.buildSql(context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subquery.js","sourceRoot":"","sources":["../../src/query/subquery.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"subquery.js","sourceRoot":"","sources":["../../src/query/subquery.ts"],"names":[],"mappings":";;;AAsHA,gCAEC;AA0HD,wBAEC;AAKD,8BAEC;AAKD,gCAKC;AAKD,sCAKC;AAKD,gCAKC;AAED,gCAKC;AAED,gCAKC;AAED,kCAKC;AAED,gCAKC;AAED,kCAKC;AA5TD,6CAA6E;AAE7E;;;;GAIG;AACH,MAAa,QAAQ;IA4BnB,YACE,UAA0E,EAC1E,OAAc,OAAgB,EAC9B,iBAAuC,EACvC,cAA2B;QAhB7B;;;WAGG;QACK,mBAAc,GAAe,EAAE,CAAC;QActC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,cAAc,GAAG,cAAc,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,EAAE,CAAC,KAAa;QACd,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAiB,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAe,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/H,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,OAAkD;QACzD,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,oBAAoB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC;IACjC,CAAC;CACF;AAlGD,4BAkGC;AAUD;;GAEG;AACH,SAAgB,UAAU,CAAC,KAAU;IACnC,OAAO,KAAK,YAAY,QAAQ,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAa,eAAgB,SAAQ,+BAAkB;IACrD,YAAoB,QAAkB;QACpC,KAAK,EAAE,CAAC;QADU,aAAQ,GAAR,QAAQ,CAAU;IAEtC,CAAC;IAED;;;OAGG;IACM,YAAY;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAC3C,CAAC;IAED,QAAQ,CAAC,OAAwB;QAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,WAAW,WAAW,GAAG,CAAC;IACnC,CAAC;CACF;AAjBD,0CAiBC;AAED;;GAEG;AACH,MAAa,kBAAmB,SAAQ,+BAAkB;IACxD,YAAoB,QAAkB;QACpC,KAAK,EAAE,CAAC;QADU,aAAQ,GAAR,QAAQ,CAAU;IAEtC,CAAC;IAED;;;OAGG;IACM,YAAY;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;IAC3C,CAAC;IAED,QAAQ,CAAC,OAAwB;QAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,eAAe,WAAW,GAAG,CAAC;IACvC,CAAC;CACF;AAjBD,gDAiBC;AAED;;;GAGG;AACH,MAAa,mBAAuB,SAAQ,+BAAkB;IAC5D,YACU,KAAuB,EACvB,QAAgC;QAExC,KAAK,EAAE,CAAC;QAHA,UAAK,GAAL,KAAK,CAAkB;QACvB,aAAQ,GAAR,QAAQ,CAAwB;IAG1C,CAAC;IAEQ,YAAY;QACnB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,QAAQ,CAAC,OAAwB;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,GAAG,SAAS,QAAQ,WAAW,GAAG,CAAC;IAC5C,CAAC;CACF;AAjBD,kDAiBC;AAED;;GAEG;AACH,MAAa,sBAA0B,SAAQ,+BAAkB;IAC/D,YACU,KAAuB,EACvB,QAAgC;QAExC,KAAK,EAAE,CAAC;QAHA,UAAK,GAAL,KAAK,CAAkB;QACvB,aAAQ,GAAR,QAAQ,CAAwB;IAG1C,CAAC;IAEQ,YAAY;QACnB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,QAAQ,CAAC,OAAwB;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,GAAG,SAAS,YAAY,WAAW,GAAG,CAAC;IAChD,CAAC;CACF;AAjBD,wDAiBC;AAED;;;GAGG;AACH,MAAa,wBAA4B,SAAQ,+BAAkB;IACjE,YACU,KAAuB,EACvB,QAA8C,EAC9C,QAA+B;QAEvC,KAAK,EAAE,CAAC;QAJA,UAAK,GAAL,KAAK,CAAkB;QACvB,aAAQ,GAAR,QAAQ,CAAsC;QAC9C,aAAQ,GAAR,QAAQ,CAAuB;IAGzC,CAAC;IAEQ,YAAY;QACnB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,QAAQ,CAAC,OAAwB;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW,GAAG,CAAC;IAC1D,CAAC;CACF;AAlBD,4DAkBC;AAED;;GAEG;AAEH;;GAEG;AACH,SAAgB,MAAM,CAAC,QAAkB;IACvC,OAAO,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,QAAkB;IAC1C,OAAO,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CACxB,KAAuB,EACvB,QAAgC;IAEhC,OAAO,IAAI,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAC3B,KAAuB,EACvB,QAAgC;IAEhC,OAAO,IAAI,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CACxB,KAAuB,EACvB,QAA+B;IAE/B,OAAO,IAAI,wBAAwB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,UAAU,CACxB,KAAuB,EACvB,QAA+B;IAE/B,OAAO,IAAI,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED,SAAgB,UAAU,CACxB,KAAuB,EACvB,QAA+B;IAE/B,OAAO,IAAI,wBAAwB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,WAAW,CACzB,KAAuB,EACvB,QAA+B;IAE/B,OAAO,IAAI,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED,SAAgB,UAAU,CACxB,KAAuB,EACvB,QAA+B;IAE/B,OAAO,IAAI,wBAAwB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,WAAW,CACzB,KAAuB,EACvB,QAA+B;IAE/B,OAAO,IAAI,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { ICollectionStrategy, CollectionStrategyType, CollectionAggregationConfig, CollectionAggregationResult } from '../collection-strategy.interface';
|
|
2
|
-
import { QueryContext } from '../query-builder';
|
|
3
|
-
/**
|
|
4
|
-
* JSONB-based collection strategy using CTEs
|
|
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 JsonbCollectionStrategy implements ICollectionStrategy {
|
|
35
|
-
getType(): CollectionStrategyType;
|
|
36
|
-
requiresParentIds(): boolean;
|
|
37
|
-
buildAggregation(config: CollectionAggregationConfig, context: QueryContext): CollectionAggregationResult;
|
|
38
|
-
/**
|
|
39
|
-
* Build JSONB aggregation CTE
|
|
40
|
-
*/
|
|
41
|
-
private buildJsonbAggregation;
|
|
42
|
-
/**
|
|
43
|
-
* Build array aggregation CTE (for toNumberList/toStringList)
|
|
44
|
-
*/
|
|
45
|
-
private buildArrayAggregation;
|
|
46
|
-
/**
|
|
47
|
-
* Build scalar aggregation CTE (COUNT, MIN, MAX, SUM)
|
|
48
|
-
*/
|
|
49
|
-
private buildScalarAggregation;
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=jsonb-collection-strategy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsonb-collection-strategy.d.ts","sourceRoot":"","sources":["../../../src/query/strategies/jsonb-collection-strategy.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC5B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,OAAO,IAAI,sBAAsB;IAIjC,iBAAiB,IAAI,OAAO;IAK5B,gBAAgB,CACd,MAAM,EAAE,2BAA2B,EACnC,OAAO,EAAE,YAAY,GACpB,2BAA2B;IA0C9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgE7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsD7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAuC/B"}
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JsonbCollectionStrategy = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* JSONB-based collection strategy using CTEs
|
|
6
|
-
*
|
|
7
|
-
* This is the current/default strategy that uses PostgreSQL CTEs with jsonb_agg
|
|
8
|
-
* to aggregate related records into JSONB arrays.
|
|
9
|
-
*
|
|
10
|
-
* Benefits:
|
|
11
|
-
* - Single query execution
|
|
12
|
-
* - No temp table management
|
|
13
|
-
* - Works well for moderate data sizes
|
|
14
|
-
*
|
|
15
|
-
* SQL Pattern:
|
|
16
|
-
* ```sql
|
|
17
|
-
* WITH "cte_0" AS (
|
|
18
|
-
* SELECT
|
|
19
|
-
* "user_id" as parent_id,
|
|
20
|
-
* jsonb_agg(
|
|
21
|
-
* jsonb_build_object('id', "id", 'title', "title")
|
|
22
|
-
* ORDER BY "views" DESC
|
|
23
|
-
* ) as data
|
|
24
|
-
* FROM (
|
|
25
|
-
* SELECT "user_id", "id", "title", "views"
|
|
26
|
-
* FROM "posts"
|
|
27
|
-
* WHERE "views" > $1
|
|
28
|
-
* ORDER BY "views" DESC
|
|
29
|
-
* ) sub
|
|
30
|
-
* GROUP BY "user_id"
|
|
31
|
-
* )
|
|
32
|
-
* SELECT ... COALESCE("cte_0".data, '[]'::jsonb) as "posts" ...
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
class JsonbCollectionStrategy {
|
|
36
|
-
getType() {
|
|
37
|
-
return 'jsonb';
|
|
38
|
-
}
|
|
39
|
-
requiresParentIds() {
|
|
40
|
-
// JSONB strategy doesn't need parent IDs upfront - it aggregates for all parents
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
buildAggregation(config, context) {
|
|
44
|
-
const cteName = `cte_${config.counter}`;
|
|
45
|
-
let cteSQL;
|
|
46
|
-
let selectExpression;
|
|
47
|
-
switch (config.aggregationType) {
|
|
48
|
-
case 'jsonb':
|
|
49
|
-
cteSQL = this.buildJsonbAggregation(config, cteName, context);
|
|
50
|
-
selectExpression = `COALESCE("${cteName}".data, ${config.defaultValue})`;
|
|
51
|
-
break;
|
|
52
|
-
case 'array':
|
|
53
|
-
cteSQL = this.buildArrayAggregation(config, cteName, context);
|
|
54
|
-
selectExpression = `COALESCE("${cteName}".data, ${config.defaultValue})`;
|
|
55
|
-
break;
|
|
56
|
-
case 'count':
|
|
57
|
-
case 'min':
|
|
58
|
-
case 'max':
|
|
59
|
-
case 'sum':
|
|
60
|
-
cteSQL = this.buildScalarAggregation(config, cteName, context);
|
|
61
|
-
selectExpression = `COALESCE("${cteName}".data, ${config.defaultValue})`;
|
|
62
|
-
break;
|
|
63
|
-
default:
|
|
64
|
-
throw new Error(`Unknown aggregation type: ${config.aggregationType}`);
|
|
65
|
-
}
|
|
66
|
-
// Store CTE in context
|
|
67
|
-
context.ctes.set(cteName, { sql: cteSQL, params: [] });
|
|
68
|
-
return {
|
|
69
|
-
sql: cteSQL,
|
|
70
|
-
params: context.allParams,
|
|
71
|
-
tableName: cteName,
|
|
72
|
-
joinClause: `LEFT JOIN "${cteName}" ON "${config.sourceTable}"."id" = "${cteName}".parent_id`,
|
|
73
|
-
selectExpression,
|
|
74
|
-
isCTE: true,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Build JSONB aggregation CTE
|
|
79
|
-
*/
|
|
80
|
-
buildJsonbAggregation(config, cteName, context) {
|
|
81
|
-
const { selectedFields, targetTable, foreignKey, whereClause, orderByClause, limitValue, offsetValue, isDistinct } = config;
|
|
82
|
-
// Build the subquery SELECT fields
|
|
83
|
-
const allSelectFields = [
|
|
84
|
-
`"${foreignKey}" as "__fk_${foreignKey}"`,
|
|
85
|
-
...selectedFields.map(f => {
|
|
86
|
-
// Always add alias if expression doesn't already match the quoted alias
|
|
87
|
-
if (f.expression !== `"${f.alias}"`) {
|
|
88
|
-
return `${f.expression} as "${f.alias}"`;
|
|
89
|
-
}
|
|
90
|
-
return f.expression;
|
|
91
|
-
}),
|
|
92
|
-
];
|
|
93
|
-
// Build the JSONB fields for jsonb_build_object using the aliases from the subquery
|
|
94
|
-
const jsonbFields = selectedFields
|
|
95
|
-
.map(f => `'${f.alias}', "${f.alias}"`)
|
|
96
|
-
.join(', ');
|
|
97
|
-
// Build WHERE clause
|
|
98
|
-
const whereSQL = whereClause ? `WHERE ${whereClause}` : '';
|
|
99
|
-
// Build ORDER BY clause
|
|
100
|
-
const orderBySQL = orderByClause ? `ORDER BY ${orderByClause}` : '';
|
|
101
|
-
// Build LIMIT/OFFSET
|
|
102
|
-
let limitOffsetClause = '';
|
|
103
|
-
if (limitValue !== undefined) {
|
|
104
|
-
limitOffsetClause = `LIMIT ${limitValue}`;
|
|
105
|
-
}
|
|
106
|
-
if (offsetValue !== undefined) {
|
|
107
|
-
limitOffsetClause += ` OFFSET ${offsetValue}`;
|
|
108
|
-
}
|
|
109
|
-
// Build DISTINCT clause
|
|
110
|
-
const distinctClause = isDistinct ? 'DISTINCT ' : '';
|
|
111
|
-
// Build the jsonb_agg ORDER BY clause
|
|
112
|
-
const jsonbAggOrderBy = orderByClause ? ` ORDER BY ${orderByClause}` : '';
|
|
113
|
-
const cteSQL = `
|
|
114
|
-
SELECT
|
|
115
|
-
"__fk_${foreignKey}" as parent_id,
|
|
116
|
-
jsonb_agg(
|
|
117
|
-
jsonb_build_object(${jsonbFields})${jsonbAggOrderBy}
|
|
118
|
-
) as data
|
|
119
|
-
FROM (
|
|
120
|
-
SELECT ${distinctClause}${allSelectFields.join(', ')}
|
|
121
|
-
FROM "${targetTable}"
|
|
122
|
-
${whereSQL}
|
|
123
|
-
${orderBySQL}
|
|
124
|
-
${limitOffsetClause}
|
|
125
|
-
) sub
|
|
126
|
-
GROUP BY "__fk_${foreignKey}"
|
|
127
|
-
`.trim();
|
|
128
|
-
return cteSQL;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Build array aggregation CTE (for toNumberList/toStringList)
|
|
132
|
-
*/
|
|
133
|
-
buildArrayAggregation(config, cteName, context) {
|
|
134
|
-
const { arrayField, targetTable, foreignKey, whereClause, orderByClause, limitValue, offsetValue, isDistinct } = config;
|
|
135
|
-
if (!arrayField) {
|
|
136
|
-
throw new Error('arrayField is required for array aggregation');
|
|
137
|
-
}
|
|
138
|
-
// Build WHERE clause
|
|
139
|
-
const whereSQL = whereClause ? `WHERE ${whereClause}` : '';
|
|
140
|
-
// Build ORDER BY clause
|
|
141
|
-
const orderBySQL = orderByClause ? `ORDER BY ${orderByClause}` : '';
|
|
142
|
-
// Build LIMIT/OFFSET
|
|
143
|
-
let limitOffsetClause = '';
|
|
144
|
-
if (limitValue !== undefined) {
|
|
145
|
-
limitOffsetClause = `LIMIT ${limitValue}`;
|
|
146
|
-
}
|
|
147
|
-
if (offsetValue !== undefined) {
|
|
148
|
-
limitOffsetClause += ` OFFSET ${offsetValue}`;
|
|
149
|
-
}
|
|
150
|
-
// Build DISTINCT clause
|
|
151
|
-
const distinctClause = isDistinct ? 'DISTINCT ' : '';
|
|
152
|
-
// Build the array_agg ORDER BY clause
|
|
153
|
-
const arrayAggOrderBy = orderByClause ? ` ORDER BY ${orderByClause}` : '';
|
|
154
|
-
const cteSQL = `
|
|
155
|
-
SELECT
|
|
156
|
-
"__fk_${foreignKey}" as parent_id,
|
|
157
|
-
array_agg(
|
|
158
|
-
"${arrayField}"${arrayAggOrderBy}
|
|
159
|
-
) as data
|
|
160
|
-
FROM (
|
|
161
|
-
SELECT ${distinctClause}"__fk_${foreignKey}", "${arrayField}"
|
|
162
|
-
FROM (
|
|
163
|
-
SELECT "${foreignKey}" as "__fk_${foreignKey}", "${arrayField}"
|
|
164
|
-
FROM "${targetTable}"
|
|
165
|
-
${whereSQL}
|
|
166
|
-
${orderBySQL}
|
|
167
|
-
${limitOffsetClause}
|
|
168
|
-
) inner_sub
|
|
169
|
-
) sub
|
|
170
|
-
GROUP BY "__fk_${foreignKey}"
|
|
171
|
-
`.trim();
|
|
172
|
-
return cteSQL;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Build scalar aggregation CTE (COUNT, MIN, MAX, SUM)
|
|
176
|
-
*/
|
|
177
|
-
buildScalarAggregation(config, cteName, context) {
|
|
178
|
-
const { aggregationType, aggregateField, targetTable, foreignKey, whereClause } = config;
|
|
179
|
-
// Build WHERE clause
|
|
180
|
-
const whereSQL = whereClause ? `WHERE ${whereClause}` : '';
|
|
181
|
-
// Build aggregation expression
|
|
182
|
-
let aggregateExpression;
|
|
183
|
-
switch (aggregationType) {
|
|
184
|
-
case 'count':
|
|
185
|
-
aggregateExpression = 'COUNT(*)';
|
|
186
|
-
break;
|
|
187
|
-
case 'min':
|
|
188
|
-
case 'max':
|
|
189
|
-
case 'sum':
|
|
190
|
-
if (!aggregateField) {
|
|
191
|
-
throw new Error(`${aggregationType.toUpperCase()} requires an aggregate field`);
|
|
192
|
-
}
|
|
193
|
-
aggregateExpression = `${aggregationType.toUpperCase()}("${aggregateField}")`;
|
|
194
|
-
break;
|
|
195
|
-
default:
|
|
196
|
-
throw new Error(`Unknown aggregation type: ${aggregationType}`);
|
|
197
|
-
}
|
|
198
|
-
const cteSQL = `
|
|
199
|
-
SELECT
|
|
200
|
-
"${foreignKey}" as parent_id,
|
|
201
|
-
${aggregateExpression} as data
|
|
202
|
-
FROM "${targetTable}"
|
|
203
|
-
${whereSQL}
|
|
204
|
-
GROUP BY "${foreignKey}"
|
|
205
|
-
`.trim();
|
|
206
|
-
return cteSQL;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
exports.JsonbCollectionStrategy = JsonbCollectionStrategy;
|
|
210
|
-
//# sourceMappingURL=jsonb-collection-strategy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsonb-collection-strategy.js","sourceRoot":"","sources":["../../../src/query/strategies/jsonb-collection-strategy.ts"],"names":[],"mappings":"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"}
|