all files / lib/offshore/adapter/sync/strategies/ create.js

12.12% Statements 4/33
0% Branches 0/20
0% Functions 0/5
13.33% Lines 4/30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76                                                                                                                                               
/**
 * Module dependencies
 */
 
var _ = require('lodash');
var async = require('async');
var hasOwnProperty = require('../../../utils/helpers').object.hasOwnProperty;
 
 
/**
 * Try and synchronize the underlying physical-layer schema
 * in safely manner by only adding new collections and new attributes
 * to work with our app's collections. (i.e. models)
 *
 * @param  {Function} cb
 */
module.exports = function(cb) {
  var self = this;
 
 
  // Check that collection exists
  self.describe(function afterDescribe(err, attrs) {
 
    if (err) return cb(err);
 
    // if it doesn't go ahead and add it and get out
    if (!attrs) return self.define(cb);
 
 
    var query = self._query || {};
    var connName = self.connection;
    // check default connection
    if (connName === 'default' && query.defaultConnection) {
      connName = query.defaultConnection;
    }
    var connection = self.query.offshore.connections[connName];
    // check connection
    if (!connection) {
      return cb(new Error('No valid connection specified'));
    }
    var adapter = connection._adapter;
 
    // Check if an addAttribute adapter method is defined
    if (!hasOwnProperty(adapter, 'addAttribute')) {
      return cb();
    }
 
    // The collection we're working with
    var collectionID = self.collection;
 
    // Remove hasMany association keys before sending down to adapter
    var schema = _.clone(self.query._schema.schema) || {};
    Object.keys(schema).forEach(function(key) {
      if (schema[key].type) return;
      delete schema[key];
    });
 
    // Iterate through each attribute in the new definition
    // Used for keeping track of previously undefined attributes
    // when updating the data stored at the physical layer.
    var newAttributes = _.reduce(schema, function checkAttribute(newAttributes, attribute, attrName) {
      if (!attrs[attrName]) {
        newAttributes[attrName] = attribute;
      }
      return newAttributes;
    }, {});
 
    // Add new attributes
    async.eachSeries(_.keys(newAttributes), function(attrName, next) {
      var attrDef = newAttributes[attrName];
      adapter.addAttribute(connName, collectionID, attrName, attrDef, next);
    }, cb);
 
  });
};