<commit_before>// membasedatabank.js
//
// implementation of Databank interface using membase
//
// Copyright 2011, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var databank = require('../databank');
var memcached = require('memcached');

var Databank = databank.Databank;
var DatabankError = databank.DatabankError;
var AlreadyExistsError = databank.AlreadyExistsError;
var NoSuchThingError = databank.NoSuchThingError;
var NotConnectedError = databank.NotConnectedError;
var AlreadyConnectedError = databank.AlreadyConnectedError;

function MembaseDatabank(params) {
    this.serverLocations = params.serverLocations || '127.0.0.1:11211';
    this.options = params.options || {};
    this.schema = params.schema || {};
    this.expire = params.expire || 2592000;
    this.client = null;
}

MembaseDatabank.prototype = new Databank();

MembaseDatabank.prototype.toKey = function(type, id) {
    return type + ':' + id;
};

MembaseDatabank.prototype.connect = function(params, onCompletion) {
    if (this.client) {
        onCompletion(new AlreadyConnectedError());
        return;
    }
    // FIXME: accept serverLocations or options in params...?
    this.client = new memcached(this.serverLocations, this.options);
    onCompletion(null);
};

MembaseDatabank.prototype.disconnect = function(onCompletion) {
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client = null;
    onCompletion(null);
};

MembaseDatabank.prototype.create = function(type, id, value, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.add(key, JSON.stringify(value), this.expire, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else if (!result) { // key clash
            onCompletion(new AlreadyExistsError(type, id), null);
        } else {
            onCompletion(null, value);
        }
    });
};

MembaseDatabank.prototype.read = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.get(key, function(err, value) {
        if (err) {
            // FIXME: find key-misses and return no-such-thing error
            onCompletion(err, null);
        } else {
            onCompletion(null, JSON.parse(value));
        }
    });
};

MembaseDatabank.prototype.update = function(type, id, value, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.replace(key, JSON.stringify(value), this.expire, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else if (!result) { // key miss
            onCompletion(new NoSuchThingError(type, id), null);
        } else {
            onCompletion(null, value);
        }
    });
};

MembaseDatabank.prototype.del = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.del(key, function(err, value) {
        if (err) {
            onCompletion(err);
        } else if (!value) { // key miss
            onCompletion(new NoSuchThingError(type, id), null);
        } else {
            onCompletion(null);
        }
    });
};

MembaseDatabank.prototype.save = function(type, id, value, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.set(key, JSON.stringify(value), this.expire, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else if (!result) { // key miss
            onCompletion(new NoSuchThingError(type, id), null);
        } else {
            onCompletion(null, value);
        }
    });
};

MembaseDatabank.prototype.readAll = function(type, ids, onCompletion) {
    var keys = [], keyToId = {}, key, i;
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    for (i = 0; i < ids.length; i++) {
        key = this.toKey(type, ids[i]);
        keys.push(key);
        keyToId[key] = ids[i];
    }
    this.client.getMulti(keys, function(err, results) {
        var key, idMap = {}, i, id;
        if (err) {
            onCompletion(err, null);
        } else {
            for (i = 0; i < keys.length; i++) {
                key = keys[i];
                id = keyToId[key];
                if (results.hasOwnProperty(key)) {
                    idMap[id] = JSON.parse(results[key]);
                } else {
                    idMap[id] = null;
                }
            }
            onCompletion(null, idMap);
        }
    });
};

MembaseDatabank.prototype.incr = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    this.client.incr(key, 1, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else {
            onCompletion(null, result);
        }
    });
};

MembaseDatabank.prototype.decr = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    this.client.decr(key, 1, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else {
            onCompletion(null, result);
        }
    });
};

module.exports = MembaseDatabank;
<commit_msg>rename module<commit_after>// memcacheddatabank.js
//
// implementation of Databank interface using memcached
//
// Copyright 2011,2012 StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var databank = require('../databank');
var memcached = require('memcached');

var Databank = databank.Databank;
var DatabankError = databank.DatabankError;
var AlreadyExistsError = databank.AlreadyExistsError;
var NoSuchThingError = databank.NoSuchThingError;
var NotConnectedError = databank.NotConnectedError;
var AlreadyConnectedError = databank.AlreadyConnectedError;

function MemcachedDatabank(params) {
    this.serverLocations = params.serverLocations || '127.0.0.1:11211';
    this.options = params.options || {};
    this.schema = params.schema || {};
    this.expire = params.expire || 2592000;
    this.client = null;
}

MemcachedDatabank.prototype = new Databank();

MemcachedDatabank.prototype.toKey = function(type, id) {
    return type + ':' + id;
};

MemcachedDatabank.prototype.connect = function(params, onCompletion) {
    if (this.client) {
        onCompletion(new AlreadyConnectedError());
        return;
    }
    // FIXME: accept serverLocations or options in params...?
    this.client = new memcached(this.serverLocations, this.options);
    onCompletion(null);
};

MemcachedDatabank.prototype.disconnect = function(onCompletion) {
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client = null;
    onCompletion(null);
};

MemcachedDatabank.prototype.create = function(type, id, value, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.add(key, JSON.stringify(value), this.expire, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else if (!result) { // key clash
            onCompletion(new AlreadyExistsError(type, id), null);
        } else {
            onCompletion(null, value);
        }
    });
};

MemcachedDatabank.prototype.read = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.get(key, function(err, value) {
        if (err) {
            // FIXME: find key-misses and return no-such-thing error
            onCompletion(err, null);
        } else {
            onCompletion(null, JSON.parse(value));
        }
    });
};

MemcachedDatabank.prototype.update = function(type, id, value, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.replace(key, JSON.stringify(value), this.expire, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else if (!result) { // key miss
            onCompletion(new NoSuchThingError(type, id), null);
        } else {
            onCompletion(null, value);
        }
    });
};

MemcachedDatabank.prototype.del = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.del(key, function(err, value) {
        if (err) {
            onCompletion(err);
        } else if (!value) { // key miss
            onCompletion(new NoSuchThingError(type, id), null);
        } else {
            onCompletion(null);
        }
    });
};

MemcachedDatabank.prototype.save = function(type, id, value, onCompletion) {
    var key = this.toKey(type, id);
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    this.client.set(key, JSON.stringify(value), this.expire, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else if (!result) { // key miss
            onCompletion(new NoSuchThingError(type, id), null);
        } else {
            onCompletion(null, value);
        }
    });
};

MemcachedDatabank.prototype.readAll = function(type, ids, onCompletion) {
    var keys = [], keyToId = {}, key, i;
    if (!this.client) {
        onCompletion(new NotConnectedError());
        return;
    }
    for (i = 0; i < ids.length; i++) {
        key = this.toKey(type, ids[i]);
        keys.push(key);
        keyToId[key] = ids[i];
    }
    this.client.getMulti(keys, function(err, results) {
        var key, idMap = {}, i, id;
        if (err) {
            onCompletion(err, null);
        } else {
            for (i = 0; i < keys.length; i++) {
                key = keys[i];
                id = keyToId[key];
                if (results.hasOwnProperty(key)) {
                    idMap[id] = JSON.parse(results[key]);
                } else {
                    idMap[id] = null;
                }
            }
            onCompletion(null, idMap);
        }
    });
};

MemcachedDatabank.prototype.incr = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    this.client.incr(key, 1, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else {
            onCompletion(null, result);
        }
    });
};

MemcachedDatabank.prototype.decr = function(type, id, onCompletion) {
    var key = this.toKey(type, id);
    this.client.decr(key, 1, function(err, result) {
        if (err) {
            onCompletion(err, null);
        } else {
            onCompletion(null, result);
        }
    });
};

module.exports = MemcachedDatabank;
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var path = require('path');
var async = require('async');
var Asset = require('./asset');
var isArray = require('lodash.isarray');
var discovery = require('./discovery');
var Farcaster = require('./farcaster');
var spawnSync = require('child_process').spawnSync;
var partialRender = require('./render');

/**
 * Parse commmand line arguments
 */
var argv = require('minimist')(process.argv);
var SERVICE_DIR = argv['service-dir'];

/**
 * Constructor for MicroMono class
 *
 * @return {MicroMono} Instance of MicroMono class
 */
var MicroMono = module.exports = function MicroMono(options) {
  this.options = this.getDefaultOptions(options);
  this.services = {};
};

/**
 * MicroMono public API.
 *
 * @type {Object}
 */
MicroMono.prototype = {

  getDefaultOptions: function(options) {
    options = options || {};

    if (!options.packagePath) {
      var parentFile = module.parent.parent.filename;
      options.packagePath = path.dirname(parentFile);
    }

    return options;
  },

  getPackageInfo: function(packagePath) {
    this.asset = new Asset(packagePath);

    try {
      this.asset.parseJSPM();
    } catch (e) {}
  },

  require: function(package) {
    var ServiceClass;

    try {
      // @todo handle path start with './'?
      if (SERVICE_DIR) {
        package = path.resolve(SERVICE_DIR, package);
      }
      ServiceClass = require(package);
    } catch (e) {
      var expectedMessage = 'Cannot find module \'' + package + '\'';
      if (e.code !== 'MODULE_NOT_FOUND' || e.message !== expectedMessage) {
        // throw error if we found the module which contains error.
        throw e;
      }
      var probedResult = spawnSync('node', [require.resolve('./prober'), package]);
      if (probedResult.status !== 0) {
        throw new Error(probedResult.stderr.toString());
      } else {
        var serviceInfo = JSON.parse(probedResult.stdout);
        console.log('New service `%s` probed from network.', serviceInfo.name);
        console.log(serviceInfo);
        ServiceClass = Farcaster.build(serviceInfo);
      }
    }

    var serviceInstance;
    // Singleton service factory
    var ServiceFactory = ServiceClass.extend({
      constructor: function() {
        if (!serviceInstance) {
          serviceInstance = new ServiceClass();
        }
        return serviceInstance;
      }
    });

    this.registerService(package, ServiceFactory);

    return ServiceFactory;
  },

  /**
   * @param  {Function} [app] Instance of express application
   * @return {Promise}
   */
  boot: function(app) {
    if (typeof app === 'function') {
      if (app.prototype.isRemote) {
        var Service = app;
        var service = new Service();
        this.registerService(service.announcement.name, service);
        app = null;
      } else if (app.get('views')) {
        app.use(partialRender(app));
      }
    } else if (typeof app === 'string') {
      this.require(app);
      app = null;
    } else if (isArray(app)) {
      app.forEach(function(package) {
        this.require(package);
      }, this);
      app = null;
    }

    var self = this;
    var services = this.services;
    this.getPackageInfo(this.options.packagePath);
    var asset = this.asset;

    var promise = asset.configJSPM()
      .then(function() {
        return new Promise(function(resolve, reject) {
          async.each(Object.keys(services), function runService(name, callback) {
            var serviceInstance = services[name];
            if (typeof serviceInstance === 'function') {
              var ServiceFactory = serviceInstance;
              serviceInstance = new ServiceFactory();
              self.registerService(name, serviceInstance);
            }
            asset.mergeJSPMDeps(serviceInstance.announcement.client);
            var p = serviceInstance.run(app);
            if (!app) {
              p = p.then(function() {
                discovery.announce(serviceInstance.announcement);
              });
            }
            p.then(callback).catch(callback);
          }, function bootServicesFinished(err) {
            err ? reject(err) : resolve();
          });
        });
      });

    if (app) {
      // assume we are in the consumer mode
      promise = promise.then(function() {
        discovery.listen(function(err, data, rinfo) {
          if (data && data.name) {
            var serviceName = data.name;
            var serviceInstance = services[serviceName];
            if (serviceInstance && serviceInstance.isRemote()) {
              // Only remote probed service has the ability to add provider.
              serviceInstance.addProvider(data);
            }
          }
        });
      });

      if (asset.publicURL && asset.publicPath) {
        // serve local asset files
        promise = promise.then(function() {
          app.use(asset.publicURL, require('express').static(asset.publicPath));
        });
      }
    }

    return promise;
  },

  registerService: function(name, serviceInstance) {
    this.services[name] = serviceInstance;
  }
};
<commit_msg>Load services with command line option `--service`.<commit_after>/**
 * Module dependencies
 */

