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.
207 lines (204 loc) • 9.81 kB
JavaScript
;
/*
* 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.getDocumentIdsAndVersions = exports.getDocumentById = exports.getByKeyAttributes = exports.getByKeyAttribute = void 0;
const Logging_1 = require("./Logging");
const Constants_1 = require("./Constants");
const Util_1 = require("./Util");
const logger = Logging_1.log.getLogger("qldb-helper");
function prepareGetDocumentResult(resultList) {
return resultList.map((dataWithVersion) => {
return {
data: dataWithVersion.get("data"),
version: dataWithVersion.get("version").numberValue()
};
});
}
/**
* Generates parameter string for queries with many similar params.
* @param numberOfParams Number of ? characters in query.
* @returns A paramter string formatted similar to [?, ?, ?].
*/
function getBindParametersString(numberOfParams) {
let paramStr = "[";
for (let i = 0; i < numberOfParams; i++) {
if (i == (numberOfParams - 1)) {
//Handle the last element
paramStr += "?]";
}
else {
//everything else
paramStr += "?, ";
}
}
return paramStr;
}
/**
* Gets a document by the value of one attribute.
* @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 keyAttributeValue A value of a key attribute.
* @returns Array of results as ION documents.
* @throws Error: If error happen during the process.
*/
function getByKeyAttribute(txn, tableName, keyAttributeName, keyAttributeValue) {
return __awaiter(this, void 0, void 0, function* () {
const fcnName = "[GetDocument.getByKeyAttribute]";
const startTime = new Date().getTime();
try {
(0, Util_1.validateTableNameConstrains)(tableName);
(0, Util_1.validateAttributeNameConstrains)(keyAttributeName);
const query = `SELECT data, metadata.version FROM _ql_committed_${tableName} AS d WHERE d.data.${keyAttributeName} = ?`;
logger.debug(`${fcnName} Retrieving document values for Key: ${keyAttributeValue}`);
logger.debug(`${fcnName} Query statement: ${query}`);
const result = yield txn.execute(query, keyAttributeValue);
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
const resultList = result.getResultList();
if (resultList.length === 0) {
throw `${fcnName} Unable to find document with Key: ${keyAttributeValue}.`;
}
return prepareGetDocumentResult(resultList);
}
catch (err) {
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
throw err;
}
});
}
exports.getByKeyAttribute = getByKeyAttribute;
/**
* Gets a document by the value of one attribute.
* @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 keyAttributeValues An array of values of key attribute.
* @returns Array of results as ION documents.
* @throws Error: If error happen during the process.
*/
function getByKeyAttributes(txn, tableName, keyAttributeName, keyAttributeValues) {
return __awaiter(this, void 0, void 0, function* () {
const fcnName = "[GetDocument.getByKeyAttributes]";
const startTime = new Date().getTime();
try {
(0, Util_1.validateTableNameConstrains)(tableName);
(0, Util_1.validateAttributeNameConstrains)(keyAttributeName);
const query = `SELECT data, metadata.version FROM _ql_committed_${tableName} AS d WHERE d.data.${keyAttributeName} IN ${getBindParametersString(keyAttributeValues.length)}`;
if (keyAttributeValues.length > Constants_1.MAX_KEYS_TO_RETRIEVE)
throw `Maximum number of keys (${Constants_1.MAX_KEYS_TO_RETRIEVE}) exceeded.`;
logger.debug(`${fcnName} Retrieving document values for Keys: ${keyAttributeValues}`);
logger.debug(`${fcnName} Query statement: ${query}`);
const result = yield txn.execute(query, ...keyAttributeValues);
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
const resultList = result.getResultList();
if (resultList.length === 0) {
throw `${fcnName} Unable to find documents with keys: ${keyAttributeValues}.`;
}
return prepareGetDocumentResult(resultList);
}
catch (err) {
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
throw err;
}
});
}
exports.getByKeyAttributes = getByKeyAttributes;
/**
* Gets a document by QLDB Document Id
* @param txn The {@linkcode TransactionExecutor} for lambda execute.
* @param tableName The name of a table.
* @param documentId Document Id string.
* @returns Array of results as ION documents.
* @throws Error: If error happen during the process.
*/
function getDocumentById(txn, tableName, documentId) {
return __awaiter(this, void 0, void 0, function* () {
const fcnName = "[GetDocument.getDocumentById]";
const startTime = new Date().getTime();
try {
(0, Util_1.validateTableNameConstrains)(tableName);
const query = `SELECT data, metadata.version FROM _ql_committed_${tableName} WHERE metadata.id = ?`;
logger.debug(`${fcnName} Retrieving document with Id: ${documentId}`);
logger.debug(`${fcnName} Query statement: ${query}`);
const result = yield txn.execute(query, documentId);
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
const resultList = result.getResultList();
if (resultList.length === 0) {
throw `${fcnName} Unable to find document Id: ${documentId}.`;
}
return prepareGetDocumentResult(resultList);
}
catch (err) {
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
throw err;
}
});
}
exports.getDocumentById = getDocumentById;
/**
* Get the document IDs from the given table.
* @param txn The {@linkcode TransactionExecutor} for lambda execute.
* @param tableName The table name to query.
* @param keyAttributeName A keyAttributeName to query.
* @param keyAttributeValue The key of the given keyAttributeName.
* @returns Promise which fulfills with the document ID as a string.
*/
function getDocumentIdsAndVersions(txn, tableName, keyAttributeName, keyAttributeValue) {
return __awaiter(this, void 0, void 0, function* () {
const fcnName = "[GetDocument.getDocumentIdsAndVersions]";
const startTime = new Date().getTime();
(0, Util_1.validateTableNameConstrains)(tableName);
(0, Util_1.validateAttributeNameConstrains)(keyAttributeName);
const query = `SELECT metadata.id, metadata.version FROM _ql_committed_${tableName} AS t BY id WHERE t.data.${keyAttributeName} = ?`;
const documentIds = [];
try {
const result = yield txn.execute(query, keyAttributeValue);
const resultList = result.getResultList();
if (resultList.length === 0) {
throw `Unable to retrieve document ID using ${keyAttributeValue}.`;
}
resultList.forEach((result, index) => __awaiter(this, void 0, void 0, function* () {
const id = resultList[index].get("id").stringValue();
const version = resultList[index].get("version").numberValue();
documentIds.push({
id: id,
version: version
});
}));
return documentIds;
}
catch (err) {
const endTime = new Date().getTime();
logger.debug(`${fcnName} Execution time: ${endTime - startTime}ms`);
throw new Error(`${fcnName} ${err}`);
}
});
}
exports.getDocumentIdsAndVersions = getDocumentIdsAndVersions;