@forestadmin-experimental/datasource-cosmos 1.6.2 → 1.6.3
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/dist/collection.d.ts +5 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +42 -15
- package/dist/model-builder/model.d.ts +12 -11
- package/dist/model-builder/model.d.ts.map +1 -1
- package/dist/model-builder/model.js +66 -73
- package/dist/utils/partition-key-extractor.d.ts +19 -0
- package/dist/utils/partition-key-extractor.d.ts.map +1 -0
- package/dist/utils/partition-key-extractor.js +61 -0
- package/package.json +1 -1
package/dist/collection.d.ts
CHANGED
|
@@ -21,5 +21,10 @@ export default class CosmosCollection extends BaseCollection {
|
|
|
21
21
|
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
|
22
22
|
delete(caller: Caller, filter: Filter): Promise<void>;
|
|
23
23
|
aggregate(caller: Caller, filter: Filter, aggregation: Aggregation, limit?: number): Promise<AggregateResult[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get the partition key field name in Forest Admin notation (with -> for nested paths)
|
|
26
|
+
* Converts Cosmos DB path like "/tenantId" or "/address/city" to "tenantId" or "address->city"
|
|
27
|
+
*/
|
|
28
|
+
private getPartitionKeyFieldName;
|
|
24
29
|
}
|
|
25
30
|
//# sourceMappingURL=collection.d.ts.map
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,MAAM,EACN,UAAU,EACV,MAAM,EACN,MAAM,EACN,eAAe,EACf,UAAU,EACV,UAAU,EACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,WAAW,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,MAAM,EACN,UAAU,EACV,MAAM,EACN,MAAM,EACN,eAAe,EACf,UAAU,EACV,UAAU,EACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAMhD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc;IAC1D;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAK;IAEvD,SAAS,CAAC,aAAa,EAAE,WAAW,CAAC;IAErC,OAAO,CAAC,cAAc,CAAiB;gBAGrC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY;IAmB5B;;;OAGG;IACI,kCAAkC,CAAC,qBAAqB,EAAE,MAAM,EAAE,GAAG,IAAI;IAgB1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAkBjE,IAAI,CACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,EAAE,CAAC;IA4ElB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BxE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BrD,SAAS,CACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,EAAE,CAAC;IAgC7B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;CAMjC"}
|
package/dist/collection.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
7
|
const aggregation_converter_1 = __importDefault(require("./utils/aggregation-converter"));
|
|
8
8
|
const model_to_collection_schema_converter_1 = __importDefault(require("./utils/model-to-collection-schema-converter"));
|
|
9
|
+
const partition_key_extractor_1 = require("./utils/partition-key-extractor");
|
|
9
10
|
const query_converter_1 = __importDefault(require("./utils/query-converter"));
|
|
10
11
|
class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
11
12
|
constructor(datasource, model, logger, nativeDriver) {
|
|
@@ -78,9 +79,11 @@ class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
78
79
|
}
|
|
79
80
|
// Build query with projection to only fetch needed fields
|
|
80
81
|
const querySpec = this.queryConverter.getSqlQuerySpec(filter.conditionTree, filteredSort, projection);
|
|
82
|
+
// Extract partition key from filter for single-partition query optimization
|
|
83
|
+
const partitionKey = (0, partition_key_extractor_1.extractPartitionKeyFromFilter)(filter.conditionTree, this.internalModel.getPartitionKeyPath());
|
|
81
84
|
try {
|
|
82
|
-
// Execute the query with pagination
|
|
83
|
-
const recordsResponse = await this.internalModel.query(querySpec, filter.page?.skip, filter.page?.limit);
|
|
85
|
+
// Execute the query with pagination and partition key optimization
|
|
86
|
+
const recordsResponse = await this.internalModel.query(querySpec, filter.page?.skip, filter.page?.limit, partitionKey);
|
|
84
87
|
return recordsResponse;
|
|
85
88
|
}
|
|
86
89
|
catch (error) {
|
|
@@ -102,13 +105,19 @@ class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
102
105
|
}
|
|
103
106
|
async update(caller, filter, patch) {
|
|
104
107
|
try {
|
|
105
|
-
//
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
108
|
+
// Fetch id and partition key field for efficient point operations
|
|
109
|
+
const partitionKeyField = this.getPartitionKeyFieldName();
|
|
110
|
+
const projection = new datasource_toolkit_1.Projection('id', partitionKeyField);
|
|
111
|
+
const records = await this.list(caller, filter, projection);
|
|
112
|
+
if (records.length === 0) {
|
|
109
113
|
return; // Nothing to update
|
|
110
114
|
}
|
|
111
|
-
|
|
115
|
+
// Extract id and partition key pairs for point operations
|
|
116
|
+
const itemsWithPartitionKeys = records.map(record => ({
|
|
117
|
+
id: record.id,
|
|
118
|
+
partitionKey: record[partitionKeyField],
|
|
119
|
+
}));
|
|
120
|
+
await this.internalModel.update(itemsWithPartitionKeys, patch);
|
|
112
121
|
}
|
|
113
122
|
catch (error) {
|
|
114
123
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
@@ -121,13 +130,19 @@ class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
121
130
|
}
|
|
122
131
|
async delete(caller, filter) {
|
|
123
132
|
try {
|
|
124
|
-
//
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
|
|
133
|
+
// Fetch id and partition key field for efficient point operations
|
|
134
|
+
const partitionKeyField = this.getPartitionKeyFieldName();
|
|
135
|
+
const projection = new datasource_toolkit_1.Projection('id', partitionKeyField);
|
|
136
|
+
const records = await this.list(caller, filter, projection);
|
|
137
|
+
if (records.length === 0) {
|
|
128
138
|
return; // Nothing to delete
|
|
129
139
|
}
|
|
130
|
-
|
|
140
|
+
// Extract id and partition key pairs for point operations
|
|
141
|
+
const itemsWithPartitionKeys = records.map(record => ({
|
|
142
|
+
id: record.id,
|
|
143
|
+
partitionKey: record[partitionKeyField],
|
|
144
|
+
}));
|
|
145
|
+
await this.internalModel.delete(itemsWithPartitionKeys);
|
|
131
146
|
}
|
|
132
147
|
catch (error) {
|
|
133
148
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
@@ -142,8 +157,10 @@ class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
142
157
|
try {
|
|
143
158
|
// Build aggregation query
|
|
144
159
|
const querySpec = aggregation_converter_1.default.buildAggregationQuery(aggregation, filter.conditionTree, limit);
|
|
145
|
-
//
|
|
146
|
-
const
|
|
160
|
+
// Extract partition key from filter for single-partition query optimization
|
|
161
|
+
const partitionKey = (0, partition_key_extractor_1.extractPartitionKeyFromFilter)(filter.conditionTree, this.internalModel.getPartitionKeyPath());
|
|
162
|
+
// Execute aggregation query with partition key optimization
|
|
163
|
+
const rawResults = await this.internalModel.aggregateQuery(querySpec, partitionKey);
|
|
147
164
|
// Process results into Forest Admin format
|
|
148
165
|
return aggregation_converter_1.default.processAggregationResults(rawResults, aggregation);
|
|
149
166
|
}
|
|
@@ -156,6 +173,16 @@ class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
156
173
|
throw wrappedError;
|
|
157
174
|
}
|
|
158
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Get the partition key field name in Forest Admin notation (with -> for nested paths)
|
|
178
|
+
* Converts Cosmos DB path like "/tenantId" or "/address/city" to "tenantId" or "address->city"
|
|
179
|
+
*/
|
|
180
|
+
getPartitionKeyFieldName() {
|
|
181
|
+
return this.internalModel
|
|
182
|
+
.getPartitionKeyPath()
|
|
183
|
+
.replace(/^\//, '') // Remove leading slash
|
|
184
|
+
.replace(/\//g, '->'); // Convert nested paths to arrow notation
|
|
185
|
+
}
|
|
159
186
|
}
|
|
160
187
|
/**
|
|
161
188
|
* Maximum nesting depth for sortable fields
|
|
@@ -164,4 +191,4 @@ class CosmosCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
164
191
|
*/
|
|
165
192
|
CosmosCollection.MAX_SORTABLE_NESTING_DEPTH = 2;
|
|
166
193
|
exports.default = CosmosCollection;
|
|
167
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
194
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0Esd0VBV3lDO0FBR3pDLDBGQUFpRTtBQUNqRSx3SEFBMEU7QUFDMUUsNkVBQWdGO0FBQ2hGLDhFQUFxRDtBQUVyRCxNQUFxQixnQkFBaUIsU0FBUSxtQ0FBYztJQVkxRCxZQUNFLFVBQXNCLEVBQ3RCLEtBQWtCLEVBQ2xCLE1BQWMsRUFDZCxZQUEwQjtRQUUxQixJQUFJLENBQUMsS0FBSztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUU5RCxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFNUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFFM0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLHlCQUFjLEVBQUUsQ0FBQztRQUUzQyxNQUFNLFdBQVcsR0FBRyw4Q0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRXZFLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEtBQUssS0FBSztZQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqRSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV2QyxNQUFNLENBQUMsT0FBTyxFQUFFLHNCQUFzQixJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksa0NBQWtDLENBQUMscUJBQStCO1FBQ3ZFLEtBQUssTUFBTSxTQUFTLElBQUkscUJBQXFCLEVBQUUsQ0FBQztZQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJ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
|
|
@@ -8,6 +8,10 @@ export interface CosmosSchema {
|
|
|
8
8
|
indexed?: boolean;
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
+
export interface ItemWithPartitionKey {
|
|
12
|
+
id: string;
|
|
13
|
+
partitionKey: string | number;
|
|
14
|
+
}
|
|
11
15
|
export default class ModelCosmos {
|
|
12
16
|
name: string;
|
|
13
17
|
/**
|
|
@@ -39,19 +43,16 @@ export default class ModelCosmos {
|
|
|
39
43
|
constructor(cosmosClient: CosmosClient, name: string, databaseName: string, containerName: string, partitionKeyPath: string, schema: CosmosSchema, overrideTypeConverter?: OverrideTypeConverter, enableCount?: boolean);
|
|
40
44
|
getCosmosClient(): CosmosClient;
|
|
41
45
|
create(data: RecordData[]): Promise<RecordData[]>;
|
|
42
|
-
update(
|
|
43
|
-
delete(
|
|
44
|
-
query(querySpec: SqlQuerySpec, offset?: number, limit?: number): Promise<RecordData[]>;
|
|
45
|
-
aggregateQuery(querySpec: SqlQuerySpec): Promise<RecordData[]>;
|
|
46
|
-
count(querySpec?: SqlQuerySpec): Promise<number>;
|
|
47
|
-
/**
|
|
48
|
-
* Get items by their IDs (requires scanning as we don't have partition keys)
|
|
49
|
-
*/
|
|
50
|
-
private getItemsByIds;
|
|
46
|
+
update(items: ItemWithPartitionKey[], patch: RecordData): Promise<void>;
|
|
47
|
+
delete(items: ItemWithPartitionKey[]): Promise<void>;
|
|
48
|
+
query(querySpec: SqlQuerySpec, offset?: number, limit?: number, partitionKey?: string | number): Promise<RecordData[]>;
|
|
49
|
+
aggregateQuery(querySpec: SqlQuerySpec, partitionKey?: string | number): Promise<RecordData[]>;
|
|
50
|
+
count(querySpec?: SqlQuerySpec, partitionKey?: string | number): Promise<number>;
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* Convert a SELECT query to a COUNT query
|
|
53
|
+
* Extracts the WHERE clause and creates a COUNT query with the same filters
|
|
53
54
|
*/
|
|
54
|
-
private
|
|
55
|
+
private convertToCountQuery;
|
|
55
56
|
/**
|
|
56
57
|
* Generate a unique ID for new items
|
|
57
58
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model-builder/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAkB,YAAY,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAG7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,MAAM,CAAC,OAAO,OAAO,WAAW;IACvB,IAAI,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,YAAY,CAAS;IAE7B;;OAEG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAe;IAE7B;;OAEG;IACH,OAAO,CAAC,YAAY,CAAe;IAEnC;;OAEG;IACH,OAAO,CAAC,SAAS,CAAY;IAEtB,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAE9C,WAAW,CAAC,EAAE,OAAO,CAAC;gBAG3B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,YAAY,EACpB,qBAAqB,CAAC,EAAE,qBAAqB,EAC7C,WAAW,CAAC,EAAE,OAAO;IAchB,eAAe,IAAI,YAAY;IAIzB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAiCjD,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/model-builder/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAkB,YAAY,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAG7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,MAAM,CAAC,OAAO,OAAO,WAAW;IACvB,IAAI,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,YAAY,CAAS;IAE7B;;OAEG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAe;IAE7B;;OAEG;IACH,OAAO,CAAC,YAAY,CAAe;IAEnC;;OAEG;IACH,OAAO,CAAC,SAAS,CAAY;IAEtB,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAE9C,WAAW,CAAC,EAAE,OAAO,CAAC;gBAG3B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,YAAY,EACpB,qBAAqB,CAAC,EAAE,qBAAqB,EAC7C,WAAW,CAAC,EAAE,OAAO;IAchB,eAAe,IAAI,YAAY;IAIzB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAiCjD,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBvE,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASpD,KAAK,CAChB,SAAS,EAAE,YAAY,EACvB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAC7B,OAAO,CAAC,UAAU,EAAE,CAAC;IAqDX,cAAc,CACzB,SAAS,EAAE,YAAY,EACvB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAC7B,OAAO,CAAC,UAAU,EAAE,CAAC;IAaX,KAAK,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6B7F;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACI,aAAa,IAAI,YAAY;IAIpC;;OAEG;IACI,YAAY,IAAI,SAAS;IAIhC;;OAEG;IACI,mBAAmB,IAAI,MAAM;IAIpC;;OAEG;IACI,eAAe,IAAI,MAAM;IAIhC;;OAEG;IACI,gBAAgB,IAAI,MAAM;CAGlC"}
|
|
@@ -47,45 +47,49 @@ class ModelCosmos {
|
|
|
47
47
|
}
|
|
48
48
|
return createdRecords;
|
|
49
49
|
}
|
|
50
|
-
async update(
|
|
51
|
-
// Cosmos DB requires both id and partition key for updates
|
|
52
|
-
// We need to fetch the items first to get their partition keys
|
|
53
|
-
const itemsToUpdate = await this.getItemsByIds(ids);
|
|
50
|
+
async update(items, patch) {
|
|
54
51
|
// Unflatten the patch to restore nested structure for Cosmos DB
|
|
55
52
|
const unflattenedPatch = serializer_1.default.unflatten(patch);
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
for (const
|
|
59
|
-
|
|
60
|
-
// Deep merge the unflattened patch with the existing item
|
|
61
|
-
const updatedItem = serializer_1.default.deepMerge(item, unflattenedPatch);
|
|
53
|
+
// Use point reads to fetch items (1 RU each) instead of cross-partition query
|
|
54
|
+
// Then perform point updates (also optimized with partition key)
|
|
55
|
+
for (const { id, partitionKey } of items) {
|
|
56
|
+
// Point read: directly fetch item using id + partition key (1 RU)
|
|
62
57
|
// eslint-disable-next-line no-await-in-loop -- Sequential maintains consistency
|
|
63
|
-
await this.container.item(
|
|
58
|
+
const { resource: existingItem } = await this.container.item(id, partitionKey).read();
|
|
59
|
+
if (existingItem) {
|
|
60
|
+
// Deep merge the unflattened patch with the existing item
|
|
61
|
+
const updatedItem = serializer_1.default.deepMerge(existingItem, unflattenedPatch);
|
|
62
|
+
// Point update: directly update using id + partition key
|
|
63
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential maintains consistency
|
|
64
|
+
await this.container.item(id, partitionKey).replace(updatedItem);
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
|
-
async delete(
|
|
67
|
-
//
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
// to ensure consistency and prevent conflicts
|
|
71
|
-
for (const item of itemsToDelete) {
|
|
72
|
-
const partitionKeyValue = this.getPartitionKeyValue(item);
|
|
68
|
+
async delete(items) {
|
|
69
|
+
// Use point deletes with id + partition key (optimized, no cross-partition scan needed)
|
|
70
|
+
for (const { id, partitionKey } of items) {
|
|
71
|
+
// Point delete: directly delete using id + partition key
|
|
73
72
|
// eslint-disable-next-line no-await-in-loop -- Sequential maintains consistency
|
|
74
|
-
await this.container.item(
|
|
73
|
+
await this.container.item(id, partitionKey).delete();
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
|
-
async query(querySpec, offset, limit) {
|
|
76
|
+
async query(querySpec, offset, limit, partitionKey) {
|
|
77
|
+
// Build query options
|
|
78
|
+
const queryOptions = {};
|
|
79
|
+
// Add partition key if provided (enables single-partition query optimization)
|
|
80
|
+
if (partitionKey !== undefined) {
|
|
81
|
+
queryOptions.partitionKey = partitionKey;
|
|
82
|
+
}
|
|
78
83
|
// If no pagination parameters, fetch all (backward compatibility)
|
|
79
84
|
if (offset === undefined && limit === undefined) {
|
|
80
|
-
const { resources } = await this.container.items.query(querySpec).fetchAll();
|
|
85
|
+
const { resources } = await this.container.items.query(querySpec, queryOptions).fetchAll();
|
|
81
86
|
return resources.map(item => serializer_1.default.serialize(item));
|
|
82
87
|
}
|
|
83
88
|
// Use efficient pagination when limit is specified
|
|
84
89
|
// Note: Cosmos DB doesn't support native OFFSET, so we need to skip items client-side
|
|
85
90
|
// but we can still benefit from maxItemCount to limit network transfers
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
});
|
|
91
|
+
queryOptions.maxItemCount = limit ? (offset || 0) + limit : undefined;
|
|
92
|
+
const query = this.container.items.query(querySpec, queryOptions);
|
|
89
93
|
const results = [];
|
|
90
94
|
let itemsFetched = 0;
|
|
91
95
|
const targetCount = (offset || 0) + (limit || 0);
|
|
@@ -109,68 +113,57 @@ class ModelCosmos {
|
|
|
109
113
|
}
|
|
110
114
|
return finalResults.map(item => serializer_1.default.serialize(item));
|
|
111
115
|
}
|
|
112
|
-
async aggregateQuery(querySpec) {
|
|
113
|
-
|
|
116
|
+
async aggregateQuery(querySpec, partitionKey) {
|
|
117
|
+
// Build query options with partition key if provided
|
|
118
|
+
const queryOptions = {};
|
|
119
|
+
if (partitionKey !== undefined) {
|
|
120
|
+
queryOptions.partitionKey = partitionKey;
|
|
121
|
+
}
|
|
122
|
+
const { resources } = await this.container.items.query(querySpec, queryOptions).fetchAll();
|
|
114
123
|
return resources.map(item => serializer_1.default.serialize(item));
|
|
115
124
|
}
|
|
116
|
-
async count(querySpec) {
|
|
125
|
+
async count(querySpec, partitionKey) {
|
|
126
|
+
// Build query options with partition key if provided
|
|
127
|
+
const queryOptions = {};
|
|
128
|
+
if (partitionKey !== undefined) {
|
|
129
|
+
queryOptions.partitionKey = partitionKey;
|
|
130
|
+
}
|
|
117
131
|
if (!querySpec) {
|
|
118
132
|
// Simple count without filters
|
|
119
133
|
const countQuery = {
|
|
120
134
|
query: 'SELECT VALUE COUNT(1) FROM c',
|
|
121
135
|
};
|
|
122
|
-
const { resources } = await this.container.items
|
|
136
|
+
const { resources } = await this.container.items
|
|
137
|
+
.query(countQuery, queryOptions)
|
|
138
|
+
.fetchAll();
|
|
123
139
|
return resources[0] || 0;
|
|
124
140
|
}
|
|
125
|
-
//
|
|
126
|
-
const
|
|
127
|
-
|
|
141
|
+
// Convert the query to a COUNT query to avoid fetching all records
|
|
142
|
+
const countQuery = this.convertToCountQuery(querySpec);
|
|
143
|
+
const { resources } = await this.container.items
|
|
144
|
+
.query(countQuery, queryOptions)
|
|
145
|
+
.fetchAll();
|
|
146
|
+
return resources[0] || 0;
|
|
128
147
|
}
|
|
129
|
-
// INTERNAL HELPER METHODS
|
|
130
148
|
/**
|
|
131
|
-
*
|
|
149
|
+
* Convert a SELECT query to a COUNT query
|
|
150
|
+
* Extracts the WHERE clause and creates a COUNT query with the same filters
|
|
132
151
|
*/
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
152
|
+
convertToCountQuery(querySpec) {
|
|
153
|
+
const { query, parameters } = querySpec;
|
|
154
|
+
// Extract WHERE clause from original query
|
|
155
|
+
// Query format: "SELECT ... FROM c WHERE ... ORDER BY ..."
|
|
156
|
+
const whereMatch = query.match(/WHERE\s+(.+?)(?:\s+ORDER\s+BY|$)/i);
|
|
157
|
+
const whereClause = whereMatch ? whereMatch[1].trim() : '';
|
|
158
|
+
const countQueryString = whereClause
|
|
159
|
+
? `SELECT VALUE COUNT(1) FROM c WHERE ${whereClause}`
|
|
160
|
+
: 'SELECT VALUE COUNT(1) FROM c';
|
|
161
|
+
return {
|
|
162
|
+
query: countQueryString,
|
|
163
|
+
parameters,
|
|
142
164
|
};
|
|
143
|
-
const { resources } = await this.container.items.query(querySpec).fetchAll();
|
|
144
|
-
return resources;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Extract the partition key value from an item
|
|
148
|
-
*/
|
|
149
|
-
getPartitionKeyValue(item) {
|
|
150
|
-
// Remove leading slash from partition key path
|
|
151
|
-
const keyPath = this.partitionKeyPath.replace(/^\//, '');
|
|
152
|
-
// Handle nested paths (e.g., "/address/city")
|
|
153
|
-
const keys = keyPath.split('/');
|
|
154
|
-
let value = item;
|
|
155
|
-
for (const key of keys) {
|
|
156
|
-
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
157
|
-
value = value[key];
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
// Validate that we found a valid partition key value
|
|
164
|
-
if (value === undefined || value === null) {
|
|
165
|
-
throw new Error(`Partition key '${this.partitionKeyPath}' is undefined or null in item. ` +
|
|
166
|
-
`Item ID: ${item.id || 'unknown'}`);
|
|
167
|
-
}
|
|
168
|
-
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
169
|
-
throw new Error(`Partition key '${this.partitionKeyPath}' must be string or number, ` +
|
|
170
|
-
`but got ${typeof value}. Item ID: ${item.id || 'unknown'}`);
|
|
171
|
-
}
|
|
172
|
-
return value;
|
|
173
165
|
}
|
|
166
|
+
// INTERNAL HELPER METHODS
|
|
174
167
|
/**
|
|
175
168
|
* Generate a unique ID for new items
|
|
176
169
|
*/
|
|
@@ -209,4 +202,4 @@ class ModelCosmos {
|
|
|
209
202
|
}
|
|
210
203
|
}
|
|
211
204
|
exports.default = ModelCosmos;
|
|
212
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
205
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbW9kZWwtYnVpbGRlci9tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLG1DQUFvQztBQUdwQyxxRUFBNkM7QUFlN0MsTUFBcUIsV0FBVztJQXFDOUIsWUFDRSxZQUEwQixFQUMxQixJQUFZLEVBQ1osWUFBb0IsRUFDcEIsYUFBcUIsRUFDckIsZ0JBQXdCLEVBQ3hCLE1BQW9CLEVBQ3BCLHFCQUE2QyxFQUM3QyxXQUFxQjtRQUVyQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNqQyxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7UUFDekMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLHFCQUFxQixHQUFHLHFCQUFxQixDQUFDO1FBQ25ELElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBRS9CLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFTSxlQUFlO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBRU0sS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFrQjtRQUNwQyxNQUFNLGNBQWMsR0FBaUIsRUFBRSxDQUFDO1FBRXhDLHlDQUF5QztRQUN6QyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDdkIsU0FBUyxDQUFD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
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ConditionTree } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
export type PartitionKeyValue = string | number | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Extracts the partition key value from a ConditionTree if present.
|
|
5
|
+
*
|
|
6
|
+
* This optimization allows Cosmos DB to target a single partition instead of
|
|
7
|
+
* performing a cross-partition query, significantly reducing RU consumption.
|
|
8
|
+
*
|
|
9
|
+
* The extraction works when:
|
|
10
|
+
* - There's an equality condition (operator = 'Equal') on the partition key field
|
|
11
|
+
* - The condition is at the root level or within an AND branch
|
|
12
|
+
*
|
|
13
|
+
* The extraction does NOT work when:
|
|
14
|
+
* - The partition key is filtered with IN, NotEqual, or range operators
|
|
15
|
+
* - The partition key condition is inside an OR branch (multiple partitions needed)
|
|
16
|
+
* - No filter on partition key exists
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractPartitionKeyFromFilter(conditionTree: ConditionTree | undefined, partitionKeyPath: string): PartitionKeyValue;
|
|
19
|
+
//# sourceMappingURL=partition-key-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partition-key-extractor.d.ts","sourceRoot":"","sources":["../../src/utils/partition-key-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAGd,MAAM,iCAAiC,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AA6C5D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,gBAAgB,EAAE,MAAM,GACvB,iBAAiB,CAUnB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractPartitionKeyFromFilter = void 0;
|
|
4
|
+
function extractFromTree(conditionTree, partitionKeyField) {
|
|
5
|
+
// Handle leaf nodes (single conditions)
|
|
6
|
+
if (conditionTree.operator !== undefined) {
|
|
7
|
+
const leaf = conditionTree;
|
|
8
|
+
// Only extract if it's an equality condition on the partition key field
|
|
9
|
+
if (leaf.field === partitionKeyField && leaf.operator === 'Equal') {
|
|
10
|
+
const { value } = leaf;
|
|
11
|
+
// Partition keys must be string or number
|
|
12
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
// Handle branch nodes (AND/OR conditions)
|
|
19
|
+
if (conditionTree.aggregator !== undefined) {
|
|
20
|
+
const branch = conditionTree;
|
|
21
|
+
// Only extract from AND branches - OR branches require multiple partitions
|
|
22
|
+
if (branch.aggregator === 'And') {
|
|
23
|
+
for (const condition of branch.conditions) {
|
|
24
|
+
const extracted = extractFromTree(condition, partitionKeyField);
|
|
25
|
+
if (extracted !== undefined) {
|
|
26
|
+
return extracted;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// For OR branches, we cannot optimize as we'd need multiple partitions
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extracts the partition key value from a ConditionTree if present.
|
|
37
|
+
*
|
|
38
|
+
* This optimization allows Cosmos DB to target a single partition instead of
|
|
39
|
+
* performing a cross-partition query, significantly reducing RU consumption.
|
|
40
|
+
*
|
|
41
|
+
* The extraction works when:
|
|
42
|
+
* - There's an equality condition (operator = 'Equal') on the partition key field
|
|
43
|
+
* - The condition is at the root level or within an AND branch
|
|
44
|
+
*
|
|
45
|
+
* The extraction does NOT work when:
|
|
46
|
+
* - The partition key is filtered with IN, NotEqual, or range operators
|
|
47
|
+
* - The partition key condition is inside an OR branch (multiple partitions needed)
|
|
48
|
+
* - No filter on partition key exists
|
|
49
|
+
*/
|
|
50
|
+
function extractPartitionKeyFromFilter(conditionTree, partitionKeyPath) {
|
|
51
|
+
if (!conditionTree)
|
|
52
|
+
return undefined;
|
|
53
|
+
// Convert partition key path (e.g., "/tenantId" or "/address/city")
|
|
54
|
+
// to field notation (e.g., "tenantId" or "address->city")
|
|
55
|
+
const partitionKeyField = partitionKeyPath
|
|
56
|
+
.replace(/^\//, '') // Remove leading slash
|
|
57
|
+
.replace(/\//g, '->'); // Convert nested paths to arrow notation
|
|
58
|
+
return extractFromTree(conditionTree, partitionKeyField);
|
|
59
|
+
}
|
|
60
|
+
exports.extractPartitionKeyFromFilter = extractPartitionKeyFromFilter;
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydGl0aW9uLWtleS1leHRyYWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvcGFydGl0aW9uLWtleS1leHRyYWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBUUEsU0FBUyxlQUFlLENBQ3RCLGFBQTRCLEVBQzVCLGlCQUF5QjtJQUV6Qix3Q0FBd0M7SUFDeEMsSUFBSyxhQUFtQyxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNoRSxNQUFNLElBQUksR0FBRyxhQUFrQyxDQUFDO1FBRWhELHdFQUF3RTtRQUN4RSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssaUJBQWlCLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNsRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDO1lBRXZCLDBDQUEwQztZQUMxQyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDM0QsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCwwQ0FBMEM7SUFDMUMsSUFBSyxhQUFxQyxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNwRSxNQUFNLE1BQU0sR0FBRyxhQUFvQyxDQUFDO1FBRXBELDJFQUEyRTtRQUMzRSxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDaEMsS0FBSyxNQUFNLFNBQVMsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztnQkFFaEUsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzVCLE9BQU8sU0FBUyxDQUFDO2dCQUNuQixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCx1RUFBdUU7UUFDdkUsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILFNBQWdCLDZCQUE2QixDQUMzQyxhQUF3QyxFQUN4QyxnQkFBd0I7SUFFeEIsSUFBSSxDQUFDLGFBQWE7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUVyQyxvRUFBb0U7SUFDcEUsMERBQTBEO0lBQzFELE1BQU0saUJBQWlCLEdBQUcsZ0JBQWdCO1NBQ3ZDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsdUJBQXVCO1NBQzFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyx5Q0FBeUM7SUFFbEUsT0FBTyxlQUFlLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDM0QsQ0FBQztBQWJELHNFQWFDIn0=
|