@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
93 lines • 4.9 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { mergeHeaders, getInitialHeader } from "./headerUtils.js";
import { ContinuationTokenManagerFactory } from "./ContinuationTokenManager/ContinuationTokenManagerFactory.js";
import { Constants } from "../common/index.js";
/**
* Query control enabled fetch implementation with continuation token support
* @hidden
*/
export class QueryControlFetchImplementation {
endpoint;
pageSize;
// Required fields for query control - not optional
continuationTokenManager;
querySupportsTokens;
constructor(endpoint, pageSize, collectionLink, continuationToken, isOrderByQuery, querySupportsTokens) {
this.endpoint = endpoint;
this.pageSize = pageSize;
this.querySupportsTokens = querySupportsTokens;
// Initialize continuation token manager immediately for query control
this.continuationTokenManager = ContinuationTokenManagerFactory.create(collectionLink, continuationToken, isOrderByQuery);
}
async fetchMore(diagnosticNode, fetchBuffer) {
// Initialize headers fresh for each fetchMore call
const fetchMoreRespHeaders = getInitialHeader();
// Use continuation token logic for supported queries when query control is enabled
// Otherwise use simplified buffer-only logic
if (this.querySupportsTokens) {
return this._handleQueryFetch(diagnosticNode, fetchBuffer, fetchMoreRespHeaders);
}
else {
return this._handleSimpleBufferFetch(diagnosticNode, fetchBuffer, fetchMoreRespHeaders);
}
}
async _handleSimpleBufferFetch(diagnosticNode, fetchBuffer, fetchMoreRespHeaders) {
// Return buffered data if available
if (fetchBuffer.length > 0) {
const temp = fetchBuffer.slice(0, this.pageSize);
fetchBuffer.splice(0, this.pageSize); // Remove items in place
return { result: temp, headers: fetchMoreRespHeaders };
}
// Fetch new data from endpoint
const response = await this.endpoint.fetchMore(diagnosticNode);
mergeHeaders(fetchMoreRespHeaders, response.headers);
if (!response?.result?.buffer?.length) {
return this._createEmptyResult(response?.headers);
}
// Buffer new data and return up to pageSize
fetchBuffer.length = 0; // Clear existing items
fetchBuffer.push(...response.result.buffer); // Add new items
const temp = fetchBuffer.slice(0, this.pageSize);
fetchBuffer.splice(0, this.pageSize); // Remove returned items in place
return { result: temp, headers: fetchMoreRespHeaders };
}
async _handleQueryFetch(diagnosticNode, fetchBuffer, fetchMoreRespHeaders) {
if (fetchBuffer.length > 0) {
const { endIndex, continuationToken } = this.continuationTokenManager.paginateResults(this.pageSize, false);
const temp = fetchBuffer.slice(0, endIndex);
fetchBuffer.splice(0, endIndex); // Remove returned items in place
this._setContinuationTokenInHeaders(continuationToken, fetchMoreRespHeaders);
return { result: temp, headers: fetchMoreRespHeaders };
}
// Fetch new data from endpoint
fetchBuffer.length = 0; // Clear existing items in place
const response = await this.endpoint.fetchMore(diagnosticNode);
mergeHeaders(fetchMoreRespHeaders, response.headers);
if (!response?.result?.buffer || response.result.buffer.length === 0) {
const { continuationToken } = this.continuationTokenManager.paginateResults(this.pageSize, true, // isResponseEmpty = true
response?.result);
this._setContinuationTokenInHeaders(continuationToken, fetchMoreRespHeaders);
return this._createEmptyResult(fetchMoreRespHeaders);
}
fetchBuffer.push(...response.result.buffer); // Add new items to existing buffer
const { endIndex, continuationToken } = this.continuationTokenManager.paginateResults(this.pageSize, false, // isResponseEmpty = false
response.result);
const temp = fetchBuffer.slice(0, endIndex);
fetchBuffer.splice(0, endIndex); // Remove returned items in place
this._setContinuationTokenInHeaders(continuationToken, fetchMoreRespHeaders);
return { result: temp, headers: fetchMoreRespHeaders };
}
_setContinuationTokenInHeaders(continuationToken, fetchMoreRespHeaders) {
if (continuationToken) {
Object.assign(fetchMoreRespHeaders, {
[Constants.HttpHeaders.Continuation]: continuationToken,
});
}
}
_createEmptyResult(headers) {
const hdrs = headers || getInitialHeader();
return { result: [], headers: hdrs };
}
}
//# sourceMappingURL=QueryControlFetchImplementation.js.map