var path = require('path');
var async = require('async');
var Asset = require('./asset');
var isArray = require('lodash.isarray');
var discovery = require('./discovery');
var Farcaster = require('./farcaster');
var spawnSync = require('child_process').spawnSync;
var partialRender = require('./render');

/**
 * Parse commmand line arguments
 */
var argv = require('minimist')(process.argv);
var SERVICE_DIR = argv['service-dir'];

/**
 * Constructor for MicroMono class
 *
 * @return {MicroMono} Instance of MicroMono class
 */
var MicroMono = module.exports = function MicroMono(options) {
  this.options = this.getDefaultOptions(options);
  this.services = {};
  if (SERVICE) {
    var services = SERVICE.split(',');
    // load services required from command line
    services.forEach(function(name) {
      this.require(name);
    }, this);
  }
};

/**
 * MicroMono public API.
 *
 * @type {Object}
 */
MicroMono.prototype = {

  getDefaultOptions: function(options) {
    options = options || {};

    if (!options.packagePath) {
      var parentFile = module.parent.parent.filename;
      options.packagePath = path.dirname(parentFile);
    }

    return options;
  },

  getPackageInfo: function(packagePath) {
    this.asset = new Asset(packagePath);

    try {
      this.asset.parseJSPM();
    } catch (e) {}
  },

  require: function(package) {
    var ServiceClass;

    try {
      // @todo handle path start with './'?
      if (SERVICE_DIR) {
        package = path.resolve(SERVICE_DIR, package);
      }
      ServiceClass = require(package);
    } catch (e) {
      var expectedMessage = 'Cannot find module \'' + package + '\'';
      if (e.code !== 'MODULE_NOT_FOUND' || e.message !== expectedMessage) {
        // throw error if we found the module which contains error.
        throw e;
      }
      var probedResult = spawnSync('node', [require.resolve('./prober'), package]);
      if (probedResult.status !== 0) {
        throw new Error(probedResult.stderr.toString());
      } else {
        var serviceInfo = JSON.parse(probedResult.stdout);
        console.log('New service `%s` probed from network.', serviceInfo.name);
        console.log(serviceInfo);
        ServiceClass = Farcaster.build(serviceInfo);
      }
    }

    var serviceInstance;
    // Singleton service factory
    var ServiceFactory = ServiceClass.extend({
      constructor: function() {
        if (!serviceInstance) {
          serviceInstance = new ServiceClass();
        }
        return serviceInstance;
      }
    });

    this.registerService(package, ServiceFactory);

    return ServiceFactory;
  },

  /**
   * @param  {Function} [app] Instance of express application
   * @return {Promise}
   */
  boot: function(app) {
    if (typeof app === 'function') {
      if (app.prototype.isRemote) {
        var Service = app;
        var service = new Service();
        this.registerService(service.announcement.name, service);
        app = null;
      } else if (app.get('views')) {
        app.use(partialRender(app));
      }
    } else if (typeof app === 'string') {
      this.require(app);
      app = null;
    } else if (isArray(app)) {
      app.forEach(function(package) {
        this.require(package);
      }, this);
      app = null;
    }

    var self = this;
    var services = this.services;
    this.getPackageInfo(this.options.packagePath);
    var asset = this.asset;

    var promise = asset.configJSPM()
      .then(function() {
        return new Promise(function(resolve, reject) {
          async.each(Object.keys(services), function runService(name, callback) {
            var serviceInstance = services[name];
            if (typeof serviceInstance === 'function') {
              var ServiceFactory = serviceInstance;
              serviceInstance = new ServiceFactory();
              self.registerService(name, serviceInstance);
            }
            asset.mergeJSPMDeps(serviceInstance.announcement.client);
            var p = serviceInstance.run(app);
            if (!app) {
              p = p.then(function() {
                discovery.announce(serviceInstance.announcement);
              });
            }
            p.then(callback).catch(callback);
          }, function bootServicesFinished(err) {
            err ? reject(err) : resolve();
          });
        });
      });

    if (app) {
      // assume we are in the consumer mode
      promise = promise.then(function() {
        discovery.listen(function(err, data, rinfo) {
          if (data && data.name) {
            var serviceName = data.name;
            var serviceInstance = services[serviceName];
            if (serviceInstance && serviceInstance.isRemote()) {
              // Only remote probed service has the ability to add provider.
              serviceInstance.addProvider(data);
            }
          }
        });
      });

      if (asset.publicURL && asset.publicPath) {
        // serve local asset files
        promise = promise.then(function() {
          app.use(asset.publicURL, require('express').static(asset.publicPath));
        });
      }
    }

    return promise;
  },

  registerService: function(name, serviceInstance) {
    this.services[name] = serviceInstance;
  }
};
<|endoftext|>


<commit_before>/**
 * For the takeEval and preview views
 */
$(document).ready(function() {

    var instrSel = $('div[@rel=evalinstructorSelector]');
    var assSel = $('div[@rel=evalassistantSelector]');
    instrSel.evalSelector({type:0});
    assSel.evalSelector({type:1});
    $('[id=form-branch::submitEvaluation]').bind('click', function() {
        if (instrSel.find('input[type=checkbox]').length != 0) {
            var selectedInstrDomArray = instrSel.find('input:checked').get();
            if (selectedInstrDomArray.length > 0) {
                instrSel.find("fieldset").css({
                    background:'#fff'
                });
                var selectedInstrArray = new Array();
                $.each(selectedInstrDomArray, function(i, item) {
                    selectedInstrArray.push($(item).val());
                });
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-instructor-multiple%3A%3Aselect-instructor-multiple-row" value="' + selectedInstrArray.toString() + '" />');
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-instructor-multiple%3A%3Aselect-instructor-multiple-row-fossil" value="istring#{takeEvalBean.selectioninstructorIds}" />');
            } else {
                return  error("LECTURER", instrSel);
            }
        }
        if (assSel.find('input[type=checkbox]').length != 0) {
            var selectedassistantDomArray = assSel.find('input:checked').get();
            if (selectedassistantDomArray.length > 0) {
                assSel.find("fieldset").css({
                    background:'#fff'
                });
                var selectedassistantArray = new Array();
                $.each(selectedassistantDomArray, function(i, item) {
                    selectedassistantArray.push($(item).val());
                });
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-assistant-multiple%3A%3Aselect-assistant-multiple-row" value="' + selectedassistantArray.toString() + '" />');
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-assistant-multiple%3A%3Aselect-assistant-multiple-row-fossil" value="istring#{takeEvalBean.selectionassistantIds}" />');
            } else {
                return error("TUTOR", assSel);
            }
        }
        if (assSel.find('select').length != 0) {
            var valid = true;
            assSel.find('select').each(function() {
                if (this.selectedIndex == 0) {
                    valid = false;
                }
            });
            if (!valid) {
                return error("TUTOR", assSel);
            } else {
                assSel.find("fieldset").css({
                    background:'#fff'
                });
            }
        }
        if (instrSel.find('select').length != 0) {
            valid = true;
            instrSel.find('select').each(function() {
                if (this.selectedIndex == 0) {
                    valid = false;
                }
            });
            if (!valid) {
                return  error("LECTURER", instrSel);
            } else {
                instrSel.find("fieldset").css({
                    background:'#fff'
                });
            }
        }
        $(this).hide();
        $('input[name=submit_process]').show();
    });

    function error(type, that) {
        alert('Please evaluate at least one ' + type + '.');
        that.find("fieldset").css({
            background:'#fee'
        });
        return false;
    }

});

