UNPKG

amazon-qldb-kvs-nodejs

Version:

A helper module, simplifying basic interactions with Amazon Quantum Ledger Database for Node.js through a simple key-value store interface.

115 lines (112 loc) 5.88 kB
"use strict"; /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.upsert = exports.UpsertResult = void 0; const Util_1 = require("./Util"); const GetDocument_1 = require("./GetDocument"); const Logging_1 = require("./Logging"); const logger = Logging_1.log.getLogger("qldb-helper"); class UpsertResult { } exports.UpsertResult = UpsertResult; /** * Updates or inserts a new document, using keyAttributeName to hold a unique key. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName The name of a table. * @param keyAttributeName The name of an attribute for indexing. * @param documentIon Document to add to the table. Should contain an attribute with the name "keyAttributeName". * @returns A number of changes made to the ledger. * @throws Error: If error happen during the process. */ function upsert(txn, tableName, keyAttributeName, documentIon, version) { return __awaiter(this, void 0, void 0, function* () { const fcnName = "[UpsertDocument.upsert]"; const startTime = new Date().getTime(); const txId = txn.getTransactionId(); try { // Retrieve document id by key value let documentIonKeyValue = ""; if (keyAttributeName in documentIon) { documentIonKeyValue = documentIon[keyAttributeName]; } else { throw `Attribute with name ${keyAttributeName} does not exist in document passed: ${JSON.stringify(documentIon)}`; } let docIdsAndVersions = []; try { docIdsAndVersions = yield (0, GetDocument_1.getDocumentIdsAndVersions)(txn, tableName, keyAttributeName, documentIonKeyValue); } catch (err) { logger.debug(`${fcnName} Unable to find a document. So assuming we are inserting a new document.`); } // If multiple, return an error if (docIdsAndVersions.length > 1) { throw `More than one document found with ${keyAttributeName} = ${documentIonKeyValue}. Found ids and versions: ${JSON.stringify(docIdsAndVersions)}`; } // Preparing request statement and parameters let statement = ""; let result; // If exists, update the doc if (docIdsAndVersions.length == 1) { logger.debug(`${fcnName} Document exists, updating.`); const documentId = docIdsAndVersions[0].id; const documentVersion = docIdsAndVersions[0].version; // Number with value 0 is falsy, so need to check whether it is defined if (Number.isFinite(version) && (version !== documentVersion)) { throw new Error(`Expected version number ${version} does not equal ${documentVersion} the latest version number in the ledger `); } // Just to be 100% sure we are updating a right document in deterministic way (0, Util_1.validateTableNameConstrains)(tableName); statement = `UPDATE ${tableName} AS d BY id SET d = ? WHERE id = ?`; logger.debug(`${fcnName} Executing statement ${statement}`); result = yield txn.execute(statement, documentIon, documentId); } // If not exists, insert a new doc if (docIdsAndVersions.length == 0) { logger.debug(`${fcnName} Document does not exist yet, inserting a new one.`); (0, Util_1.validateTableNameConstrains)(tableName); statement = `INSERT INTO ${tableName} ?`; logger.debug(`${fcnName} Executing statement ${statement}`); result = yield txn.execute(statement, documentIon); } logger.info(`${fcnName} Document with key "${documentIonKeyValue}" is added to the table with name "${tableName}"`); logger.debug(`${fcnName} Returned results list: ${result.getResultList()}`); const finalResult = result.getResultList().map((returnObject) => { return { documentId: returnObject.get("documentId").stringValue(), txId: txId }; }); return finalResult[0]; } catch (err) { throw `${fcnName} ${err}`; } finally { const endTime = new Date().getTime(); logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`); } }); } exports.upsert = upsert;