<commit_before>
/*!
 * migrate - Set
 * Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter
  , fs = require('fs');

/**
 * Expose `Set`.
 */

module.exports = Set;

/**
 * Initialize a new migration `Set` with the given `path`
 * which is used to store data between migrations.
 *
 * @param {String} path
 * @api private
 */

function Set(path) {
  this.migrations = [];
  this.path = path;
  this.pos = 0;
};

/**
 * Inherit from `EventEmitter.prototype`.
 */

Set.prototype.__proto__ = EventEmitter.prototype;

/**
 * Save the migration data and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Set.prototype.save = function(fn){
  var self = this
    , json = JSON.stringify(this);
  fs.writeFile(this.path, json, function(err){
    self.emit('save');
    fn && fn(err);
  });
};

/**
 * Load the migration data and call `fn(err, obj)`.
 *
 * @param {Function} fn
 * @return {Type}
 * @api public
 */

Set.prototype.load = function(fn){
  this.emit('load');
  fs.readFile(this.path, 'utf8', function(err, json){
    if (err) return fn(err);
    try {
      fn(null, JSON.parse(json));
    } catch (err) {
      fn(err);
    }
  });
};

/**
 * Run down migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Set.prototype.down = function(fn, migrationName){
  this.migrate('down', fn, migrationName);
};

/**
 * Run up migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Set.prototype.up = function(fn, migrationName){
  this.migrate('up', fn, migrationName);
};

/**
 * Migrate in the given `direction`, calling `fn(err)`.
 *
 * @param {String} direction
 * @param {Function} fn
 * @api public
 */

Set.prototype.migrate = function(direction, fn, migrationName){
  var self = this;
  fn = fn || function(){};
  this.load(function(err, obj){
    if (err) {
      if ('ENOENT' != err.code) return fn(err);
    } else {
      self.pos = obj.pos;
    }
    self._migrate(direction, fn, migrationName);
  });
};

/**
 * Get index of given migration in list of migrations
 *
 * @api private
 */

 function positionOfMigration(migrations, filename) {
   for(var i=0; i < migrations.length; ++i) {
     if (migrations[i].title == filename) return i;
   }
   return -1;
 }

/**
 * Perform migration.
 *
 * @api private
 */

Set.prototype._migrate = function(direction, fn, migrationName){
  var self = this
    , migrations
    , migrationPos;

  if (!migrationName) {
    migrationPos = direction == 'up' ? this.migrations.length : 0;
  } else if ((migrationPos = positionOfMigration(this.migrations, migrationName)) == -1) {
    console.error("Could not find migration: " + migrationName);
    process.exit(1);
  }

  switch (direction) {
    case 'up':
      migrations = this.migrations.slice(this.pos, migrationPos+1);
      this.pos += migrations.length;
      break;
    case 'down':
      migrations = this.migrations.slice(migrationPos, this.pos+1).reverse();
      this.pos -= migrations.length;
      break;
  }

  function next(err, migration) {
    // error from previous migration
    if (err) return fn(err);

    // done
    if (!migration) {
      self.emit('complete');
      self.save(fn);
      return;
    }

    self.emit('migration', migration, direction);
    migration[direction](function(err){
      next(err, migrations.shift());
    });
  }

  next(null, migrations.shift());
};
<commit_msg>Revert single migration fix<commit_after>
/*!
 * migrate - Set
 * Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter
  , fs = require('fs');

/**
 * Expose `Set`.
 */

module.exports = Set;

/**
 * Initialize a new migration `Set` with the given `path`
 * which is used to store data between migrations.
 *
 * @param {String} path
 * @api private
 */

function Set(path) {
  this.migrations = [];
  this.path = path;
  this.pos = 0;
};

/**
 * Inherit from `EventEmitter.prototype`.
 */

Set.prototype.__proto__ = EventEmitter.prototype;

/**
 * Save the migration data and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Set.prototype.save = function(fn){
  var self = this
    , json = JSON.stringify(this);
  fs.writeFile(this.path, json, function(err){
    self.emit('save');
    fn && fn(err);
  });
};

/**
 * Load the migration data and call `fn(err, obj)`.
 *
 * @param {Function} fn
 * @return {Type}
 * @api public
 */

Set.prototype.load = function(fn){
  this.emit('load');
  fs.readFile(this.path, 'utf8', function(err, json){
    if (err) return fn(err);
    try {
      fn(null, JSON.parse(json));
    } catch (err) {
      fn(err);
    }
  });
};

/**
 * Run down migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Set.prototype.down = function(fn, migrationName){
  this.migrate('down', fn, migrationName);
};

/**
 * Run up migrations and call `fn(err)`.
 *
 * @param {Function} fn
 * @api public
 */

Set.prototype.up = function(fn, migrationName){
  this.migrate('up', fn, migrationName);
};

/**
 * Migrate in the given `direction`, calling `fn(err)`.
 *
 * @param {String} direction
 * @param {Function} fn
 * @api public
 */

Set.prototype.migrate = function(direction, fn, migrationName){
  var self = this;
  fn = fn || function(){};
  this.load(function(err, obj){
    if (err) {
      if ('ENOENT' != err.code) return fn(err);
    } else {
      self.pos = obj.pos;
    }
    self._migrate(direction, fn, migrationName);
  });
};

/**
 * Get index of given migration in list of migrations
 *
 * @api private
 */

 function positionOfMigration(migrations, filename) {
   for(var i=0; i < migrations.length; ++i) {
     if (migrations[i].title == filename) return i;
   }
   return -1;
 }

/**
 * Perform migration.
 *
 * @api private
 */

Set.prototype._migrate = function(direction, fn, migrationName){
  var self = this
    , migrations
    , migrationPos;

  if (!migrationName) {
    migrationPos = direction == 'up' ? this.migrations.length : 0;
  } else if ((migrationPos = positionOfMigration(this.migrations, migrationName)) == -1) {
    console.error("Could not find migration: " + migrationName);
    process.exit(1);
  }

  switch (direction) {
    case 'up':
      migrations = this.migrations.slice(this.pos, migrationPos+1);
      this.pos += migrations.length;
      break;
    case 'down':
      migrations = this.migrations.slice(migrationPos, this.pos).reverse();
      this.pos -= migrations.length;
      break;
  }

  function next(err, migration) {
    // error from previous migration
    if (err) return fn(err);

    // done
    if (!migration) {
      self.emit('complete');
      self.save(fn);
      return;
    }

    self.emit('migration', migration, direction);
    migration[direction](function(err){
      next(err, migrations.shift());
    });
  }

  next(null, migrations.shift());
};
<|endoftext|>


<commit_before>import Bus from './bus';
import List from './list';
import Area from './area';
import Footer from './footer';
import Editor from './editor';
import lifeCycle from './lifeCycle';

import { LEYLIM_ROOT } from './constant';

/**
 * Constructor of Leylim
 *
 * @example
 * ```javascript
 * const leylim = new Leylim({
 *   el: '#app',
 *   components,
 *   rowList
 * });
 * ```
 *
 * @export
 * @class Leylim
 * @extends {Bus}
 */
export default class Leylim extends Bus {

  constructor(options) {
    super();
    /**
     * @todo extends options
     * @todo check is options.el dom element?
     */
    this.options = options;
    const {beforeCreate = lifeCycle.beforeCreate} = this.options;
    beforeCreate(this.options);
    this.init();
  }
  /**
   * For plugin using
   * @static
   * @memberof Leylim
   */
  static use() {}
  /**
   * Update all member of Leylim
   * Avilable update options; components, rowList, buttons
   */
  update(options) {
    /* eslint-disable */
    const {components} = options;
    this.options.components = components;
    this._list.update(components);
  }
  /**
   * Public method for get all rowList
   * @public
   * @returns
   * @memberof Leylim
   */
  getRowData() {
    return this._area.getRowData();
  }
  /**
   * init member of leylim for example; List, Area etc
   * @private
   */
  init() {
    const {
      components = [],
      el, rowList = [],
      buttons,
      customEditorButtons = [],
      created = lifeCycle.created,
      beforeRowUpdate = lifeCycle.beforeRowUpdate,
      rowUpdated = lifeCycle.rowUpdated,
      beforeRowDelete = lifeCycle.beforeRowDelete,
      rowDeleted = lifeCycle.rowDeleted,
      beforeRowDuplicate = lifeCycle.beforeRowDuplicate,
      rowDuplicated = lifeCycle.rowDuplicated,
      beforeRowAdd = lifeCycle.beforeRowAdd,
      rowAdded = lifeCycle.rowAdded,
    } = this.options;

    if (!components.length)
      throw new Error("Can you give me components? please! If you don't have an idea; https://github.com/abdullah/leylim ");

    const appNode = document.querySelector(el);
    const leylimNode = document.createElement('div');
    leylimNode.classList.add(LEYLIM_ROOT);
    appNode.appendChild(leylimNode);

    this._list = new List({
      rootNode: `.${LEYLIM_ROOT}`,
      components
    });

    this._footer = new Footer({
      rootNode: `.${LEYLIM_ROOT}`,
      buttons
    })

    this._area = new Area({
      rootNode: `.${LEYLIM_ROOT}`,
      rowList,
      events: {
        beforeRowUpdate,
        rowUpdated,
        beforeRowDelete,
        rowDeleted,
        beforeRowDuplicate,
        rowDuplicated,
        beforeRowAdd,
        rowAdded
      }
    });

    this._editor = new Editor({
      buttons: customEditorButtons
    })

    created();
  }
}
<commit_msg>re format<commit_after>import Bus from './bus';
import List from './list';
import Area from './area';
import Footer from './footer';
import Editor from './editor';
import lifeCycle from './lifeCycle';