(function($) {
    $.fn.evalSelector = function(opts) {
        var options = $.extend({}, $.fn.evalSelector.defaults, opts);
        init($(this), options);
    };
    /**
     * Public variables. Once init() has ran, do not reference directly to these, use variables.options instead.
     */
    $.fn.evalSelector.defaults = {
        css:{
            activeCheckbox: {background:'#eee'}
        },
        type: 1, //Type is for type of category we are handling. ie: 0 = instructor, 1 = assistant (TA)
        debug: true,
        fields: ['input', 'select', 'textarea'] //Array of fields in the form
    };
    /**
     * Private methods and variables
     */

    var variables = {
        typeOfSelector:{
            one: false,
            multiple: false
        },
        questionsToShow: new Array(),
        questionsToHide: new Array(),
        get:{
            typeOfBranch:function() {
                //log("Active code type is: " + variables.options.type);
                switch (variables.options.type) {
                    case 0: return "instructor";break;
                    case 1: return "assistant";break;
                }
            } ,
            shownQuestions: function() {
                //log("Getting questions for type: " + variables.get.typeOfBranch());
                var str = 'div.' + variables.get.typeOfBranch() + 'Branch:visible';
                var temp = new Array();
                $.each($(str).get(), function(i, item) {
                    temp.push($(item).attr("name"));
                    //log("Search found: " + $(item).attr("name"));
                });
                //log("Search found total: " + temp.length);
                return temp;
            },

            selectedBoxesArray:function(that) {
                var checked = new Array();
                that.find('input[@type=checkbox]').each(function() {
                    if (this.checked)checked.push(this);
                });
                //log("Found " + checked.length + " checked boxes");
                return checked;
            } ,
            selectedBoxesBool:function(that) {
                return variables.get.selectedBoxesArray(that).length > 0;
            }
        },
        set:{
            typeOfBranch:function(that) {
                var temp;
                if (that.attr('name').search(/instructor/i) != -1)
                    temp = 0;
                else if (that.attr('name').search(/assistant/i) != -1)
                    temp = 1;
                variables.options.type = temp;
                //log("Active type is: " + variables.get.typeOfBranch());

            }
        },
        options:null,
        savedIds:new Array(),
        that:null,
        foundArray: function() {
            var temp = new Array();
            $.each(variables.questionsToShow, function(s, shown) {
                //log("Checking if " + shown + " is already showing in dom. Dom has:" + variables.get.shownQuestions().length + " visible.");
                $.each(variables.get.shownQuestions(), function(h, hidden) {
                    if (shown == hidden) {
                        temp.push(shown);
                        //log("Found visible field: " + shown);
                    }
                });
            });
            return temp;
        },
        foundBool: function() {
            var temp = variables.foundArray();
            //log("Found " + temp.length + " with IDs: " + temp.toString());
            return (temp.length > 0);
        },
        foundSplice:function(item) {
            if (variables.foundBool()) {
                $.each(variables.questionsToShow, function(s, show) {
                    if (show == item) {
                        variables.questionsToShow.splice(parseInt(s), 1);
                        //log("Spliced: " + show + " from selected list.");
                        return true;
                    }
                });
            }
            return false;
        },
        isVisible:function(item) {
            var visible = false;
            if (variables.foundBool) {
                $.each(variables.get.shownQuestions(), function(i, found) {
                    if (item == found) {
                        visible = true;
                    }
                });
            }
            return visible;
        }
    };

    function renderSelections(type){
           $('div[@rel=eval' + type + 'Selector] input[type=checkbox]:checked').each(function() {
                var _id = $(this).val();
                $('div[name=' + _id + '].' + type + 'Branch').show();
                frameGrow($('div[name=' + _id + '].' + type + 'Branch').css('height'));
            });
             var index = 0;
            $('div[@rel=eval' + type + 'Selector]').find('select').each(function() {
                index = this.selectedIndex;
              });
            if (index != 0) {
                var _id = $('div[@rel=eval' + type + 'Selector]').find('select').find('option').eq(index);
                $('div[name=' + $(_id).val() + '].' + type + 'Branch').show();
                frameGrow($('div[name=' + _id + '].' + type + 'Branch').css('height'));
            }
    }
    function init(that, options) {
        //copy options to this class
        variables.options = options;
        var temp = $('input#selectedPeopleInResponse').val();
        variables.savedIds = temp==null?'':temp.replace('[','').replace(']','').split(', ');return that.each(function() {
            if ($(this).find('select').length > 0) {
                variables.typeOfSelector.one = true;
                //log("Found a selector for: " + variables.get.typeOfBranch());
            } else {
                variables.typeOfSelector.multiple = true;
                //log("Found a checkbox list for: " + variables.get.typeOfBranch());
            }
            initControls($(this));
            initClassVars();
        });
    }

    function initClassVars() {
        variables.questionsToHide = new Array();
        variables.questionsToShow = new Array();
        variables.savedIds=new Array();
        variables.that=null;
    }

    function initControls(that) {
         variables.that=that;
        if (variables.typeOfSelector.multiple) {
            //Working with checkboxes
            that.find('input[type=checkbox]').each(function() {
                var elem = $(this);
                                var elemId = elem.val();
                var elemLabel = elem.parent().find('label').text();
                //log("Attaching event listener for: " + elemLabel + " with id: " + elemId);
                elem.bind('click', function() {
                    variables.set.typeOfBranch($(this));
                    if (this.checked) {
                        //Fn for Check
                        elem.parent().css('background', variables.options.css.activeCheckbox.background);
                        //log("SELECTED: " + elemLabel + " with id: " + elemId);
                        if (!variables.isVisible(elemId)) {
                            variables.questionsToShow.push(elemId);
                            //log("ADDED: " + elemLabel + " with id: " + elemId);
                            showQuestions();
                            initClassVars();
                        } else {
                            //log("Person: " + elemLabel + " with id: " + elemId + " is already visible.");
                        }
                    }
                    else {
                        this.checked = true;
                        if (variables.isVisible(elemId) && confirmSelection(elemLabel)) {
                            elem.parent().css('background', '');
                            //log("DESELECTED: " + elemLabel + " with id: " + elemId);
                            variables.questionsToHide.push(elemId);
                            variables.foundSplice(elemId);
                            //log("DELETED: " + elemLabel + " with id: " + elemId);
                            showQuestions();
                            initClassVars();
                            this.checked = false;
                        }
                    }
                });
                checkSavedPeople(elemId, this,'','checkbox');
            });
        }
        var elem = that.find('select');
        $.each(elem.find('option'), function(i, item) {
            //checkValidity($(item).val(), item, i);
            checkSavedPeople($(item).val(), item, i, 'select');
        });
        elem.bind('change', function() {
            variables.set.typeOfBranch(elem);
            if (variables.typeOfSelector.one) {
                //Working with dropdown
                var elemId = elem.val();
                var render = false;
                //log("Selected guy with id: " + elemId);
                if (variables.get.shownQuestions().length == 0) {
                    render = true;
                }
                else if (variables.isVisible(elemId)) {
                    //log("Person with id: " + elemId + " is already visible.");
                    return false;
                } else
                {
                    var temp = 'div[name=' + variables.get.shownQuestions()[0] + '].'+variables.get.typeOfBranch()+'Branch';
                    render = confirmSelection($(temp).find('legend').attr('title'));
                }
                if (render) {
                    variables.questionsToHide = variables.get.shownQuestions();
                    variables.questionsToShow = new Array();
                    variables.questionsToShow.push(elemId);
                    //log("Added item " + elemId + " to array. Now Array has this number of elements: " + variables.questionsToShow.length);
                    showQuestions('noFrameExpand');
                    initClassVars();
                }else{
                    //Reset active person
                    var selectedindex =0;
                    $(this).find('option').each(function(i, item){
                        if($(item).val() == variables.get.shownQuestions()[0]){
                            selectedindex = i;
                        }
                    });

                    this.selectedIndex = parseInt(selectedindex);
                }
            }
        });
        //Handle reSelecting previous selections
        renderSelections('instructor');
        renderSelections('assistant');
    }

    function showQuestions(iframe) {
        hideQuestions(iframe);
        //log("Showing " + variables.questionsToShow.length + " items in dom.");
        $.each(variables.questionsToShow, function(i, item) {
            var tempFound = 0;
            $.each(variables.get.shownQuestions(), function(s, toSkip) {
                if (item == toSkip) {
                    tempFound++;
                }
            });
            if (tempFound == 0) {
                var str = 'div[name=' + item + '].'+variables.get.typeOfBranch()+'Branch';
                $(str).slideDown('normal', function() {
                    frameGrow($(str).css('height'));
                    //log("Revealing: " + item)
                });
            }
        });
    }

    function hideQuestions(all) {
        var temp = new Array();
        temp = (all && all == 1) ? variables.get.shownQuestions() : variables.questionsToHide;
        $.each(temp, function(i, item) {
            var str = 'div[name=' + item + '].'+variables.get.typeOfBranch()+'Branch';
            $(str).slideUp('normal', function() {
                frameShrink($(str).css('height'));
                //log("WARN: Hiding " + item + " in dom.");
                clearFieldsFor($(this));
            });
        });
    }

    function confirmSelection(name) {
        return confirm($('div#evalSelectWarn').text().replace(/XXX/, name));
    }

    function clearFieldsFor(item) {
        item.find('div.validFail').removeClass('validFail');
        $.each(variables.options.fields, function(f, field) {
            //log("Clearing all " + field.toLowerCase() + " fields.");
            item.find(field.toLowerCase()).each(function() {
                var t = this.type, tag = this.tagName.toLowerCase();
                if (t == 'text' || t == 'password' || tag == 'textarea')
                    this.value = '';
                else if (t == 'checkbox' || t == 'radio')
                    this.checked = false;
                else if (tag == 'select')
                        this.selectedIndex = -1;
            });
        });
    }

    function checkSavedPeople(elemId, that, num,tag) {
        var savedIds = variables.savedIds;
        if (savedIds.length > 0) {
            for (var i = 0; i < savedIds.length; i++) {
                if(elemId == savedIds[i]){
                if (tag == 'checkbox') {
                    that.checked = true;
                }
                    if (tag == 'select') {
                    variables.that.find('select:eq(0)').each(function(){
                        this.selectedIndex = (parseInt(num));
                        });
                    }
                }
            }
        }
    }

    function frameGrow(height){
		try {
			var frame = parent.document.getElementById(window.name);
			$(frame).height(parent.document.body.scrollHeight + parseInt(height.replace('px',''))+20);
		}catch(e){}
}

    function frameShrink(height){
	  		var frame = parent.document.getElementById(window.name);
			$(frame).height(parent.document.body.scrollHeight - parseInt(height.replace('px','')));
	}

    // Debugging
    function log($obj) {
        if (variables.options.debug) {
            if (window.console && window.console.log) {
                window.console.log('INFO: ' + $obj);
            }
        }
    }
})($);
<commit_msg>EVALSYS-661. undo unneeded iframe shrink function.Does not work and causes exceptions in IE7 and Safari.<commit_after>/**
 * For the takeEval and preview views
 */
