UNPKG

dynalite

Version:

An implementation of Amazon's DynamoDB built on LevelDB

96 lines (78 loc) 3.82 kB
var once = require('once'), db = require('../db') module.exports = function scan(store, data, cb) { cb = once(cb) store.getTable(data.TableName, function(err, table) { if (err) return cb(err) var keySchema = table.KeySchema, startKeyNames = keySchema.map(function(key) { return key.AttributeName }), fetchFromItemDb = false, isLocal if (data.IndexName) { var index = db.traverseIndexes(table, function(attr, type, index, isGlobal) { if (index.IndexName == data.IndexName) { isLocal = !isGlobal return index } }) if (index == null) { return cb(db.validationError('The table does not have the specified index: ' + data.IndexName)) } if (!isLocal && data.ConsistentRead) { return cb(db.validationError('Consistent reads are not supported on global secondary indexes')) } keySchema = index.KeySchema fetchFromItemDb = data.Select == 'ALL_ATTRIBUTES' && index.Projection.ProjectionType != 'ALL' keySchema.forEach(function(key) { if (!~startKeyNames.indexOf(key.AttributeName)) startKeyNames.push(key.AttributeName) }) } if (data.ExclusiveStartKey && Object.keys(data.ExclusiveStartKey).length != startKeyNames.length) { return data.IndexName ? cb(db.validationError('The provided starting key is invalid')) : cb(db.validationError('The provided starting key is invalid: The provided key element does not match the schema')) } if (data.IndexName && data.ExclusiveStartKey) { err = db.traverseKey(table, keySchema, function(attr, type, isHash) { if (!data.ExclusiveStartKey[attr]) { return db.validationError('The provided starting key is invalid') } return db.validateKeyPiece(data.ExclusiveStartKey, attr, type, isHash) }) if (err) return cb(err) } if (fetchFromItemDb && !isLocal) { return cb(db.validationError('One or more parameter values were invalid: ' + 'Select type ALL_ATTRIBUTES is not supported for global secondary index ' + data.IndexName + ' because its projection type is not ALL')) } if (data.ExclusiveStartKey) { var tableStartKey = table.KeySchema.reduce(function(obj, attr) { obj[attr.AttributeName] = data.ExclusiveStartKey[attr.AttributeName] return obj }, {}) if ((err = db.validateKey(tableStartKey, table)) != null) { return cb(db.validationError('The provided starting key is invalid: ' + err.message)) } } if (data.TotalSegments > 1) { if (data.Segment > 0) var hashStart = ('00' + Math.ceil(4096 * data.Segment / data.TotalSegments).toString(16)).slice(-3) var hashEnd = ('00' + (Math.ceil(4096 * (data.Segment + 1) / data.TotalSegments) - 1).toString(16)).slice(-3) + '~' } if (data.ExclusiveStartKey) { var startKey = db.createIndexKey(data.ExclusiveStartKey, table, keySchema) if (data.TotalSegments > 1 && (startKey < hashStart || startKey > hashEnd)) { return cb(db.validationError('The provided starting key is invalid: Invalid ExclusiveStartKey. ' + 'Please use ExclusiveStartKey with correct Segment. ' + 'TotalSegments: ' + data.TotalSegments + ' Segment: ' + data.Segment)) } hashStart = startKey } if ((err = db.validateKeyPaths((data._projection || {}).nestedPaths, table)) != null) return cb(err) if ((err = db.validateKeyPaths((data._filter || {}).nestedPaths, table)) != null) return cb(err) var opts = {limit: data.Limit ? data.Limit + 1 : -1} if (hashStart != null) { opts.gt = hashStart } if (hashEnd != null) { opts.lt = hashEnd } db.queryTable(store, table, data, opts, isLocal, fetchFromItemDb, startKeyNames, cb) }) }