import { LEYLIM_ROOT } from './constant';

/**
 * Constructor of Leylim
 *
 * @example
 * ```javascript
 * const leylim = new Leylim({
 *   el: '#app',
 *   components,
 *   rowList
 * });
 * ```
 *
 * @export
 * @class Leylim
 * @extends {Bus}
 */
export default class Leylim extends Bus {

  constructor(options) {
    super();
    /**
     * @todo extends options
     * @todo check is options.el dom element?
     */
    this.options = options;
    const { beforeCreate = lifeCycle.beforeCreate } = this.options;
    beforeCreate(this.options);
    this.init();
  }
  /**
   * For plugin using
   * @static
   * @memberof Leylim
   */
  static use() {

  }
  /**
   * Update all member of Leylim
   * Avilable update options; components, rowList, buttons
   */
  update(options) {
    const { components } = options;
    this.options.components = components;
    this._list.update(components);
  }
  /**
   * Public method for get all rowList
   * @public
   * @returns
   * @memberof Leylim
   */
  getRowData() {
    return this._area.getRowData();
  }
  /**
   * init member of leylim for example; List, Area etc
   * @private
   */
  init() {
    const {
      components = [],
      el, rowList = [],
      buttons,
      customEditorButtons = {
        merge: true,
        buttons: [],
      },
      created = lifeCycle.created,
      beforeRowUpdate = lifeCycle.beforeRowUpdate,
      rowUpdated = lifeCycle.rowUpdated,
      beforeRowDelete = lifeCycle.beforeRowDelete,
      rowDeleted = lifeCycle.rowDeleted,
      beforeRowDuplicate = lifeCycle.beforeRowDuplicate,
      rowDuplicated = lifeCycle.rowDuplicated,
      beforeRowAdd = lifeCycle.beforeRowAdd,
      rowAdded = lifeCycle.rowAdded,
    } = this.options;

    if (!components.length)
      throw new Error("Can you give me components? please! If you don't have an idea; https://github.com/abdullah/leylim ");

    const appNode = document.querySelector(el);
    const leylimNode = document.createElement('div');
    leylimNode.classList.add(LEYLIM_ROOT);
    appNode.appendChild(leylimNode);

    this._list = new List({
      rootNode: `.${LEYLIM_ROOT}`,
      components
    });

    this._footer = new Footer({
      rootNode: `.${LEYLIM_ROOT}`,
      buttons
    });

    this._area = new Area({
      rootNode: `.${LEYLIM_ROOT}`,
      rowList,
      events: {
        beforeRowUpdate,
        rowUpdated,
        beforeRowDelete,
        rowDeleted,
        beforeRowDuplicate,
        rowDuplicated,
        beforeRowAdd,
        rowAdded
      }
    });

    this._editor = new Editor({
      merge: customEditorButtons.merge,
      buttons: customEditorButtons.buttons,
      filter: customEditorButtons.filter
    });

    created();
  }
}
<|endoftext|>


<commit_before>/**
 * @author David V. Lu!! - davidvlu@gmail.com
 */

function read_point(msg, index){
    pt = [];
    var base = msg.point_step * index;
    for(var fi=0; fi<msg.fields.length; fi++){
        var si = base + msg.fields[fi].offset;
        var ar = new Uint8Array(4);
        for(var i=0; i<ar.length; i++){
            ar[i] = msg.data.buffer[si + i];
        }

        var dv = new DataView(ar.buffer);

        if( msg.fields[fi].name == 'rgb' ){
            pt[ 'rgb' ] =dv.getInt32(0, 1);
        }else{
            pt[ msg.fields[fi].name ] = dv.getFloat32(0, 1);
        }
    }
    return pt;
}

/**
 * A PointCloud2 client that listens to a given topic and displays the points.
 *
 * @constructor
 * @param options - object with following keys:
 *
 *  * ros - the ROSLIB.Ros connection handle
 *  * topic - the marker topic to listen to
 *  * tfClient - the TF client handle to use
 *  * rootObject (optional) - the root object to add this marker to
 *  * size (optional) - size to draw each point (default 0.05)
 *  * max_pts (optional) - number of points to draw (default 100)
 */
ROS3D.PointCloud2 = function(options) {
  options = options || {};
  var ros = options.ros;
  var topic = options.topic || '/points';
  var size = options.size || 0.05;
  var max_pts = options.max_pts || 100;
  this.rootObject = options.rootObject || new THREE.Object3D();
  var that = this;
  THREE.Object3D.call(this);

  this.vertex_shader = [
    'attribute vec3 customColor;',
    'varying vec3 vColor;',
    'void main() ',
    '{',
    '    vColor = customColor; // set color associated to vertex; use later in fragment shader',
    '    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
    '',
    '    // option (1): draw particles at constant size on screen',
    '    // gl_PointSize = size;',
    '    // option (2): scale particles as objects in 3D space',
    '    gl_PointSize = ', size, '* ( 300.0 / length( mvPosition.xyz ) );',
    '    gl_Position = projectionMatrix * mvPosition;',
    '}'
    ].join('\n');

  this.fragment_shader = [
    'uniform sampler2D texture;',
    'varying vec3 vColor; // colors associated to vertices; assigned by vertex shader',
    'void main() ',
    '{',
    '    // calculates a color for the particle',
    '    gl_FragColor = vec4( vColor, 1.0 );',
    '    // sets particle texture to desired color',
    '    gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );',
    '}'
    ].join('\n');

    this.geom = new THREE.Geometry();
    for(var i=0;i<max_pts;i++){
        this.geom.vertices.push(new THREE.Vector3( ));
    }

    var customUniforms =
    {
        texture:   { type: "t", value: THREE.ImageUtils.loadTexture( 'pixel.png' ) },
    };

    this.attribs =
    {
        customColor:   { type: "c", value: [] },
    };

    this.shaderMaterial = new THREE.ShaderMaterial(
    {
        uniforms:         customUniforms,
        attributes:        this.attribs,
        vertexShader : that.vertex_shader,
        fragmentShader : that.fragment_shader,
        transparent: true, alphaTest: 0.5
    });

    this.ps = new THREE.ParticleSystem( this.geom, this.shaderMaterial );
    this.rootObject.add(this.ps);

    var rosTopic = new ROSLIB.Topic({
      ros : ros,
      name : topic,
      messageType : 'sensor_msgs/PointCloud2'
    });

    rosTopic.subscribe(function(message) {
        for(var i=0;i<message.height*message.width;i++){
            var pt = read_point(message, i);
            that.geom.vertices[i] = new THREE.Vector3( pt['x'], pt['y'], pt['z'] );
            that.attribs.customColor.value[ i ] = new THREE.Color( pt['rgb'] );
        }
        that.geom.verticesNeedUpdate = true;
        that.attribs.customColor.needsUpdate = true;
    });

};
ROS3D.PointCloud2.prototype.__proto__ = THREE.Object3D.prototype;
<commit_msg>Style fixes<commit_after>/**
 * @author David V. Lu!! - davidvlu@gmail.com
 */

function read_point(msg, index){
    var pt = [];
    var base = msg.point_step * index;
    for(var fi=0; fi<msg.fields.length; fi++){
        var si = base + msg.fields[fi].offset;
        var ar = new Uint8Array(4);
        for(var i=0; i<ar.length; i++){
            ar[i] = msg.data.buffer[si + i];
        }

        var dv = new DataView(ar.buffer);

        if( msg.fields[fi].name === 'rgb' ){
            pt[ 'rgb' ] =dv.getInt32(0, 1);
        }else{
            pt[ msg.fields[fi].name ] = dv.getFloat32(0, 1);
        }
    }
    return pt;
}

/**
 * A PointCloud2 client that listens to a given topic and displays the points.
 *
 * @constructor
 * @param options - object with following keys:
 *
 *  * ros - the ROSLIB.Ros connection handle
 *  * topic - the marker topic to listen to
 *  * tfClient - the TF client handle to use
 *  * rootObject (optional) - the root object to add this marker to
 *  * size (optional) - size to draw each point (default 0.05)
 *  * max_pts (optional) - number of points to draw (default 100)
 */