$(document).ready(function() {

    var instrSel = $('div[@rel=evalinstructorSelector]');
    var assSel = $('div[@rel=evalassistantSelector]');
    instrSel.evalSelector({type:0});
    assSel.evalSelector({type:1});
    $('[id=form-branch::submitEvaluation]').bind('click', function() {
        if (instrSel.find('input[type=checkbox]').length != 0) {
            var selectedInstrDomArray = instrSel.find('input:checked').get();
            if (selectedInstrDomArray.length > 0) {
                instrSel.find("fieldset").css({
                    background:'#fff'
                });
                var selectedInstrArray = new Array();
                $.each(selectedInstrDomArray, function(i, item) {
                    selectedInstrArray.push($(item).val());
                });
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-instructor-multiple%3A%3Aselect-instructor-multiple-row" value="' + selectedInstrArray.toString() + '" />');
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-instructor-multiple%3A%3Aselect-instructor-multiple-row-fossil" value="istring#{takeEvalBean.selectioninstructorIds}" />');
            } else {
                return  error("LECTURER", instrSel);
            }
        }
        if (assSel.find('input[type=checkbox]').length != 0) {
            var selectedassistantDomArray = assSel.find('input:checked').get();
            if (selectedassistantDomArray.length > 0) {
                assSel.find("fieldset").css({
                    background:'#fff'
                });
                var selectedassistantArray = new Array();
                $.each(selectedassistantDomArray, function(i, item) {
                    selectedassistantArray.push($(item).val());
                });
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-assistant-multiple%3A%3Aselect-assistant-multiple-row" value="' + selectedassistantArray.toString() + '" />');
                $('form').append('<input type="hidden" name="form-branch%3A%3Aselect-assistant-multiple%3A%3Aselect-assistant-multiple-row-fossil" value="istring#{takeEvalBean.selectionassistantIds}" />');
            } else {
                return error("TUTOR", assSel);
            }
        }
        if (assSel.find('select').length != 0) {
            var valid = true;
            assSel.find('select').each(function() {
                if (this.selectedIndex == 0) {
                    valid = false;
                }
            });
            if (!valid) {
                return error("TUTOR", assSel);
            } else {
                assSel.find("fieldset").css({
                    background:'#fff'
                });
            }
        }
        if (instrSel.find('select').length != 0) {
            valid = true;
            instrSel.find('select').each(function() {
                if (this.selectedIndex == 0) {
                    valid = false;
                }
            });
            if (!valid) {
                return  error("LECTURER", instrSel);
            } else {
                instrSel.find("fieldset").css({
                    background:'#fff'
                });
            }
        }
        $(this).hide();
        $('input[name=submit_process]').show();
    });

    function error(type, that) {
        alert('Please evaluate at least one ' + type + '.');
        that.find("fieldset").css({
            background:'#fee'
        });
        return false;
    }

});

(function($) {
    $.fn.evalSelector = function(opts) {
        var options = $.extend({}, $.fn.evalSelector.defaults, opts);
        init($(this), options);
    };
    /**
     * Public variables. Once init() has ran, do not reference directly to these, use variables.options instead.
     */
    $.fn.evalSelector.defaults = {
        css:{
            activeCheckbox: {background:'#eee'}
        },
        type: 1, //Type is for type of category we are handling. ie: 0 = instructor, 1 = assistant (TA)
        debug: true,
        fields: ['input', 'select', 'textarea'] //Array of fields in the form
    };
    /**
     * Private methods and variables
     */

    var variables = {
        typeOfSelector:{
            one: false,
            multiple: false
        },
        questionsToShow: new Array(),
        questionsToHide: new Array(),
        get:{
            typeOfBranch:function() {
                //log("Active code type is: " + variables.options.type);
                switch (variables.options.type) {
                    case 0: return "instructor";break;
                    case 1: return "assistant";break;
                }
            } ,
            shownQuestions: function() {
                //log("Getting questions for type: " + variables.get.typeOfBranch());
                var str = 'div.' + variables.get.typeOfBranch() + 'Branch:visible';
                var temp = new Array();
                $.each($(str).get(), function(i, item) {
                    temp.push($(item).attr("name"));
                    //log("Search found: " + $(item).attr("name"));
                });
                //log("Search found total: " + temp.length);
                return temp;
            },

            selectedBoxesArray:function(that) {
                var checked = new Array();
                that.find('input[@type=checkbox]').each(function() {
                    if (this.checked)checked.push(this);
                });
                //log("Found " + checked.length + " checked boxes");
                return checked;
            } ,
            selectedBoxesBool:function(that) {
                return variables.get.selectedBoxesArray(that).length > 0;
            }
        },
        set:{
            typeOfBranch:function(that) {
                var temp;
                if (that.attr('name').search(/instructor/i) != -1)
                    temp = 0;
                else if (that.attr('name').search(/assistant/i) != -1)
                    temp = 1;
                variables.options.type = temp;
                //log("Active type is: " + variables.get.typeOfBranch());

            }
        },
        options:null,
        savedIds:new Array(),
        that:null,
        foundArray: function() {
            var temp = new Array();
            $.each(variables.questionsToShow, function(s, shown) {
                //log("Checking if " + shown + " is already showing in dom. Dom has:" + variables.get.shownQuestions().length + " visible.");
                $.each(variables.get.shownQuestions(), function(h, hidden) {
                    if (shown == hidden) {
                        temp.push(shown);
                        //log("Found visible field: " + shown);
                    }
                });
            });
            return temp;
        },
        foundBool: function() {
            var temp = variables.foundArray();
            //log("Found " + temp.length + " with IDs: " + temp.toString());
            return (temp.length > 0);
        },
        foundSplice:function(item) {
            if (variables.foundBool()) {
                $.each(variables.questionsToShow, function(s, show) {
                    if (show == item) {
                        variables.questionsToShow.splice(parseInt(s), 1);
                        //log("Spliced: " + show + " from selected list.");
                        return true;
                    }
                });
            }
            return false;
        },
        isVisible:function(item) {
            var visible = false;
            if (variables.foundBool) {
                $.each(variables.get.shownQuestions(), function(i, found) {
                    if (item == found) {
                        visible = true;
                    }
                });
            }
            return visible;
        }
    };

    function renderSelections(type){
           $('div[@rel=eval' + type + 'Selector] input[type=checkbox]:checked').each(function() {
                var _id = $(this).val();
                $('div[name=' + _id + '].' + type + 'Branch').show();
                frameGrow($('div[name=' + _id + '].' + type + 'Branch').css('height'));
            });
             var index = 0;
            $('div[@rel=eval' + type + 'Selector]').find('select').each(function() {
                index = this.selectedIndex;
              });
            if (index != 0) {
                var _id = $('div[@rel=eval' + type + 'Selector]').find('select').find('option').eq(index);
                $('div[name=' + $(_id).val() + '].' + type + 'Branch').show();
                frameGrow($('div[name=' + _id + '].' + type + 'Branch').css('height'));
            }
    }
    function init(that, options) {
        //copy options to this class
        variables.options = options;
        var temp = $('input#selectedPeopleInResponse').val();
        variables.savedIds = temp==null?'':temp.replace('[','').replace(']','').split(', ');return that.each(function() {
            if ($(this).find('select').length > 0) {
                variables.typeOfSelector.one = true;
                //log("Found a selector for: " + variables.get.typeOfBranch());
            } else {
                variables.typeOfSelector.multiple = true;
                //log("Found a checkbox list for: " + variables.get.typeOfBranch());
            }
            initControls($(this));
            initClassVars();
        });
    }

    function initClassVars() {
        variables.questionsToHide = new Array();
        variables.questionsToShow = new Array();
        variables.savedIds=new Array();
        variables.that=null;
    }

    function initControls(that) {
         variables.that=that;
        if (variables.typeOfSelector.multiple) {
            //Working with checkboxes
            that.find('input[type=checkbox]').each(function() {
                var elem = $(this);
                                var elemId = elem.val();
                var elemLabel = elem.parent().find('label').text();
                //log("Attaching event listener for: " + elemLabel + " with id: " + elemId);
                elem.bind('click', function() {
                    variables.set.typeOfBranch($(this));
                    if (this.checked) {
                        //Fn for Check
                        elem.parent().css('background', variables.options.css.activeCheckbox.background);
                        //log("SELECTED: " + elemLabel + " with id: " + elemId);
                        if (!variables.isVisible(elemId)) {
                            variables.questionsToShow.push(elemId);
                            //log("ADDED: " + elemLabel + " with id: " + elemId);
                            showQuestions();
                            initClassVars();
                        } else {
                            //log("Person: " + elemLabel + " with id: " + elemId + " is already visible.");
                        }
                    }
                    else {
                        this.checked = true;
                        if (variables.isVisible(elemId) && confirmSelection(elemLabel)) {
                            elem.parent().css('background', '');
                            //log("DESELECTED: " + elemLabel + " with id: " + elemId);
                            variables.questionsToHide.push(elemId);
                            variables.foundSplice(elemId);
                            //log("DELETED: " + elemLabel + " with id: " + elemId);
                            showQuestions();
                            initClassVars();
                            this.checked = false;
                      }
                    }
                });
                checkSavedPeople(elemId, this,'','checkbox');
            });
        }
        var elem = that.find('select');
        $.each(elem.find('option'), function(i, item) {
            //checkValidity($(item).val(), item, i);
            checkSavedPeople($(item).val(), item, i, 'select');
        });
        elem.bind('change', function() {
            variables.set.typeOfBranch(elem);
            if (variables.typeOfSelector.one) {
                //Working with dropdown
                var elemId = elem.val();
                var render = false;
                //log("Selected guy with id: " + elemId);
                if (variables.get.shownQuestions().length == 0) {
                    render = true;
                }
                else if (variables.isVisible(elemId)) {
                    //log("Person with id: " + elemId + " is already visible.");
                    return false;
                } else
                {
                    var temp = 'div[name=' + variables.get.shownQuestions()[0] + '].'+variables.get.typeOfBranch()+'Branch';
                    render = confirmSelection($(temp).find('legend').attr('title'));
                }
                if (render) {
                    variables.questionsToHide = variables.get.shownQuestions();
                    variables.questionsToShow = new Array();
                    variables.questionsToShow.push(elemId);
                    //log("Added item " + elemId + " to array. Now Array has this number of elements: " + variables.questionsToShow.length);
                    showQuestions();
                    initClassVars();
                }else{
                    //Reset active person
                    var selectedindex =0;
                    $(this).find('option').each(function(i, item){
                        if($(item).val() == variables.get.shownQuestions()[0]){
                            selectedindex = i;
                        }
                    });

                    this.selectedIndex = parseInt(selectedindex);
                }
            }
        });
        //Handle reSelecting previous selections
        renderSelections('instructor');
        renderSelections('assistant');
    }

    function showQuestions() {
        hideQuestions(0);
        //log("Showing " + variables.questionsToShow.length + " items in dom.");
        $.each(variables.questionsToShow, function(i, item) {
            var tempFound = 0;
            $.each(variables.get.shownQuestions(), function(s, toSkip) {
                if (item == toSkip) {
                    tempFound++;
                }
            });
            if (tempFound == 0) {
                var str = 'div[name=' + item + '].'+variables.get.typeOfBranch()+'Branch';
                $(str).slideDown('normal', function() {
                    frameGrow($(str).css('height'));
                    //log("Revealing: " + item)
                });
            }
        });
    }

    function hideQuestions(all) {
        var temp = new Array();
        temp = (all && all == 1) ? variables.get.shownQuestions() : variables.questionsToHide;
        $.each(temp, function(i, item) {
            var str = 'div[name=' + item + '].'+variables.get.typeOfBranch()+'Branch';
            $(str).slideUp('normal', function() {
                //log("WARN: Hiding " + item + " in dom.");
                clearFieldsFor($(this));
            });
        });
    }

    function confirmSelection(name) {
        return confirm($('div#evalSelectWarn').text().replace(/XXX/, name));
    }

    function clearFieldsFor(item) {
        item.find('div.validFail').removeClass('validFail');
        $.each(variables.options.fields, function(f, field) {
            //log("Clearing all " + field.toLowerCase() + " fields.");
            item.find(field.toLowerCase()).each(function() {
                var t = this.type, tag = this.tagName.toLowerCase();
                if (t == 'text' || t == 'password' || tag == 'textarea')
                    this.value = '';
                else if (t == 'checkbox' || t == 'radio')
                    this.checked = false;
                else if (tag == 'select')
                        this.selectedIndex = -1;
            });
        });
    }

    function checkSavedPeople(elemId, that, num,tag) {
        var savedIds = variables.savedIds;
        if (savedIds.length > 0) {
            for (var i = 0; i < savedIds.length; i++) {
                if(elemId == savedIds[i]){
                if (tag == 'checkbox') {
                    that.checked = true;
                }
                    if (tag == 'select') {
                    variables.that.find('select:eq(0)').each(function(){
                        this.selectedIndex = (parseInt(num));
                        });
                    }
                }
            }
        }
    }

    function frameGrow(height){
		try {
			var frame = parent.document.getElementById(window.name);
			$(frame).height(parent.document.body.scrollHeight + parseInt(height.replace('px',''))+20);
		}catch(e){}
}

    // Debugging
    function log($obj) {
        if (variables.options.debug) {
            if (window.console && window.console.log) {
                window.console.log('INFO: ' + $obj);
            }
        }
    }
})($);
<|endoftext|>


