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
|
@@ -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":"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"}
|
|
@@ -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"}
|