ROS3D.PointCloud2 = function(options) {
  options = options || {};
  var ros = options.ros;
  var topic = options.topic || '/points';
  var size = options.size || 0.05;
  var max_pts = options.max_pts || 100;
  this.rootObject = options.rootObject || new THREE.Object3D();
  var that = this;
  THREE.Object3D.call(this);

  this.vertex_shader = [
    'attribute vec3 customColor;',
    'varying vec3 vColor;',
    'void main() ',
    '{',
    '    vColor = customColor; // set color associated to vertex; use later in fragment shader',
    '    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
    '',
    '    // option (1): draw particles at constant size on screen',
    '    // gl_PointSize = size;',
    '    // option (2): scale particles as objects in 3D space',
    '    gl_PointSize = ', size, '* ( 300.0 / length( mvPosition.xyz ) );',
    '    gl_Position = projectionMatrix * mvPosition;',
    '}'
    ].join('\n');

  this.fragment_shader = [
    'uniform sampler2D texture;',
    'varying vec3 vColor; // colors associated to vertices; assigned by vertex shader',
    'void main() ',
    '{',
    '    // calculates a color for the particle',
    '    gl_FragColor = vec4( vColor, 1.0 );',
    '    // sets particle texture to desired color',
    '    gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );',
    '}'
    ].join('\n');

    this.geom = new THREE.Geometry();
    for(var i=0;i<max_pts;i++){
        this.geom.vertices.push(new THREE.Vector3( ));
    }

    var customUniforms =
    {
        texture:   { type: 't', value: THREE.ImageUtils.loadTexture( 'pixel.png' ) },
    };

    this.attribs =
    {
        customColor:   { type: 'c', value: [] },
    };

    this.shaderMaterial = new THREE.ShaderMaterial(
    {
        uniforms:         customUniforms,
        attributes:        this.attribs,
        vertexShader : that.vertex_shader,
        fragmentShader : that.fragment_shader,
        transparent: true, alphaTest: 0.5
    });

    this.ps = new THREE.ParticleSystem( this.geom, this.shaderMaterial );
    this.rootObject.add(this.ps);

    var rosTopic = new ROSLIB.Topic({
      ros : ros,
      name : topic,
      messageType : 'sensor_msgs/PointCloud2'
    });

    rosTopic.subscribe(function(message) {
        for(var i=0;i<message.height*message.width;i++){
            var pt = read_point(message, i);
            that.geom.vertices[i] = new THREE.Vector3( pt['x'], pt['y'], pt['z'] );
            that.attribs.customColor.value[ i ] = new THREE.Color( pt['rgb'] );
        }
        that.geom.verticesNeedUpdate = true;
        that.attribs.customColor.needsUpdate = true;
    });

};
ROS3D.PointCloud2.prototype.__proto__ = THREE.Object3D.prototype;
<|endoftext|>


<commit_before>// --------------------
// Sequelize definer
// --------------------

// modules
var requireFolderTree = require('require-folder-tree');

// imports
var utils = require('./utils'),
	errors = require('./errors');

// exports
module.exports = function(Sequelize) {
	if (!Sequelize) Sequelize = require('sequelize');

	var Utils = Sequelize.Utils,
		_ = Utils._;

	utils = utils(Sequelize);

	// add custom errors to Sequelize
	errors = errors(Sequelize);
	_.extend(Sequelize, errors);
	_.extend(Sequelize.prototype, errors);

	// define a set of models at once
	// input expected in form of a Javascript object with names of the models as keys
	Sequelize.prototype.defineAll = function(definitions, defineOptions) {
		var sequelize = this;

		var globalOptions = sequelize.options.define || {};

		defineOptions = _.extend({
			primaryKey: 'id',
			primaryKeyType: Sequelize.INTEGER,
			primaryKeyFirst: false,
			autoAssociate: false,
			//onDelete: undefined,
			//onUpdate: undefined,
			//fields: undefined,
			skipFieldsOnThrough: false,
			labels: false,
			freezeTableName: globalOptions.freezeTableName,
			camelThrough: globalOptions.camelThrough
		}, defineOptions || {});

		_.defaults(defineOptions, {
			freezeTableName: false,
			camelThrough: false
		});

		// prep definitions
		var primaryKeys = {};

		_.forIn(definitions, function(definition, modelName) {
			prepOne(modelName, definition);
		});

		// process definitions
		var relationshipsOne = [];
		var relationshipsMany = [];

		_.forIn(definitions, function(definition, modelName) {
			defineOne(modelName, definition);
		});

		// create relationships
		defineRelationships();

		// functions

		function prepOne(modelName, definition)
		{
			// inherit options from defineOptions (except defineOptions.fields)
			var fields = definition.fields = definition.fields || {},
				options = definition.options = definition.options || {};

			utils.defaultsNoUndef(options, defineOptions);
			delete options.fields;

			// add additional fields
			if (defineOptions.fields && !options.skipFields) {
				_.forIn(defineOptions.fields, function(field, fieldName) {
					if (fields[fieldName] !== undefined) return;
					fields[fieldName] = utils.functionValue(_.clone(field), modelName, definition, definitions);
				});
			}

			// delete empty fields and set field type where shorthand definition used
			_.forIn(fields, function(field, fieldName) {
				if (!field) {
					delete fields[fieldName];
				} else if (!_.isPlainObject(field)) {
					fields[fieldName] = {type: field};
				}
			});

			// find primary key
			var key;
			_.forIn(fields, function(field, fieldName) {
				if (field.primaryKey) {
					key = fieldName;
					return false;
				}
			});

			// if no primary key, create primary key column
			if (!key) {
				if (!options.primaryKey) throw new Sequelize.SequelizeDefinerError("Model '" + modelName + "' has no primary key defined");

				key = utils.functionValue(options.primaryKey, modelName, definition, definitions);
				var keyField = {type: options.primaryKeyType, allowNull: false, primaryKey: true, autoIncrement: true, _autoGenerated: true};

				if (options.primaryKeyFirst) {
					utils.unshift(fields, key, keyField);
				} else {
					fields[key] = keyField;
				}
			}

			definition.primaryKey = key;
			primaryKeys[modelName + Utils.uppercaseFirst(key)] = {model: modelName, field: key};

			// get table name
			utils.defaultNoUndef(options, 'tableName', options.freezeTableName ? modelName : Utils.pluralize(modelName));
		}

		function defineOne(modelName, definition)
		{
			var fields = definition.fields,
				options = definition.options;

			// populate details of fields
			_.forIn(fields, function(params, fieldName) {
				var label = fieldName;

				// process oneToMany associations
				var reference = params.reference;
				if (reference !== undefined && !reference) {
					delete params.reference;
				} else if (reference || (options.autoAssociate && primaryKeys[fieldName])) {
					// field references another model
					var referencesKey;
					if (reference) {
						if (!definitions[reference]) throw new Sequelize.SequelizeDefinerError("Referenced model '" + reference + "' in field '" + fieldName + "' does not exist");

						if (!params.referencesKey) params.referencesKey = definitions[reference].primaryKey;

						if (utils.endsWith(fieldName, Utils.uppercaseFirst(params.referencesKey))) {
							var as = fieldName.slice(0, -params.referencesKey.length);
							if (!params.as && as != reference) params.as = as;
							label = params.as || as;
						} else {
							label = reference;
						}
					} else {
						reference = primaryKeys[fieldName].model;
						params.referencesKey = primaryKeys[fieldName].field;
						label = reference;
					}

					params.references = definitions[reference].options.tableName;

					var referenceType = utils.pop(params, 'referenceType') || 'many';
					if (['one', 'many'].indexOf(referenceType) == -1) throw new Sequelize.SequelizeDefinerError("referenceType must be either 'one' or 'many' in " + modelName + '.' + fieldName);

					utils.defaultsNoUndef(params, {
						onDelete: options.onDelete,
						onUpdate: options.onUpdate
					});

					var relationshipOptions = {
						modelName1: modelName,
						modelName2: reference,
						foreignKey: fieldName,
						referenceType: 'has' + Utils.uppercaseFirst(referenceType)
					};

					utils.extendNoUndef(relationshipOptions, {
						as: params.as,
						asReverse: params.asReverse,
						onDelete: params.onDelete,
						onUpdate: params.onUpdate
					});

					// set field type according to referred to field
					var referenceField = definitions[reference].fields[params.referencesKey];
					params.type = referenceField ? referenceField.type : options.primaryKeyType;

					// store details in relationships array
					relationshipsOne.push(relationshipOptions);
				}

				// create label
				if (options.labels && !params.label) params.label = (label == 'id' ? 'ID' : utils.camelToHuman(label));
			});

			// process manyToMany relationships
			if (definition.manyToMany) {
				_.forIn(definition.manyToMany, function(options, modelName2) {
					if (options === true) options = {};
					relationshipsMany.push(_.extend(options, {modelName1: modelName, modelName2: modelName2}));
				});
			}

			// define model in sequelize
			var model = sequelize.define(modelName, fields, options);

			// done
			return model;
		}

		function defineRelationships()
		{
			// define relationships
			var models = sequelize.models;

			// define one-to-one/one-to-many relationships
			_.forEach(relationshipsOne, function(options) {
				var model1 = models[utils.pop(options, 'modelName1')],
					model2 = models[utils.pop(options, 'modelName2')];

				var asReverse = utils.pop(options, 'asReverse');

				var joinOptions = _.clone(options);
				utils.setNoUndef(joinOptions, 'as', asReverse);
				model2[options.referenceType](model1, joinOptions); // NB referenceType = 'hasOne' or 'hasMany'

				joinOptions = _.clone(options);
				model1.belongsTo(model2, options);
			});

			// define many-to-many relationships
			_.forEach(relationshipsMany, function(options) {
				var modelName1 = utils.pop(options, 'modelName1'),
					modelName2 = utils.pop(options, 'modelName2'),
					model1 = models[modelName1],
					model2 = models[modelName2],
					key1 = definitions[modelName1].primaryKey,
					key2 = definitions[modelName2].primaryKey,
					foreignKey1 = modelName1 + Utils.uppercaseFirst(key1),
					foreignKey2 = modelName2 + Utils.uppercaseFirst(key2);

				utils.defaultsNoUndef(options, {
					associate: defineOptions.associateThrough,
					skipFields: defineOptions.skipFieldsOnThrough,
					labels: defineOptions.labels,
					freezeTableName: defineOptions.freezeTableName,
					camel: defineOptions.camelThrough,
					onDelete: defineOptions.onDelete,
					onUpdate: defineOptions.onUpdate
				});

				if (options.through) {
					// use defined through table
					options.through = models[options.through];
				} else {
					// make through table
					var fields = {};
					fields[foreignKey1] = {type: definitions[modelName1].fields[key1].type, allowNull: false, reference: null, _autoGenerated: true};
					fields[foreignKey2] = {type: definitions[modelName2].fields[key2].type, allowNull: false, reference: null, _autoGenerated: true};

					if (options.labels) {
						fields[foreignKey1].label = utils.camelToHuman(modelName1);
						fields[foreignKey2].label = utils.camelToHuman(modelName2);
					}

					var modelName = modelName1 + (options.camel ? Utils.uppercaseFirst(modelName2) : modelName2);
					var tableName = options.freezeTableName ? modelName : (Utils.pluralize(modelName1) + Utils.pluralize(options.camel ? Utils.uppercaseFirst(modelName2) : modelName2));

					var throughOptions = {
						tableName: tableName,
						labels: false,
						skipFields: options.skipFields
					};

					options.through = defineOne(modelName, {fields: fields, options: throughOptions});
				}

				var asReverse = utils.pop(options, 'asReverse');

				var joinOptions = _.clone(options);
				joinOptions.foreignKey = foreignKey1;
				model1.hasMany(model2, joinOptions);

				joinOptions = _.clone(options);
				utils.setNoUndef(joinOptions, 'as', asReverse);
				joinOptions.foreignKey = foreignKey2;
				model2.hasMany(model1, joinOptions);
			});
		}
	};

	Sequelize.prototype.defineFromFolder = function(path, options) {
		options = _.clone(options || {});

		var loadOptions = _.clone(utils.pop(options, 'loadOptions') || {});
		loadOptions.flatten = true;

		var definitions = requireFolderTree(path, loadOptions);

		return this.defineAll(definitions, options);
	};

	return Sequelize;
};
<commit_msg>Change comment<commit_after>// --------------------
// Sequelize definer
// --------------------

