fireball-db
Version:
a lightweight model wrapper for DynamoDB
370 lines (333 loc) • 10.6 kB
JavaScript
var Instance, KeySchema, Model, Pipeline, apply_identifier, apply_table, apply_timestamps, assign, aws, cloneDeep, key_overides, map_parameters, omit, pick, process_results, ref, update_builder;
aws = require('aws-sdk');
ref = require('lodash'), assign = ref.assign, cloneDeep = ref.cloneDeep, omit = ref.omit, pick = ref.pick;
Pipeline = require('ppl');
KeySchema = require('./key_schema');
map_parameters = require('./param_mapper').map_parameters;
Instance = require('./instance');
update_builder = require('./update_builder');
apply_timestamps = function(item) {
var now;
if (!this.auto_timestamps) {
return item;
}
now = new Date();
if (item.created_at == null) {
item.created_at = now;
}
if (item.updated_at == null) {
item.updated_at = now;
}
if (item.created_at instanceof Date) {
item.created_at = item.created_at.toISOString();
}
if (item.updated_at instanceof Date) {
item.updated_at = item.updated_at.toISOString();
}
return item;
};
apply_identifier = function(item) {
return this.key_schema.generate_for(item);
};
apply_table = function(params) {
return assign(params, {
TableName: this.name
});
};
process_results = function(results) {
return Pipeline.source(results != null ? results.Items : void 0).context(this).map([this.post_read_hook, this.wrap]).then(function(processed) {
var model, params;
processed.last_key = results != null ? results.LastEvaluatedKey : void 0;
if (processed.last_key != null) {
params = assign({}, results.params, {
ExclusiveStartKey: processed.last_key
});
model = this;
processed.next = (function(_this) {
return function() {
return _this._piped(params).pipe(function(params) {
return _this._request(results.method, params);
}).pipe(process_results);
};
})(this);
}
return processed;
});
};
key_overides = ['hash_key', 'range_key', 'key_size', 'generate_hash_key'];
Model = (function() {
function Model(name1, extension) {
var prop, ref1, value;
this.name = name1;
if (extension == null) {
extension = {};
}
this.doc_client = new aws.DynamoDB.DocumentClient();
this.key_schema = new KeySchema(pick(extension, key_overides));
this.instance_type = Instance.extend_with(this);
this.auto_timestamps = true;
ref1 = omit(extension, key_overides);
for (prop in ref1) {
value = ref1[prop];
this[prop] = value;
}
}
Model.prototype.put = function(item, params) {
var final_item;
if (params == null) {
params = {};
}
item = assign({}, item);
final_item = void 0;
return this._piped(item).pipe([apply_timestamps, apply_identifier, this.pre_write_hook]).pipe(function(item) {
final_item = item;
return assign(params, {
Item: item
});
}).pipe([map_parameters, apply_table]).pipe((function(_this) {
return function(params) {
return _this._request('put', params);
};
})(this)).pipe(function() {
return final_item;
}).pipe([this.post_read_hook, this.wrap]);
};
Model.prototype.put_all = function(items) {
var new_items;
new_items = [];
return this._piped(items).map([cloneDeep, apply_timestamps, apply_identifier, this.pre_write_hook]).pipe((function(_this) {
return function(items) {
var item, params;
new_items = items;
params = {
RequestItems: {}
};
params.RequestItems[_this.name] = (function() {
var i, len, results1;
results1 = [];
for (i = 0, len = items.length; i < len; i++) {
item = items[i];
results1.push({
PutRequest: {
Item: item
}
});
}
return results1;
})();
return params;
};
})(this)).pipe((function(_this) {
return function(params) {
return _this._request('batchWrite', params);
};
})(this)).pipe(function() {
return new_items;
}).map([this.post_read_hook, this.wrap]);
};
Model.prototype.insert = function(item, params) {
if (params == null) {
params = {};
}
item = assign({}, item);
return this._piped(item).pipe(apply_identifier).pipe(function(item) {
return assign(params, {
condition: 'identifier <> :identifier',
values: {
':identifier': item.identifier
}
});
}).pipe((function(_this) {
return function() {
return _this.put(item, params);
};
})(this));
};
Model.prototype.update = function(hash_key, range_key, params) {
return this._piped(this.key_schema.keyed_params(hash_key, range_key, params)).pipe([map_parameters, apply_table]).pipe(function(params) {
if (params.ReturnValues == null) {
params.ReturnValues = 'ALL_NEW';
}
return params;
}).pipe((function(_this) {
return function(params) {
return _this._request('update', params);
};
})(this)).pipe(function(result) {
return result.Attributes;
});
};
Model.prototype.get = function(hash_key, range_key, params) {
return this._piped(this.key_schema.keyed_params(hash_key, range_key, params)).pipe([map_parameters, apply_table]).pipe((function(_this) {
return function(params) {
return _this._request('get', params);
};
})(this)).pipe(function(result) {
return result != null ? result.Item : void 0;
}).pipe([this.post_read_hook, this.wrap]);
};
Model.prototype["delete"] = function(hash_key, range_key, params) {
return this._piped(this.key_schema.keyed_params(hash_key, range_key, params)).pipe([map_parameters, apply_table]).pipe((function(_this) {
return function(params) {
return _this._request('delete', params);
};
})(this));
};
Model.prototype.query = function(key_condition, params) {
if (params == null) {
params = {};
}
return this._piped(params).pipe(function(params) {
return assign(params, {
key_condition: key_condition
});
}).pipe([map_parameters, apply_table]).pipe((function(_this) {
return function(params) {
return _this._request('query', params);
};
})(this)).pipe(process_results);
};
Model.prototype.query_single = function(key_condition, params) {
if (params == null) {
params = {};
}
params.limit = 1;
return this.query(key_condition, params).pipe(function(result) {
return result[0];
});
};
Model.prototype.query_complete = function(key_condition, params) {
var process, results;
if (params == null) {
params = {};
}
results = [];
process = function(page) {
results = results.concat(page);
if (page.next != null) {
return page.next().pipe(process);
}
return Pipeline.resolve(results);
};
return this.query(key_condition, params).pipe(process);
};
Model.prototype.query_count = function(key_condition, params) {
if (params == null) {
params = {};
}
return this._piped(params).pipe(function(params) {
return assign(params, {
key_condition: key_condition,
select: 'COUNT'
});
}).pipe([map_parameters, apply_table]).pipe((function(_this) {
return function(params) {
return _this._request('query', params);
};
})(this)).pipe(function(result) {
return result.Count;
});
};
Model.prototype.scan = function(filter, params) {
var ref1;
if (params == null) {
ref1 = [void 0, filter], filter = ref1[0], params = ref1[1];
}
return this._piped(params || {}).pipe(function(params) {
return assign(params, {
filter: filter
});
}).pipe([map_parameters, apply_table]).pipe((function(_this) {
return function(params) {
return _this._request('scan', params);
};
})(this)).pipe(process_results);
};
Model.prototype.scan_complete = function(filter, params) {
var process, results;
results = [];
process = function(page) {
results = results.concat(page);
if (page.next != null) {
return page.next().pipe(process);
}
return Pipeline.resolve(results);
};
return this.scan(filter, params).pipe(process);
};
Model.prototype.all = function(params) {
return this.scan(void 0, params);
};
Model.prototype.for_keys = function(keys) {
return this._piped(keys).map((function(_this) {
return function(key) {
return _this.key_schema.key_for(key);
};
})(this)).pipe((function(_this) {
return function(keys) {
var params;
params = {
RequestItems: {}
};
params.RequestItems[_this.name] = {
Keys: keys
};
return params;
};
})(this)).pipe((function(_this) {
return function(params) {
return _this._request('batchGet', params);
};
})(this)).pipe((function(_this) {
return function(results) {
return results.Responses[_this.name];
};
})(this)).map([this.post_read_hook, this.wrap]);
};
Model.prototype.wrap = function(item) {
var ref1;
if ((item == null) || ((item != null ? (ref1 = item.constructor) != null ? ref1.model : void 0 : void 0) != null)) {
return item;
}
return new this.instance_type(item);
};
Model.prototype._request = function(method, params) {
return new Pipeline((function(_this) {
return function(resolve, reject) {
return _this.doc_client[method](params, function(err, result) {
var error;
if (err != null) {
error = {
dynamo_error: err,
method: method,
params: params
};
return reject(error);
}
return resolve(assign({}, result, {
params: params,
method: method
}));
});
};
})(this));
};
Model.prototype._piped = function(source) {
return Pipeline.source(source).context(this);
};
Model.model = function(name, extension) {
if (extension == null) {
extension = {};
}
return new this(name, extension);
};
Model.extend = function(module, name, extension) {
if (extension == null) {
extension = {};
}
return module.exports = this.model(name, extension);
};
Model.update_builder = update_builder;
return Model;
})();
module.exports = Model;