2023-10-19 15:22:12 -04:00
|
|
|
import { PartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
|
2021-01-20 09:15:01 -06:00
|
|
|
import * as DataModels from "../Contracts/DataModels";
|
|
|
|
import * as ViewModels from "../Contracts/ViewModels";
|
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
export function buildDocumentsQuery(
|
|
|
|
filter: string,
|
2022-04-21 13:37:02 -07:00
|
|
|
partitionKeyProperties: string[],
|
2023-10-03 15:13:24 +00:00
|
|
|
partitionKey: DataModels.PartitionKey,
|
2021-03-30 07:56:41 +05:30
|
|
|
): string {
|
2022-04-21 13:37:02 -07:00
|
|
|
let query =
|
|
|
|
partitionKeyProperties && partitionKeyProperties.length > 0
|
|
|
|
? `select c.id, c._self, c._rid, c._ts, [${buildDocumentsQueryPartitionProjections(
|
|
|
|
"c",
|
2023-10-03 15:13:24 +00:00
|
|
|
partitionKey,
|
2022-04-21 13:37:02 -07:00
|
|
|
)}] as _partitionKeyValue from c`
|
|
|
|
: `select c.id, c._self, c._rid, c._ts from c`;
|
2021-01-20 09:15:01 -06:00
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
if (filter) {
|
|
|
|
query += " " + filter;
|
2021-01-20 09:15:01 -06:00
|
|
|
}
|
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
return query;
|
|
|
|
}
|
2021-01-20 09:15:01 -06:00
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
export function buildDocumentsQueryPartitionProjections(
|
|
|
|
collectionAlias: string,
|
2023-10-03 15:13:24 +00:00
|
|
|
partitionKey?: DataModels.PartitionKey,
|
2021-03-30 07:56:41 +05:30
|
|
|
): string {
|
|
|
|
if (!partitionKey) {
|
|
|
|
return "";
|
|
|
|
}
|
2021-01-20 09:15:01 -06:00
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
// e.g., path /order/id will be projected as c["order"]["id"],
|
|
|
|
// to escape any property names that match a keyword
|
|
|
|
const projections = [];
|
|
|
|
for (const index in partitionKey.paths) {
|
|
|
|
// TODO: Handle "/" in partition key definitions
|
|
|
|
const projectedProperties: string[] = partitionKey.paths[index].split("/").slice(1);
|
|
|
|
let projectedProperty = "";
|
2021-01-20 09:15:01 -06:00
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
projectedProperties.forEach((property: string) => {
|
|
|
|
const projection = property.trim();
|
|
|
|
if (projection.length > 0 && projection.charAt(0) !== "'" && projection.charAt(0) !== '"') {
|
|
|
|
projectedProperty += `["${projection}"]`;
|
|
|
|
} else if (projection.length > 0 && projection.charAt(0) === "'") {
|
|
|
|
// trim single quotes and escape double quotes
|
|
|
|
const projectionSlice = projection.slice(1, projection.length - 1);
|
|
|
|
projectedProperty += `["${projectionSlice.replace(/\\"/g, '"').replace(/"/g, '\\\\\\"')}"]`;
|
|
|
|
} else {
|
|
|
|
projectedProperty += `[${projection}]`;
|
|
|
|
}
|
|
|
|
});
|
2021-01-20 09:15:01 -06:00
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
projections.push(`${collectionAlias}${projectedProperty}`);
|
2021-01-20 09:15:01 -06:00
|
|
|
}
|
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
return projections.join(",");
|
|
|
|
}
|
|
|
|
|
|
|
|
export const queryPagesUntilContentPresent = async (
|
|
|
|
firstItemIndex: number,
|
2023-10-03 15:13:24 +00:00
|
|
|
queryItems: (itemIndex: number) => Promise<ViewModels.QueryResults>,
|
2021-03-30 07:56:41 +05:30
|
|
|
): Promise<ViewModels.QueryResults> => {
|
|
|
|
let roundTrips = 0;
|
|
|
|
let netRequestCharge = 0;
|
|
|
|
const doRequest = async (itemIndex: number): Promise<ViewModels.QueryResults> => {
|
|
|
|
const results = await queryItems(itemIndex);
|
|
|
|
roundTrips = roundTrips + 1;
|
|
|
|
results.roundTrips = roundTrips;
|
|
|
|
results.requestCharge = Number(results.requestCharge) + netRequestCharge;
|
|
|
|
netRequestCharge = Number(results.requestCharge);
|
|
|
|
const resultsMetadata = {
|
|
|
|
hasMoreResults: results.hasMoreResults,
|
|
|
|
itemCount: results.itemCount,
|
|
|
|
firstItemIndex: results.firstItemIndex,
|
|
|
|
lastItemIndex: results.lastItemIndex,
|
2021-01-20 09:15:01 -06:00
|
|
|
};
|
2021-03-30 07:56:41 +05:30
|
|
|
if (resultsMetadata.itemCount === 0 && resultsMetadata.hasMoreResults) {
|
|
|
|
return await doRequest(resultsMetadata.lastItemIndex);
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
};
|
2021-01-20 09:15:01 -06:00
|
|
|
|
2021-03-30 07:56:41 +05:30
|
|
|
return await doRequest(firstItemIndex);
|
|
|
|
};
|
2023-10-19 15:22:12 -04:00
|
|
|
|
|
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
|
|
export const extractPartitionKeyValues = (
|
|
|
|
documentContent: any,
|
|
|
|
partitionKeyDefinition: PartitionKeyDefinition,
|
|
|
|
): PartitionKey[] => {
|
|
|
|
if (!partitionKeyDefinition.paths || partitionKeyDefinition.paths.length === 0) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
const partitionKeyValues: PartitionKey[] = [];
|
|
|
|
partitionKeyDefinition.paths.forEach((partitionKeyPath: string) => {
|
|
|
|
const partitionKeyPathWithoutSlash: string = partitionKeyPath.substring(1);
|
2024-08-13 10:00:34 -07:00
|
|
|
partitionKeyValues.push(documentContent[partitionKeyPathWithoutSlash]);
|
2023-10-19 15:22:12 -04:00
|
|
|
});
|
|
|
|
return partitionKeyValues;
|
|
|
|
};
|