// modules
var requireFolderTree = require('require-folder-tree');

// imports
var utils = require('./utils'),
	errors = require('./errors');

// exports
module.exports = function(Sequelize) {
	if (!Sequelize) Sequelize = require('sequelize');

	var Utils = Sequelize.Utils,
		_ = Utils._;

	utils = utils(Sequelize);

	// add custom errors to Sequelize
	errors = errors(Sequelize);
	_.extend(Sequelize, errors);
	_.extend(Sequelize.prototype, errors);

	// define a set of models at once
	// input expected in form of a Javascript object with names of the models as keys
	Sequelize.prototype.defineAll = function(definitions, defineOptions) {
		var sequelize = this;

		var globalOptions = sequelize.options.define || {};

		defineOptions = _.extend({
			primaryKey: 'id',
			primaryKeyType: Sequelize.INTEGER,
			primaryKeyFirst: false,
			autoAssociate: false,
			//onDelete: undefined,
			//onUpdate: undefined,
			//fields: undefined,
			skipFieldsOnThrough: false,
			labels: false,
			freezeTableName: globalOptions.freezeTableName,
			camelThrough: globalOptions.camelThrough
		}, defineOptions || {});

		_.defaults(defineOptions, {
			freezeTableName: false,
			camelThrough: false
		});

		// prep definitions
		var primaryKeys = {};

		_.forIn(definitions, function(definition, modelName) {
			prepOne(modelName, definition);
		});

		// process definitions
		var relationshipsOne = [];
		var relationshipsMany = [];

		_.forIn(definitions, function(definition, modelName) {
			defineOne(modelName, definition);
		});

		// create relationships
		defineRelationships();

		// functions

		function prepOne(modelName, definition)
		{
			// inherit options from defineOptions (except defineOptions.fields)
			var fields = definition.fields = definition.fields || {},
				options = definition.options = definition.options || {};

			utils.defaultsNoUndef(options, defineOptions);
			delete options.fields;

			// add additional fields
			if (defineOptions.fields && !options.skipFields) {
				_.forIn(defineOptions.fields, function(field, fieldName) {
					if (fields[fieldName] !== undefined) return;
					fields[fieldName] = utils.functionValue(_.clone(field), modelName, definition, definitions);
				});
			}

			// delete empty fields and set field type where shorthand definition used
			_.forIn(fields, function(field, fieldName) {
				if (!field) {
					delete fields[fieldName];
				} else if (!_.isPlainObject(field)) {
					fields[fieldName] = {type: field};
				}
			});

			// find primary key
			var key;
			_.forIn(fields, function(field, fieldName) {
				if (field.primaryKey) {
					key = fieldName;
					return false;
				}
			});

			// if no primary key, create primary key column
			if (!key) {
				if (!options.primaryKey) throw new Sequelize.SequelizeDefinerError("Model '" + modelName + "' has no primary key defined");

				key = utils.functionValue(options.primaryKey, modelName, definition, definitions);
				var keyField = {type: options.primaryKeyType, allowNull: false, primaryKey: true, autoIncrement: true, _autoGenerated: true};

				if (options.primaryKeyFirst) {
					utils.unshift(fields, key, keyField);
				} else {
					fields[key] = keyField;
				}
			}

			definition.primaryKey = key;
			primaryKeys[modelName + Utils.uppercaseFirst(key)] = {model: modelName, field: key};

			// get table name
			utils.defaultNoUndef(options, 'tableName', options.freezeTableName ? modelName : Utils.pluralize(modelName));
		}

		function defineOne(modelName, definition)
		{
			var fields = definition.fields,
				options = definition.options;

			// populate details of fields
			_.forIn(fields, function(params, fieldName) {
				var label = fieldName;

				// process one-to-one/one-to-many associations
				var reference = params.reference;
				if (reference !== undefined && !reference) {
					delete params.reference;
				} else if (reference || (options.autoAssociate && primaryKeys[fieldName])) {
					// field references another model
					var referencesKey;
					if (reference) {
						if (!definitions[reference]) throw new Sequelize.SequelizeDefinerError("Referenced model '" + reference + "' in field '" + fieldName + "' does not exist");

						if (!params.referencesKey) params.referencesKey = definitions[reference].primaryKey;

						if (utils.endsWith(fieldName, Utils.uppercaseFirst(params.referencesKey))) {
							var as = fieldName.slice(0, -params.referencesKey.length);
							if (!params.as && as != reference) params.as = as;
							label = params.as || as;
						} else {
							label = reference;
						}
					} else {
						reference = primaryKeys[fieldName].model;
						params.referencesKey = primaryKeys[fieldName].field;
						label = reference;
					}

					params.references = definitions[reference].options.tableName;

					var referenceType = utils.pop(params, 'referenceType') || 'many';
					if (['one', 'many'].indexOf(referenceType) == -1) throw new Sequelize.SequelizeDefinerError("referenceType must be either 'one' or 'many' in " + modelName + '.' + fieldName);

					utils.defaultsNoUndef(params, {
						onDelete: options.onDelete,
						onUpdate: options.onUpdate
					});

					var relationshipOptions = {
						modelName1: modelName,
						modelName2: reference,
						foreignKey: fieldName,
						referenceType: 'has' + Utils.uppercaseFirst(referenceType)
					};

					utils.extendNoUndef(relationshipOptions, {
						as: params.as,
						asReverse: params.asReverse,
						onDelete: params.onDelete,
						onUpdate: params.onUpdate
					});

					// set field type according to referred to field
					var referenceField = definitions[reference].fields[params.referencesKey];
					params.type = referenceField ? referenceField.type : options.primaryKeyType;

					// store details in relationships array
					relationshipsOne.push(relationshipOptions);
				}

				// create label
				if (options.labels && !params.label) params.label = (label == 'id' ? 'ID' : utils.camelToHuman(label));
			});

			// process manyToMany relationships
			if (definition.manyToMany) {
				_.forIn(definition.manyToMany, function(options, modelName2) {
					if (options === true) options = {};
					relationshipsMany.push(_.extend(options, {modelName1: modelName, modelName2: modelName2}));
				});
			}

			// define model in sequelize
			var model = sequelize.define(modelName, fields, options);

			// done
			return model;
		}

		function defineRelationships()
		{
			// define relationships
			var models = sequelize.models;

			// define one-to-one/one-to-many relationships
			_.forEach(relationshipsOne, function(options) {
				var model1 = models[utils.pop(options, 'modelName1')],
					model2 = models[utils.pop(options, 'modelName2')];

				var asReverse = utils.pop(options, 'asReverse');

				var joinOptions = _.clone(options);
				utils.setNoUndef(joinOptions, 'as', asReverse);
				model2[options.referenceType](model1, joinOptions); // NB referenceType = 'hasOne' or 'hasMany'

				joinOptions = _.clone(options);
				model1.belongsTo(model2, options);
			});

			// define many-to-many relationships
			_.forEach(relationshipsMany, function(options) {
				var modelName1 = utils.pop(options, 'modelName1'),
					modelName2 = utils.pop(options, 'modelName2'),
					model1 = models[modelName1],
					model2 = models[modelName2],
					key1 = definitions[modelName1].primaryKey,
					key2 = definitions[modelName2].primaryKey,
					foreignKey1 = modelName1 + Utils.uppercaseFirst(key1),
					foreignKey2 = modelName2 + Utils.uppercaseFirst(key2);

				utils.defaultsNoUndef(options, {
					associate: defineOptions.associateThrough,
					skipFields: defineOptions.skipFieldsOnThrough,
					labels: defineOptions.labels,
					freezeTableName: defineOptions.freezeTableName,
					camel: defineOptions.camelThrough,
					onDelete: defineOptions.onDelete,
					onUpdate: defineOptions.onUpdate
				});

				if (options.through) {
					// use defined through table
					options.through = models[options.through];
				} else {
					// make through table
					var fields = {};
					fields[foreignKey1] = {type: definitions[modelName1].fields[key1].type, allowNull: false, reference: null, _autoGenerated: true};
					fields[foreignKey2] = {type: definitions[modelName2].fields[key2].type, allowNull: false, reference: null, _autoGenerated: true};

					if (options.labels) {
						fields[foreignKey1].label = utils.camelToHuman(modelName1);
						fields[foreignKey2].label = utils.camelToHuman(modelName2);
					}

					var modelName = modelName1 + (options.camel ? Utils.uppercaseFirst(modelName2) : modelName2);
					var tableName = options.freezeTableName ? modelName : (Utils.pluralize(modelName1) + Utils.pluralize(options.camel ? Utils.uppercaseFirst(modelName2) : modelName2));

					var throughOptions = {
						tableName: tableName,
						labels: false,
						skipFields: options.skipFields
					};

					options.through = defineOne(modelName, {fields: fields, options: throughOptions});
				}

				var asReverse = utils.pop(options, 'asReverse');

				var joinOptions = _.clone(options);
				joinOptions.foreignKey = foreignKey1;
				model1.hasMany(model2, joinOptions);

				joinOptions = _.clone(options);
				utils.setNoUndef(joinOptions, 'as', asReverse);
				joinOptions.foreignKey = foreignKey2;
				model2.hasMany(model1, joinOptions);
			});
		}
	};

	Sequelize.prototype.defineFromFolder = function(path, options) {
		options = _.clone(options || {});

		var loadOptions = _.clone(utils.pop(options, 'loadOptions') || {});
		loadOptions.flatten = true;

		var definitions = requireFolderTree(path, loadOptions);

		return this.defineAll(definitions, options);
	};

	return Sequelize;
};
<|endoftext|>


