UNPKG

ravendb

Version:
172 lines 7.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SingleNodeBatchCommand = void 0; const RavenCommand_js_1 = require("../../../Http/RavenCommand.js"); const index_js_1 = require("../../../Exceptions/index.js"); const PutAttachmentCommandData_js_1 = require("./PutAttachmentCommandData.js"); const HttpUtil_js_1 = require("../../../Utility/HttpUtil.js"); const Serializer_js_1 = require("../../../Mapping/Json/Serializer.js"); const RavenCommandResponsePipeline_js_1 = require("../../../Http/RavenCommandResponsePipeline.js"); const node_stream_1 = require("node:stream"); const TimeUtil_js_1 = require("../../../Utility/TimeUtil.js"); const PutAttachmentCommandHelper_js_1 = require("./PutAttachmentCommandHelper.js"); const TypeUtil_js_1 = require("../../../Utility/TypeUtil.js"); const ObjectUtil_js_1 = require("../../../Utility/ObjectUtil.js"); const StreamUtil_js_1 = require("../../../Utility/StreamUtil.js"); class SingleNodeBatchCommand extends RavenCommand_js_1.RavenCommand { _supportsAtomicWrites; _attachmentStreams; _conventions; _commands; _options; _mode; constructor(conventions, commands, options = null, mode = null) { super(); this._commands = commands; this._conventions = conventions; this._options = options; this._mode = mode; if (!conventions) { (0, index_js_1.throwError)("InvalidArgumentException", "conventions cannot be null"); } if (!commands) { (0, index_js_1.throwError)("InvalidArgumentException", "commands cannot be null"); } for (const command of this._commands) { if (command instanceof PutAttachmentCommandData_js_1.PutAttachmentCommandData) { const putAttachmentCommandData = command; if (!this._attachmentStreams) { this._attachmentStreams = new Set(); } const { attStream } = putAttachmentCommandData; if (this._attachmentStreams.has(attStream)) { PutAttachmentCommandHelper_js_1.PutAttachmentCommandHelper.throwStreamWasAlreadyUsed(); } else { this._attachmentStreams.add(attStream); } } } } async send(agent, requestOptions) { const { body } = requestOptions; if (body instanceof FormData) { const attachments = [...this._attachmentStreams] .map(attStream => { return { body: attStream, headers: { "Command-Type": "AttachmentStream" } }; }); for (let i = 0; i < attachments.length; i++) { const part = attachments[i].body; const payload = part instanceof node_stream_1.Readable ? await (0, StreamUtil_js_1.readToBuffer)(part) : part; body.append("attachment_" + i, payload); } } return super.send(agent, requestOptions); } createRequest(node) { const uri = node.url + "/databases/" + node.database + "/bulk_docs"; const headers = HttpUtil_js_1.HeadersBuilder.create().typeAppJson().build(); if (TypeUtil_js_1.TypeUtil.isNullOrUndefined(this._supportsAtomicWrites)) { this._supportsAtomicWrites = node.supportsAtomicClusterWrites; } const commandsArray = this._commands.map(x => { const serialized = x.serialize(this._conventions); if (!this._supportsAtomicWrites) { delete serialized["OriginalChangeVector"]; } return serialized; }); const body = Serializer_js_1.JsonSerializer.getDefault().serialize({ Commands: commandsArray, TransactionMode: this._mode === "ClusterWide" ? "ClusterWide" : undefined }); const queryString = this._appendOptions(); const request = { method: "POST", uri: uri + queryString, }; if (this._attachmentStreams && this._attachmentStreams.size > 0) { // NOTE: payload is created in send method in async fashion - to support conversion from readable to buffers // strip out content type, see: https://stackoverflow.com/questions/39280438/fetch-missing-boundary-in-multipart-form-data-post if (request.headers && "Content-Type" in request.headers) { const { "Content-Type": contentType, ...restHeaders } = request.headers; request.headers = restHeaders; } const multipart = new FormData(); multipart.append("main", new Blob([body], { type: "application/json" })); request.body = multipart; } else { request.body = body; request.headers = headers; } return request; } async setResponseAsync(bodyStream, fromCache) { if (!bodyStream) { (0, index_js_1.throwError)("InvalidOperationException", "Got null response from the server after doing a batch," + " something is very wrong. Probably a garbled response."); } let body = null; this.result = await RavenCommandResponsePipeline_js_1.RavenCommandResponsePipeline.create() .collectBody(_ => body = _) .parseJsonSync() .objectKeysTransform({ defaultTransform: ObjectUtil_js_1.ObjectUtil.camel, ignoreKeys: [/^@/], ignorePaths: [/results\.\[\]\.modifiedDocument\./i], }) .process(bodyStream); return body; } _appendOptions() { if (!this._options) { return "?"; } return SingleNodeBatchCommand.appendOptions(this._options.indexOptions, this._options.replicationOptions, this._options.shardedOptions); } static appendOptions(indexOptions, replicationOptions, shardedOptions) { let result = "?"; if (replicationOptions) { result += `&waitForReplicasTimeout=${TimeUtil_js_1.TimeUtil.millisToTimeSpan(replicationOptions.timeout)}`; result += "&throwOnTimeoutInWaitForReplicas=" + (replicationOptions.throwOnTimeout ? "true" : "false"); result += "&numberOfReplicasToWaitFor="; result += replicationOptions.majority ? "majority" : replicationOptions.replicas; } if (indexOptions) { result += "&waitForIndexesTimeout="; result += TimeUtil_js_1.TimeUtil.millisToTimeSpan(indexOptions.timeout); if (indexOptions.throwOnTimeout) { result += "&waitForIndexThrow=true"; } else { result += "&waitForIndexThrow=false"; } if (indexOptions.indexes) { for (const specificIndex of indexOptions.indexes) { result += "&waitForSpecificIndex=" + encodeURIComponent(specificIndex); } } } if (shardedOptions) { if (shardedOptions.batchBehavior !== "Default") { result += "&shardedBatchBehavior=" + shardedOptions.batchBehavior; } } return result; } get isReadRequest() { return false; } // eslint-disable-next-line @typescript-eslint/no-empty-function dispose() { // empty } } exports.SingleNodeBatchCommand = SingleNodeBatchCommand; //# sourceMappingURL=SingleNodeBatchCommand.js.map