Created
February 22, 2017 15:52
-
-
Save rebolyte/d69c8bc694eb9fb7d94e8acdaf3c878c to your computer and use it in GitHub Desktop.
wrapper to get a list of items from DynamoDB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getItems(opts) { | |
passMuster(opts, { | |
table: 'string', | |
hashkey: 'string', | |
items: 'array', | |
_optional: { | |
rangekey: 'string', | |
rangeval: 'string', | |
project: 'string' | |
} | |
}); | |
// Check that they're all truthy to avoid the `typeof null === object` | |
// problem when we check the type below. | |
var allTruthy = opts.items.every(function (item) { | |
return !!item; | |
}); | |
// Check based on the first item in the array passed in | |
var allSameType = opts.items.every(function (item, idx, arr) { | |
return typeof item === typeof arr[0]; | |
}); | |
if (!allTruthy) { | |
throw new Error('getItems: All objects or hashvals passed in must be truthy.'); | |
} | |
if (!allSameType) { | |
throw new Error('getItems: All objects or hashvals passed in must be same type.'); | |
} | |
return new Promise(function (resolve, reject) { | |
// let params = { | |
// RequestItems: { | |
// users: { <-- table name | |
// Keys: [ | |
// { | |
// HashKey: 'hashkey' | |
// }, | |
// ] | |
// }, | |
// } | |
// Make a copy of the array passed in so we don't alter it. | |
// Shouldn't be necessary since primitives are passed by value, | |
// but hey, let's be safe. | |
var arr = opts.items.slice(); | |
var arrOut = []; | |
// A callback that repeatedly calls batchWrite until all of the gets have completed | |
function callback(err, data) { | |
if (err) { | |
reject(err); | |
} else { | |
// console.log(data.ConsumedCapacity); | |
// Save the stuff we got back to our array of results | |
arrOut = arrOut.concat(data.Responses[opts.table]); | |
if ('UnprocessedKeys' in data && opts.table in data.UnprocessedKeys) { | |
// More data. Call again with the unprocessed items. | |
var retryParams = { | |
RequestItems: data.UnprocessedKeys | |
}; | |
// console.log('Calling BatchGet again to retry ' + params.RequestItems[opts.table].length + ' UnprocessedKeys'); | |
docClient.batchGet(retryParams, callback); | |
} else { | |
if (arr.length > 0) { | |
// console.log('BatchGet processed all items in the batch - going on'); | |
// Start another round | |
doBatchGet(); | |
} else { | |
// console.log('BatchGet processed all items in the batch - done'); | |
resolve(arrOut); | |
} | |
} | |
} | |
} | |
function doBatchGet() { | |
var params = { | |
RequestItems: {}, | |
ReturnConsumedCapacity: 'TOTAL' | |
}; | |
params.RequestItems[opts.table] = { | |
Keys: [] | |
}; | |
if (opts.project) { | |
params.RequestItems[opts.table].ProjectionExpression = opts.project; | |
} | |
// console.log(arr); | |
for (var i = params.RequestItems[opts.table].Keys.length; i < 100; i++) { | |
// Nothing else to add to the batch if the input list is empty | |
if (arr.length === 0) { | |
break; | |
} | |
var curHash = arr.pop(); | |
var curItem = {}; | |
if (opts.rangekey) { | |
// Doing it this way, we can just pass in whole items | |
// to the function and extract the hash or hash+range info. | |
curItem[opts.hashkey] = curHash[opts.hashkey]; | |
curItem[opts.rangekey] = curHash[opts.rangekey]; | |
} else { | |
curItem[opts.hashkey] = (typeof curHash === 'object') ? curHash[opts.hashkey] : curHash; | |
} | |
params.RequestItems[opts.table].Keys.push(curItem); | |
} | |
// console.log('Calling BatchGet on ' + opts.table + ' with a new batch of ' + params.RequestItems[opts.table].Keys.length + ' items'); | |
// console.log(params.RequestItems[opts.table].Keys[params.RequestItems[opts.table].Keys.length - 1]); | |
docClient.batchGet(params, callback); | |
} | |
// Kick off the first run | |
doBatchGet(); | |
}); | |
} | |
// Usage: | |
// getItems({ | |
// table: 'users', | |
// hashkey: 'username', | |
// items: ['1', '2', '3'] | |
// }); | |
// or | |
// getItems({ | |
// table: 'userTask', | |
// hashkey: 'username', | |
// rangekey: 'taskId', | |
// items: [ | |
// { username: '1', taskId: '1', otherAttr: 'foo' }, | |
// { username: '1', taskId: '2', otherAttr: 'foo' }, | |
// { username: '1', taskId: '3', otherAttr: 'foo' } | |
// ] | |
// }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment