UNPKG

ravendb

Version:
804 lines 38.7 kB
"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