UNPKG

ravendb

Version:
269 lines 13.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DocumentSubscriptions = void 0; const TypeUtil_js_1 = require("../../Utility/TypeUtil.js"); const index_js_1 = require("../../Exceptions/index.js"); const CreateSubscriptionCommand_js_1 = require("../Commands/CreateSubscriptionCommand.js"); const SubscriptionWorker_js_1 = require("./SubscriptionWorker.js"); const DeleteSubscriptionCommand_js_1 = require("../Commands/DeleteSubscriptionCommand.js"); const StringUtil_js_1 = require("../../Utility/StringUtil.js"); const GetSubscriptionStateCommand_js_1 = require("../Commands/GetSubscriptionStateCommand.js"); const DropSubscriptionConnectionCommand_js_1 = require("../Commands/DropSubscriptionConnectionCommand.js"); const GetSubscriptionsCommand_js_1 = require("../Commands/GetSubscriptionsCommand.js"); const ToggleOngoingTaskStateOperation_js_1 = require("../Operations/OngoingTasks/ToggleOngoingTaskStateOperation.js"); const SubscriptionIncludeBuilder_js_1 = require("../Session/Loaders/SubscriptionIncludeBuilder.js"); const IncludesUtil_js_1 = require("../Session/IncludesUtil.js"); const StringBuilder_js_1 = require("../../Utility/StringBuilder.js"); const UpdateSubscriptionCommand_js_1 = require("../Commands/UpdateSubscriptionCommand.js"); const CounterIncludesToken_js_1 = require("../Session/Tokens/CounterIncludesToken.js"); const TimeSeriesIncludesToken_js_1 = require("../Session/Tokens/TimeSeriesIncludesToken.js"); const QueryToken_js_1 = require("../Session/Tokens/QueryToken.js"); const OsUtil_js_1 = require("../../Utility/OsUtil.js"); const INCLUDE_REVISIONS_RQL = " (Revisions = true)"; class DocumentSubscriptions { _store; _subscriptions = new Map(); constructor(store) { this._store = store; } /** * Creates a data subscription in a database. The subscription will expose all * documents that match the specified subscription options for a given type. */ async create(optionsOrDocumentType, database) { let options = null; if (TypeUtil_js_1.TypeUtil.isDocumentType(optionsOrDocumentType)) { options = { documentType: optionsOrDocumentType }; return this.create(this._ensureCriteria(options, false), database); } else { options = this._ensureCriteria(optionsOrDocumentType, false); } if (!options) { (0, index_js_1.throwError)("InvalidArgumentException", "Cannot create a subscription if options are null"); } if (!options.query) { (0, index_js_1.throwError)("InvalidArgumentException", "Cannot create a subscription if the script is null"); } const requestExecutor = this._store.getRequestExecutor(this._store.getEffectiveDatabase(database)); const command = new CreateSubscriptionCommand_js_1.CreateSubscriptionCommand(options); await requestExecutor.execute(command); return command.result.name; } /** * Creates a data subscription in a database. The subscription will expose all documents * that match the specified subscription options for a given type. */ createForRevisions(options, database) { options = options || {}; return this.create(this._ensureCriteria(options, true), database); } _ensureCriteria(criteria, revisions) { if (!criteria) { criteria = {}; } const objectDescriptor = this._store.conventions.getJsTypeByDocumentType(criteria.documentType); const collectionName = this._store.conventions.getCollectionNameForType(objectDescriptor); let queryBuilder; if (criteria.query) { queryBuilder = new StringBuilder_js_1.StringBuilder(criteria.query); } else { queryBuilder = new StringBuilder_js_1.StringBuilder("from '"); StringUtil_js_1.StringUtil.escapeString(queryBuilder, collectionName); queryBuilder.append("'"); if (revisions) { queryBuilder.append(INCLUDE_REVISIONS_RQL); } queryBuilder.append(" as doc"); } if (criteria.includes) { const builder = new SubscriptionIncludeBuilder_js_1.SubscriptionIncludeBuilder(this._store.conventions); criteria.includes(builder); let numberOfIncludesAdded = 0; if (builder.documentsToInclude && builder.documentsToInclude.size) { queryBuilder.append(OsUtil_js_1.EOL + "include "); for (const inc of builder.documentsToInclude) { const include = "doc." + inc; if (numberOfIncludesAdded > 0) { queryBuilder.append(","); } let escapedInclude; if (IncludesUtil_js_1.IncludesUtil.requiresQuotes(include, x => escapedInclude = x)) { queryBuilder .append("'") .append(escapedInclude) .append("'"); } else { queryBuilder .append(QueryToken_js_1.QueryToken.isKeyword(include) ? "'" + include + "'" : include); } numberOfIncludesAdded++; } } if (builder.isAllCounters) { if (!numberOfIncludesAdded) { queryBuilder .append(OsUtil_js_1.EOL) .append("include "); } const token = CounterIncludesToken_js_1.CounterIncludesToken.all(""); token.writeTo(queryBuilder); numberOfIncludesAdded++; } else if (builder.countersToInclude && builder.countersToInclude.size) { if (!numberOfIncludesAdded) { queryBuilder .append(OsUtil_js_1.EOL) .append("include "); } for (const counterName of builder.countersToInclude) { if (numberOfIncludesAdded > 0) { queryBuilder.append(","); } const token = CounterIncludesToken_js_1.CounterIncludesToken.create("", counterName); token.writeTo(queryBuilder); numberOfIncludesAdded++; } } if (builder.timeSeriesToInclude) { for (const timeSeriesRange of builder.timeSeriesToInclude) { if (numberOfIncludesAdded === 0) { queryBuilder .append(OsUtil_js_1.EOL) .append("include "); } if (numberOfIncludesAdded > 0) { queryBuilder.append(","); } const token = TimeSeriesIncludesToken_js_1.TimeSeriesIncludesToken.create("", timeSeriesRange); token.writeTo(queryBuilder); numberOfIncludesAdded++; } } } criteria.query = queryBuilder.toString(); return criteria; } /** * It opens a subscription and starts pulling documents since a last processed document for that subscription. * The connection options determine client and server cooperation rules like document batch sizes * or a timeout in a matter of which a client needs to acknowledge that batch has been processed. * The acknowledgment is sent after all documents are processed by subscription's handlers. * * There can be only a single client that is connected to a subscription. */ getSubscriptionWorker(optionsOrSubscriptionName, database) { if (TypeUtil_js_1.TypeUtil.isString(optionsOrSubscriptionName)) { return this.getSubscriptionWorker({ subscriptionName: optionsOrSubscriptionName }, database); } const options = optionsOrSubscriptionName; this._store.assertInitialized(); if (!options) { (0, index_js_1.throwError)("InvalidArgumentException", "Cannot open a subscription if options are null"); } const subscription = new SubscriptionWorker_js_1.SubscriptionWorker(options, false, this._store, database); subscription.on("end", () => this._subscriptions.delete(subscription)); this._subscriptions.set(subscription, true); return subscription; } /** * It opens a subscription and starts pulling documents since a last processed document for that subscription. * The connection options determine client and server cooperation rules like document batch sizes * or a timeout in a matter of which a client needs to acknowledge that batch has been processed. * The acknowledgment is sent after all documents are processed by subscription's handlers. * * There can be only a single client that is connected to a subscription. */ getSubscriptionWorkerForRevisions(optionsOrSubscriptionName, database) { if (TypeUtil_js_1.TypeUtil.isString(optionsOrSubscriptionName)) { return this.getSubscriptionWorkerForRevisions({ subscriptionName: optionsOrSubscriptionName, }, database); } const options = optionsOrSubscriptionName; const subscription = new SubscriptionWorker_js_1.SubscriptionWorker(options, true, this._store, database); subscription.on("end", () => this._subscriptions.delete(subscription)); this._subscriptions.set(subscription, true); return subscription; } /** * It downloads a list of all existing subscriptions in a database. */ async getSubscriptions(start, take, database) { const requestExecutor = this._store.getRequestExecutor(this._store.getEffectiveDatabase(database)); const command = new GetSubscriptionsCommand_js_1.GetSubscriptionsCommand(start, take); await requestExecutor.execute(command); return command.result; } /** * Delete a subscription. */ async delete(name, database) { const requestExecutor = this._store.getRequestExecutor(this._store.getEffectiveDatabase(database)); const command = new DeleteSubscriptionCommand_js_1.DeleteSubscriptionCommand(name); return requestExecutor.execute(command); } /** * Returns subscription definition and it's current state */ async getSubscriptionState(subscriptionName, database) { if (StringUtil_js_1.StringUtil.isNullOrEmpty(subscriptionName)) { (0, index_js_1.throwError)("InvalidArgumentException", "SubscriptionName cannot be null"); } const requestExecutor = this._store.getRequestExecutor(this._store.getEffectiveDatabase(database)); const command = new GetSubscriptionStateCommand_js_1.GetSubscriptionStateCommand(subscriptionName); await requestExecutor.execute(command); return command.result; } dispose() { if (!this._subscriptions.size) { return; } for (const [key, value] of this._subscriptions.entries()) key.dispose(); } async dropSubscriptionWorker(worker, database = null) { database ??= this._store.database; const requestExecutor = this._store.getRequestExecutor(database); const command = new DropSubscriptionConnectionCommand_js_1.DropSubscriptionConnectionCommand(worker.subscriptionName, worker.getWorkerId()); await requestExecutor.execute(command); } /** * Force server to close all current client subscription connections to the server */ async dropConnection(name, database) { const requestExecutor = this._store.getRequestExecutor(this._store.getEffectiveDatabase(database)); const command = new DropSubscriptionConnectionCommand_js_1.DropSubscriptionConnectionCommand(name); return requestExecutor.execute(command); } async enable(name, database) { const operation = new ToggleOngoingTaskStateOperation_js_1.ToggleOngoingTaskStateOperation(name, "Subscription", false); await this._store.maintenance.forDatabase(this._store.getEffectiveDatabase(database)) .send(operation); } async disable(name, database) { const operation = new ToggleOngoingTaskStateOperation_js_1.ToggleOngoingTaskStateOperation(name, "Subscription", true); await this._store.maintenance.forDatabase(this._store.getEffectiveDatabase(database)) .send(operation); } async update(options, database) { if (!options) { (0, index_js_1.throwError)("InvalidArgumentException", "Cannot update a subscription if options is null"); } if (StringUtil_js_1.StringUtil.isNullOrEmpty(options.name) && !options.id) { (0, index_js_1.throwError)("InvalidArgumentException", "Cannot update a subscription if both options.name and options.if are null"); } const requestExecutor = this._store.getRequestExecutor(database); const command = new UpdateSubscriptionCommand_js_1.UpdateSubscriptionCommand(options); await requestExecutor.execute(command, null); return command.result.name; } } exports.DocumentSubscriptions = DocumentSubscriptions; //# sourceMappingURL=DocumentSubscriptions.js.map