@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
303 lines (302 loc) • 10.6 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var documentProducer_exports = {};
__export(documentProducer_exports, {
DocumentProducer: () => DocumentProducer
});
module.exports = __toCommonJS(documentProducer_exports);
var import_common = require("../common/index.js");
var import_defaultQueryExecutionContext = require("./defaultQueryExecutionContext.js");
var import_FetchResult = require("./FetchResult.js");
var import_headerUtils = require("./headerUtils.js");
class DocumentProducer {
/**
* Provides the Target Partition Range Query Execution Context.
* @param clientContext - The service endpoint to use to create the client.
* @param collectionLink - Represents collection link
* @param query - A SQL query.
* @param targetPartitionKeyRange - Query Target Partition key Range
* @hidden
*/
constructor(clientContext, collectionLink, query, targetPartitionKeyRange, options, correlatedActivityId, startEpk, endEpk, populateEpkRangeHeaders = false, filter) {
this.clientContext = clientContext;
this.collectionLink = collectionLink;
this.query = query;
this.targetPartitionKeyRange = targetPartitionKeyRange;
this.fetchResults = [];
this.allFetched = false;
this.err = void 0;
this.previousContinuationToken = void 0;
this.continuationToken = void 0;
this.internalExecutionContext = new import_defaultQueryExecutionContext.DefaultQueryExecutionContext(
options,
this.fetchFunction,
correlatedActivityId
);
this.startEpk = startEpk;
this.endEpk = endEpk;
this.populateEpkRangeHeaders = populateEpkRangeHeaders;
this.filter = filter;
}
collectionLink;
query;
targetPartitionKeyRange;
fetchResults;
allFetched;
err;
previousContinuationToken;
continuationToken;
generation = 0;
internalExecutionContext;
startEpk;
endEpk;
populateEpkRangeHeaders;
filter;
queryExecutionInfo;
peekBufferedItems() {
const bufferedResults = [];
for (let i = 0, done = false; i < this.fetchResults.length && !done; i++) {
const fetchResult = this.fetchResults[i];
switch (fetchResult.fetchResultType) {
case import_FetchResult.FetchResultType.Done:
done = true;
break;
case import_FetchResult.FetchResultType.Exception:
done = true;
break;
case import_FetchResult.FetchResultType.Result:
bufferedResults.push(fetchResult.feedResponse);
break;
}
}
return bufferedResults;
}
fetchFunction = async (diagnosticNode, options, correlatedActivityId) => {
const path = (0, import_common.getPathFromLink)(this.collectionLink, import_common.ResourceType.item);
diagnosticNode.addData({ partitionKeyRangeId: this.targetPartitionKeyRange.id });
const id = (0, import_common.getIdFromLink)(this.collectionLink);
const startEpk = this.populateEpkRangeHeaders ? this.startEpk : void 0;
const endEpk = this.populateEpkRangeHeaders ? this.endEpk : void 0;
return this.clientContext.queryFeed({
path,
resourceType: import_common.ResourceType.item,
resourceId: id,
resultFn: (result) => result.Documents,
query: this.query,
options,
diagnosticNode,
partitionKeyRangeId: this.targetPartitionKeyRange["id"],
correlatedActivityId,
startEpk,
endEpk
});
};
hasMoreResults() {
return this.internalExecutionContext.hasMoreResults() || this.fetchResults.length !== 0;
}
gotSplit() {
if (this.fetchResults.length !== 0) {
const fetchResult = this.fetchResults[0];
if (fetchResult.fetchResultType === import_FetchResult.FetchResultType.Exception) {
if (DocumentProducer._needPartitionKeyRangeCacheRefresh(fetchResult.error)) {
return true;
}
}
}
return false;
}
_updateStates(err, allFetched) {
if (err) {
this.err = err;
return;
}
if (allFetched) {
this.allFetched = true;
}
if (this.internalExecutionContext.continuationToken === this.continuationToken) {
return;
}
this.previousContinuationToken = this.continuationToken;
this.continuationToken = this.internalExecutionContext.continuationToken;
}
static _needPartitionKeyRangeCacheRefresh(error) {
return error.code === import_common.StatusCodes.Gone && "substatus" in error && error["substatus"] === import_common.SubStatusCodes.PartitionKeyRangeGone;
}
/**
* Fetches and bufferes the next page of results in internal buffer
*/
async bufferMore(diagnosticNode) {
if (this.err) {
throw this.err;
}
try {
const { result: resourcesResult, headers: headerResponse } = await this.internalExecutionContext.fetchMore(diagnosticNode);
let resources = resourcesResult;
++this.generation;
this._updateStates(void 0, resources === void 0);
if (headerResponse && headerResponse["x-ms-cosmos-query-execution-info"]) {
this.queryExecutionInfo = JSON.parse(headerResponse["x-ms-cosmos-query-execution-info"]);
}
if (this.filter && resources) {
resources = this.filter.applyFilter(resources);
}
if (resources !== void 0) {
let addHeaderToFetchResult = true;
resources.forEach((element) => {
this.fetchResults.push(
new import_FetchResult.FetchResult(
element,
void 0,
addHeaderToFetchResult ? headerResponse : (0, import_headerUtils.getInitialHeader)()
)
);
addHeaderToFetchResult = false;
});
}
if (headerResponse != null && import_common.Constants.HttpHeaders.QueryMetrics in headerResponse) {
const queryMetrics = headerResponse[import_common.Constants.HttpHeaders.QueryMetrics]["0"];
headerResponse[import_common.Constants.HttpHeaders.QueryMetrics] = {};
headerResponse[import_common.Constants.HttpHeaders.QueryMetrics][this.targetPartitionKeyRange.id] = queryMetrics;
}
return headerResponse;
} catch (err) {
if (DocumentProducer._needPartitionKeyRangeCacheRefresh(err)) {
const bufferedError = new import_FetchResult.FetchResult(void 0, err);
this.fetchResults.push(bufferedError);
return err.headers;
} else {
this._updateStates(err, err.resources === void 0);
throw err;
}
}
}
getTargetPartitionKeyRange() {
return this.targetPartitionKeyRange;
}
/**
* Peak the next item in the buffer
*/
peakNextItem() {
if (this.err) {
throw this.err;
}
if (this.allFetched || this.fetchResults.length === 0) {
return void 0;
}
const fetchResult = this.fetchResults[0];
switch (fetchResult.fetchResultType) {
case import_FetchResult.FetchResultType.Done:
return void 0;
case import_FetchResult.FetchResultType.Exception:
return void 0;
case import_FetchResult.FetchResultType.Result:
return fetchResult.feedResponse;
}
}
/**
* Returns the first item in the buffered results if any, or [] otherwise.
*/
async fetchNextItem() {
if (this.err) {
this._updateStates(this.err, void 0);
throw this.err;
}
if (this.allFetched) {
return { result: void 0, headers: (0, import_headerUtils.getInitialHeader)() };
}
try {
const { result, headers } = this.current();
this._updateStates(void 0, result === void 0);
if (result === void 0 || result.length === 0) {
return { result: void 0, headers };
}
return { result, headers };
} catch (err) {
this._updateStates(err, err.item === void 0);
throw err;
}
}
/**
* Fetches all the buffered results
*/
async fetchBufferedItems() {
if (this.err) {
this._updateStates(this.err, void 0);
throw this.err;
}
if (this.allFetched) {
return { result: void 0, headers: (0, import_headerUtils.getInitialHeader)() };
}
const resources = [];
try {
while (this.fetchResults.length > 0) {
const { result } = this.current();
this._updateStates(void 0, result === void 0);
if (result === void 0) {
return {
result: resources.length > 0 ? resources : void 0,
headers: (0, import_headerUtils.getInitialHeader)()
};
} else {
resources.push(result);
}
}
return { result: resources, headers: (0, import_headerUtils.getInitialHeader)() };
} catch (err) {
this._updateStates(err, err.item === void 0);
throw err;
}
}
/**
* Retrieve the current element on the DocumentProducer.
*/
current() {
if (this.fetchResults.length > 0) {
const fetchResult = this.fetchResults.shift();
switch (fetchResult.fetchResultType) {
case import_FetchResult.FetchResultType.Done:
return {
result: void 0,
headers: (0, import_headerUtils.getInitialHeader)()
};
case import_FetchResult.FetchResultType.Exception:
fetchResult.error.headers = (0, import_headerUtils.getInitialHeader)();
throw fetchResult.error;
case import_FetchResult.FetchResultType.Result:
return {
result: fetchResult.feedResponse,
headers: (0, import_headerUtils.getInitialHeader)()
};
}
}
if (this.allFetched) {
return {
result: void 0,
headers: (0, import_headerUtils.getInitialHeader)()
};
}
return { result: [], headers: (0, import_headerUtils.getInitialHeader)() };
}
getQueryExecutionInfo() {
return this.queryExecutionInfo;
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DocumentProducer
});