git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
Log | Files | Refs | README

document_client.js (15858B)


      1 var AWS = require('../core');
      2 var Translator = require('./translator');
      3 var DynamoDBSet = require('./set');
      4 
      5 /**
      6  * The document client simplifies working with items in Amazon DynamoDB
      7  * by abstracting away the notion of attribute values. This abstraction
      8  * annotates native JavaScript types supplied as input parameters, as well
      9  * as converts annotated response data to native JavaScript types.
     10  *
     11  * ## Marshalling Input and Unmarshalling Response Data
     12  *
     13  * The document client affords developers the use of native JavaScript types
     14  * instead of `AttributeValue`s to simplify the JavaScript development
     15  * experience with Amazon DynamoDB. JavaScript objects passed in as parameters
     16  * are marshalled into `AttributeValue` shapes required by Amazon DynamoDB.
     17  * Responses from DynamoDB are unmarshalled into plain JavaScript objects
     18  * by the `DocumentClient`. The `DocumentClient`, does not accept
     19  * `AttributeValue`s in favor of native JavaScript types.
     20  *
     21  * |                             JavaScript Type                            | DynamoDB AttributeValue |
     22  * |:----------------------------------------------------------------------:|-------------------------|
     23  * | String                                                                 | S                       |
     24  * | Number                                                                 | N                       |
     25  * | Boolean                                                                | BOOL                    |
     26  * | null                                                                   | NULL                    |
     27  * | Array                                                                  | L                       |
     28  * | Object                                                                 | M                       |
     29  * | Buffer, File, Blob, ArrayBuffer, DataView, and JavaScript typed arrays | B                       |
     30  *
     31  * ## Support for Sets
     32  *
     33  * The `DocumentClient` offers a convenient way to create sets from
     34  * JavaScript Arrays. The type of set is inferred from the first element
     35  * in the array. DynamoDB supports string, number, and binary sets. To
     36  * learn more about supported types see the
     37  * [Amazon DynamoDB Data Model Documentation](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataModel.html)
     38  * For more information see {AWS.DynamoDB.DocumentClient.createSet}
     39  *
     40  */
     41 AWS.DynamoDB.DocumentClient = AWS.util.inherit({
     42 
     43   /**
     44    * @api private
     45    */
     46   operations: {
     47     batchGetItem: 'batchGet',
     48     batchWriteItem: 'batchWrite',
     49     putItem: 'put',
     50     getItem: 'get',
     51     deleteItem: 'delete',
     52     updateItem: 'update',
     53     scan: 'scan',
     54     query: 'query'
     55   },
     56 
     57   /**
     58    * Creates a DynamoDB document client with a set of configuration options.
     59    *
     60    * @option options params [map] An optional map of parameters to bind to every
     61    *   request sent by this service object.
     62    * @option options service [AWS.DynamoDB] An optional pre-configured instance
     63    *  of the AWS.DynamoDB service object to use for requests. The object may
     64    *  bound parameters used by the document client.
     65    * @see AWS.DynamoDB.constructor
     66    *
     67    */
     68   constructor: function DocumentClient(options) {
     69     var self = this;
     70     self.options = options || {};
     71     self.configure(self.options);
     72   },
     73 
     74   /**
     75    * @api private
     76    */
     77   configure: function configure(options) {
     78     var self = this;
     79     self.service = options.service;
     80     self.bindServiceObject(options);
     81     self.attrValue =
     82       self.service.api.operations.putItem.input.members.Item.value.shape;
     83   },
     84 
     85   /**
     86    * @api private
     87    */
     88   bindServiceObject: function bindServiceObject(options) {
     89     var self = this;
     90     options = options || {};
     91 
     92     if (!self.service) {
     93       self.service = new AWS.DynamoDB(options);
     94     } else {
     95       var config = AWS.util.copy(self.service.config);
     96       self.service = new self.service.constructor.__super__(config);
     97       self.service.config.params =
     98         AWS.util.merge(self.service.config.params || {}, options.params);
     99     }
    100   },
    101 
    102   /**
    103    * Returns the attributes of one or more items from one or more tables
    104    * by delegating to `AWS.DynamoDB.batchGetItem()`.
    105    *
    106    * Supply the same parameters as {AWS.DynamoDB.batchGetItem} with
    107    * `AttributeValue`s substituted by native JavaScript types.
    108    *
    109    * @see AWS.DynamoDB.batchGetItem
    110    * @example Get items from multiple tables
    111    *  var params = {
    112    *    RequestItems: {
    113    *      'Table-1': {
    114    *        Keys: [
    115    *          {
    116    *             HashKey: 'haskey',
    117    *             NumberRangeKey: 1
    118    *          }
    119    *        ]
    120    *      },
    121    *      'Table-2': {
    122    *        Keys: [
    123    *          { foo: 'bar' },
    124    *        ]
    125    *      }
    126    *    }
    127    *  };
    128    *
    129    *  var docClient = new AWS.DynamoDB.DocumentClient();
    130    *
    131    *  docClient.batchGet(params, function(err, data) {
    132    *    if (err) console.log(err);
    133    *    else console.log(data);
    134    *  });
    135    *
    136    */
    137   batchGet: function(params, callback) {
    138     var self = this;
    139     var request = self.service.batchGetItem(params);
    140     self.setupRequest(request);
    141     self.setupResponse(request);
    142     if (typeof callback === 'function') {
    143       request.send(callback);
    144     }
    145     return request;
    146   },
    147 
    148   /**
    149    * Puts or deletes multiple items in one or more tables by delegating
    150    * to `AWS.DynamoDB.batchWriteItem()`.
    151    *
    152    * Supply the same parameters as {AWS.DynamoDB.batchWriteItem} with
    153    * `AttributeValue`s substituted by native JavaScript types.
    154    *
    155    * @see AWS.DynamoDB.batchWriteItem
    156    * @example Write to and delete from a table
    157    *  var params = {
    158    *    RequestItems: {
    159    *      'Table-1': [
    160    *        {
    161    *          DeleteRequest: {
    162    *            Key: { HashKey: 'someKey' }
    163    *          }
    164    *        },
    165    *        {
    166    *          PutRequest: {
    167    *            Item: {
    168    *              HashKey: 'anotherKey',
    169    *              NumAttribute: 1,
    170    *              BoolAttribute: true,
    171    *              ListAttribute: [1, 'two', false],
    172    *              MapAttribute: { foo: 'bar' }
    173    *            }
    174    *          }
    175    *        }
    176    *      ]
    177    *    }
    178    *  };
    179    *
    180    *  var docClient = new AWS.DynamoDB.DocumentClient();
    181    *
    182    *  docClient.batchWrite(params, function(err, data) {
    183    *    if (err) console.log(err);
    184    *    else console.log(data);
    185    *  });
    186    *
    187    */
    188   batchWrite: function(params, callback) {
    189     var self = this;
    190     var request = self.service.batchWriteItem(params);
    191     self.setupRequest(request);
    192     self.setupResponse(request);
    193     if (typeof callback === 'function') {
    194       request.send(callback);
    195     }
    196     return request;
    197   },
    198 
    199   /**
    200    * Deletes a single item in a table by primary key by delegating to
    201    * `AWS.DynamoDB.deleteItem()`
    202    *
    203    * Supply the same parameters as {AWS.DynamoDB.deleteItem} with
    204    * `AttributeValue`s substituted by native JavaScript types.
    205    *
    206    * @see AWS.DynamoDB.deleteItem
    207    * @example Delete an item from a table
    208    *  var params = {
    209    *    TableName : 'Table',
    210    *    Key: {
    211    *      HashKey: 'hashkey',
    212    *      NumberRangeKey: 1
    213    *    }
    214    *  };
    215    *
    216    *  var docClient = new AWS.DynamoDB.DocumentClient();
    217    *
    218    *  docClient.delete(params, function(err, data) {
    219    *    if (err) console.log(err);
    220    *    else console.log(data);
    221    *  });
    222    *
    223    */
    224   delete: function(params, callback) {
    225     var self = this;
    226     var request = self.service.deleteItem(params);
    227     self.setupRequest(request);
    228     self.setupResponse(request);
    229     if (typeof callback === 'function') {
    230       request.send(callback);
    231     }
    232     return request;
    233   },
    234 
    235   /**
    236    * Returns a set of attributes for the item with the given primary key
    237    * by delegating to `AWS.DynamoDB.getItem()`.
    238    *
    239    * Supply the same parameters as {AWS.DynamoDB.getItem} with
    240    * `AttributeValue`s substituted by native JavaScript types.
    241    *
    242    * @see AWS.DynamoDB.getItem
    243    * @example Get an item from a table
    244    *  var params = {
    245    *    TableName : 'Table',
    246    *    Key: {
    247    *      HashKey: 'hashkey'
    248    *    }
    249    *  };
    250    *
    251    *  var docClient = new AWS.DynamoDB.DocumentClient();
    252    *
    253    *  docClient.get(params, function(err, data) {
    254    *    if (err) console.log(err);
    255    *    else console.log(data);
    256    *  });
    257    *
    258    */
    259   get: function(params, callback) {
    260     var self = this;
    261     var request = self.service.getItem(params);
    262     self.setupRequest(request);
    263     self.setupResponse(request);
    264     if (typeof callback === 'function') {
    265       request.send(callback);
    266     }
    267     return request;
    268   },
    269 
    270   /**
    271    * Creates a new item, or replaces an old item with a new item by
    272    * delegating to `AWS.DynamoDB.putItem()`.
    273    *
    274    * Supply the same parameters as {AWS.DynamoDB.putItem} with
    275    * `AttributeValue`s substituted by native JavaScript types.
    276    *
    277    * @see AWS.DynamoDB.putItem
    278    * @example Create a new item in a table
    279    *  var params = {
    280    *    TableName : 'Table',
    281    *    Item: {
    282    *       HashKey: 'haskey',
    283    *       NumAttribute: 1,
    284    *       BoolAttribute: true,
    285    *       ListAttribute: [1, 'two', false],
    286    *       MapAttribute: { foo: 'bar'},
    287    *       NullAttribute: null
    288    *    }
    289    *  };
    290    *
    291    *  var docClient = new AWS.DynamoDB.DocumentClient();
    292    *
    293    *  docClient.put(params, function(err, data) {
    294    *    if (err) console.log(err);
    295    *    else console.log(data);
    296    *  });
    297    *
    298    */
    299   put: function put(params, callback) {
    300     var self = this;
    301     var request = self.service.putItem(params);
    302     self.setupRequest(request);
    303     self.setupResponse(request);
    304     if (typeof callback === 'function') {
    305       request.send(callback);
    306     }
    307     return request;
    308   },
    309 
    310   /**
    311    * Edits an existing item's attributes, or adds a new item to the table if
    312    * it does not already exist by delegating to `AWS.DynamoDB.updateItem()`.
    313    *
    314    * Supply the same parameters as {AWS.DynamoDB.updateItem} with
    315    * `AttributeValue`s substituted by native JavaScript types.
    316    *
    317    * @see AWS.DynamoDB.updateItem
    318    * @example Update an item with expressions
    319    *  var params = {
    320    *    TableName: 'Table',
    321    *    Key: { HashKey : 'hashkey' },
    322    *    UpdateExpression: 'set #a = :x + :y',
    323    *    ConditionExpression: '#a < :MAX',
    324    *    ExpressionAttributeNames: {'#a' : 'Sum'},
    325    *    ExpressionAttributeValues: {
    326    *      ':x' : 20,
    327    *      ':y' : 45,
    328    *      ':MAX' : 100,
    329    *    }
    330    *  };
    331    *
    332    *  var docClient = new AWS.DynamoDB.DocumentClient();
    333    *
    334    *  docClient.update(params, function(err, data) {
    335    *     if (err) console.log(err);
    336    *     else console.log(data);
    337    *  });
    338    *
    339    */
    340   update: function(params, callback) {
    341     var self = this;
    342     var request = self.service.updateItem(params);
    343     self.setupRequest(request);
    344     self.setupResponse(request);
    345     if (typeof callback === 'function') {
    346       request.send(callback);
    347     }
    348     return request;
    349   },
    350 
    351   /**
    352    * Returns one or more items and item attributes by accessing every item
    353    * in a table or a secondary index.
    354    *
    355    * Supply the same parameters as {AWS.DynamoDB.scan} with
    356    * `AttributeValue`s substituted by native JavaScript types.
    357    *
    358    * @see AWS.DynamoDB.scan
    359    * @example Scan the table with a filter expression
    360    *  var params = {
    361    *    TableName : 'Table',
    362    *    FilterExpression : 'Year = :this_year',
    363    *    ExpressionAttributeValues : {':this_year' : 2015}
    364    *  };
    365    *
    366    *  var docClient = new AWS.DynamoDB.DocumentClient();
    367    *
    368    *  docClient.scan(params, function(err, data) {
    369    *     if (err) console.log(err);
    370    *     else console.log(data);
    371    *  });
    372    *
    373    */
    374   scan: function(params, callback) {
    375     var self = this;
    376     var request = self.service.scan(params);
    377     self.setupRequest(request);
    378     self.setupResponse(request);
    379     if (typeof callback === 'function') {
    380       request.send(callback);
    381     }
    382     return request;
    383   },
    384 
    385    /**
    386     * Directly access items from a table by primary key or a secondary index.
    387     *
    388     * Supply the same parameters as {AWS.DynamoDB.query} with
    389     * `AttributeValue`s substituted by native JavaScript types.
    390     *
    391     * @see AWS.DynamoDB.query
    392     * @example Query an index
    393     *  var params = {
    394     *    TableName: 'Table',
    395     *    IndexName: 'Index',
    396     *    KeyConditionExpression: 'HashKey = :hkey and RangeKey > :rkey',
    397     *    ExpressionAttributeValues: {
    398     *      ':hkey': 'key',
    399     *      ':rkey': 2015
    400     *    }
    401     *  };
    402     *
    403     *  var docClient = new AWS.DynamoDB.DocumentClient();
    404     *
    405     *  docClient.query(params, function(err, data) {
    406     *     if (err) console.log(err);
    407     *     else console.log(data);
    408     *  });
    409     *
    410     */
    411   query: function(params, callback) {
    412     var self = this;
    413     var request = self.service.query(params);
    414     self.setupRequest(request);
    415     self.setupResponse(request);
    416     if (typeof callback === 'function') {
    417       request.send(callback);
    418     }
    419     return request;
    420   },
    421 
    422   /**
    423    * Creates a set of elements inferring the type of set from
    424    * the type of the first element. Amazon DynamoDB currently supports
    425    * the number sets, string sets, and binary sets. For more information
    426    * about DynamoDB data types see the documentation on the
    427    * [Amazon DynamoDB Data Model](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataModel.html#DataModel.DataTypes).
    428    *
    429    * @param list [Array] Collection to represent your DynamoDB Set
    430    * @param options [map]
    431    *  * **validate** [Boolean] set to true if you want to validate the type
    432    *    of each element in the set. Defaults to `false`.
    433    * @example Creating a number set
    434    *  var docClient = new AWS.DynamoDB.DocumentClient();
    435    *
    436    *  var params = {
    437    *    Item: {
    438    *      hashkey: 'hashkey'
    439    *      numbers: docClient.createSet([1, 2, 3]);
    440    *    }
    441    *  };
    442    *
    443    *  docClient.put(params, function(err, data) {
    444    *    if (err) console.log(err);
    445    *    else console.log(data);
    446    *  });
    447    *
    448    */
    449   createSet: function(list, options) {
    450     options = options || {};
    451     return new DynamoDBSet(list, options);
    452   },
    453 
    454   /**
    455    * @api private
    456    */
    457   getTranslator: function() {
    458     return new Translator({attrValue: this.attrValue});
    459   },
    460 
    461   /**
    462    * @api private
    463    */
    464   setupRequest: function setupRequest(request) {
    465     var self = this;
    466     var translator = self.getTranslator();
    467     var operation = request.operation;
    468     var inputShape = request.service.api.operations[operation].input;
    469     request._events.validate.unshift(function(req) {
    470       req.rawParams = AWS.util.copy(req.params);
    471       req.params = translator.translateInput(req.rawParams, inputShape);
    472     });
    473   },
    474 
    475   /**
    476    * @api private
    477    */
    478   setupResponse: function setupResponse(request) {
    479     var self = this;
    480     var translator = self.getTranslator();
    481     var outputShape = self.service.api.operations[request.operation].output;
    482     request.on('extractData', function(response) {
    483       response.data = translator.translateOutput(response.data, outputShape);
    484     });
    485 
    486     var response = request.response;
    487     response.nextPage = function(cb) {
    488       var resp = this;
    489       var req = resp.request;
    490       var config;
    491       var service = req.service;
    492       var operation = req.operation;
    493       try {
    494         config = service.paginationConfig(operation, true);
    495       } catch (e) { resp.error = e; }
    496 
    497       if (!resp.hasNextPage()) {
    498         if (cb) cb(resp.error, null);
    499         else if (resp.error) throw resp.error;
    500         return null;
    501       }
    502 
    503       var params = AWS.util.copy(req.rawParams);
    504       if (!resp.nextPageTokens) {
    505         return cb ? cb(null, null) : null;
    506       } else {
    507         var inputTokens = config.inputToken;
    508         if (typeof inputTokens === 'string') inputTokens = [inputTokens];
    509         for (var i = 0; i < inputTokens.length; i++) {
    510           params[inputTokens[i]] = resp.nextPageTokens[i];
    511         }
    512         return self[operation](params, cb);
    513       }
    514     };
    515   }
    516 
    517 });
    518 
    519 module.exports = AWS.DynamoDB.DocumentClient;