ravendb
Version:
RavenDB client for Node.js
804 lines • 38.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DocumentSession = void 0;
const node_stream_1 = require("node:stream");
const DocumentQuery_js_1 = require("./DocumentQuery.js");
const MultiLoaderWithInclude_js_1 = require("./Loaders/MultiLoaderWithInclude.js");
const BatchOperation_js_1 = require("./Operations/BatchOperation.js");
const TypeUtil_js_1 = require("../../Utility/TypeUtil.js");
const index_js_1 = require("../../Exceptions/index.js");
const LoadOperation_js_1 = require("./Operations/LoadOperation.js");
const InMemoryDocumentSessionOperations_js_1 = require("./InMemoryDocumentSessionOperations.js");
const GetDocumentsCommand_js_1 = require("../Commands/GetDocumentsCommand.js");
const HeadDocumentCommand_js_1 = require("../Commands/HeadDocumentCommand.js");
const LoadStartingWithOperation_js_1 = require("./Operations/LoadStartingWithOperation.js");
const RawDocumentQuery_js_1 = require("./RawDocumentQuery.js");
const DocumentSessionAttachments_js_1 = require("./DocumentSessionAttachments.js");
const Lazy_js_1 = require("../Lazy.js");
const LazyLoadOperation_js_1 = require("./Operations/Lazy/LazyLoadOperation.js");
const ResponseTimeInformation_js_1 = require("./ResponseTimeInformation.js");
const MultiGetOperation_js_1 = require("./Operations/MultiGetOperation.js");
const Stopwatch_js_1 = require("../../Utility/Stopwatch.js");
const Constants_js_1 = require("../../Constants.js");
const PromiseUtil_js_1 = require("../../Utility/PromiseUtil.js");
const LazySessionOperations_js_1 = require("./Operations/Lazy/LazySessionOperations.js");
const JavaScriptArray_js_1 = require("./JavaScriptArray.js");
const PatchRequest_js_1 = require("../Operations/PatchRequest.js");
const PatchCommandData_js_1 = require("../Commands/Batches/PatchCommandData.js");
const IdTypeAndName_js_1 = require("../IdTypeAndName.js");
const DocumentSessionRevisions_js_1 = require("./DocumentSessionRevisions.js");
const StreamUtil_js_1 = require("../../Utility/StreamUtil.js");
const StreamOperation_js_1 = require("./Operations/StreamOperation.js");
const QueryOperation_js_1 = require("./Operations/QueryOperation.js");
const Pipelines_js_1 = require("../../Mapping/Json/Streams/Pipelines.js");
const ClusterTransactionOperations_js_1 = require("./ClusterTransactionOperations.js");
const SessionDocumentCounters_js_1 = require("./SessionDocumentCounters.js");
const IncludeBuilder_js_1 = require("./Loaders/IncludeBuilder.js");
const JavaScriptMap_js_1 = require("./JavaScriptMap.js");
const SessionDocumentTimeSeries_js_1 = require("./SessionDocumentTimeSeries.js");
const TimeSeriesOperations_js_1 = require("../TimeSeries/TimeSeriesOperations.js");
const SessionDocumentTypedTimeSeries_js_1 = require("./SessionDocumentTypedTimeSeries.js");
const SessionDocumentRollupTypedTimeSeries_js_1 = require("./SessionDocumentRollupTypedTimeSeries.js");
const RawTimeSeriesTypes_js_1 = require("../Operations/TimeSeries/RawTimeSeriesTypes.js");
const DocumentInfo_js_1 = require("./DocumentInfo.js");
const MetadataAsDictionary_js_1 = require("../../Mapping/MetadataAsDictionary.js");
const StringUtil_js_1 = require("../../Utility/StringUtil.js");
const ConditionalGetDocumentsCommand_js_1 = require("../Commands/ConditionalGetDocumentsCommand.js");
const StatusCode_js_1 = require("../../Http/StatusCode.js");
const OsUtil_js_1 = require("../../Utility/OsUtil.js");
class DocumentSession extends InMemoryDocumentSessionOperations_js_1.InMemoryDocumentSessionOperations {
constructor(documentStore, id, options) {
super(documentStore, id, options);
}
get advanced() {
return this;
}
get session() {
return this;
}
_generateId(entity) {
return this.conventions.generateDocumentId(this.databaseName, entity);
}
numberOfRequestsInSession;
async load(idOrIds, optionsOrDocumentType) {
const isLoadingSingle = !Array.isArray(idOrIds);
if (isLoadingSingle && StringUtil_js_1.StringUtil.isNullOrWhitespace(idOrIds)) {
return null;
}
const ids = isLoadingSingle ? [idOrIds] : idOrIds;
let options;
if (TypeUtil_js_1.TypeUtil.isDocumentType(optionsOrDocumentType)) {
options = { documentType: optionsOrDocumentType };
}
else if (TypeUtil_js_1.TypeUtil.isObject(optionsOrDocumentType)) {
options = optionsOrDocumentType;
}
const internalOpts = this._prepareLoadInternalOpts(options || {});
const docs = await this.loadInternal(ids, internalOpts);
return isLoadingSingle
? docs[Object.keys(docs)[0]]
: docs;
}
_prepareLoadInternalOpts(options) {
const internalOpts = { documentType: options.documentType };
this.conventions.tryRegisterJsType(internalOpts.documentType);
if ("includes" in options) {
if (TypeUtil_js_1.TypeUtil.isFunction(options.includes)) {
const builder = new IncludeBuilder_js_1.IncludeBuilder(this.conventions);
options.includes(builder);
if (builder.countersToInclude) {
internalOpts.counterIncludes = [...builder.countersToInclude];
}
if (builder.documentsToInclude) {
internalOpts.includes = [...builder.documentsToInclude];
}
if (builder.timeSeriesToInclude) {
internalOpts.timeSeriesIncludes = [...builder.timeSeriesToInclude];
}
if (builder.compareExchangeValuesToInclude) {
internalOpts.compareExchangeValueIncludes = [...builder.compareExchangeValuesToInclude];
}
internalOpts.revisionIncludesByChangeVector = builder.revisionsToIncludeByChangeVector ? Array.from(builder.revisionsToIncludeByChangeVector) : null;
internalOpts.revisionsToIncludeByDateTime = builder.revisionsToIncludeByDateTime;
internalOpts.includeAllCounters = builder.isAllCounters;
}
else {
internalOpts.includes = options.includes;
}
}
return internalOpts;
}
async _loadInternal(ids, operation, writable) {
if (!ids) {
(0, index_js_1.throwError)("InvalidArgumentException", "Ids cannot be null");
}
operation.byIds(ids);
const command = operation.createRequest();
if (command) {
await this._requestExecutor.execute(command, this._sessionInfo);
if (!writable) {
operation.setResult(command.result);
}
else {
const readable = (0, StreamUtil_js_1.stringToReadable)(JSON.stringify(command.result));
await (0, StreamUtil_js_1.pipelineAsync)(readable, writable);
}
}
}
async saveChanges() {
const saveChangeOperation = new BatchOperation_js_1.BatchOperation(this);
let command;
try {
command = saveChangeOperation.createRequest();
if (!command) {
return;
}
if (this.noTracking) {
(0, index_js_1.throwError)("InvalidOperationException", "Cannot execute saveChanges when entity tracking is disabled in session.");
}
await this._requestExecutor.execute(command, this._sessionInfo);
this._updateSessionAfterSaveChanges(command.result);
saveChangeOperation.setResult(command.result);
}
finally {
if (command) {
command.dispose();
}
}
}
async refresh(entityOrEntities) {
if (TypeUtil_js_1.TypeUtil.isArray(entityOrEntities)) {
return this._refreshEntitiesInternal(entityOrEntities);
}
else {
return this._refreshEntityInternal(entityOrEntities);
}
}
async _refreshEntityInternal(entity) {
const documentInfo = this.documentsByEntity.get(entity);
if (!documentInfo) {
DocumentSession._throwCouldNotRefreshDocument("Cannot refresh a transient instance");
}
this.incrementRequestCount();
const command = new GetDocumentsCommand_js_1.GetDocumentsCommand({
id: documentInfo.id,
conventions: this.conventions
});
await this._requestExecutor.execute(command, this._sessionInfo);
const commandResult = command.result.results[0];
this._refreshInternal(entity, commandResult, documentInfo);
}
async _refreshEntitiesInternal(entities) {
const idsEntitiesPairs = this._buildEntityDocInfoByIdHolder(entities);
this.incrementRequestCount();
const command = new GetDocumentsCommand_js_1.GetDocumentsCommand({
ids: Array.from(idsEntitiesPairs.keys()),
includes: null,
metadataOnly: false,
conventions: this.conventions
});
await this._requestExecutor.execute(command, this.sessionInfo);
this._refreshEntities(command, idsEntitiesPairs);
}
/**
* Check if document exists without loading it
*/
async exists(id) {
if (!id) {
(0, index_js_1.throwError)("InvalidArgumentException", "id cannot be null");
}
if (this._knownMissingIds.has(id)) {
return false;
}
if (this.documentsById.getValue(id)) {
return true;
}
const command = new HeadDocumentCommand_js_1.HeadDocumentCommand(id, null);
await this._requestExecutor.execute(command, this._sessionInfo);
return !TypeUtil_js_1.TypeUtil.isNullOrUndefined(command.result);
}
async loadStartingWith(idPrefix, opts) {
const loadStartingWithOperation = new LoadStartingWithOperation_js_1.LoadStartingWithOperation(this);
opts ||= {};
await this._loadStartingWithInternal(idPrefix, loadStartingWithOperation, opts);
return loadStartingWithOperation.getDocuments(opts.documentType);
}
async loadStartingWithIntoStream(idPrefix, writable, opts) {
if (!writable) {
(0, index_js_1.throwError)("InvalidArgumentException", "writable cannot be null.");
}
if (!idPrefix) {
(0, index_js_1.throwError)("InvalidArgumentException", "idPrefix cannot be null.");
}
const loadStartingWithOperation = new LoadStartingWithOperation_js_1.LoadStartingWithOperation(this);
opts ||= {};
await this._loadStartingWithInternal(idPrefix, loadStartingWithOperation, opts, writable);
}
async loadIntoStream(ids, writable) {
return this._loadInternal(ids, new LoadOperation_js_1.LoadOperation(this), writable);
}
async _loadStartingWithInternal(idPrefix, operation, opts, writable) {
const { matches, start, pageSize, exclude, startAfter } = opts || {};
operation.withStartWith(idPrefix, {
matches, start, pageSize, exclude, startAfter
});
const command = operation.createRequest();
if (command) {
await this._requestExecutor.execute(command, this._sessionInfo);
if (writable) {
return (0, StreamUtil_js_1.pipelineAsync)((0, StreamUtil_js_1.stringToReadable)(JSON.stringify(command.result)), writable);
}
else {
operation.setResult(command.result);
}
}
return command;
}
async loadInternal(ids, opts) {
if (!ids) {
(0, index_js_1.throwError)("InvalidArgumentException", "Ids cannot be null");
}
opts = opts || {};
const loadOperation = new LoadOperation_js_1.LoadOperation(this);
loadOperation.byIds(ids);
loadOperation.withIncludes(opts.includes);
if (opts.includeAllCounters) {
loadOperation.withAllCounters();
}
else {
loadOperation.withCounters(opts.counterIncludes);
}
loadOperation.withRevisions(opts.revisionIncludesByChangeVector);
loadOperation.withRevisions(opts.revisionsToIncludeByDateTime);
loadOperation.withTimeSeries(opts.timeSeriesIncludes);
loadOperation.withCompareExchange(opts.compareExchangeValueIncludes);
const command = loadOperation.createRequest();
if (command) {
await this._requestExecutor.execute(command, this._sessionInfo);
loadOperation.setResult(command.result);
}
const clazz = this.conventions.getJsTypeByDocumentType(opts.documentType);
return loadOperation.getDocuments(clazz);
}
/**
* Begin a load while including the specified path
*/
include(path) {
return new MultiLoaderWithInclude_js_1.MultiLoaderWithInclude(this).include(path);
}
increment(entityOrId, path, valueToAdd) {
let id;
if (TypeUtil_js_1.TypeUtil.isString(entityOrId)) {
id = entityOrId;
}
else {
const metadata = this.getMetadataFor(entityOrId);
id = metadata["@id"];
}
const patchRequest = new PatchRequest_js_1.PatchRequest();
const variable = `this.${path}`;
const value = `args.val_${this._valsCount}`;
patchRequest.script = `${variable} = ${variable} ? ${variable} + ${value} : ${value};`;
const valKey = "val_" + this._valsCount;
patchRequest.values = { [valKey]: valueToAdd };
this._valsCount++;
if (!this._tryMergePatches(id, patchRequest)) {
this.defer(new PatchCommandData_js_1.PatchCommandData(id, null, patchRequest, null));
}
}
addOrIncrement(id, entity, pathToObject, valToAdd) {
const variable = "this." + pathToObject;
const value = "args.val_" + this._valsCount;
const patchRequest = new PatchRequest_js_1.PatchRequest();
patchRequest.script = variable + " = " + variable + " ? " + variable + " + " + value + " : " + value;
patchRequest.values = {
["val_" + this._valsCount]: valToAdd
};
const collectionName = this._requestExecutor.conventions.getCollectionNameForEntity(entity);
const metadataAsDictionary = MetadataAsDictionary_js_1.MetadataDictionary.create();
metadataAsDictionary[Constants_js_1.CONSTANTS.Documents.Metadata.COLLECTION] = collectionName;
const descriptor = this._requestExecutor.conventions.getTypeDescriptorByEntity(entity);
const jsType = this._requestExecutor.conventions.getJsTypeName(descriptor);
if (jsType) {
metadataAsDictionary[Constants_js_1.CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] = jsType;
}
const documentInfo = new DocumentInfo_js_1.DocumentInfo();
documentInfo.id = id;
documentInfo.collection = collectionName;
documentInfo.metadataInstance = metadataAsDictionary;
const newInstance = this.entityToJson.convertEntityToJson(entity, documentInfo);
this._valsCount++;
const patchCommandData = new PatchCommandData_js_1.PatchCommandData(id, null, patchRequest);
patchCommandData.createIfMissing = newInstance;
this.defer(patchCommandData);
}
addOrPatchArray(id, entity, pathToArray, arrayAdder) {
const scriptArray = new JavaScriptArray_js_1.JavaScriptArray(this._customCount++, pathToArray);
arrayAdder(scriptArray);
const patchRequest = new PatchRequest_js_1.PatchRequest();
patchRequest.script = scriptArray.script;
patchRequest.values = scriptArray.parameters;
const collectionName = this._requestExecutor.conventions.getCollectionNameForEntity(entity);
const metadataAsDictionary = MetadataAsDictionary_js_1.MetadataDictionary.create();
metadataAsDictionary[Constants_js_1.CONSTANTS.Documents.Metadata.COLLECTION] = collectionName;
const descriptor = this._requestExecutor.conventions.getTypeDescriptorByEntity(entity);
const jsType = this._requestExecutor.conventions.getJsTypeName(descriptor);
if (jsType) {
metadataAsDictionary[Constants_js_1.CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] = jsType;
}
const documentInfo = new DocumentInfo_js_1.DocumentInfo();
documentInfo.id = id;
documentInfo.collection = collectionName;
documentInfo.metadataInstance = metadataAsDictionary;
const newInstance = this.entityToJson.convertEntityToJson(entity, documentInfo);
this._valsCount++;
const patchCommandData = new PatchCommandData_js_1.PatchCommandData(id, null, patchRequest);
patchCommandData.createIfMissing = newInstance;
this.defer(patchCommandData);
}
addOrPatch(id, entity, pathToObject, value) {
const patchRequest = new PatchRequest_js_1.PatchRequest();
patchRequest.script = "this." + pathToObject + " = args.val_" + this._valsCount;
patchRequest.values = {
["val_" + this._valsCount]: value
};
const collectionName = this._requestExecutor.conventions.getCollectionNameForEntity(entity);
const metadataAsDictionary = MetadataAsDictionary_js_1.MetadataDictionary.create();
metadataAsDictionary[Constants_js_1.CONSTANTS.Documents.Metadata.COLLECTION] = collectionName;
const descriptor = this._requestExecutor.conventions.getTypeDescriptorByEntity(entity);
const jsType = this._requestExecutor.conventions.getJsTypeName(descriptor);
if (jsType) {
metadataAsDictionary[Constants_js_1.CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] = jsType;
}
const documentInfo = new DocumentInfo_js_1.DocumentInfo();
documentInfo.id = id;
documentInfo.collection = collectionName;
documentInfo.metadataInstance = metadataAsDictionary;
const newInstance = this.entityToJson.convertEntityToJson(entity, documentInfo);
this._valsCount++;
const patchCommandData = new PatchCommandData_js_1.PatchCommandData(id, null, patchRequest);
patchCommandData.createIfMissing = newInstance;
this.defer(patchCommandData);
}
_valsCount = 0;
_customCount = 0;
patch(entityOrId, path, value) {
let id;
if (TypeUtil_js_1.TypeUtil.isString(entityOrId)) {
id = entityOrId;
}
else {
const metadata = this.getMetadataFor(entityOrId);
id = metadata["@id"];
}
const patchRequest = new PatchRequest_js_1.PatchRequest();
patchRequest.script = "this." + path + " = args.val_" + this._valsCount + ";";
const valKey = "val_" + this._valsCount;
patchRequest.values = {};
patchRequest.values[valKey] = value;
this._valsCount++;
if (!this._tryMergePatches(id, patchRequest)) {
this.defer(new PatchCommandData_js_1.PatchCommandData(id, null, patchRequest, null));
}
}
patchArray(entityOrId, path, arrayAdder) {
let id;
if (TypeUtil_js_1.TypeUtil.isString(entityOrId)) {
id = entityOrId;
}
else {
const metadata = this.getMetadataFor(entityOrId);
id = metadata["@id"];
}
const scriptArray = new JavaScriptArray_js_1.JavaScriptArray(this._customCount++, path);
arrayAdder(scriptArray);
const patchRequest = new PatchRequest_js_1.PatchRequest();
patchRequest.script = scriptArray.script;
patchRequest.values = scriptArray.parameters;
if (!this._tryMergePatches(id, patchRequest)) {
this.defer(new PatchCommandData_js_1.PatchCommandData(id, null, patchRequest, null));
}
}
patchObject(idOrEntity, pathToObject, mapAdder) {
if (TypeUtil_js_1.TypeUtil.isString(idOrEntity)) {
const scriptMap = new JavaScriptMap_js_1.JavaScriptMap(this._customCount++, pathToObject);
mapAdder(scriptMap);
const patchRequest = new PatchRequest_js_1.PatchRequest();
patchRequest.script = scriptMap.getScript();
patchRequest.values = scriptMap.parameters;
if (!this._tryMergePatches(idOrEntity, patchRequest)) {
this.defer(new PatchCommandData_js_1.PatchCommandData(idOrEntity, null, patchRequest, null));
}
}
else {
const metadata = this.getMetadataFor(idOrEntity);
const id = metadata[Constants_js_1.CONSTANTS.Documents.Metadata.ID];
this.patchObject(id, pathToObject, mapAdder);
}
}
_tryMergePatches(id, patchRequest) {
const command = this.deferredCommandsMap.get(IdTypeAndName_js_1.IdTypeAndName.keyFor(id, "PATCH", null));
if (!command) {
return false;
}
const commandIdx = this._deferredCommands.indexOf(command);
if (commandIdx > -1) {
this._deferredCommands.splice(commandIdx, 1);
}
// We'll overwrite the deferredCommandsMap when calling Defer
// No need to call deferredCommandsMap.remove((id, CommandType.PATCH, null));
const oldPatch = command;
const newScript = oldPatch.patch.script + "\n" + patchRequest.script;
const newVals = {};
for (const key of Object.keys(oldPatch.patch.values)) {
newVals[key] = oldPatch.patch.values[key];
}
for (const key of Object.keys(patchRequest.values)) {
newVals[key] = patchRequest.values[key];
}
const newPatchRequest = new PatchRequest_js_1.PatchRequest();
newPatchRequest.script = newScript;
newPatchRequest.values = newVals;
this.defer(new PatchCommandData_js_1.PatchCommandData(id, null, newPatchRequest, null));
return true;
}
rawQuery(query, documentType) {
if (documentType) {
this.conventions.tryRegisterJsType(documentType);
}
return new RawDocumentQuery_js_1.RawDocumentQuery(this, query, documentType);
}
query(docTypeOrOpts, index) {
if (TypeUtil_js_1.TypeUtil.isDocumentType(docTypeOrOpts)) {
return this.documentQuery({
documentType: docTypeOrOpts,
index
});
}
return this.documentQuery(docTypeOrOpts);
}
documentQuery(documentTypeOrOpts) {
let opts;
if (TypeUtil_js_1.TypeUtil.isDocumentType(documentTypeOrOpts)) {
opts = { documentType: documentTypeOrOpts };
}
else {
opts = documentTypeOrOpts;
const { index, ...restOpts } = opts;
if (index) {
opts = {
...restOpts,
indexName: new opts.index().getIndexName()
};
}
}
if (opts.documentType) {
this.conventions.tryRegisterJsType(opts.documentType);
}
const { indexName, collection } = this._processQueryParameters(opts, this.conventions);
return new DocumentQuery_js_1.DocumentQuery(opts.documentType, this, indexName, collection, !!opts.isMapReduce);
}
_processQueryParameters(opts, conventions) {
let { collection } = opts;
const { indexName } = opts;
const isIndex = !!indexName;
const isCollection = !!collection;
if (isIndex && isCollection) {
(0, index_js_1.throwError)("InvalidOperationException", "Parameters indexName and collectionName are mutually exclusive. Please specify only one of them.");
}
if (!isIndex && !isCollection) {
const entityType = this.conventions.getJsTypeByDocumentType(opts.documentType);
collection = this.conventions.getCollectionNameForType(entityType)
|| Constants_js_1.CONSTANTS.Documents.Metadata.ALL_DOCUMENTS_COLLECTION;
}
return { indexName, collection };
}
_attachments;
get attachments() {
if (!this._attachments) {
this._attachments = new DocumentSessionAttachments_js_1.DocumentSessionAttachments(this);
}
return this._attachments;
}
_revisions;
get revisions() {
if (!this._revisions) {
this._revisions = new DocumentSessionRevisions_js_1.DocumentSessionRevisions(this);
}
return this._revisions;
}
_clusterTransaction;
get clusterTransaction() {
if (!this._clusterTransaction) {
this._clusterTransaction = new ClusterTransactionOperations_js_1.ClusterTransactionOperations(this);
}
return this._clusterTransaction;
}
_hasClusterSession() {
return !!this._clusterTransaction;
}
_clearClusterSession() {
if (!this._hasClusterSession()) {
return;
}
this.clusterSession.clear();
}
get clusterSession() {
if (!this._clusterTransaction) {
this._clusterTransaction = new ClusterTransactionOperations_js_1.ClusterTransactionOperations(this);
}
return this._clusterTransaction;
}
get lazily() {
return new LazySessionOperations_js_1.LazySessionOperations(this);
}
get eagerly() {
return this;
}
async executeAllPendingLazyOperations() {
const requests = [];
for (let i = this._pendingLazyOperations.length - 1; i >= 0; i -= 1) {
const op = this._pendingLazyOperations[i];
const req = op.createRequest();
if (!req) {
this._pendingLazyOperations.splice(i, 1);
continue;
}
requests.unshift(req);
}
if (!requests.length) {
return new ResponseTimeInformation_js_1.ResponseTimeInformation();
}
try {
const sw = Stopwatch_js_1.Stopwatch.createStarted();
const responseTimeDuration = new ResponseTimeInformation_js_1.ResponseTimeInformation();
while (await this._executeLazyOperationsSingleStep(responseTimeDuration, requests, sw)) {
await (0, PromiseUtil_js_1.delay)(100);
}
responseTimeDuration.computeServerTotal();
sw.stop();
responseTimeDuration.totalClientDuration = sw.elapsed;
return responseTimeDuration;
}
finally {
this._pendingLazyOperations.length = 0;
}
}
async _executeLazyOperationsSingleStep(responseTimeInformation, requests, sw) {
const multiGetOperation = new MultiGetOperation_js_1.MultiGetOperation(this);
const multiGetCommand = multiGetOperation.createRequest(requests);
try {
await this.requestExecutor.execute(multiGetCommand, this._sessionInfo);
const responses = multiGetCommand.result;
if (!multiGetCommand.aggressivelyCached) {
this.incrementRequestCount();
}
for (let i = 0; i < this._pendingLazyOperations.length; i++) {
const response = responses[i];
const tempReqTime = response.headers[Constants_js_1.HEADERS.REQUEST_TIME];
response.elapsed = sw.elapsed;
const totalTime = tempReqTime ? Number.parseInt(tempReqTime, 10) : 0;
const timeItem = {
url: requests[i].urlAndQuery,
duration: totalTime
};
responseTimeInformation.durationBreakdown.push(timeItem);
if (response.requestHasErrors()) {
(0, index_js_1.throwError)("InvalidOperationException", "Got an error from server, status code: " + response.statusCode + OsUtil_js_1.EOL + response.result);
}
await this._pendingLazyOperations[i].handleResponseAsync(response);
if (this._pendingLazyOperations[i].requiresRetry) {
return true;
}
}
}
finally {
multiGetCommand.dispose();
}
return false;
}
addLazyOperation(operation) {
this._pendingLazyOperations.push(operation);
return new Lazy_js_1.Lazy(async () => {
await this.executeAllPendingLazyOperations();
return operation.result;
});
}
addLazyCountOperation(operation) {
this._pendingLazyOperations.push(operation);
return new Lazy_js_1.Lazy(async () => {
await this.executeAllPendingLazyOperations();
return operation.queryResult.totalResults;
});
}
lazyLoadInternal(ids, includes, clazz) {
if (this.checkIfIdAlreadyIncluded(ids, includes)) {
return new Lazy_js_1.Lazy(() => this.load(ids, { documentType: clazz }));
}
const loadOperation = new LoadOperation_js_1.LoadOperation(this)
.byIds(ids)
.withIncludes(includes);
const lazyOp = new LazyLoadOperation_js_1.LazyLoadOperation(this, loadOperation, clazz)
.byIds(ids)
.withIncludes(includes);
return this.addLazyOperation(lazyOp);
}
async stream(queryOrIdPrefix, optsOrStatsCallback) {
if (TypeUtil_js_1.TypeUtil.isString(queryOrIdPrefix)) {
return this._streamStartingWith(queryOrIdPrefix, optsOrStatsCallback);
}
if (arguments.length > 1 && typeof optsOrStatsCallback !== "function") {
(0, index_js_1.throwError)("InvalidArgumentException", "Statistics callback must be a function.");
}
return this._streamQueryResults(queryOrIdPrefix, optsOrStatsCallback);
}
async _streamStartingWith(idPrefix, opts) {
const streamOperation = new StreamOperation_js_1.StreamOperation(this);
const command = streamOperation.createRequest(idPrefix, opts);
await this.requestExecutor.execute(command, this.sessionInfo);
const docsReadable = streamOperation.setResult(command.result);
let clazz = null;
if (opts && "documentType" in opts) {
clazz = this.conventions.getJsTypeByDocumentType(opts.documentType);
}
const result = this._getStreamResultTransform(this, clazz, null, false);
result.on("newListener", (event, listener) => {
if (event === "data") {
result.resume();
}
});
result.on("removeListener", (event, listener) => {
if (event === "data") {
result.pause();
}
});
return (0, node_stream_1.pipeline)(docsReadable, result, TypeUtil_js_1.TypeUtil.NOOP);
}
async _streamQueryResults(query, streamQueryStatsCallback) {
const streamOperation = new StreamOperation_js_1.StreamOperation(this);
const command = streamOperation.createRequest(query.getIndexQuery());
await this.requestExecutor.execute(command, this.sessionInfo);
const docsReadable = streamOperation.setResult(command.result);
const result = this._getStreamResultTransform(this, query.getQueryType(), query.fieldsToFetchToken, query.isProjectInto);
docsReadable.once("stats", stats => {
(streamQueryStatsCallback || TypeUtil_js_1.TypeUtil.NOOP)(stats);
result.emit("stats", stats);
});
result.on("newListener", (event, listener) => {
if (event === "data") {
result.resume();
}
});
result.on("removeListener", (event, listener) => {
if (event === "data") {
result.pause();
}
});
return (0, node_stream_1.pipeline)(docsReadable, result, TypeUtil_js_1.TypeUtil.NOOP);
}
_getStreamResultTransform(session, clazz, fieldsToFetchToken, isProjectInto) {
return new node_stream_1.Transform({
objectMode: true,
transform(chunk, encoding, callback) {
const doc = chunk["value"];
const metadata = doc[Constants_js_1.CONSTANTS.Documents.Metadata.KEY];
let changeVector = null;
// MapReduce indexes return reduce results that don't have @id property
const id = metadata[Constants_js_1.CONSTANTS.Documents.Metadata.ID] || null;
//TODO: pass timeseries fields!
const entity = QueryOperation_js_1.QueryOperation.deserialize(id, doc, metadata, fieldsToFetchToken || null, true, session, clazz, isProjectInto);
if (id) {
changeVector = metadata[Constants_js_1.CONSTANTS.Documents.Metadata.CHANGE_VECTOR];
}
callback(null, {
changeVector,
metadata,
id,
document: entity
});
}
});
}
/**
* Returns the results of a query directly into stream
*/
async streamInto(query, writable) {
const streamOperation = new StreamOperation_js_1.StreamOperation(this);
const command = streamOperation.createRequest(query.getIndexQuery());
await this.requestExecutor.execute(command, this._sessionInfo);
return (0, Pipelines_js_1.streamResultsIntoStream)(command.result.stream, this.conventions, writable);
}
countersFor(entityOrId) {
return new SessionDocumentCounters_js_1.SessionDocumentCounters(this, entityOrId);
}
timeSeriesFor(entityOrDocumentId, nameOrClass, clazz) {
if (clazz) {
const name = nameOrClass;
const tsName = name ?? TimeSeriesOperations_js_1.TimeSeriesOperations.getTimeSeriesName(clazz, this.conventions);
InMemoryDocumentSessionOperations_js_1.InMemoryDocumentSessionOperations.validateTimeSeriesName(tsName);
return new SessionDocumentTypedTimeSeries_js_1.SessionDocumentTypedTimeSeries(this, entityOrDocumentId, tsName, clazz);
}
if (TypeUtil_js_1.TypeUtil.isString(nameOrClass)) {
return new SessionDocumentTimeSeries_js_1.SessionDocumentTimeSeries(this, entityOrDocumentId, nameOrClass);
}
else {
const tsName = TimeSeriesOperations_js_1.TimeSeriesOperations.getTimeSeriesName(nameOrClass, this.conventions);
InMemoryDocumentSessionOperations_js_1.InMemoryDocumentSessionOperations.validateTimeSeriesName(tsName);
return new SessionDocumentTypedTimeSeries_js_1.SessionDocumentTypedTimeSeries(this, entityOrDocumentId, tsName, nameOrClass);
}
}
timeSeriesRollupFor(entityOrDocumentId, policy, rawOrClass, clazz) {
if (clazz) {
const name = rawOrClass;
const tsName = name ?? TimeSeriesOperations_js_1.TimeSeriesOperations.getTimeSeriesName(clazz, this.conventions);
return new SessionDocumentRollupTypedTimeSeries_js_1.SessionDocumentRollupTypedTimeSeries(this, entityOrDocumentId, tsName + RawTimeSeriesTypes_js_1.TIME_SERIES_ROLLUP_SEPARATOR + policy, clazz);
}
const tsName = TimeSeriesOperations_js_1.TimeSeriesOperations.getTimeSeriesName(rawOrClass, this.conventions);
return new SessionDocumentRollupTypedTimeSeries_js_1.SessionDocumentRollupTypedTimeSeries(this, entityOrDocumentId, tsName + RawTimeSeriesTypes_js_1.TIME_SERIES_ROLLUP_SEPARATOR + policy, rawOrClass);
}
incrementalTimeSeriesFor(entityOrDocumentId, nameOrClass, clazz) {
if (clazz) {
const name = nameOrClass;
const tsName = name ?? TimeSeriesOperations_js_1.TimeSeriesOperations.getTimeSeriesName(clazz, this.conventions);
InMemoryDocumentSessionOperations_js_1.InMemoryDocumentSessionOperations.validateIncrementalTimeSeriesName(tsName);
return new SessionDocumentTypedTimeSeries_js_1.SessionDocumentTypedTimeSeries(this, entityOrDocumentId, tsName, clazz);
}
if (TypeUtil_js_1.TypeUtil.isString(nameOrClass)) {
InMemoryDocumentSessionOperations_js_1.InMemoryDocumentSessionOperations.validateIncrementalTimeSeriesName(nameOrClass);
return new SessionDocumentTimeSeries_js_1.SessionDocumentTimeSeries(this, entityOrDocumentId, nameOrClass);
}
else {
const tsName = TimeSeriesOperations_js_1.TimeSeriesOperations.getTimeSeriesName(nameOrClass, this.conventions);
InMemoryDocumentSessionOperations_js_1.InMemoryDocumentSessionOperations.validateIncrementalTimeSeriesName(tsName);
return new SessionDocumentTypedTimeSeries_js_1.SessionDocumentTypedTimeSeries(this, entityOrDocumentId, tsName, nameOrClass);
}
}
async conditionalLoad(id, changeVector, clazz) {
if (StringUtil_js_1.StringUtil.isNullOrEmpty(id)) {
(0, index_js_1.throwError)("InvalidArgumentException", "Id cannot be null");
}
if (this.advanced.isLoaded(id)) {
const entity = await this.load(id, clazz);
if (!entity) {
return {
entity: null,
changeVector: null
};
}
const cv = this.advanced.getChangeVectorFor(entity);
return {
entity,
changeVector: cv
};
}
if (StringUtil_js_1.StringUtil.isNullOrEmpty(changeVector)) {
(0, index_js_1.throwError)("InvalidArgumentException", "The requested document with id '" + id + "' is not loaded into the session and could not conditional load when changeVector is null or empty.");
}
this.incrementRequestCount();
const cmd = new ConditionalGetDocumentsCommand_js_1.ConditionalGetDocumentsCommand(id, changeVector, this.conventions);
await this.advanced.requestExecutor.execute(cmd);
switch (cmd.statusCode) {
case StatusCode_js_1.StatusCodes.NotModified: {
return {
entity: null, // value not changed
changeVector
};
}
case StatusCode_js_1.StatusCodes.NotFound: {
this.registerMissing(id);
return {
entity: null,
changeVector: null // value is missing
};
}
}
const documentInfo = DocumentInfo_js_1.DocumentInfo.getNewDocumentInfo(cmd.result.results[0]);
const r = this.trackEntity(clazz, documentInfo);
return {
entity: r,
changeVector: cmd.result.changeVector
};
}
}
exports.DocumentSession = DocumentSession;
//# sourceMappingURL=DocumentSession.js.map