lib/schema/builder.js
'use strict';
var types = require('./types');
var Chainable = require('./chainable');
var _ = require('lodash');
var utils = require('../utils');
module.exports = SchemaBuilder;
function SchemaBuilder(options){
this._schema = new Schema(options);
this.childBuilders = [];
this.initialized = false;
this.builtSchema = {
hashKeys: [],
rangeKeys: [],
struct: {},
};
_.each(_.omit(types, 'map', 'list'), function(originalType, npdType){
SchemaBuilder.prototype[npdType] = function(column){
var chainable = new Chainable();
this._schema.extend(
utils.newObject(column, {
type: originalType,
chainable: chainable
})
);
return chainable;
};
});
}
SchemaBuilder.Schema = Schema;
SchemaBuilder.prototype._definePropsIfNotExists = function(propName){
if(!this._schema.tableInfo[propName]) {
this._schema.tableInfo[propName] = {};
}
};
SchemaBuilder.prototype.provisionedThroughput = function(r, w){
this._definePropsIfNotExists('ProvisionedThroughput');
this._schema.tableInfo.ProvisionedThroughput.ReadCapacityUnits = r;
this._schema.tableInfo.ProvisionedThroughput.WriteCapacityUnits = w;
};
SchemaBuilder.prototype.projectionTypeAll = function() {
return this.ProjectionTypeAll();
};
SchemaBuilder.prototype.projectionTypeKeysOnly = function() {
return this.ProjectionTypeKeysOnly();
};
SchemaBuilder.prototype.projectionTypeInclude = function() {
return this.ProjectionTypeInclude();
};
/******* TODO Will be duplicated in 0.3.x *******/
SchemaBuilder.prototype.ProjectionTypeAll = function() {
this._definePropsIfNotExists('Projection');
this._schema.tableInfo.Projection.ProjectionType = 'ALL';
};
SchemaBuilder.prototype.ProjectionTypeKeysOnly = function() {
this._definePropsIfNotExists('Projection');
this._schema.tableInfo.Projection.ProjectionType = 'KEYS_ONLY';
};
SchemaBuilder.prototype.ProjectionTypeInclude = function(nonKeyAttributes) {
var projection = {
ProjectionType: 'INCLUDE'
};
if(_.isArray(nonKeyAttributes)) projection.NonKeyAttributes = nonKeyAttributes;
_.extend(this._schema.tableInfo.Projection, projection);
};
/******* TODO Will be duplicated in 0.3.x *******/
SchemaBuilder.prototype.streamSpecificationEnabled = function(bool){
this._definePropsIfNotExists('StreamSpecification');
this._schema.tableInfo.StreamSpecification.StreamEnabled = bool;
};
SchemaBuilder.prototype.streamSpecificationViewType = function(type){
this._definePropsIfNotExists('StreamSpecification');
this._schema.tableInfo.StreamSpecification.StreamViewType = type;
};
SchemaBuilder.prototype.globalSecondaryIndex = function(indexName, callback){
callback(this.__newBuilder({
IndexType: Schema.IndexType.GSI,
tableInfo: {
IndexName: indexName
}
}));
};
SchemaBuilder.prototype.globalSecondaryIndexUpdates = function(callback){
var self = this;
function capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function __newBuilder(indexName, action) {
return self.__newBuilder({
IndexName: indexName,
Action: action,
withoutDefaultTableInfo: true
});
}
var actions = {
create: function(indexName, callback){
var builder = __newBuilder(indexName, 'Create');
callback(builder);
},
delete: function(indexName){
var builder = __newBuilder(indexName, 'Delete');
},
update: function(indexName, callback){
var builder = __newBuilder(indexName, 'Update');
callback(builder);
}
};
callback(actions);
};
SchemaBuilder.prototype.localSecondaryIndex = function(indexName, callback){
var def = this.__newBuilder({
IndexType: Schema.IndexType.LSI,
tableInfo: {
IndexName: indexName
}
});
def._schema.tableInfo = _.omit(def._schema.tableInfo, 'ProvisionedThroughput');
callback(def);
};
SchemaBuilder.prototype.__newBuilder = function(params){
var child = new SchemaBuilder(params);
this.childBuilders.push(child);
return child;
};
['buildCreateTable', 'buildUpdateTable'].forEach(function(name){
SchemaBuilder.prototype[name] = function(){
return require('../dialects/' + this._schema.apiVer + "/schema")[name].call(this);
};
});
Schema.IndexType = {
DEFAULT: 'Default',
GSI: 'GlobalSecondaryIndexes',
GSIU: 'GlobalSecondaryIndexUpdates',
LSI: 'LocalSecondaryIndexes'
};
function Schema(options){
this.apiVer;
this.tableName;
this.column;
this.type;
this._schema = {};
this.IndexType = Schema.IndexType.DEFAULT;
this.tableInfo = options.withoutDefaultTableInfo ? {} : {
IndexName: null,
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 10
},
Projection: {
ProjectionType: 'NONE'
}
};
this.mergeProps(options);
}
Schema.prototype.extend = function(props){
_.extend(this._schema, props);
};
Schema.prototype.mergeProps = function(props){
var keys = _.keys(props);
var self = this;
keys.forEach(function(key){
if(_.isObject(props[key])) {
self[key] = _.extend(self[key], props[key]);
}else{
self[key] = props[key];
}
});
};