<commit_before>
const reqTests = require.context('./unit', true, /^.*\.js$/);
require('./boot');
reqTests.keys().map(reqTests);
<commit_msg>refactor: Whitespace.<commit_after>const reqTests = require.context('./unit', true, /^.*\.js$/);
require('./boot');
reqTests.keys().map(reqTests);
<|endoftext|>


<commit_before>const _ = require('lodash')
const mysql = require('mysql')
const util = require('util')
const fmt = util.format.bind(util)
const escapeId = mysql.escapeId.bind(mysql)
const escape = mysql.escape.bind(mysql)

function getFields(table, tableCache) {
  if (!tableCache[table]) {
    throw new Error('table ' + escapeId(table) + ' does not appear to be registered')
  }

  return tableCache[table].fields.map(function (field) {
    return [table,field].join('.')
  })
}

function selectWithJoinStatement(opts) {
  const table = opts.table
  const fields = opts.fields
  const relationships = opts.relationships
  const tableCache = opts.tableCache

  var allFields = fields.slice().map(function (field) {
    return [table,field].join('.')
  })

  var joinString = ''

  _.forEach(relationships, function (rel, key) {
    const otherTable = rel.table
    const joinKey = (rel.from || key)
    const joinType = rel.optional ? ' LEFT ' : ' INNER '
    allFields = allFields.concat(getFields(otherTable, tableCache))
    joinString = joinString +
      joinType + ' JOIN '+ escapeId(otherTable) +
      ' ON ' + escapeId([table, joinKey].join('.')) +
      ' = ' + escapeId([otherTable, rel.foreign].join('.'))
  })

  const escapedFields = allFields.map(function (field) {
    return escapeId(field)
  })

  return fmt('SELECT %s FROM %s %s',
             escapedFields.join(','),
             escapeId(table),
             joinString)
}

function selectStatement(opts) {
  const table = opts.table
  const fields = opts.fields
  const relationships = opts.relationships

  if (relationships) {
    return selectWithJoinStatement.apply(null, arguments)
  }

  const fieldList = fields.map(escapeId.bind(mysql)).join(',')
  return fmt('SELECT %s FROM %s', fieldList, escapeId(table))
}

function deleteStatement(table) {
  return fmt('DELETE FROM %s', escapeId(table))
}

function limitStatement(opts) {
  console.dir(opts)

  if (!opts || !opts.limit) { return '' }

  if (!opts.page)
    return fmt(' LIMIT %s ', opts.limit)

  return fmt(' LIMIT %s,%s ', opts.page - 1, opts.limit)
}

function whereStatement(conditions, table) {
  if (!conditions || !_.keys(conditions).length) {
    return ''
  }

  var where = ' WHERE '

  const clauses = _.keys(conditions).map(function (key) {
    const field = escapeId([table, key].join('.'))
    var cnd = conditions[key]

    // if the condition is an array, e.g { release_date: [2000, 1996] },
    // use an `in` operator.
    if (Array.isArray(cnd)) {
      cnd = cnd.map(function (x) { return escape(x) })
      return fmt('%s IN (%s)', field, cnd.join(','))
    }

    const op = cnd.operation || cnd.op || '='

    if (cnd.value) {
      cnd = cnd.value
    }

    return fmt('%s %s %s', field, op, escape(cnd))
  })

  where += clauses.join(' AND ')
  return where
}

function sortStatement(sorting) {
  if (!sorting) return ''

  // sorting can be one of three styles:
  // * implicit ascending, single: 'title'
  // * implicit ascending, multi: ['release_date', 'title']
  // * explicit: { title: 'desc', release_date: 'asc' }

  if (typeof sorting == 'string')
    return fmt(' ORDER BY %s', escapeId(sorting))

  if (Array.isArray(sorting))
    return fmt(' ORDER BY %s', sorting.map(escapeId).join(','))

  // must be an object
  return fmt(' ORDER BY %s', _.map(sorting, function (value, key) {
    return fmt('%s %s', escapeId(key), value.toUpperCase())
  }).join(','))
}

function selectQuery(opts, callback) {
  const queryString = selectStatement(opts)
    + whereStatement(opts.conditions, opts.table)
    + limitStatement(opts)
    + sortStatement(opts.sort)

  const queryOpts = { sql: queryString }

  if (opts.relationships)
    queryOpts.nestTables = true

  if (!callback)
    return opts.query(queryOpts, opts.fields)

  return opts.query(queryOpts, opts.fields, callback)
}