<commit_before>/*
 A new Migration is instantiated for each migration file.

 It is responsible for storing the name of the file and knowing how to execute
 the up and down migrations defined in the file.

 */

import fs from 'fs';
import mkdirp from 'mkdirp';
import path from 'path';

import MigrationBuilder from './migration-builder';
import { getMigrationTableSchema } from './utils';

const SEPARATOR = '_';

class Migration {
  // class method that creates a new migration file by cloning the migration template
  static create(name, directory, language) {
    // ensure the migrations directory exists
    mkdirp.sync(directory);

    // file name looks like migrations/1391877300255_migration-title.js
    const newFile = `${directory}/${Date.now()}${SEPARATOR}${name}.${language}`;

    // copy the default migration template to the new file location
    fs.createReadStream(path.resolve(__dirname, `./migration-template.${language}`))
      .pipe(fs.createWriteStream(newFile));

    return new Migration(newFile, directory);
  }

  constructor(db, migrationPath, { up, down } = {}, options = {}, log = console.log) {
    this.db = db;
    this.path = migrationPath;
    this.name = path.basename(migrationPath, path.extname(migrationPath));
    this.timestamp = Number(this.name.split(SEPARATOR)[0]) || 0;
    this.up = up;
    this.down = down;
    this.options = options;
    this.log = log;
  }

  _apply(action, pgm) {
    return new Promise((resolve, reject) => {
      if (action.length === 2) {
        action(pgm, resolve);
      } else {
        const result = action(pgm);
        // result conforms to Promises/A+ spec
        if (typeof result === 'object' && typeof result.then === 'function') {
          result.then(resolve).catch(reject);
        } else {
          resolve();
        }
      }
    }).then(() => {
      const sqlSteps = pgm.getSqlSteps();

      const schema = getMigrationTableSchema(this.options);
      switch (action) {
        case this.down:
          this.log(`### MIGRATION ${this.name} (DOWN) ###`);
          sqlSteps.push(`DELETE FROM "${schema}"."${this.options.migrations_table}" WHERE name='${this.name}';`);
          break;
        case this.up:
          this.log(`### MIGRATION ${this.name} (UP) ###`);
          sqlSteps.push(`INSERT INTO "${schema}"."${this.options.migrations_table}" (name, run_on) VALUES ('${this.name}', NOW());`);
          break;
        default:
          throw new Error('Unknown direction');
      }

      if (pgm.isUsingTransaction()) {
        // in single_transaction mode we are already wrapped in a
        // global transaction
        if (!this.options.single_transaction) {
          // otherwise we need to create our own transaction
          sqlSteps.unshift('BEGIN;');
          sqlSteps.push('COMMIT;');
        }
      } else {
        this.log('#> WARNING: This migration is not wrapped in a transaction! <');
      }

      this.log(`${sqlSteps.join('\n')}\n\n`);

      return sqlSteps.reduce(
        (promise, sql) => promise.then(() => this.options.dryRun || this.db.query(sql)),
        Promise.resolve()
      );
    });
  }

  applyUp() {
    const pgm = new MigrationBuilder(this.options);

    return this._apply(this.up, pgm);
  }

  applyDown() {
    const pgm = new MigrationBuilder(this.options);

    if (this.down === false) {
      return Promise.reject(new Error(`User has disabled down migration on file: ${this.name}`));
    } else if (this.down === undefined) {
      // automatically infer the down migration by running the up migration in reverse mode...
      pgm.enableReverseMode();
      this.down = this.up;
    }

    return this._apply(this.down, pgm);
  }
}

export default Migration;
<commit_msg>Transaction handling (#213)<commit_after>/*
 A new Migration is instantiated for each migration file.

 It is responsible for storing the name of the file and knowing how to execute
 the up and down migrations defined in the file.

 */

import fs from 'fs';
import mkdirp from 'mkdirp';
import path from 'path';

import MigrationBuilder from './migration-builder';
import { getMigrationTableSchema } from './utils';

const SEPARATOR = '_';

class Migration {
  // class method that creates a new migration file by cloning the migration template
  static create(name, directory, language) {
    // ensure the migrations directory exists
    mkdirp.sync(directory);

    // file name looks like migrations/1391877300255_migration-title.js
    const newFile = `${directory}/${Date.now()}${SEPARATOR}${name}.${language}`;

    // copy the default migration template to the new file location
    fs.createReadStream(path.resolve(__dirname, `./migration-template.${language}`))
      .pipe(fs.createWriteStream(newFile));

    return new Migration(newFile, directory);
  }

  constructor(db, migrationPath, { up, down } = {}, options = {}, log = console.log) {
    this.db = db;
    this.path = migrationPath;
    this.name = path.basename(migrationPath, path.extname(migrationPath));
    this.timestamp = Number(this.name.split(SEPARATOR)[0]) || 0;
    this.up = up;
    this.down = down;
    this.options = options;
    this.log = log;
  }

  _apply(action, pgm) {
    return new Promise((resolve, reject) => {
      if (action.length === 2) {
        action(pgm, resolve);
      } else {
        const result = action(pgm);
        // result conforms to Promises/A+ spec
        if (typeof result === 'object' && typeof result.then === 'function') {
          result.then(resolve).catch(reject);
        } else {
          resolve();
        }
      }
    }).then(() => {
      const sqlSteps = pgm.getSqlSteps();

      const schema = getMigrationTableSchema(this.options);
      switch (action) {
        case this.down:
          this.log(`### MIGRATION ${this.name} (DOWN) ###`);
          sqlSteps.push(`DELETE FROM "${schema}"."${this.options.migrations_table}" WHERE name='${this.name}';`);
          break;
        case this.up:
          this.log(`### MIGRATION ${this.name} (UP) ###`);
          sqlSteps.push(`INSERT INTO "${schema}"."${this.options.migrations_table}" (name, run_on) VALUES ('${this.name}', NOW());`);
          break;
        default:
          throw new Error('Unknown direction');
      }

      if (!this.options.single_transaction && pgm.isUsingTransaction()) {
        // if not in single_transaction mode we need to create our own transaction
        sqlSteps.unshift('BEGIN;');
        sqlSteps.push('COMMIT;');
      } else if (this.options.single_transaction && !pgm.isUsingTransaction()) {
        // in single_transaction mode we are already wrapped in a global transaction
        this.log('#> WARNING: Need to break single transaction! <');
        sqlSteps.unshift('COMMIT;');
        sqlSteps.push('BEGIN;');
      } else if (!this.options.single_transaction || !pgm.isUsingTransaction()) {
        this.log('#> WARNING: This migration is not wrapped in a transaction! <');
      }

      this.log(`${sqlSteps.join('\n')}\n\n`);

      return sqlSteps.reduce(
        (promise, sql) => promise.then(() => this.options.dryRun || this.db.query(sql)),
        Promise.resolve()
      );
    });
  }

  applyUp() {
    const pgm = new MigrationBuilder(this.options);

    return this._apply(this.up, pgm);
  }

  applyDown() {
    const pgm = new MigrationBuilder(this.options);

    if (this.down === false) {
      return Promise.reject(new Error(`User has disabled down migration on file: ${this.name}`));
    } else if (this.down === undefined) {
      // automatically infer the down migration by running the up migration in reverse mode...
      pgm.enableReverseMode();
      this.down = this.up;
    }

    return this._apply(this.down, pgm);
  }
}

export default Migration;
<|endoftext|>


<commit_before>TIMEOUT(300000);

/* conf */
ADDRESS_ROUTER = "aaaa::212:7401:1:101";
ADDRESS_SERVER = "aaaa::212:7402:2:202";
NR_PINGS = 10;
CMD_PING_PREFIX = "ping6 -c " + NR_PINGS + " -I tun0 ";
CMD_TUNNEL = "make connect-router-cooja";
CMD_WGET_ROUTER = "wget -t 1 -T 10 -O - http:\/\/[" + ADDRESS_ROUTER + "]";
CMD_WGET_SERVER = "wget -t 1 -T 10 -O - http:\/\/[" + ADDRESS_SERVER + "]";
COAP_SAMPLECLIENT_JAR = "/home/user/Californium/ExampleClient.jar";

/* delay */
msg = "";
GENERATE_MSG(5000, "continue");
WAIT_UNTIL(msg.equals("continue"));

/* override simulation delay to realtime */
sim.setDelayTime(java.lang.Integer.MIN_VALUE);

/* create tunnel interface */
log.log("create tunnel interface\n");
launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_TUNNEL]);
launcher.directory(new java.io.File("../../../examples/er-rest-example"));
launcher.redirectErrorStream(true);
tunProcess = launcher.start();
tunRunnable = new Object();
tunRunnable.run = function() {
  var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream()));
  while ((line = stdIn.readLine()) != null) {
    if (line != null && !line.trim().equals("")) {
      log.log("TUN> " + line + "\n");
    }
  }
  tunProcess.destroy();
}
new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start();

