UNPKG

@amazon-dax-sdk/client-dax

Version:

Amazon DAX Client for JavaScript

300 lines (265 loc) 11.4 kB
/* * Copyright 2017 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. A copy of the License * is located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file 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. */ 'use strict'; const Assembler = require('./Assembler'); const Util = require('./Util'); const DaxClientError = require('./DaxClientError'); const DaxErrorCode = require('./DaxErrorCode'); exports.Custom_defineKeySchema_N742646399_1_Assembler = class Custom_defineKeySchema_N742646399_1_Assembler extends Assembler { _assembleResult() { let schema = []; this.dec.processMap(() => { let attrName = this.dec.decodeString(); let attrType = this.dec.decodeString(); schema.push({AttributeName: attrName, AttributeType: attrType}); }); return schema; } }; exports.Custom_defineAttributeList_670678385_1_Assembler = class Custom_defineAttributeList_670678385_1_Assembler extends Assembler { _assembleResult() { return this.dec.decodeObject(); } }; exports.Custom_defineAttributeListId_N1230579644_1_Assembler = class Custom_defineAttributeListId_N1230579644_1_Assembler extends Assembler { _assembleResult() { return this.dec.decodeInt(); } }; exports.Custom_endpoints_455855874_1_Assembler = class Custom_endpoints_455855874_1_Assembler extends Assembler { _assembleResult() { let result = this.dec.decodeObject(); let eps = []; for(let ep of result) { if(!(ep[2] instanceof Buffer) && ep[2].length !== 4) { throw new DaxClientError('unexpected Endpoint IP address', DaxErrorCode.MalformedResult); } ep[2] = ep[2].readUInt8(0) + '.' + ep[2].readUInt8(1) + '.' + ep[2].readUInt8(2) + '.' + ep[2].readUInt8(3); eps.push(Util.serviceEndpointFrom(ep[0], ep[1], ep[2], ep[3], ep[4], ep[5], ep[6])); } return eps; } }; exports.Custom_batchGetItem_N697851100_1_Assembler = class Custom_batchGetItem_N697851100_1_Assembler extends Assembler { _expectedResponseValues() { // Due to a mistake in the server-side response serialization, the response for BatchGetItem // consists of *two* top-level CBOR values instead of just one. The server side declares an // array of length 2, but then sends *three* elements. Therefore, the third element is outside // the array and is its own top-level CBOR value. return 2; } _assembleResult() { // Assume the error response has already been handled let result = {}; let length = this.dec.decodeArrayLength(); if(length !== 2) { throw new DaxClientError('BatchGetResponse needs to have two elements, instead had: ' + length, DaxErrorCode.MalformedResult); } result.Responses = {}; this.dec.processMap(() => { let tableName = this.dec.decodeString(); let projOrdinals = this._request._tableProjOrdinals[tableName]; let items = []; if(projOrdinals && projOrdinals.length > 0) { this.dec.processArray(() => { let item = this._decodeItemInternalHelper(projOrdinals); items.push(item); }); } else { let keySchema = this._request._keysPerTable[tableName]; let numItems = this.dec.decodeArrayLength(); for(let i = 0; i < numItems; i += 2) { let key = Assembler._decodeKeyBytes(this.dec, keySchema); let item = Assembler._decodeStreamItem(this.dec.decodeCbor()); item = Object.assign(item, key); items.push(item); } } result.Responses[tableName] = items; }); result.UnprocessedKeys = {}; this.dec.processMap(() => { let tableName = this.dec.decodeString(); let keySchema = this._request._keysPerTable[tableName]; let keys = this.dec.buildArray(() => Assembler._decodeKeyBytes(this.dec, keySchema)); if(keys.length > 0) { let requestInfo = {Keys: keys}; // Copy the RequestInfo back into the UnprocessedKeys items let tableRequest = this._request.RequestItems[tableName]; // A table in the response should always be in the request, but guard just in case if(tableRequest) { for(let field of ['ProjectionExpression', 'ConsistentRead', 'AttributesToGet', 'ExpressionAttributeNames']) { let requestField = tableRequest[field]; if(requestField) { requestInfo[field] = requestField; } } } result.UnprocessedKeys[tableName] = requestInfo; } }); let consumedCapacities = this.dec.buildArray(() => Assembler._decodeConsumedCapacityData(this.dec.decodeCbor())); if(this._request.ReturnConsumedCapacity && this._request.ReturnConsumedCapacity !== 'NONE') { result.ConsumedCapacity = verifyBatchConsumedCapacity(consumedCapacities, Object.getOwnPropertyNames(this._request.RequestItems)); } return result; } }; exports.Custom_batchWriteItem_116217951_1_Assembler = class Custom_batchWriteItem_116217951_1_Assembler extends Assembler { _expectedResponseValues() { // Server response is three separate values: unprocessed items, consumed capacity and item collection metrics return 3; } _assembleResult() { let unprocessedItemsByTable = {}; this.dec.processMap(() => { let tableName = this.dec.decodeString(); let numItems = this.dec.decodeArrayLength(); let keySchema = this._request._keysPerTable[tableName]; unprocessedItemsByTable[tableName] = []; for(let i = 0; i < numItems; i += 2) { let key = Assembler._decodeKeyBytes(this.dec, keySchema); if(this.dec.tryDecodeNull()) { // DeleteRequest unprocessedItemsByTable[tableName].push({DeleteRequest: {Key: key}}); } else { // PutRequest let item = Assembler._decodeStreamItem(this.dec.decodeCbor()); // These get de-anonymized later unprocessedItemsByTable[tableName].push({PutRequest: {Item: item}}); } } }); let result = { UnprocessedItems: unprocessedItemsByTable, }; let consumedCapacities = this.dec.buildArray(() => Assembler._decodeConsumedCapacityData(this.dec.decodeCbor())); if(this._request.ReturnConsumedCapacity && this._request.ReturnConsumedCapacity !== 'NONE') { result.ConsumedCapacity = verifyBatchConsumedCapacity(consumedCapacities, Object.getOwnPropertyNames(this._request.RequestItems)); } let itemCollectionMetrics = this.dec.buildMap(() => { let tableName = this.dec.decodeString(); let keySchema = this._request._keysPerTable[tableName]; let metrics = this.dec.buildArray(() => Assembler._decodeItemCollectionMetricsData(this.dec.decodeCbor(), keySchema)); return [tableName, metrics]; }); if(this._request.ReturnItemCollectionMetrics && this._request.ReturnItemCollectionMetrics !== 'NONE') { result.ItemCollectionMetrics = itemCollectionMetrics; } return result; } }; function verifyBatchConsumedCapacity(consumedCapacityByTable, tables) { let tablesWithConsumedCapacity = new Set(); if(consumedCapacityByTable) { for(let capacity of consumedCapacityByTable) { if(capacity) { tablesWithConsumedCapacity.add(capacity.TableName); } } } for(let table of tables) { if(!tablesWithConsumedCapacity.has(table)) { let consumedCapacity = {}; consumedCapacity.TableName = table; consumedCapacity.CapacityUnits = 0; consumedCapacityByTable.push(consumedCapacity); } } return consumedCapacityByTable; } exports.Custom_transactGetItems_1866287579_1_Assembler = class Custom_transactGetItems_1866287579_1_Assembler extends Assembler { _assembleResult() { // Assume the error response has already been handled let result = {}; // Response is an array of two elements. The first element is an array // of items, the second is a nullable array of consumed capacity // responses, one entry per table. let length = this.dec.decodeArrayLength(); if(length !== 2) { throw new DaxClientError('TransactGetResponse needs to have 2 elements, instead had: ' + length, DaxErrorCode.MalformedResult); } // Read the items let itemCount = this.dec.decodeArrayLength(); let items = []; for(let i = 0; i < itemCount; i++) { if(this.dec.tryDecodeNull()) { items.push(null); } else { let projectionOrdinals = this._request.TransactItems[i].Get._projectionOrdinals; if(projectionOrdinals && projectionOrdinals.length > 0) { items.push(this._decodeItemInternalHelper(projectionOrdinals)); } else { let item = Assembler._decodeStreamItem(this.dec.decodeCbor()); // Add the keys from the request item = Object.assign(item, this._request.TransactItems[i].Get.Key); items.push(item); } } } // Read the consumed capacity let consumedCapacities = []; if(!this.dec.tryDecodeNull()) { let consumedCapacityCount = this.dec.decodeArrayLength(); while(consumedCapacityCount-- > 0) { let consumedCapacity = Assembler._decodeConsumedCapacityExtended(this.dec); if(consumedCapacity) { consumedCapacities.push(consumedCapacity); } } } if(consumedCapacities.length > 0) { result.ConsumedCapacity = consumedCapacities; } result.Responses = items.map((item) => item ? {'Item': item} : {}); return result; } }; exports.Custom_transactWriteItems_N1160037738_1_Assembler = class Custom_transactWriteItems_N1160037738_1_Assembler extends Assembler { _assembleResult() { let arrayLen = this.dec.decodeArrayLength(); if(arrayLen !== 3) { throw new DaxClientError(`TransactWriteResponse needs to have 3 elements, instead had: ${length}`, DaxErrorCode.MalformedResult); } // skip Responses field in TransactWriteItem response since DDB removed this field after preview. this.dec.decodeObject(); let result = {}; // Read the consumed capacity let consumedCapacities; if(!this.dec.tryDecodeNull()) { consumedCapacities = this.dec.buildArray(() => { return Assembler._decodeConsumedCapacityExtended(this.dec); }); } if(consumedCapacities && consumedCapacities.length > 0) { result.ConsumedCapacity = consumedCapacities; } let itemCollectionMetrics; if(!this.dec.tryDecodeNull()) { itemCollectionMetrics = this.dec.buildMap(() => { let tableName = this.dec.decodeString(); let keySchema = this._request._keysPerTable[tableName]; let metrics = this.dec.buildArray(() => Assembler._decodeItemCollectionMetricsData(this.dec.decodeCbor(), keySchema)); return [tableName, metrics]; }); } if(this._request.ReturnItemCollectionMetrics && this._request.ReturnItemCollectionMetrics !== 'NONE') { result.ItemCollectionMetrics = itemCollectionMetrics; } return result; } };