module.exports = {
  selectQuery: selectQuery,
  selectStatement: selectStatement,
  deleteStatement: deleteStatement,
  whereStatement: whereStatement,
  limitStatement: limitStatement,
  sortStatement: sortStatement,
}
<commit_msg>Fix pagination<commit_after>const _ = require('lodash')
const mysql = require('mysql')
const util = require('util')
const fmt = util.format.bind(util)
const escapeId = mysql.escapeId.bind(mysql)
const escape = mysql.escape.bind(mysql)

function getFields(table, tableCache) {
  if (!tableCache[table]) {
    throw new Error('table ' + escapeId(table) + ' does not appear to be registered')
  }

  return tableCache[table].fields.map(function (field) {
    return [table,field].join('.')
  })
}

function selectWithJoinStatement(opts) {
  const table = opts.table
  const fields = opts.fields
  const relationships = opts.relationships
  const tableCache = opts.tableCache

  var allFields = fields.slice().map(function (field) {
    return [table,field].join('.')
  })

  var joinString = ''

  _.forEach(relationships, function (rel, key) {
    const otherTable = rel.table
    const joinKey = (rel.from || key)
    const joinType = rel.optional ? ' LEFT ' : ' INNER '
    allFields = allFields.concat(getFields(otherTable, tableCache))
    joinString = joinString +
      joinType + ' JOIN '+ escapeId(otherTable) +
      ' ON ' + escapeId([table, joinKey].join('.')) +
      ' = ' + escapeId([otherTable, rel.foreign].join('.'))
  })

  const escapedFields = allFields.map(function (field) {
    return escapeId(field)
  })

  return fmt('SELECT %s FROM %s %s',
             escapedFields.join(','),
             escapeId(table),
             joinString)
}

function selectStatement(opts) {
  const table = opts.table
  const fields = opts.fields
  const relationships = opts.relationships

  if (relationships) {
    return selectWithJoinStatement.apply(null, arguments)
  }

  const fieldList = fields.map(escapeId.bind(mysql)).join(',')
  return fmt('SELECT %s FROM %s', fieldList, escapeId(table))
}

function deleteStatement(table) {
  return fmt('DELETE FROM %s', escapeId(table))
}

function limitStatement(opts) {
  console.dir(opts)

  if (!opts || !opts.limit) { return '' }

  if (!opts.page)
    return fmt(' LIMIT %s ', opts.limit)

  const beginning = (opts.page - 1) * opts.limit
  return fmt(' LIMIT %s,%s ', beginning, opts.limit)
}

function whereStatement(conditions, table) {
  if (!conditions || !_.keys(conditions).length) {
    return ''
  }

  var where = ' WHERE '

  const clauses = _.keys(conditions).map(function (key) {
    const field = escapeId([table, key].join('.'))
    var cnd = conditions[key]

    // if the condition is an array, e.g { release_date: [2000, 1996] },
    // use an `in` operator.
    if (Array.isArray(cnd)) {
      cnd = cnd.map(function (x) { return escape(x) })
      return fmt('%s IN (%s)', field, cnd.join(','))
    }

    const op = cnd.operation || cnd.op || '='

    if (cnd.value) {
      cnd = cnd.value
    }

    return fmt('%s %s %s', field, op, escape(cnd))
  })

  where += clauses.join(' AND ')
  return where
}

function sortStatement(sorting) {
  if (!sorting) return ''

  // sorting can be one of three styles:
  // * implicit ascending, single: 'title'
  // * implicit ascending, multi: ['release_date', 'title']
  // * explicit: { title: 'desc', release_date: 'asc' }

  if (typeof sorting == 'string')
    return fmt(' ORDER BY %s', escapeId(sorting))

  if (Array.isArray(sorting))
    return fmt(' ORDER BY %s', sorting.map(escapeId).join(','))

  // must be an object
  return fmt(' ORDER BY %s', _.map(sorting, function (value, key) {
    return fmt('%s %s', escapeId(key), value.toUpperCase())
  }).join(','))
}

function selectQuery(opts, callback) {
  const queryString = selectStatement(opts)
    + whereStatement(opts.conditions, opts.table)
    + sortStatement(opts.sort)
    + limitStatement(opts)

  const queryOpts = { sql: queryString }

  if (opts.relationships)
    queryOpts.nestTables = true

  if (!callback)
    return opts.query(queryOpts, opts.fields)

  return opts.query(queryOpts, opts.fields, callback)
}

module.exports = {
  selectQuery: selectQuery,
  selectStatement: selectStatement,
  deleteStatement: deleteStatement,
  whereStatement: whereStatement,
  limitStatement: limitStatement,
  sortStatement: sortStatement,
}
<|endoftext|>


<commit_before>var assert = require("assert");
var should = require('should');
var util = require('util');

var users = require("../index.js").user;

var config = {
    dburl: process.env.DBURL
};

function isValidUser(user) {
    (5).should.be.exactly(5).and.be.a.Number;
};

describe('User', function() {

    describe('create a new user', function() {

        var result;

        before(function(done) {
            this.timeout(0);
            var user = {
                "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "avatar": "http://pbs.twimg.com/profile_images/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_normal.jpeg",
                "username": "username",
                "bio": "username biography",
                "twitterId": 1234567890,
                "created": 1423360369814,
                "updated": 1423374082441,
                "email": "username@tlks.io"
            };
            users.create(config.dburl, user, function(err, docs) {
                if (err) {
                    throw new Error(err);
                }
                result = docs;
                done();
            });
        });

        it('returns not null', function(done) {
            assert.notEqual(result, null);
            done();
        });

        it('is valid user object', function(done) {
            isValidUser(result);
            done();
        });

    });

    describe('get user by its username', function () {

        var result;

        before(function(done) {
            this.timeout(0);
            users.getByUsername(config.dburl, "username", function(err, docs) {
                if (err) {
                    throw new Error(err);
                }
                result = docs;
                done();
            });
        });

        it('returns not null', function(done) {
            assert.notEqual(result, null);
            done();
        });

    });

    describe('update user', function () {

        var result;

        before(function(done) {
            this.timeout(0);
            users.getByUsername(config.dburl, "username", function(err, docs) {
                if (err) {
                    throw new Error(err);
                }
                result = docs;
                result.bio = 'updated';
                users.update(config.dburl, result, function (err, docs) {
                    if (err) {
                        throw new Error(err);
                    }
                    result = docs;
                    done();
                });
            });
        });

        it('returns is null', function(done) {
            assert.equal(result, null);
            done();
        });

    });

});
<commit_msg>Added code as mandatory on a talk<commit_after>var assert = require("assert");
var should = require('should');
var util = require('util');

var users = require("../index.js").user;

var config = {
    dburl: process.env.DBURL
};

function isValidUser(user) {
    user.should.have.properties([
        "id",
        "code",
        "avatar",
        "username",
        "bio",
        "twitterId",
        "created",
        "updated",
        "email",
    ]);
};

describe('User', function() {

    describe('create a new user', function() {

        var result;

        before(function(done) {
            this.timeout(0);
            var user = {
                "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "code": "xxxxxxxxx",
                "avatar": "http://pbs.twimg.com/profile_images/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_normal.jpeg",
                "username": "username",
                "bio": "username biography",
                "twitterId": 1234567890,
                "created": 1423360369814,
                "updated": 1423374082441,
                "email": "username@tlks.io"
            };
            users.create(config.dburl, user, function(err, docs) {
                if (err) {
                    throw new Error(err);
                }
                result = docs;
                done();
            });
        });

        it('returns not null', function(done) {
            should.notEqual(result, null, "user created object is not null");
            done();
        });

        it('returns a one element list', function(done) {
            result.should.have.length(1);
            done();
        });

        it('is valid user object', function(done) {
            var user = result[0];
            isValidUser(user);
            done();
        });

    });

    describe('get user by its username', function () {

        var result;

        before(function(done) {
            this.timeout(0);
            users.getByUsername(config.dburl, "username", function(err, docs) {
                if (err) {
                    throw new Error(err);
                }
                result = docs;
                done();
            });
        });

        it('returns not null', function(done) {
            assert.notEqual(result, null);
            done();
        });

    });

    describe('update user', function () {

        var result;

        before(function(done) {
            this.timeout(0);
            users.getByUsername(config.dburl, "username", function(err, docs) {
                if (err) {
                    throw new Error(err);
                }
                result = docs;
                result.bio = 'updated';
                users.update(config.dburl, result, function (err, docs) {
                    if (err) {
                        throw new Error(err);
                    }
                    result = docs;
                    done();
                });
            });
        });

        it('returns is null', function(done) {
            assert.equal(result, null);
            done();
        });

    });

});
<|endoftext|>