/* delay */
msg = "";
GENERATE_MSG(5000, "continue");
WAIT_UNTIL(msg.equals("continue"));

/* help function for executing commands */
processOutput = "";
executeAndWait = function(cmd) {
  log.log("EXEC>> " + cmd + "\n");

  launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',cmd]);
  launcher.redirectErrorStream(true);
  process = launcher.start();
  runnable = new Object();
  runnable.run = function() {
    var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
    while ((line = stdIn.readLine()) != null) {
      if (line != null && !line.trim().equals("")) {
        log.log("PROCESS> " + line + "\n");
        processOutput += line + "\n";
      }
    }
    process.destroy();
  }
  t = new java.lang.Thread(new java.lang.Runnable(runnable));
  t.start();

  while (t.isAlive()) {
    msg = "";
    GENERATE_MSG(1000, "continue");
    WAIT_UNTIL(msg.equals("continue"));
  }
}

/* PERFORM TESTS */
testSummary = "";
testFailed = false;

/* ping tests */
testname = "ping border router";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait(CMD_PING_PREFIX + ADDRESS_ROUTER);
if (processOutput.indexOf("64 bytes from") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

testname = "ping rest router";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait(CMD_PING_PREFIX + ADDRESS_SERVER);
if (processOutput.indexOf("64 bytes from") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

/* wget tests */
testname = "wget border router";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait(CMD_WGET_ROUTER);
if (processOutput.indexOf("<title>ContikiRPL</title>") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

/* coap tests: uses pre-downloaded dapaulid/JCoAP project's SampleClient.jar */
testname = "coap discovery";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait("java -jar " + COAP_SAMPLECLIENT_JAR + " DISCOVER coap:\/\/[" + ADDRESS_SERVER + "]");
if (processOutput.indexOf("+[.well-known/core]") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

testname = "coap get hello";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait("java -jar " + COAP_SAMPLECLIENT_JAR + " GET coap:\/\/[" + ADDRESS_SERVER + "]/hello");
if (processOutput.indexOf("Hello World!") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

log.log("\n\nTest finished. Summary:\n");
log.log(testSummary + "\n");

tunProcess.destroy();
if (testFailed) {
  log.testFailed();
} else {
  log.testOK();
}

<commit_msg>bugfix: use new setSpeedLimit(ratio) method in simulation instead of old setDelayTime()<commit_after>TIMEOUT(300000);

/* conf */
ADDRESS_ROUTER = "aaaa::212:7401:1:101";
ADDRESS_SERVER = "aaaa::212:7402:2:202";
NR_PINGS = 10;
CMD_PING_PREFIX = "ping6 -c " + NR_PINGS + " -I tun0 ";
CMD_TUNNEL = "make connect-router-cooja";
CMD_WGET_ROUTER = "wget -t 1 -T 10 -O - http:\/\/[" + ADDRESS_ROUTER + "]";
CMD_WGET_SERVER = "wget -t 1 -T 10 -O - http:\/\/[" + ADDRESS_SERVER + "]";
COAP_SAMPLECLIENT_JAR = "/home/user/Californium/ExampleClient.jar";

/* delay */
msg = "";
GENERATE_MSG(5000, "continue");
WAIT_UNTIL(msg.equals("continue"));

/* override simulation speed limit to realtime */
sim.setSpeedLimit(1.0);

/* create tunnel interface */
log.log("create tunnel interface\n");
launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_TUNNEL]);
launcher.directory(new java.io.File("../../../examples/er-rest-example"));
launcher.redirectErrorStream(true);
tunProcess = launcher.start();
tunRunnable = new Object();
tunRunnable.run = function() {
  var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream()));
  while ((line = stdIn.readLine()) != null) {
    if (line != null && !line.trim().equals("")) {
      log.log("TUN> " + line + "\n");
    }
  }
  tunProcess.destroy();
}
new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start();

/* delay */
msg = "";
GENERATE_MSG(5000, "continue");
WAIT_UNTIL(msg.equals("continue"));

/* help function for executing commands */
processOutput = "";
executeAndWait = function(cmd) {
  log.log("EXEC>> " + cmd + "\n");

  launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',cmd]);
  launcher.redirectErrorStream(true);
  process = launcher.start();
  runnable = new Object();
  runnable.run = function() {
    var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
    while ((line = stdIn.readLine()) != null) {
      if (line != null && !line.trim().equals("")) {
        log.log("PROCESS> " + line + "\n");
        processOutput += line + "\n";
      }
    }
    process.destroy();
  }
  t = new java.lang.Thread(new java.lang.Runnable(runnable));
  t.start();

  while (t.isAlive()) {
    msg = "";
    GENERATE_MSG(1000, "continue");
    WAIT_UNTIL(msg.equals("continue"));
  }
}

/* PERFORM TESTS */
testSummary = "";
testFailed = false;

/* ping tests */
testname = "ping border router";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait(CMD_PING_PREFIX + ADDRESS_ROUTER);
if (processOutput.indexOf("64 bytes from") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

testname = "ping rest router";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait(CMD_PING_PREFIX + ADDRESS_SERVER);
if (processOutput.indexOf("64 bytes from") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

/* wget tests */
testname = "wget border router";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait(CMD_WGET_ROUTER);
if (processOutput.indexOf("<title>ContikiRPL</title>") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

/* coap tests: uses pre-downloaded dapaulid/JCoAP project's SampleClient.jar */
testname = "coap discovery";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait("java -jar " + COAP_SAMPLECLIENT_JAR + " DISCOVER coap:\/\/[" + ADDRESS_SERVER + "]");
if (processOutput.indexOf("+[.well-known/core]") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

testname = "coap get hello";
log.log(testname + "\n");
testSummary += testname;
processOutput = "";
executeAndWait("java -jar " + COAP_SAMPLECLIENT_JAR + " GET coap:\/\/[" + ADDRESS_SERVER + "]/hello");
if (processOutput.indexOf("Hello World!") != -1) {
  testSummary += ": OK\n";
} else {
  testSummary += ": FAILED\n";
  testFailed = true;
}

log.log("\n\nTest finished. Summary:\n");
log.log(testSummary + "\n");

tunProcess.destroy();
if (testFailed) {
  log.testFailed();
} else {
  log.testOK();
}

<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var Socket = require('./socket')
  , Emitter = require('events').EventEmitter
  , debug = require('debug')('socket.io:namespace');

/**
 * Module exports.
 */

module.exports = exports = Namespace;

/**
 * Blacklisted events.
 */

exports.events = [
  'connect',    // for symmetry with client
  'connection'
];

/**
 * `Socket` flags.
 */

exports.flags = Socket.flags;

/**
 * `EventEmitter#emit` reference.
 */

var emit = Emitter.prototype.emit;

/**
 * Namespace constructor.
 *
 * @param {Server} server instance
 * @param {Socket} name
 * @api private
 */

function Namespace(server, name){
  this.server = server;
  this.name = name;
  this.sockets = [];
  this.fns = [];
  this.ids = 0;
  this.acks = {};
  this.flags = [];
  this.rooms = [];
}

/**
 * Inherits from `EventEmitter`.
 */

Namespace.prototype.__proto__ = Emitter.prototype;

/**
 * Apply flags from `Socket`.
 */

exports.flags.forEach(function(flag){
  Namespace.prototype.__defineGetter__(flag, function(name){
    this.flags.push(name);
    return this;
  });
});

/**
 * Sets up namespace middleware.
 *
 * @return {Namespace} self
 * @api public
 */

Namespace.prototype.use = function(fn){
  this.fns.push(fn);
  return this;
};

/**
 * Executes the middleware for an incoming client.
 *
 * @param {Socket} socket that will get added
 * @param {Function} last fn call in the middleware
 * @api private
 */

Namespace.prototype.run = function(socket, fn){
  var fns = this.fns.slice(0);
  if (!fns.length) return fn(null);

  function run(i){
    fns[i](socket, function(err){
      // upon error, short-circuit
      if (err) return fn(err);

      // if no middleware left, summon callback
      if (!fns[i + 1]) return fn(null);

      // go on to next
      run(i + 1);
    });
  }

  run(0);
};

/**
 * Targets a room.
 *
 * @api private
 */

Namespace.prototype.to =
Namespace.prototype.in = function(fn){
  this.rooms.push(fn);
  return this;
};

/**
 * Adds a new client.
 *
 * @return {Socket}
 * @api private
 */

Namespace.prototype.add = function(client, fn){
  var socket = new Socket(this, client);
  var self = this;
  this.run(function(err){
    if (err) return socket.err(err.data || err.message);
    self.sockets.push(socket);
    self.emit('connect', socket);
    self.emit('connection', socket);
    socket.onconnect();
  });
  return socket;
};

/**
 * Removes a client. Called by each `Socket`.
 *
 * @api private
 */

Namespace.prototype.remove = function(socket){
  var i = this.sockets.indexOf(socket);
  if (~i) {
    this.sockets.splice(i, 1);
  } else {
    debug('ignoring remove for %s', socket.id);
  }
};

/**
 * Emits to all clients.
 *
 * @return {Namespace} self
 * @api public
 */

Namespace.prototype.emit = function(ev){
  if (~exports.events.indexOf(ev)) {
    emit.apply(this, arguments);
  } else {
    for (var i = 0; i < this.sockets.length; i++) {
      var socket = this.sockets[i];
      this.rooms.forEach(function(room){
        socket.to(room);
      });
      this.flags.forEach(function(flag){
        socket = socket[flag];
      });
      socket.emit.apply(socket, arguments);
    }
    if (this.flags.length) this.flags = [];
    if (this.rooms.lenth) this.rooms = [];
  }
  return this;
};

/**
 * Sends a `message` event to all clients.
 *
 * @return {Namespace} self
 * @api public
 */

Namespace.prototype.send =
Namespace.prototype.write = function(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift('message');
  this.emit.apply(this, args);
  return this;
};
<commit_msg>namespace: fix `run` call<commit_after>
/**
 * Module dependencies.
 */

var Socket = require('./socket')
  , Emitter = require('events').EventEmitter
  , debug = require('debug')('socket.io:namespace');

/**
 * Module exports.
 */

module.exports = exports = Namespace;

/**
 * Blacklisted events.
 */

exports.events = [
  'connect',    // for symmetry with client
  'connection'
];

/**
 * `Socket` flags.
 */

exports.flags = Socket.flags;

/**
 * `EventEmitter#emit` reference.
 */

var emit = Emitter.prototype.emit;

/**
 * Namespace constructor.
 *
 * @param {Server} server instance
 * @param {Socket} name
 * @api private
 */

function Namespace(server, name){
  this.server = server;
  this.name = name;
  this.sockets = [];
  this.fns = [];
  this.ids = 0;
  this.acks = {};
  this.flags = [];
  this.rooms = [];
}

/**
 * Inherits from `EventEmitter`.
 */

Namespace.prototype.__proto__ = Emitter.prototype;

/**
 * Apply flags from `Socket`.
 */

exports.flags.forEach(function(flag){
  Namespace.prototype.__defineGetter__(flag, function(name){
    this.flags.push(name);
    return this;
  });
});

/**
 * Sets up namespace middleware.
 *
 * @return {Namespace} self
 * @api public
 */

Namespace.prototype.use = function(fn){
  this.fns.push(fn);
  return this;
};

/**
 * Executes the middleware for an incoming client.
 *
 * @param {Socket} socket that will get added
 * @param {Function} last fn call in the middleware
 * @api private
 */

Namespace.prototype.run = function(socket, fn){
  var fns = this.fns.slice(0);
  if (!fns.length) return fn(null);

  function run(i){
    fns[i](socket, function(err){
      // upon error, short-circuit
      if (err) return fn(err);

      // if no middleware left, summon callback
      if (!fns[i + 1]) return fn(null);

      // go on to next
      run(i + 1);
    });
  }

  run(0);
};

/**
 * Targets a room.
 *
 * @api private
 */

Namespace.prototype.to =
Namespace.prototype.in = function(fn){
  this.rooms.push(fn);
  return this;
};

/**
 * Adds a new client.
 *
 * @return {Socket}
 * @api private
 */

Namespace.prototype.add = function(client, fn){
  var socket = new Socket(this, client);
  var self = this;
  this.run(socket, function(err){
    if (err) return socket.err(err.data || err.message);
    self.sockets.push(socket);
    self.emit('connect', socket);
    self.emit('connection', socket);
    socket.onconnect();
  });
  return socket;
};

/**
 * Removes a client. Called by each `Socket`.
 *
 * @api private
 */

Namespace.prototype.remove = function(socket){
  var i = this.sockets.indexOf(socket);
  if (~i) {
    this.sockets.splice(i, 1);
  } else {
    debug('ignoring remove for %s', socket.id);
  }
};

/**
 * Emits to all clients.
 *
 * @return {Namespace} self
 * @api public
 */

Namespace.prototype.emit = function(ev){
  if (~exports.events.indexOf(ev)) {
    emit.apply(this, arguments);
  } else {
    for (var i = 0; i < this.sockets.length; i++) {
      var socket = this.sockets[i];
      this.rooms.forEach(function(room){
        socket.to(room);
      });
      this.flags.forEach(function(flag){
        socket = socket[flag];
      });
      socket.emit.apply(socket, arguments);
    }
    if (this.flags.length) this.flags = [];
    if (this.rooms.lenth) this.rooms = [];
  }
  return this;
};

/**
 * Sends a `message` event to all clients.
 *
 * @return {Namespace} self
 * @api public
 */

Namespace.prototype.send =
Namespace.prototype.write = function(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift('message');
  this.emit.apply(this, args);
  return this;
};
<|endoftext|>


<commit_before>'use strict';

var debug   = require('debug')('kiss.io:namespace');
var util    = require('util');
var parser  = require('socket.io-parser');

var Socket  = require('./socket');
var Plugin  = require('./plugin');
var Router  = require('./router');

/**
 * A namespace is an individual, independent, autonomous arena
 * ..for real-time data transfer.
 *
 * It can be initialized in its own self-contained module,
 * ..and later be mounted into a kiss.io server, OR be initialized
 * ..within the server itself.
 *
 * @constructs Namespace
 * @access public
 *
 * @param {String} name (must start with '/')
 * @param {Object} [opts]
 * @returns {Namespace} self
 */
function Namespace(name, opts)
{
  if(!(this instanceof Namespace))
  {
    return new Namespace(name, opts);
  }

  this.name = Namespace.slugify(name);
  this.opts = opts || {};
  this.router = new Router(this.opts);
  this.sockets = {};
  this.middlewares = [];
  this.plugins = [];
  this.locals = {};
}

/**
 * Static function that used as helper to generate a slug for the nsp.
 * Currently just appends '/' to the beginning of the name.
 *
 * @access public
 *
 * @param name
 * @returns {String} id
 */
Namespace.slugify = function(name)
{
  if(String(name)[0] !== '/')
  {
    name = '/' + name;
  }

  return name;
};

/***
 * Plugs a plug-in to the namespace.
 *
 * @alias {Namespace.plugin}
 * @access public
 *
 * @param {Function|Plugin} plugin
 * @param {Object} [opts]: special options for the plugin
 * @returns {Namespace} self
 */
Namespace.prototype.plug =
Namespace.prototype.plugin = function(plugin, opts)
{
  if(typeof plugin == 'function')
  {
    plugin = new plugin(this, opts);
  }

  if(plugin instanceof Plugin)
  {
    this.plugins.push(plugin.attachTo(this));
  }

  return this;
};

/**
 * A helper method used to configure the namespace before
 * ..mounting it on the server.
 *
 * Works synchronously, and bind the namespace to the function.
 *
 * @access public
 *
 * @param {Function} fn
 * @returns {Namespace} self
 */
Namespace.prototype.configure = function(fn)
{
  if(typeof fn == 'function')
  {
    fn.apply(this);
  }

  return this;
};

/**
 * Set/get a temporary flag.
 *
 * @access public
 *
 * @param {String} key: the name of the flag.
 * @param {*} [value]
 * @returns {*|undefined} value
 */
Namespace.prototype.flag = function(key, value)
{
  this._flags = this._flags || {};

  if(arguments.length == 2)
  {
    this._flags[key] = value;
  }

  return this._flags[key];
};

/**
 * Reset temporary flags
 *
 * @access public
 *
 * @returns {Namespace} self
 */
Namespace.prototype.reset = function()
{
  delete this._flags;
};

/**
 * Set/get a local parameter for the namespace.
 *
 * @access public
 *
 * @param {String} key
 * @param {*} value
 * @returns {*} value
 */
Namespace.prototype.local = function(key, value)
{
  if(arguments.length == 2)
  {
    this.locals[key] = value;
  }

  return this.locals[key];
};

/**
 * Mounts a middleware/plugin/route/router on the namespace.
 *
 * @access public
 *
 * @param {Function|String|Router|Route} item
 * @return {Namespace} self
 */
Namespace.prototype.use = function(item)
{
  if(typeof item == 'function')
  {
    this.middlewares.push(item);
  }
  else if(item instanceof Plugin)
  {
    this.plug(item);
  }
  else if(typeof item == 'string')
  {
    this.reg.apply(this, arguments);
  }
  else if(item instanceof Router)
  {
    this.router.use(item);
  }
  else if(item instanceof Router.Route)
  {
    this.router.use(item);
  }

  return this;
};

/**
 * Registers a route for the the namespace.
 * @see Router.on
 *
 * @alias {Namespace.event}
 * @access public
 *
 * @param {String|Router|Route} event: the name of the event to register
 * @param {Function} [handler]: (if string event provided) the handler for the event
 * @returns {Namespace} self
 */
Namespace.prototype.on =
Namespace.prototype.event = function(event, handler)
{
  return this.router.on.apply(this.router, arguments);
};

/**
 * Executes the middleware for an incoming client.
 *
 * @access private
 *
 * @param {Socket} socket to execute the middleware on
 * @param {Function} fn: last fn call in the middleware
 */
Namespace.prototype.execMiddleware = function(socket, fn)
{
  var fns = this.middlewares.slice(0);

  if (!fns.length)
  {
    return fn(null);
  }

  function exec(i)
  {
    fns[i](socket, function(err)
    {
      // upon error, short-circuit
      if (err) return fn(err);

      // if no middleware left, summon callback
      if (!fns[i + 1]) return fn(null);

      // go on to next
      exec(i + 1);
    });
  }

  exec(0);
};

/**
 * Adds a new client to the namespace.
 *
 * @access public
 *
 * @param {Socket} socket
 * @param {Function} [fn]: an optional fn to execute before
 * ..connecting the socket to the namespace.
 * @return {Socket} the socket that was added to the namespace.
 */
Namespace.prototype.add = function(socket, fn)
{
  var self = this;

  socket.merge(this.router);

  this.plugins.forEach(function(plugin)
  {
    plugin.attachTo(socket);
  });

  this.execMiddleware(socket, function(err)
  {
    process.nextTick(function()
    {
      if ('open' !== socket.conn.readyState)
      {
        debug('next called after client was closed - ignoring socket');
        return;
      }
      else if (err)
      {
        return socket.error(err.data || err.message);
      }

      self.sockets[socket.id] = socket;

      if(typeof fn == 'function')
      {
        fn(err, socket);
      }

      // fire user-set events
      socket.trigger('connect', socket);
      socket.trigger('connection', socket);
    });
  });

  return socket;
};

/**
 * Removes a socket from the namespace.
 * Called by each `Socket`.
 *
 * @access private
 */
Namespace.prototype.remove = function(socket)
{
  delete this.sockets[socket.id];
};

/**
 * Sets the `except` flag to ignore sockets when broadcasting.
 *
 * @access public
 *
 * @param {Array<String>} sids: the ids of the of sockets to ignore.
 * @returns {Namespace} self
 */
Namespace.prototype.except = function(sids)
{
  if(!Array.isArray(sids))
  {
    sids = [sids];
  }

  this.flag('except', sids);
  return this;
};

/**
 * Broadcasts an event to every socket connected to the namespace,
 * ..and ignores those who are specified in the `except` flag.
 *
 * @access public
 *
 * @param {String} ev: the event to broadcast.
 * @params {...} the params to emit together with the event.
 * @returns {Namespace} self
 */
Namespace.prototype.broadcast = function(ev)
{
  var except = this.flag('except') || [];

  for(var sid of Object.keys(this.sockets))
  {
    if(except.indexOf(sid) !== -1)
    {
      continue;
    }

    var s = this.socket(sid);

    if(s instanceof Socket)
    {
      s.emit.apply(s, arguments);
    }
  }

  this.reset();
  return this;
};

/**
 * Sends a `message` event to all clients.
 *
 * @access private
 *
 * @return {Namespace} self
 */
Namespace.prototype.send =
Namespace.prototype.write = function()
{
  this.broadcast('message', ...args);
  return this;
};

/**
 * Returns a socket that's connected to the namespace,
 * ..correspondent a given id.
 *
 * @access public
 *
 * @param {String} id
 * @returns {Socket}
 */
Namespace.prototype.socket = function(id)
{
  return this.sockets[id];
};

/**
 * Sets the compress flag.
 *
 * @access public
 *
 * @param {Boolean} compress: if `true`, compresses the sending data
 * @return {Namespace} self
 */
Namespace.prototype.compress = function(compress)
{
  this.flag('compress', compress);
  return this;
};

/*!
 * Module exports.
 */
module.exports = Namespace;
<commit_msg>Fixed Namespace.use using the wrong method to register string routes<commit_after>'use strict';

var debug   = require('debug')('kiss.io:namespace');
var util    = require('util');
var parser  = require('socket.io-parser');

var Socket  = require('./socket');
var Plugin  = require('./plugin');
var Router  = require('./router');

/**
 * A namespace is an individual, independent, autonomous arena
 * ..for real-time data transfer.
 *
 * It can be initialized in its own self-contained module,
 * ..and later be mounted into a kiss.io server, OR be initialized
 * ..within the server itself.
 *
 * @constructs Namespace
 * @access public
 *
 * @param {String} name (must start with '/')
 * @param {Object} [opts]
 * @returns {Namespace} self
 */
function Namespace(name, opts)
{
  if(!(this instanceof Namespace))
  {
    return new Namespace(name, opts);
  }

  this.name = Namespace.slugify(name);
  this.opts = opts || {};
  this.router = new Router(this.opts);
  this.sockets = {};
  this.middlewares = [];
  this.plugins = [];
  this.locals = {};
}

/**
 * Static function that used as helper to generate a slug for the nsp.
 * Currently just appends '/' to the beginning of the name.
 *
 * @access public
 *
 * @param name
 * @returns {String} id
 */
Namespace.slugify = function(name)
{
  if(String(name)[0] !== '/')
  {
    name = '/' + name;
  }

  return name;
};

/***
 * Plugs a plug-in to the namespace.
 *
 * @alias {Namespace.plugin}
 * @access public
 *
 * @param {Function|Plugin} plugin
 * @param {Object} [opts]: special options for the plugin
 * @returns {Namespace} self
 */
Namespace.prototype.plug =
Namespace.prototype.plugin = function(plugin, opts)
{
  if(typeof plugin == 'function')
  {
    plugin = new plugin(this, opts);
  }

  if(plugin instanceof Plugin)
  {
    this.plugins.push(plugin.attachTo(this));
  }

  return this;
};

/**
 * A helper method used to configure the namespace before
 * ..mounting it on the server.
 *
 * Works synchronously, and bind the namespace to the function.
 *
 * @access public
 *
 * @param {Function} fn
 * @returns {Namespace} self
 */
Namespace.prototype.configure = function(fn)
{
  if(typeof fn == 'function')
  {
    fn.apply(this);
  }

  return this;
};

/**
 * Set/get a temporary flag.
 *
 * @access public
 *
 * @param {String} key: the name of the flag.
 * @param {*} [value]
 * @returns {*|undefined} value
 */
Namespace.prototype.flag = function(key, value)
{
  this._flags = this._flags || {};

  if(arguments.length == 2)
  {
    this._flags[key] = value;
  }

  return this._flags[key];
};

/**
 * Reset temporary flags
 *
 * @access public
 *
 * @returns {Namespace} self
 */
Namespace.prototype.reset = function()
{
  delete this._flags;
};

/**
 * Set/get a local parameter for the namespace.
 *
 * @access public
 *
 * @param {String} key
 * @param {*} value
 * @returns {*} value
 */
Namespace.prototype.local = function(key, value)
{
  if(arguments.length == 2)
  {
    this.locals[key] = value;
  }

  return this.locals[key];
};

/**
 * Mounts a middleware/plugin/route/router on the namespace.
 *
 * @access public
 *
 * @param {Function|String|Router|Route} item
 * @return {Namespace} self
 */
Namespace.prototype.use = function(item)
{
  if(typeof item == 'function')
  {
    this.middlewares.push(item);
  }
  else if(item instanceof Plugin)
  {
    this.plug(item);
  }
  else if(typeof item == 'string')
  {
    this.event.apply(this, arguments);
  }
  else if(item instanceof Router)
  {
    this.router.use(item);
  }
  else if(item instanceof Router.Route)
  {
    this.router.use(item);
  }

  return this;
};

/**
 * Registers a route for the the namespace.
 * @see Router.on
 *
 * @alias {Namespace.event}
 * @access public
 *
 * @param {String|Router|Route} event: the name of the event to register
 * @param {Function} [handler]: (if string event provided) the handler for the event
 * @returns {Namespace} self
 */
Namespace.prototype.on =
Namespace.prototype.event = function(event, handler)
{
  return this.router.on.apply(this.router, arguments);
};

/**
 * Executes the middleware for an incoming client.
 *
 * @access private
 *
 * @param {Socket} socket to execute the middleware on
 * @param {Function} fn: last fn call in the middleware
 */
Namespace.prototype.execMiddleware = function(socket, fn)
{
  var fns = this.middlewares.slice(0);

  if (!fns.length)
  {
    return fn(null);
  }

  function exec(i)
  {
    fns[i](socket, function(err)
    {
      // upon error, short-circuit
      if (err) return fn(err);

      // if no middleware left, summon callback
      if (!fns[i + 1]) return fn(null);

      // go on to next
      exec(i + 1);
    });
  }

  exec(0);
};

/**
 * Adds a new client to the namespace.
 *
 * @access public
 *
 * @param {Socket} socket
 * @param {Function} [fn]: an optional fn to execute before
 * ..connecting the socket to the namespace.
 * @return {Socket} the socket that was added to the namespace.
 */
Namespace.prototype.add = function(socket, fn)
{
  var self = this;

  socket.merge(this.router);

  this.plugins.forEach(function(plugin)
  {
    plugin.attachTo(socket);
  });

  this.execMiddleware(socket, function(err)
  {
    process.nextTick(function()
    {
      if ('open' !== socket.conn.readyState)
      {
        debug('next called after client was closed - ignoring socket');
        return;
      }
      else if (err)
      {
        return socket.error(err.data || err.message);
      }

      self.sockets[socket.id] = socket;

      if(typeof fn == 'function')
      {
        fn(err, socket);
      }

      // fire user-set events
      socket.trigger('connect', socket);
      socket.trigger('connection', socket);
    });
  });

  return socket;
};

/**
 * Removes a socket from the namespace.
 * Called by each `Socket`.
 *
 * @access private
 */
Namespace.prototype.remove = function(socket)
{
  delete this.sockets[socket.id];
};

/**
 * Sets the `except` flag to ignore sockets when broadcasting.
 *
 * @access public
 *
 * @param {Array<String>} sids: the ids of the of sockets to ignore.
 * @returns {Namespace} self
 */
Namespace.prototype.except = function(sids)
{
  if(!Array.isArray(sids))
  {
    sids = [sids];
  }

  this.flag('except', sids);
  return this;
};

/**
 * Broadcasts an event to every socket connected to the namespace,
 * ..and ignores those who are specified in the `except` flag.
 *
 * @access public
 *
 * @param {String} ev: the event to broadcast.
 * @params {...} the params to emit together with the event.
 * @returns {Namespace} self
 */
Namespace.prototype.broadcast = function(ev)
{
  var except = this.flag('except') || [];

  for(var sid of Object.keys(this.sockets))
  {
    if(except.indexOf(sid) !== -1)
    {
      continue;
    }

    var s = this.socket(sid);

    if(s instanceof Socket)
    {
      s.emit.apply(s, arguments);
    }
  }

  this.reset();
  return this;
};

/**
 * Sends a `message` event to all clients.
 *
 * @access private
 *
 * @return {Namespace} self
 */
Namespace.prototype.send =
Namespace.prototype.write = function()
{
  this.broadcast('message', ...args);
  return this;
};

/**
 * Returns a socket that's connected to the namespace,
 * ..correspondent a given id.
 *
 * @access public
 *
 * @param {String} id
 * @returns {Socket}
 */
Namespace.prototype.socket = function(id)
{
  return this.sockets[id];
};

/**
 * Sets the compress flag.
 *
 * @access public
 *
 * @param {Boolean} compress: if `true`, compresses the sending data
 * @return {Namespace} self
 */
Namespace.prototype.compress = function(compress)
{
  this.flag('compress', compress);
  return this;
};

/*!
 * Module exports.
 */
module.exports = Namespace;
<|endoftext|>