<commit_before>var async = require('async')
    , assert = require('assert')
    , host = process.env.COREOS_HOST || '127.0.0.1'
    , etcd = new (require('node-etcd'))(host)
    , winston = require('winston')
    , bunyan = require('bunyan')
    , Stream = require('stream').Stream
    , util = require('util')
    , kafka = require('kafka-node');

var logger = exports.create_logger('auth0-coreos-tools', ['system']);

// Accepts an array of strings as configuration keys.
// Each {key1} corresponds to /config/{key1} entry in etcd.
// Returns an object with properties corresponding to input keys.
// Each property is an EventEmitter. It emits the `modified` event
// when the value of the configuration key. In addition, each EventEmitter
// has a `current` property which returns the current string value stored in etcd.
exports.etcd_config = function (keys, path, callback) {
    if (typeof path === 'function') {
        callback = path;
        path = '/config/';
    }
    var config = {};
    async.each(
        keys,
        function (key, callback) {
            etcd.get(path + key, function (error, result) {
                if (error) {
                    error.key = path + key;
                    logger.error(error, 'unable to read etcd key');
                    return callback(error);
                }

                var watch = etcd.watcher(path + key, result.node.modifiedIndex + 1);
                watch.current = result.node.value;
                watch.on('change', function (result) {
                    if (watch.current !== result.node.value)
                        this.emit('modified', result.node.value);
                    watch.current = result.node.value;
                });
                watch.on('error', function (error) {
                    error.key = path + key;
                    logger.error(error, 'error watching etcd key');
                    throw error; // TODO (tjanczuk): consider surfacing etcd errors differently?
                });

                config[key] = watch;
                callback();
            });
        },
        function (error) {
            callback && (error ? callback(error) : callback(null, config));
        }
    );

    return config; // for convenience of REPL
};

// Converts response from etcd into a JS object representing only
// the data and its hierarchy. Etcd directories are represented as JS objects.

function etcd2js(node) {
    if (node.value !== undefined)
        return node.value;
    var result = {};
    if (Array.isArray(node.nodes)) {
        node.nodes.forEach(function (child) {
            result[child.key.substring(node.key.length === 1 ? 1 : node.key.length + 1)]
                = etcd2js(child);
        });
    }
    return result;
}

exports.etcd2js = etcd2js;

// Gets the key from etcd (recursively) and returns a JS representation of
// the hierarchy.
exports.etcd_get = function (key, callback) {
    etcd.get(key, { recursive: true }, function (error, result) {
        error ? callback(error): callback(null, etcd2js(result.node));
    });
};

// Convert object property names to uppercase
exports.upper = function (o) {
    var r = {};
    for (var k in o)
        r[k.toUpperCase()] = typeof o[k] === 'object' ? upper(o[k]) : o[k];
    return r;
};

// The .lowr async function completes in either of two situations:
//
// 1. If the sync_root is not locked, it obtains an exclusive, distributed lock of the sync_root
// via etcd and returns a function that can be used to release the lock as a callback parameter.
//
// 2. If the sync_root is locked, it waits for that lock to be released, and returns without any results.
//
// This logic allows several homogenic, distributed processes to ensure that a certain workload is
// completed by only one of them.
//
// The lock TTL in etcd is configured with the `/config/lock.ttl` confguration entry.
// While the lock is held, it is reset to that TTL every `/config/lock.renew` period.
var lock_id = process.pid + '.' + Date.now();
exports.lowr = function (sync_root, etcdconfig, callback) {
    // Attempt to take the lock
    etcd.set(
        '/lock/' + sync_root,
        lock_id,
        { prevExist: false, ttl: +etcdconfig.lock_ttl.current },
        function (error, result) {
            if (error) {
                if (error.errorCode === 105) {
                    // Lock is currently held, wait for its release
                    var watch = etcd.watcher('/lock/' + sync_root, error.error.index + 1);
                    watch.on('change', function (result) {
                        if (result.node.value === undefined)
                            done();
                    });
                    watch.on('error', done);

                    function done(error, result) {
                        watch.stop();
                        callback(error, result);
                    }

                    return;
                }

                return callback(error);
            }

            // Lock was taken, renew it periodically until released

            var renew = setInterval(function () {
                etcd.set('/lock/' + sync_root, lock_id, { ttl: +etcdconfig.lock_ttl.current });
            }, +etcdconfig.lock_renew.current * 1000);

            // Return a function that must be used to release the lock

            callback(null, function (callback) {
                clearInterval(renew);
                etcd.compareAndDelete('/lock/' + sync_root, lock_id, function (error) {
                    return callback && callback(error);
                });
            });
        });
};

var KafkaTransport = exports.KafkaTransport = function (options) {
    assert.ok(options, 'options must be specified');
    assert.ok(typeof options === 'object', 'options must be an object');
    assert.ok(typeof options.zookeeper === 'string', 'options.zookeeper must be specfied');
    assert.ok(Array.isArray(options.topics), 'options.topic must be an array of string topics');
    this.name = options.name || 'kafka';
    this.level = options.level || 'info';
    this.options = options;
    this._pending = [];
    this._client = new kafka.Client(this.options.zookeeper, 'kafka-transport');
    this._producer = new kafka.Producer(this._client);
    var self = this;
    this._producer
        .once('ready', function () {
            self._ready = true;
            self._send_pending();
        })
        .on('error', function (error) {
            self._error = error;
            winston.error('winston-kafka error', error);
        });
};

util.inherits(KafkaTransport, winston.Transport);

KafkaTransport.prototype.log = function (level, msg, meta, callback) {
    if (!this._error) {
        this._pending.push({ time: new Date(), level: level, msg: msg, meta: meta, callback: callback });
        this._send_pending();
    }
    else
        callback(this._error);
};

KafkaTransport.prototype._send_pending = function () {
    if (this._ready && this._pending.length > 0) {
        var current = this._pending;
        this._pending = [];
        var messages = [];
        current.forEach(function (entry) {
            var meta;
            if (entry.meta && Object.getOwnPropertyNames(entry.meta).length > 0)
                meta = ' ' + util.inspect(entry.meta);
            messages.push(
                entry.time.toISOString() + ' '
                + entry.level + ': '
                + entry.msg
                + (meta || '')
            );
        });
        var payload = [];
        this.options.topics.forEach(function (topic) {
            payload.push({
                topic: topic,
                messages: messages
            });
        });
        this._producer.send(payload, function (error) {
            current.forEach(function (entry) {
                entry.callback && entry.callback(error);
            });
        });
    }
};

var KafkaStream = exports.KafkaStream = function (options) {
    assert.ok(options, 'options must be specified');
    assert.ok(typeof options === 'object', 'options must be an object');
    assert.ok(typeof options.zookeeper === 'string', 'options.zookeeper must be specfied');
    assert.ok(Array.isArray(options.topics), 'options.topic must be an array of string topics');
    Stream.call(this);
    this.name = options.name || 'kafka';
    this.writable = true;
    this.options = options;
    this._pending = [];
    this._client = new kafka.Client(this.options.zookeeper, 'kafka-transport');
    this._producer = new kafka.Producer(this._client);
    var self = this;
    this._producer
        .once('ready', function () {
            self._ready = true;
            self._send_pending();
        })
        .on('error', function (error) {
            self._error = error;
            self.emit('error', error);
        });
};

util.inherits(KafkaStream, Stream);

KafkaStream.prototype.close = function close() {
    this._client.close();
};

KafkaStream.prototype.destroy = function destroy() {
    this.writable = false;
    this.close();
};

KafkaStream.prototype.end = function end() {
    if (arguments.length > 0)
            this.write.apply(this, Array.prototype.slice.call(arguments));

    this.writable = false;
    this.close();
};

KafkaStream.prototype.write = function write(r) {
    if (!this._error) {
        this._pending.push(r);
        this._send_pending();
    }
    else
        throw this._error;
};

KafkaStream.prototype._send_pending = function () {
    if (this._ready && this._pending.length > 0) {
        var current = this._pending;
        this._pending = [];
        var messages = [];
        current.forEach(function (entry) {
            messages.push(typeof entry === 'string' ? message : JSON.stringify(entry));
        });
        var payload = [];
        this.options.topics.forEach(function (topic) {
            payload.push({
                topic: topic,
                messages: messages
            });
        });
        var self = this;
        this._producer.send(payload, function (error) {
            if (error) self.emit('error', error);
        });
    }
};

exports.create_logger = function (name, topics) {
    var logger_options = {
        name: name,
        streams: [
            {
                level: 'info',
                stream: process.stdout
            }
        ]
    };

    if (Array.isArray(topics) && process.env.KAFKA_ZOOKEEPER) {
        // Enable Kafka stream
        logger_options.streams.push(new KafkaStream({
            zookeeper: process.env.KAFKA_ZOOKEEPER,
            topics: topics
        }));
    }

    return bunyan.createLogger(logger_options);
};
<commit_msg>fix bug<commit_after>var async = require('async')
    , assert = require('assert')
    , host = process.env.COREOS_HOST || '127.0.0.1'
    , etcd = new (require('node-etcd'))(host)
    , winston = require('winston')
    , bunyan = require('bunyan')
    , Stream = require('stream').Stream
    , util = require('util')
    , kafka = require('kafka-node');

var logger = create_logger('auth0-coreos-tools', ['system']);

// Accepts an array of strings as configuration keys.
// Each {key1} corresponds to /config/{key1} entry in etcd.
// Returns an object with properties corresponding to input keys.
// Each property is an EventEmitter. It emits the `modified` event
// when the value of the configuration key. In addition, each EventEmitter
// has a `current` property which returns the current string value stored in etcd.
exports.etcd_config = function (keys, path, callback) {
    if (typeof path === 'function') {
        callback = path;
        path = '/config/';
    }
    var config = {};
    async.each(
        keys,
        function (key, callback) {
            etcd.get(path + key, function (error, result) {
                if (error) {
                    error.key = path + key;
                    logger.error(error, 'unable to read etcd key');
                    return callback(error);
                }

                var watch = etcd.watcher(path + key, result.node.modifiedIndex + 1);
                watch.current = result.node.value;
                watch.on('change', function (result) {
                    if (watch.current !== result.node.value)
                        this.emit('modified', result.node.value);
                    watch.current = result.node.value;
                });
                watch.on('error', function (error) {
                    error.key = path + key;
                    logger.error(error, 'error watching etcd key');
                    throw error; // TODO (tjanczuk): consider surfacing etcd errors differently?
                });

                config[key] = watch;
                callback();
            });
        },
        function (error) {
            callback && (error ? callback(error) : callback(null, config));
        }
    );

    return config; // for convenience of REPL
};

// Converts response from etcd into a JS object representing only
// the data and its hierarchy. Etcd directories are represented as JS objects.

function etcd2js(node) {
    if (node.value !== undefined)
        return node.value;
    var result = {};
    if (Array.isArray(node.nodes)) {
        node.nodes.forEach(function (child) {
            result[child.key.substring(node.key.length === 1 ? 1 : node.key.length + 1)]
                = etcd2js(child);
        });
    }
    return result;
}

exports.etcd2js = etcd2js;

// Gets the key from etcd (recursively) and returns a JS representation of
// the hierarchy.
exports.etcd_get = function (key, callback) {
    etcd.get(key, { recursive: true }, function (error, result) {
        error ? callback(error): callback(null, etcd2js(result.node));
    });
};

// Convert object property names to uppercase
exports.upper = function (o) {
    var r = {};
    for (var k in o)
        r[k.toUpperCase()] = typeof o[k] === 'object' ? upper(o[k]) : o[k];
    return r;
};

// The .lowr async function completes in either of two situations:
//
// 1. If the sync_root is not locked, it obtains an exclusive, distributed lock of the sync_root
// via etcd and returns a function that can be used to release the lock as a callback parameter.
//
// 2. If the sync_root is locked, it waits for that lock to be released, and returns without any results.
//
// This logic allows several homogenic, distributed processes to ensure that a certain workload is
// completed by only one of them.
//
// The lock TTL in etcd is configured with the `/config/lock.ttl` confguration entry.
// While the lock is held, it is reset to that TTL every `/config/lock.renew` period.
var lock_id = process.pid + '.' + Date.now();
exports.lowr = function (sync_root, etcdconfig, callback) {
    // Attempt to take the lock
    etcd.set(
        '/lock/' + sync_root,
        lock_id,
        { prevExist: false, ttl: +etcdconfig.lock_ttl.current },
        function (error, result) {
            if (error) {
                if (error.errorCode === 105) {
                    // Lock is currently held, wait for its release
                    var watch = etcd.watcher('/lock/' + sync_root, error.error.index + 1);
                    watch.on('change', function (result) {
                        if (result.node.value === undefined)
                            done();
                    });
                    watch.on('error', done);

                    function done(error, result) {
                        watch.stop();
                        callback(error, result);
                    }

                    return;
                }

                return callback(error);
            }

            // Lock was taken, renew it periodically until released

            var renew = setInterval(function () {
                etcd.set('/lock/' + sync_root, lock_id, { ttl: +etcdconfig.lock_ttl.current });
            }, +etcdconfig.lock_renew.current * 1000);

            // Return a function that must be used to release the lock

            callback(null, function (callback) {
                clearInterval(renew);
                etcd.compareAndDelete('/lock/' + sync_root, lock_id, function (error) {
                    return callback && callback(error);
                });
            });
        });
};

var KafkaTransport = exports.KafkaTransport = function (options) {
    assert.ok(options, 'options must be specified');
    assert.ok(typeof options === 'object', 'options must be an object');
    assert.ok(typeof options.zookeeper === 'string', 'options.zookeeper must be specfied');
    assert.ok(Array.isArray(options.topics), 'options.topic must be an array of string topics');
    this.name = options.name || 'kafka';
    this.level = options.level || 'info';
    this.options = options;
    this._pending = [];
    this._client = new kafka.Client(this.options.zookeeper, 'kafka-transport');
    this._producer = new kafka.Producer(this._client);
    var self = this;
    this._producer
        .once('ready', function () {
            self._ready = true;
            self._send_pending();
        })
        .on('error', function (error) {
            self._error = error;
            winston.error('winston-kafka error', error);
        });
};

util.inherits(KafkaTransport, winston.Transport);

KafkaTransport.prototype.log = function (level, msg, meta, callback) {
    if (!this._error) {
        this._pending.push({ time: new Date(), level: level, msg: msg, meta: meta, callback: callback });
        this._send_pending();
    }
    else
        callback(this._error);
};

KafkaTransport.prototype._send_pending = function () {
    if (this._ready && this._pending.length > 0) {
        var current = this._pending;
        this._pending = [];
        var messages = [];
        current.forEach(function (entry) {
            var meta;
            if (entry.meta && Object.getOwnPropertyNames(entry.meta).length > 0)
                meta = ' ' + util.inspect(entry.meta);
            messages.push(
                entry.time.toISOString() + ' '
                + entry.level + ': '
                + entry.msg
                + (meta || '')
            );
        });
        var payload = [];
        this.options.topics.forEach(function (topic) {
            payload.push({
                topic: topic,
                messages: messages
            });
        });
        this._producer.send(payload, function (error) {
            current.forEach(function (entry) {
                entry.callback && entry.callback(error);
            });
        });
    }
};

var KafkaStream = exports.KafkaStream = function (options) {
    assert.ok(options, 'options must be specified');
    assert.ok(typeof options === 'object', 'options must be an object');
    assert.ok(typeof options.zookeeper === 'string', 'options.zookeeper must be specfied');
    assert.ok(Array.isArray(options.topics), 'options.topic must be an array of string topics');
    Stream.call(this);
    this.name = options.name || 'kafka';
    this.writable = true;
    this.options = options;
    this._pending = [];
    this._client = new kafka.Client(this.options.zookeeper, 'kafka-transport');
    this._producer = new kafka.Producer(this._client);
    var self = this;
    this._producer
        .once('ready', function () {
            self._ready = true;
            self._send_pending();
        })
        .on('error', function (error) {
            self._error = error;
            self.emit('error', error);
        });
};

util.inherits(KafkaStream, Stream);

KafkaStream.prototype.close = function close() {
    this._client.close();
};

KafkaStream.prototype.destroy = function destroy() {
    this.writable = false;
    this.close();
};

KafkaStream.prototype.end = function end() {
    if (arguments.length > 0)
            this.write.apply(this, Array.prototype.slice.call(arguments));

    this.writable = false;
    this.close();
};

KafkaStream.prototype.write = function write(r) {
    if (!this._error) {
        this._pending.push(r);
        this._send_pending();
    }
    else
        throw this._error;
};

KafkaStream.prototype._send_pending = function () {
    if (this._ready && this._pending.length > 0) {
        var current = this._pending;
        this._pending = [];
        var messages = [];
        current.forEach(function (entry) {
            messages.push(typeof entry === 'string' ? message : JSON.stringify(entry));
        });
        var payload = [];
        this.options.topics.forEach(function (topic) {
            payload.push({
                topic: topic,
                messages: messages
            });
        });
        var self = this;
        this._producer.send(payload, function (error) {
            if (error) self.emit('error', error);
        });
    }
};

exports.create_logger = function create_logger(name, topics) {
    var logger_options = {
        name: name,
        streams: [
            {
                level: 'info',
                stream: process.stdout
            }
        ]
    };

    if (Array.isArray(topics) && process.env.KAFKA_ZOOKEEPER) {
        // Enable Kafka stream
        logger_options.streams.push(new KafkaStream({
            zookeeper: process.env.KAFKA_ZOOKEEPER,
            topics: topics
        }));
    }

    return bunyan.createLogger(logger_options);
};
<|endoftext|>