<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

const EventEmitter = require('events').EventEmitter;
const _ = require('lodash');
const debug = require('debug')('runner');
const debugPerf = require('debug')('perf');
const uuid = require('node-uuid');
const Stats = require('./stats2');
const JSCK = require('jsck');
const createPhaser = require('./phases');
const createReader = require('./readers');
const engineUtil = require('./engine_util');
const wl = require('./weighted-pick');

const Engines = {
  http: {},
  ws: {},
  socketio: {}
};

JSCK.Draft4 = JSCK.draft4;

const schema = new JSCK.Draft4(require('./schemas/artillery_test_script.json'));

module.exports = {
  runner: runner,
  validate: validate
};

function validate(script) {
  let validation = schema.validate(script);
  return validation;
}

function runner(script, payload, options) {
  let opts = _.assign({
    periodicStats: script.config.statsInterval || 10,
    mode: script.config.mode || 'uniform'
  },
  options);

  _.each(script.config.phases, function(phaseSpec) {
    phaseSpec.mode = phaseSpec.mode || script.config.mode;
  });

  if (payload) {
    if (_.isArray(payload[0])) {
      script.config.payload = [
        {
          fields: script.config.payload.fields,
          reader: createReader(script.config.payload.order),
          data: payload
        }
      ];
    } else {
      script.config.payload = payload;
      _.each(script.config.payload, function(el) {
        el.reader = createReader(el.order);
      });
    }
  } else {
    script.config.payload = null;
  }

  let runnableScript = _.cloneDeep(script);

  if (opts.environment) {
    debug('environment specified: %s', opts.environment);
    _.merge(
      runnableScript.config,
      script.config.environments[opts.environment]);
  }

  _.each(runnableScript.scenarios, function(scenarioSpec) {
    // if beforeRequest / afterResponse on scenario is set, make sure it's an array
    if (scenarioSpec.beforeRequest && !_.isArray(scenarioSpec.beforeRequest)) {
      scenarioSpec.beforeRequest = [scenarioSpec.beforeRequest];
    } else {
      scenarioSpec.beforeRequest = [];
    }

    if (scenarioSpec.afterResponse && !_.isArray(scenarioSpec.afterResponse)) {
      scenarioSpec.afterResponse = [scenarioSpec.afterResponse];
    } else {
      scenarioSpec.afterResponse = [];
    }
  });

  let ee = new EventEmitter();

  //
  // load engines:
  //
  let runnerEngines = _.map(
      Object.assign({}, Engines, runnableScript.config.engines),
      function loadEngine(engineConfig, engineName) {
        let moduleName = 'artillery-engine-' + engineName;
        try {
          if (Engines[engineName]) {
            moduleName = './engine_' + engineName;
          }
          let Engine = require(moduleName);
          let engine = new Engine(runnableScript, ee);
          engine.__name = engineName;
          return engine;
        } catch (e) {
          console.log(e);
          console.log(
              'WARNING: engine %s specified but module %s could not be loaded',
              engineName,
              moduleName);
        }
      }
  );

  //
  // load plugins:
  //
  let runnerPlugins = _.map(
      runnableScript.config.plugins,
      function loadPlugin(pluginConfig, pluginName) {
        let moduleName = 'artillery-plugin-' + pluginName;
        try {
          let Plugin = require(moduleName);
          let plugin = new Plugin(runnableScript.config, ee);
          plugin.__name = pluginName;
          return plugin;
        } catch (e) {
          console.log(
              'WARNING: plugin %s specified but module %s could not be loaded',
              pluginName,
              moduleName);
        }
      }
  );

  ee.run = function() {
    let runState = {
      pendingScenarios: 0,
      pendingRequests: 0,
      compiledScenarios: null,
      scenarioEvents: null,
      picker: undefined,
      Report: {
        intermediate: [],
        aggregate: {}
      },
      plugins: runnerPlugins,
      engines: runnerEngines
    };
    debug('run() with: %j', runnableScript);
    run(runnableScript, ee, opts, runState);
  };
  return ee;
}

function run(script, ee, options, runState) {
  let intermediate = Stats.create();
  let aggregate = Stats.create();

  let phaser = createPhaser(script.config.phases);
  phaser.on('arrival', function() {
    runScenario(script, intermediate, aggregate, runState);
  });
  phaser.on('phaseStarted', function(spec) {
    ee.emit('phaseStarted', spec);
  });
  phaser.on('phaseCompleted', function(spec) {
    ee.emit('phaseCompleted', spec);
  });
  phaser.on('done', function() {
    debug('All phases launched');

    const doneYet = setInterval(function checkIfDone() {
      if (runState.pendingScenarios === 0) {
        if (runState.pendingRequests !== 0) {
          debug('DONE. Pending requests: %s', runState.pendingRequests);
        }

        clearInterval(doneYet);
        clearInterval(periodicStatsTimer);

        runState.Report.aggregate = aggregate.report();
        sendStats();

        intermediate.free();
        aggregate.free();

        //
        // Add plugin reports to the final report
        //
        _.each(runState.plugins, function(plugin) {
          if (typeof plugin.report === 'function') {
            let report = plugin.report();
            if (report) {
              if (report.length) {
                _.each(report, function insertIntermediateReport(a) {
                  if (a.timestamp === 'aggregate') {
                    runState.Report.aggregate[plugin.__name] = a.value;
                  } else {
                    let ir = _.findWhere(
                      runState.Report.intermediate,
                      {timestamp: a.timestamp});
                    ir[plugin.__name] = a.value;
                  }
                });
              } else {
                runState.Report.aggregate[plugin.__name] = report;
              }
            }
          }
        });

        return ee.emit('done', runState.Report);
      } else {
        debug('Pending requests: %s', runState.pendingRequests);
        debug('Pending scenarios: %s', runState.pendingScenarios);
      }
    }, 500);
  });

  const periodicStatsTimer = setInterval(sendStats, options.periodicStats * 1000);

  function sendStats() {
    const report = intermediate.report();
    report.concurrency = runState.pendingScenarios;
    report.pendingRequests = runState.pendingRequests;
    runState.Report.intermediate.push(report);
    intermediate.reset();
    ee.emit('stats', report);
  }

  phaser.run();
}

function runScenario(script, intermediate, aggregate, runState) {
  const start = process.hrtime();

  //
  // Compile scenarios if needed
  //
  if (!runState.compiledScenarios) {
    _.each(script.scenarios, function(scenario) {
      if (!scenario.weight) {
        scenario.weight = 1;
      }
    });

    runState.picker = wl(script.scenarios);

    runState.scenarioEvents = new EventEmitter();
    runState.scenarioEvents.on('customStat', function(stat) {
      intermediate.addCustomStat(stat.stat, stat.value);
      aggregate.addCustomStat(stat.stat, stat.value);
    });
    runState.scenarioEvents.on('started', function() {
      runState.pendingScenarios++;
    });
    runState.scenarioEvents.on('error', function(errCode) {
      intermediate.addError(errCode);
      aggregate.addError(errCode);
    });
    runState.scenarioEvents.on('request', function() {
      intermediate.newRequest();
      aggregate.newRequest();

      runState.pendingRequests++;
    });
    runState.scenarioEvents.on('match', function() {
      intermediate.addMatch();
      aggregate.addMatch();
    });
    runState.scenarioEvents.on('response', function(delta, code, uid) {
      intermediate.completedRequest();
      intermediate.addLatency(delta);
      intermediate.addCode(code);

      let entry = [Date.now(), uid, delta, code];
      intermediate.addEntry(entry);
      aggregate.addEntry(entry);

      aggregate.completedRequest();
      aggregate.addLatency(delta);
      aggregate.addCode(code);

      runState.pendingRequests--;
    });

    runState.compiledScenarios = _.map(
        script.scenarios,
        function(scenarioSpec) {
          const name = scenarioSpec.engine || 'http';
          const engine = runState.engines.find((e) => e.__name === name);
          return engine.createScenario(scenarioSpec, runState.scenarioEvents);
        }
    );
  }

  intermediate.newScenario();
  aggregate.newScenario();

  let i = runState.picker()[0];

  debug('picking scenario %s (%s) weight = %s',
        i,
        script.scenarios[i].name,
        script.scenarios[i].weight);

  const scenarioStartedAt = process.hrtime();
  const scenarioContext = createContext(script);
  const finish = process.hrtime(start);
  const runScenarioDelta = (finish[0] * 1e9) + finish[1];
  debugPerf('runScenarioDelta: %s', Math.round(runScenarioDelta / 1e6 * 100) / 100);
  runState.compiledScenarios[i](scenarioContext, function(err, context) {
    runState.pendingScenarios--;
    if (err) {
      debug(err);
    } else {
      const scenarioFinishedAt = process.hrtime(scenarioStartedAt);
      const delta = (scenarioFinishedAt[0] * 1e9) + scenarioFinishedAt[1];
      intermediate.addScenarioLatency(delta);
      aggregate.addScenarioLatency(delta);
      intermediate.completedScenario();
      aggregate.completedScenario();
    }
  });
}

/**
 * Create initial context for a scenario.
 */
function createContext(script) {
  const INITIAL_CONTEXT = {
    vars: {
      target: script.config.target
    },
    funcs: {
      $randomNumber: $randomNumber,
      $randomString: $randomString
    }
  };
  let result = _.cloneDeep(INITIAL_CONTEXT);

  //
  // variables from payloads
  //
  if (script.config.payload) {
    _.each(script.config.payload, function(el) {
      let row = el.reader(el.data);
      _.each(el.fields, function(fieldName, j) {
        result.vars[fieldName] = row[j];
      });
    });
  }

  //
  // inline variables
  //
  if (script.config.variables) {
    _.each(script.config.variables, function(v, k) {
      let val;
      if (_.isArray(v)) {
        val = _.sample(v);
      } else {
        val = v;
      }
      result.vars[k] = val;
    });
  }
  result._uid = uuid.v4();
  return result;
}

//
// Generator functions for template strings:
//
function $randomNumber(min, max) {
  return _.random(min, max);
}

function $randomString(length) {
  return Math.random().toString(36).substr(2, length);
}
<commit_msg>Plugins cannot insert entries into the report anymore<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

const EventEmitter = require('events').EventEmitter;
const _ = require('lodash');
const debug = require('debug')('runner');
const debugPerf = require('debug')('perf');
const uuid = require('node-uuid');
const Stats = require('./stats2');
const JSCK = require('jsck');
const createPhaser = require('./phases');
const createReader = require('./readers');
const engineUtil = require('./engine_util');
const wl = require('./weighted-pick');

const Engines = {
  http: {},
  ws: {},
  socketio: {}
};

JSCK.Draft4 = JSCK.draft4;

const schema = new JSCK.Draft4(require('./schemas/artillery_test_script.json'));

module.exports = {
  runner: runner,
  validate: validate
};

function validate(script) {
  let validation = schema.validate(script);
  return validation;
}

function runner(script, payload, options) {
  let opts = _.assign({
    periodicStats: script.config.statsInterval || 10,
    mode: script.config.mode || 'uniform'
  },
  options);

  _.each(script.config.phases, function(phaseSpec) {
    phaseSpec.mode = phaseSpec.mode || script.config.mode;
  });

  if (payload) {
    if (_.isArray(payload[0])) {
      script.config.payload = [
        {
          fields: script.config.payload.fields,
          reader: createReader(script.config.payload.order),
          data: payload
        }
      ];
    } else {
      script.config.payload = payload;
      _.each(script.config.payload, function(el) {
        el.reader = createReader(el.order);
      });
    }
  } else {
    script.config.payload = null;
  }

  let runnableScript = _.cloneDeep(script);

  if (opts.environment) {
    debug('environment specified: %s', opts.environment);
    _.merge(
      runnableScript.config,
      script.config.environments[opts.environment]);
  }

  _.each(runnableScript.scenarios, function(scenarioSpec) {
    // if beforeRequest / afterResponse on scenario is set, make sure it's an array
    if (scenarioSpec.beforeRequest && !_.isArray(scenarioSpec.beforeRequest)) {
      scenarioSpec.beforeRequest = [scenarioSpec.beforeRequest];
    } else {
      scenarioSpec.beforeRequest = [];
    }

    if (scenarioSpec.afterResponse && !_.isArray(scenarioSpec.afterResponse)) {
      scenarioSpec.afterResponse = [scenarioSpec.afterResponse];
    } else {
      scenarioSpec.afterResponse = [];
    }
  });

  let ee = new EventEmitter();

  //
  // load engines:
  //
  let runnerEngines = _.map(
      Object.assign({}, Engines, runnableScript.config.engines),
      function loadEngine(engineConfig, engineName) {
        let moduleName = 'artillery-engine-' + engineName;
        try {
          if (Engines[engineName]) {
            moduleName = './engine_' + engineName;
          }
          let Engine = require(moduleName);
          let engine = new Engine(runnableScript, ee);
          engine.__name = engineName;
          return engine;
        } catch (e) {
          console.log(e);
          console.log(
              'WARNING: engine %s specified but module %s could not be loaded',
              engineName,
              moduleName);
        }
      }
  );

  //
  // load plugins:
  //
  let runnerPlugins = _.map(
      runnableScript.config.plugins,
      function loadPlugin(pluginConfig, pluginName) {
        let moduleName = 'artillery-plugin-' + pluginName;
        try {
          let Plugin = require(moduleName);
          let plugin = new Plugin(runnableScript.config, ee);
          plugin.__name = pluginName;
          return plugin;
        } catch (e) {
          console.log(
              'WARNING: plugin %s specified but module %s could not be loaded',
              pluginName,
              moduleName);
        }
      }
  );

  ee.run = function() {
    let runState = {
      pendingScenarios: 0,
      pendingRequests: 0,
      compiledScenarios: null,
      scenarioEvents: null,
      picker: undefined,
      Report: {
        intermediate: [],
        aggregate: {}
      },
      plugins: runnerPlugins,
      engines: runnerEngines
    };
    debug('run() with: %j', runnableScript);
    run(runnableScript, ee, opts, runState);
  };
  return ee;
}

function run(script, ee, options, runState) {
  let intermediate = Stats.create();
  let aggregate = Stats.create();

  let phaser = createPhaser(script.config.phases);
  phaser.on('arrival', function() {
    runScenario(script, intermediate, aggregate, runState);
  });
  phaser.on('phaseStarted', function(spec) {
    ee.emit('phaseStarted', spec);
  });
  phaser.on('phaseCompleted', function(spec) {
    ee.emit('phaseCompleted', spec);
  });
  phaser.on('done', function() {
    debug('All phases launched');

    const doneYet = setInterval(function checkIfDone() {
      if (runState.pendingScenarios === 0) {
        if (runState.pendingRequests !== 0) {
          debug('DONE. Pending requests: %s', runState.pendingRequests);
        }

        clearInterval(doneYet);
        clearInterval(periodicStatsTimer);

        runState.Report.aggregate = aggregate.report();
        sendStats();

        intermediate.free();
        aggregate.free();

        return ee.emit('done', runState.Report);
      } else {
        debug('Pending requests: %s', runState.pendingRequests);
        debug('Pending scenarios: %s', runState.pendingScenarios);
      }
    }, 500);
  });

  const periodicStatsTimer = setInterval(sendStats, options.periodicStats * 1000);

  function sendStats() {
    const report = intermediate.report();
    report.concurrency = runState.pendingScenarios;
    report.pendingRequests = runState.pendingRequests;
    runState.Report.intermediate.push(report);
    intermediate.reset();
    ee.emit('stats', report);
  }

  phaser.run();
}

function runScenario(script, intermediate, aggregate, runState) {
  const start = process.hrtime();

  //
  // Compile scenarios if needed
  //
  if (!runState.compiledScenarios) {
    _.each(script.scenarios, function(scenario) {
      if (!scenario.weight) {
        scenario.weight = 1;
      }
    });

    runState.picker = wl(script.scenarios);

    runState.scenarioEvents = new EventEmitter();
    runState.scenarioEvents.on('customStat', function(stat) {
      intermediate.addCustomStat(stat.stat, stat.value);
      aggregate.addCustomStat(stat.stat, stat.value);
    });
    runState.scenarioEvents.on('started', function() {
      runState.pendingScenarios++;
    });
    runState.scenarioEvents.on('error', function(errCode) {
      intermediate.addError(errCode);
      aggregate.addError(errCode);
    });
    runState.scenarioEvents.on('request', function() {
      intermediate.newRequest();
      aggregate.newRequest();

      runState.pendingRequests++;
    });
    runState.scenarioEvents.on('match', function() {
      intermediate.addMatch();
      aggregate.addMatch();
    });
    runState.scenarioEvents.on('response', function(delta, code, uid) {
      intermediate.completedRequest();
      intermediate.addLatency(delta);
      intermediate.addCode(code);

      let entry = [Date.now(), uid, delta, code];
      intermediate.addEntry(entry);
      aggregate.addEntry(entry);

      aggregate.completedRequest();
      aggregate.addLatency(delta);
      aggregate.addCode(code);

      runState.pendingRequests--;
    });

    runState.compiledScenarios = _.map(
        script.scenarios,
        function(scenarioSpec) {
          const name = scenarioSpec.engine || 'http';
          const engine = runState.engines.find((e) => e.__name === name);
          return engine.createScenario(scenarioSpec, runState.scenarioEvents);
        }
    );
  }

  intermediate.newScenario();
  aggregate.newScenario();

  let i = runState.picker()[0];

  debug('picking scenario %s (%s) weight = %s',
        i,
        script.scenarios[i].name,
        script.scenarios[i].weight);

  const scenarioStartedAt = process.hrtime();
  const scenarioContext = createContext(script);
  const finish = process.hrtime(start);
  const runScenarioDelta = (finish[0] * 1e9) + finish[1];
  debugPerf('runScenarioDelta: %s', Math.round(runScenarioDelta / 1e6 * 100) / 100);
  runState.compiledScenarios[i](scenarioContext, function(err, context) {
    runState.pendingScenarios--;
    if (err) {
      debug(err);
    } else {
      const scenarioFinishedAt = process.hrtime(scenarioStartedAt);
      const delta = (scenarioFinishedAt[0] * 1e9) + scenarioFinishedAt[1];
      intermediate.addScenarioLatency(delta);
      aggregate.addScenarioLatency(delta);
      intermediate.completedScenario();
      aggregate.completedScenario();
    }
  });
}

/**
 * Create initial context for a scenario.
 */
function createContext(script) {
  const INITIAL_CONTEXT = {
    vars: {
      target: script.config.target
    },
    funcs: {
      $randomNumber: $randomNumber,
      $randomString: $randomString
    }
  };
  let result = _.cloneDeep(INITIAL_CONTEXT);

  //
  // variables from payloads
  //
  if (script.config.payload) {
    _.each(script.config.payload, function(el) {
      let row = el.reader(el.data);
      _.each(el.fields, function(fieldName, j) {
        result.vars[fieldName] = row[j];
      });
    });
  }

  //
  // inline variables
  //
  if (script.config.variables) {
    _.each(script.config.variables, function(v, k) {
      let val;
      if (_.isArray(v)) {
        val = _.sample(v);
      } else {
        val = v;
      }
      result.vars[k] = val;
    });
  }
  result._uid = uuid.v4();
  return result;
}

//
// Generator functions for template strings:
//
function $randomNumber(min, max) {
  return _.random(min, max);
}

function $randomString(length) {
  return Math.random().toString(36).substr(2, length);
}
<|endoftext|>


<commit_before>var _ = require('lodash');
var Promise = require('bluebird');
var mysql = require('mysql');
var util = require('util');
var os = require('os');

var Logging = require('./logging');
var Config = require('./config');
var Client = require('./client');
var Util = require('./utils');

var SchemaManager = (function() {

    // Create a store to hold the private objects.
    var private = {};

    /**
     * Schema Manager.
     *
     * @param name: String, schema name.
     * @constructor
     */
    function SchemaManager(name) {

        var self = this;
        self._name = name;

        private['_client'] = new Client(Config.db);
        private['_logger'] = Logging.getLogger(util.format("[SchemaMgr/ %s]", name));
        private['_revisionTbl'] = "schema_version";
        private['_revisionTblColumns'] = [
            "version",
            "description",
            "type",
            "script",
            "checksum",
            "installed_rank",
            "installed_by",
            "installation_time",
            "execution_time",
            "status"
        ];

        // escape MySQL query to our 'schema_version' tbl and designated tbl.
        private['_escape'] = function(query, params) {
            var queryParams = [name, private._revisionTbl];
            _.each(params || [], function (param) {
                queryParams.push(param);
            });
            return mysql.format(query, queryParams);
        };

        // create objects in DB, mostly the `schema_version` tbl.
        private['_createObjects'] = function () {
            private._logger.info("Creating `%s` object in `%s` schema.", private._revisionTbl, self._name);
            return private._client.execute(private._escape(
                "CREATE TABLE IF NOT EXISTS ??.?? (" +
                "`revision` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, " +
                "`version` VARCHAR(100) NOT NULL, " +
                "`description` VARCHAR(255) DEFAULT NULL, " +
                "`type` enum('SQL','Node.js') DEFAULT NULL, " +
                "`script` VARCHAR(100) DEFAULT NULL, " +
                "`checksum` INT(10) UNSIGNED DEFAULT NULL, " +
                "`installed_rank` INT(10) UNSIGNED DEFAULT NULL, " +
                "`installed_by` VARCHAR(45) DEFAULT NULL, " +
                "`installation_time` DATETIME NOT NULL, " +
                "`execution_time` INT(10) UNSIGNED DEFAULT NULL, " +
                "`status` BIT(1) NOT NULL, " +
                "PRIMARY KEY (`revision`), " +
                "UNIQUE KEY `ux_script` (`script`,`version`) " +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"
            ));
        };

        // reset objects
        private['_deleteObjects'] = function () {
            private._logger.info("Deleting objects in `%s`.`%s`", self._name, private._revisionTbl);
            return private._client.execute(private._escape("DELETE FROM ??.??"));
        };

        // drop objects from DB
        private['_dropObjects'] = function () {
            private._logger.info("Dropping objects in `%s`", self._name);
            return private._client.execute(private._escape("DROP TABLE IF EXISTS ??.??"));
        };

        // read objects from DB
        private['_getObjects'] = function () {
            private._logger.info("Reading objects from `%s`.`%s`", self._name, private._revisionTbl);
            return private._client.execute(escape("SELECT * FROM ??.??"))
                .then(_.partialRight(_.groupBy, 'version'))
                .then(_.partialRight(_.mapValues, function (value) {
                    return _.sortBy(value, 'installed_rank');
                }));
        };

        // write object to DB
        private['_addObject'] = function (versionObject) {
            private._logger.info(
                "Saving version `%s` to `%s`.`%s`",
                versionObject.version, self._name, private._revisionTbl
            );
            var columns = _.pick(versionObject, private._revisionTblColumns);
            return private._client.execute(
                private._escape("INSERT INTO ??.?? SET ? ON DUPLICATE KEY UPDATE ?", [columns, columns])
            );
        };

        // run migration script
        private['_migration'] = function (migration) {

            var end, conn,
                promise, exec,
                start = new Date,
                status = 0;

            if (!migration) {
                throw new Error("Migration was called with no arguments.")
            }

            if (!migration.path) {
                throw new Error("Migration was called with no execution path.")
            }

            if (migration.type == "SQL") {
                promise = private._client.executeFile(migration.path);
            } else if (migration.type == 'Node.js') {
                try {
                    exec = require(migration.path);
                    if (typeof exec != "function")
                        throw new Error;
                } catch (e) {
                    throw new Error(
                        'Migration script could not be loaded ' +
                        'as `Node.js` source from: ' + migration.path
                    );
                }
                promise = private._client.getConnection()
                    .then(function connect(connection) {
                        conn = Promise.promisifyAll(connection);
                        private._logger.info("Starting transaction");
                        return conn.beginTransactionAsync();
                    })
                    .then(function migrate() {
                        return exec(conn);
                    })
                    .then(function commit() {
                        private._logger.info("Committing transaction");
                        return conn.commitAsync();
                    })
                    .catch(function (e) {
                        status = 1;
                        private._logger.error(e);
                        if (conn) {
                            private._logger.info("Something went wrong, rolling back");
                            return conn.rollbackAsync();
                        } else {
                            return Promise.resolve();
                        }
                    });
            } else {
                throw new Error(
                    "Invalid migration script type, expected type " +
                    "to be SQL / Node.js but got: " + migration.type
                );
            }

            return promise
                .then(function () {
                    end = new Date;
                    return private._addObject({
                        version: migration.version,
                        script: migration.script,
                        description: migration.description,
                        type: migration.type,
                        installed_by: os.hostname(),
                        installed_rank: migration.rank || 1,
                        installation_time: start,
                        execution_time: end - start,
                        status: status
                    });
                });
        }
    }

    SchemaManager.prototype.close = function () {
        return private._client.shutdown();
    };

    SchemaManager.prototype.clean = function () {
        return private._dropObjects();
    };

    /**
     * Creates a base version for all future DB migrations.
     * @param baseVersion: String, base version.
     * @param description: String, optional. description of the base version.
     * @returns Promise{Object}.
     */
    SchemaManager.prototype.baseline = function (baseVersion, description) {
        var self = this;
        var version = Util.parseVersion(baseVersion);

        return private._createObjects().bind(self)
            .then(private._deleteObjects)
            .then(function () {
                return private._addObject({
                    version: version,
                    description: description || "Base version",
                    type: "SQL",
                    installed_by: os.hostname(),
                    installed_rank: 1,
                    installation_time: new Date,
                    execution_time: 0,
                    status: 0
                });
            });
    };

    /**
     * Show information about schema version.
     * @returns Promise{Object}
     */
    SchemaManager.prototype.info = function () {
        var self = this;
        var result = {};

        return private._getObjects().bind(self)
            .then(function (objects) {
                var currentVersion = _.first(_.sortBy(_.keys(objects)));
                result.version = currentVersion;
                result.migrations = _.map(objects[currentVersion],
                    _.partialRight(_.pick, ['script', 'description', 'success'])
                );
            })
            .catch(function (e) {
                private._logger.error(e);
                result.version = "Unknown";
                result.migrations = [];
            })
            .then(function () {
                return result;
            });
    };

    SchemaManager.prototype.migrate = function(migration) {
        return private._migration(migration);
    };

    return SchemaManager;

}());

module.exports = SchemaManager;<commit_msg>migrate phase 1<commit_after>var _ = require('lodash');
var Promise = require('bluebird');
var mysql = require('mysql');
var util = require('util');
var os = require('os');

var Logging = require('./logging');
var Client = require('./client');
var Util = require('./utils');

var SchemaManager = (function () {

    // Create a store to hold the private objects.
    var private = {};

    /**
     * Schema Manager.
     *
     * @param schema: String, schema name.
     * @param config: Object, connection config.
     * @constructor
     */
    function SchemaManager(schema, config) {

        if (!_.isString(schema)) {
            throw new Error(
                "constructor expects first argument to be a string " +
                "but got `" + typeof(schema) + "` instead."
            );
        }

        if (!_.isObject(config)) {
            throw new Error(
                "constructor expects second argument to be an object " +
                "but got `" + typeof(config) + "` instead."
            );
        }

        var self = this;
        self._schema = schema;
        self._config = config;

        private['_client'] = new Client(config);
        private['_logger'] = Logging.getLogger(util.format("[SchemaMgr/ %s]", schema));
        private['_revisionTbl'] = "schema_version";
        private['_revisionTblColumns'] = [
            "version",
            "description",
            "type",
            "script",
            "checksum",
            "installed_rank",
            "installed_by",
            "installation_time",
            "execution_time",
            "status"
        ];

        // escape MySQL query to our 'schema_version' tbl and designated tbl.
        private['_escape'] = function (query, params) {
            var queryParams = [schema, private._revisionTbl];
            _.each(params || [], function (param) {
                queryParams.push(param);
            });
            return mysql.format(query, queryParams);
        };

        // create objects in DB, mostly the `schema_version` tbl.
        private['_createObjects'] = function () {
            private._logger.info("Creating `%s` object in `%s` schema.", private._revisionTbl, self._schema);
            return private._client.execute(private._escape(
                "CREATE TABLE IF NOT EXISTS ??.?? (" +
                "`revision` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, " +
                "`version` VARCHAR(100) NOT NULL, " +
                "`description` VARCHAR(255) DEFAULT NULL, " +
                "`type` enum('SQL','Node.js') DEFAULT NULL, " +
                "`script` VARCHAR(100) DEFAULT NULL, " +
                "`checksum` INT(10) UNSIGNED DEFAULT NULL, " +
                "`installed_rank` INT(10) UNSIGNED DEFAULT NULL, " +
                "`installed_by` VARCHAR(45) DEFAULT NULL, " +
                "`installation_time` DATETIME NOT NULL, " +
                "`execution_time` INT(10) UNSIGNED DEFAULT NULL, " +
                "`status` BIT(1) NOT NULL, " +
                "PRIMARY KEY (`revision`), " +
                "UNIQUE KEY `ux_script` (`script`,`version`) " +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8;"
            ));
        };

        // reset objects
        private['_deleteObjects'] = function () {
            private._logger.info("Deleting objects in `%s`.`%s`", self._schema, private._revisionTbl);
            return private._client.execute(private._escape("DELETE FROM ??.??"));
        };

        // drop objects from DB
        private['_dropObjects'] = function () {
            private._logger.info("Dropping objects in `%s`", self._schema);
            return private._client.execute(private._escape("DROP TABLE IF EXISTS ??.??"));
        };

        // read objects from DB
        private['_getObjects'] = function () {
            private._logger.info("Reading objects from `%s`.`%s`", self._schema, private._revisionTbl);
            return private._client.execute(private._escape("SELECT * FROM ??.??"))
                .then(_.partialRight(_.groupBy, 'version'))
                .then(_.partialRight(_.mapValues, function (value) {
                    return _.sortBy(value, 'installed_rank');
                }));
        };

        // write object to DB
        private['_addObject'] = function (obj) {
            var ov = private._parseObject(obj);
            private._logger.info(
                "Saving version `%s` to `%s`.`%s`",
                ov.version, self._schema, private._revisionTbl
            );
            return private._client.execute(
                private._escape("INSERT INTO ??.?? SET ? ON DUPLICATE KEY UPDATE ?", [ov, ov])
            );
        };

        private._parseObject = function (obj) {
            // ensure object exists
            if (!_.isObject(obj)) {
                throw new Error("Expected an object but got: " + typeof(obj));
            }

            // ensure object version is in the right format
            obj.version = Util.parseVersion(obj.version);

            // object properties
            return _.pick(obj, private._revisionTblColumns);
        };

        // run migration script
        private['_migration'] = function (migration) {

            var end, conn,
                promise, exec,
                start = new Date,
                status = 0;

            if (!migration) {
                throw new Error("Migration was called with no arguments.")
            }

            if (!migration.path) {
                throw new Error("Migration was called with no execution path.")
            }

            if (migration.type == "SQL") {
                promise = private._client.executeFile(migration.path);
            } else if (migration.type == 'Node.js') {
                try {
                    exec = require(migration.path);
                    if (typeof exec != "function")
                        throw new Error;
                } catch (e) {
                    throw new Error(
                        'Migration script could not be loaded ' +
                        'as `Node.js` source from: ' + migration.path
                    );
                }
                promise = private._client.getConnection()
                    .then(function connect(connection) {
                        conn = Promise.promisifyAll(connection);
                        private._logger.info("Starting transaction");
                        return conn.beginTransactionAsync();
                    })
                    .then(function migrate() {
                        return exec(conn);
                    })
                    .then(function commit() {
                        private._logger.info("Committing transaction");
                        return conn.commitAsync();
                    })
                    .catch(function (e) {
                        status = 1;
                        private._logger.error(e);
                        if (conn) {
                            private._logger.info("Something went wrong, rolling back");
                            return conn.rollbackAsync();
                        } else {
                            return Promise.resolve();
                        }
                    });
            } else {
                throw new Error(
                    "Invalid migration script type, expected type " +
                    "to be SQL / Node.js but got: " + migration.type
                );
            }

            return promise
                .then(function () {
                    end = new Date;
                    return private._addObject({
                        version: migration.version,
                        script: migration.script,
                        description: migration.description,
                        type: migration.type,
                        installed_by: os.hostname(),
                        installed_rank: migration.rank || 1,
                        installation_time: start,
                        execution_time: end - start,
                        status: status
                    });
                });
        }
    }

    SchemaManager.prototype.close = function () {
        return private._client.shutdown();
    };

    SchemaManager.prototype.clean = function () {
        return private._dropObjects();
    };

    /**
     * Creates a base version for all future DB migrations.
     * @param baseVersion: String, base version.
     * @param description: String, optional. description of the base version.
     * @returns Promise{Object}.
     */
    SchemaManager.prototype.baseline = function (baseVersion, description) {
        var self = this;
        var version = Util.parseVersion(baseVersion);

        return private._createObjects().bind(self)
            .then(private._deleteObjects)
            .then(function () {
                return private._addObject({
                    version: version,
                    description: description || "Base version",
                    type: "SQL",
                    installed_by: os.hostname(),
                    installed_rank: 1,
                    installation_time: new Date,
                    execution_time: 0,
                    status: 0
                });
            });
    };

    /**
     * Show information about schema version.
     * @returns Promise{Object}
     */
    SchemaManager.prototype.revision = function () {
        var self = this;
        var result = {};

        return private._getObjects().bind(self)
            .then(function (objects) {
                var currentVersion = _.last(_.sortBy(_.keys(objects)));
                result.version = currentVersion;
                result.migrations = _.map(objects[currentVersion],
                    _.partialRight(_.pick, [
                        'script',
                        'description',
                        'execution_time',
                        'status'
                    ])
                );
            })
            .catch(function (e) {
                private._logger.error(e);
                result.version = "Unknown";
                result.migrations = [];
            })
            .then(function () {
                return result;
            });
    };

    /**
     * Run migration.
     * @param directory: String, directory for discovery.
     * @param targetVersion: String, target version for the new migration.
     */
    SchemaManager.prototype.migrate = function (directory, targetVersion) {
        var self = this;

        // get current revision
        return self.revision()
            .then(function getStepByStep(revision) {
                var baseVersion = _.get(revision, 'version', 'Unknown');
                if (baseVersion.toLowerCase() == "unknown") {
                    return Promise.reject(new Error(
                        "Could not determine schema revision before running migration scripts. " +
                        "It is possible that `baseline` was never executed or database is currently not reachable."
                    ));
                } else {
                    return Util.discovery(
                        directory, targetVersion, baseVersion,
                        _.pluck(_.get(revision, 'migrations', []), 'script')
                    )
                }
            })
            .then(function(steps) {
                // no execution step found, we are done.
                if (_.isEmpty(steps)) {
                    private._logger.info("No migration steps were found.");
                    return Promise.resolve();
                }
                // start step-by-step execution
                return Promise.mapSeries(steps, function(step) {
                    // migrate a new version by running each of th
                    return Promise.map(step, function(migration, idx) {
                        // set migration installation rank
                        migration.rank = idx+1;
                        // perform one step of the version
                        return private._migration(migration);
                    });
                });
            })
            .catch(function(e) {
                private._logger.error(e);
            });
    };

    return SchemaManager;

}());

module.exports = SchemaManager;<|endoftext|>


<commit_before>var sys = require("sys");
var util = require('util');
var BaseType = require('./base');
var Utils = require("../utils");

function ArrayType() {

    ArrayType.super_.call(this);

    Utils.mixin(this, BaseType);
}

util.inherits(ArrayType, BaseType);

ArrayType.prototype.__name = 'Array';

ArrayType.prototype.convert = function(value) {

    if (typeof value === 'string') {

        // No need to try/catch, `Invalid JSON Body` exception already handled elsehwere
        try {
            var converted = JSON.parse(value);
            if (converted instanceof Array) {

                return converted;
            }
            else {

                return [converted];
            }
        }
        catch (e){
            // console.log(e, value)
        }
    }
    else {

        // Defensive programming
        // throw "Invalid data type passed to Types.Array (" + value + ", " + typeof value + " is not supported)";
        return value;
    }
}

ArrayType.prototype._base = function() {

    return function(value, qs, key, errors) {

        // console.log('value in Array.base', value)
        return value instanceof Array;
    };
}

ArrayType.prototype.base = function() {

    this.add('base', this._base(), arguments);
    return this;
}

ArrayType.prototype._includes = function() {

    var self = this;
    var subElement = (new ArrayType.super_()).getDataKey();
    var args = Array.prototype.slice.call(arguments);
    var allowedTypes = args.map(function(d) {

        return d[subElement];
    });

    return function(values, qs, key, req) {

        req = req || {}
        req.add = req.add || function(){}

        // For each allowed Type
        var valueIsValid = true;
        // var intermediateInvalidValues = [];
        var invalidValues = [];
        var failedArg = null;
        var failedIndex = null;
        var failedValue = null;
        var validatedValuesTable = {};

        for(var i = 0; i < allowedTypes.length; i++) {

            // For each validator specified
            var currentType = args[i].type;
            var validators = allowedTypes[i];
            var validatorIsValid = true;
            for(var j = 0; j < validators.length; j++) {

                // For each input supplied
                for(var m = 0; m < values.length; m++) {

                    var value = values[m];
                    var result = validators[j](value, qs, key, req);
                    if (result === false) {

                        validatorIsValid = false;
                        // intermediateInvalidValues.push(value);
                        failedArg = i
                        failedIndex = j;
                        failedValue = value;
                    }
                    else {

                        // console.log(value, "is valid", currentType)
                        validatedValuesTable[m] = true;
                    }
                }
            }
        }

        for(var m = 0; m < values.length; m++) {

            if (!validatedValuesTable.hasOwnProperty(m)) {

                invalidValues.push(values[m]);
                valueIsValid = false;
            }
        }

        // Only append error if the included types' validators return errors
        // if (valueIsValid === false && failedIndex >= 0 && args[0].__checks.indexOf("includes") < 0) {
        if (valueIsValid === false) {

            // if(self.options.debug === true) console.log("***", validatedValuesTable, values)
            var validTypes = args.map(function(d){ return d.type; });
            var vals = invalidValues.map(function(d){ return JSON.stringify(d)}).join(", ").replace(/[\"]/g, "'")
            var msg = "the value(s) `" + vals + "` in array `" + key + "` must be of the following type(s) " + sys.inspect(validTypes);
            req.add(msg);
            // console.log(msg)
            // console.log(args[failedIndex].type, args[failedArg].__checks[failedIndex], failedValue, values)
        }
        return valueIsValid;
    }
}

ArrayType.prototype.includes = function() {

    this.add('includes', this._includes.apply(this, arguments), arguments);
    return this;
}

ArrayType.prototype._excludes = function() {

    var self = this;
    var subElement = (new ArrayType.super_()).getDataKey();
    var args = Array.prototype.slice.call(arguments);
    var allowedTypes = args.map(function(d) {

        return d[subElement];
    });

    return function(value, qs, key, req) {

        req = req || {}
        req.add = req.add || function(){}

        var typeTable = {
            "string": require("./string")(),
            "boolean": require("./boolean")(),
            "number": require("./number")(),
            "array": CreateType(),
            // "object": require("./object")()
        }
        var validTypes = args.map(function(d){ return d.type});

        var handler = function(arg){
            delete typeTable[arg.type.toLowerCase()];
            var result = self._includes(arg)(value, qs, key, req);
            return result;
        }

        var components = args.map(handler);
        if (components.indexOf(true) >= 0) {

            req.add("the values supplied to array `" + key + "` must contain " + JSON.stringify(validTypes));
            return false;
        }

        var difference = Object.keys(typeTable).map(function(d){
            return typeTable[d];
        }).map(handler);

        if (difference.indexOf(true) >= 0) {

            return true
        }

        req.add("the values supplied to array `" + key + "` must contain " + JSON.stringify(validTypes));
        return false;
    }
}

ArrayType.prototype.excludes = function(){

    this.add('excludes', this._excludes.apply(this, arguments), arguments);
    return this;
}

function CreateType() {

    return new ArrayType();
}

module.exports = CreateType;
module.exports.ArrayType = ArrayType;<commit_msg>misc obvious style fixes<commit_after>var sys = require("sys");
var util = require('util');
var BaseType = require('./base');
var Utils = require("../utils");

function ArrayType() {

    ArrayType.super_.call(this);

    Utils.mixin(this, BaseType);
}

util.inherits(ArrayType, BaseType);

ArrayType.prototype.__name = 'Array';

ArrayType.prototype.convert = function(value) {

    if (typeof value === 'string') {

        // No need to try/catch, `Invalid JSON Body` exception already handled elsehwere
        try {
            var converted = JSON.parse(value);
            if (converted instanceof Array) {

                return converted;
            }
            else {

                return [converted];
            }
        }
        catch (e){
            // console.log(e, value)
        }
    }
    else {

        // Defensive programming
        // throw "Invalid data type passed to Types.Array (" + value + ", " + typeof value + " is not supported)";
        return value;
    }
}

ArrayType.prototype._base = function() {

    return function(value, qs, key, errors) {

        // console.log('value in Array.base', value)
        return value instanceof Array;
    };
}

ArrayType.prototype.base = function() {

    this.add('base', this._base(), arguments);
    return this;
}

ArrayType.prototype._includes = function() {

    var self = this;
    var subElement = (new ArrayType.super_()).getDataKey();
    var args = Array.prototype.slice.call(arguments);
    var allowedTypes = args.map(function(d) {

        return d[subElement];
    });

    return function(values, qs, key, req) {

        req = req || {}
        req.add = req.add || function(){}

        // For each allowed Type
        var valueIsValid = true;
        // var intermediateInvalidValues = [];
        var invalidValues = [];
        var failedArg = null;
        var failedIndex = null;
        var failedValue = null;
        var validatedValuesTable = {};

        for(var i = 0; i < allowedTypes.length; i++) {

            // For each validator specified
            var currentType = args[i].type;
            var validators = allowedTypes[i];
            var validatorIsValid = true;
            for(var j = 0; j < validators.length; j++) {

                // For each input supplied
                for(var m = 0; m < values.length; m++) {

                    var value = values[m];
                    var result = validators[j](value, qs, key, req);
                    if (result === false) {

                        validatorIsValid = false;
                        // intermediateInvalidValues.push(value);
                        failedArg = i
                        failedIndex = j;
                        failedValue = value;
                    }
                    else {

                        // console.log(value, "is valid", currentType)
                        validatedValuesTable[m] = true;
                    }
                }
            }
        }

        for(var m = 0; m < values.length; m++) {

            if (!validatedValuesTable.hasOwnProperty(m)) {

                invalidValues.push(values[m]);
                valueIsValid = false;
            }
        }

        // Only append error if the included types' validators return errors
        // if (valueIsValid === false && failedIndex >= 0 && args[0].__checks.indexOf("includes") < 0) {
        if (valueIsValid === false) {

            // if(self.options.debug === true) console.log("***", validatedValuesTable, values)
            var validTypes = args.map(function(d){ return d.type; });
            var vals = invalidValues.map(function(d){ return JSON.stringify(d)}).join(", ").replace(/[\"]/g, "'")
            var msg = "the value(s) `" + vals + "` in array `" + key + "` must be of the following type(s) " + sys.inspect(validTypes);
            req.add(msg);
            // console.log(msg)
            // console.log(args[failedIndex].type, args[failedArg].__checks[failedIndex], failedValue, values)
        }
        return valueIsValid;
    }
}

ArrayType.prototype.includes = function() {

    this.add('includes', this._includes.apply(this, arguments), arguments);
    return this;
}

ArrayType.prototype._excludes = function() {

    var self = this;
    var subElement = (new ArrayType.super_()).getDataKey();
    var args = Array.prototype.slice.call(arguments);
    var allowedTypes = args.map(function(d) {

        return d[subElement];
    });

    return function(value, qs, key, req) {

        req = req || {};
        req.add = req.add || function(){};

        var typeTable = {
            "string": require("./string")(),
            "boolean": require("./boolean")(),
            "number": require("./number")(),
            "array": CreateType(),
            // "object": require("./object")()
        };
        var validTypes = args.map(function(d){ return d.type; });

        var handler = function(arg) {

            delete typeTable[arg.type.toLowerCase()];
            var result = self._includes(arg)(value, qs, key, req);
            return result;
        }

        var components = args.map(handler);
        if (components.indexOf(true) >= 0) {

            req.add("the values supplied to array `" + key + "` must contain " + JSON.stringify(validTypes));
            return false;
        }

        var difference = Object.keys(typeTable).map(function(d){
            return typeTable[d];
        }).map(handler);

        if (difference.indexOf(true) >= 0) {

            return true;
        }

        req.add("the values supplied to array `" + key + "` must contain " + JSON.stringify(validTypes));
        return false;
    }
}

ArrayType.prototype.excludes = function(){

    this.add('excludes', this._excludes.apply(this, arguments), arguments);
    return this;
}

function CreateType() {

    return new ArrayType();
}

module.exports = CreateType;
module.exports.ArrayType = ArrayType;<|endoftext|>


<commit_before>import {
  loadTranslations,
  setLocale,
  syncTranslationWithStore,
} from 'react-redux-i18n';
import axios from '../axios';

const translationService = axios(
  'internal.php?object=centreon_i18n&action=translation',
);
const userService = axios(
  'internal.php?object=centreon_topcounter&action=user',
);

export default function setTranslations(store, callback) {
  const localePromise = userService.get();
  const translationsPromise = translationService.get();
  Promise.all([localePromise, translationsPromise]).then((response) => {
    let { locale } = response[0].data;
    locale = locale != null ? locale.slice(0, 2) : navigator.language;
    const translations = response[1].data;
    syncTranslationWithStore(store);
    store.dispatch(loadTranslations(translations));
    store.dispatch(setLocale(locale));
    callback();
  });
}
<commit_msg>fix(front): redirect to login page when user is unauthorized (#7687)<commit_after>import {
  loadTranslations,
  setLocale,
  syncTranslationWithStore,
} from 'react-redux-i18n';
import axios from '../axios';

const translationService = axios(
  'internal.php?object=centreon_i18n&action=translation',
);
const userService = axios(
  'internal.php?object=centreon_topcounter&action=user',
);

export default function setTranslations(store, callback) {
  const localePromise = userService.get();
  const translationsPromise = translationService.get();

  Promise.all([localePromise, translationsPromise])
    .then((response) => {
      let { locale } = response[0].data;
      locale = locale !== null ? locale.slice(0, 2) : navigator.language;
      const translations = response[1].data;
      syncTranslationWithStore(store);
      store.dispatch(loadTranslations(translations));
      store.dispatch(setLocale(locale));
      callback();
    })
    .catch((error) => {
      if (error.response.status === 401) {
        // redirect to login page
        window.location.href = 'index.php?disconnect=1';
      }
    });
}
<|endoftext|>


<commit_before>import mysql from './mysql';
import postgresql from './postgresql';
import sqlserver from './sqlserver';
import sqlite from './sqlite';
import cassandra from './cassandra';

/**
 * List of supported database clients
 */
export const CLIENTS = [
  {
    key: 'mysql',
    name: 'MySQL',
    defaultPort: 3306,
    disabledFeatures: [
      'server:schema',
      'server:domain',
    ],
  },
  {
    key: 'mariadb',
    name: 'MariaDB',
    defaultPort: 3306,
    disabledFeatures: [
      'server:schema',
      'server:domain',
    ],
  },
  {
    key: 'postgresql',
    name: 'PostgreSQL',
    defaultDatabase: 'postgres',
    defaultPort: 5432,
    disabledFeatures: [
      'server:domain',
    ],
  },
  {
    key: 'redshift',
    name: 'Redshift',
    defaultDatabase: 'postgres',
    defaultPort: 5432,
    disabledFeatures: [
      'server:domain',
    ],
  },
  {
    key: 'sqlserver',
    name: 'Microsoft SQL Server',
    defaultPort: 1433,
  },
  {
    key: 'sqlite',
    name: 'SQLite',
    defaultDatabase: ':memory:',
    disabledFeatures: [
      'server:ssl',
      'server:host',
      'server:port',
      'server:socketPath',
      'server:user',
      'server:password',
      'server:schema',
      'server:domain',
      'server:ssh',
      'scriptCreateTable',
      'cancelQuery',
    ],
  },
  {
    key: 'cassandra',
    name: 'Cassandra',
    defaultPort: 9042,
    disabledFeatures: [
      'server:ssl',
      'server:socketPath',
      'server:schema',
      'server:domain',
      'scriptCreateTable',
      'cancelQuery',
    ],
  },
];

export default {
  mysql,
  mariadb: mysql,
  postgresql,
  redshift: postgresql,
  sqlserver,
  sqlite,
  cassandra,
};
<commit_msg>remove scriptCreateTable from sqlite disabled features (#126)<commit_after>import mysql from './mysql';
import postgresql from './postgresql';
import sqlserver from './sqlserver';
import sqlite from './sqlite';
import cassandra from './cassandra';

/**
 * List of supported database clients
 */
export const CLIENTS = [
  {
    key: 'mysql',
    name: 'MySQL',
    defaultPort: 3306,
    disabledFeatures: [
      'server:schema',
      'server:domain',
    ],
  },
  {
    key: 'mariadb',
    name: 'MariaDB',
    defaultPort: 3306,
    disabledFeatures: [
      'server:schema',
      'server:domain',
    ],
  },
  {
    key: 'postgresql',
    name: 'PostgreSQL',
    defaultDatabase: 'postgres',
    defaultPort: 5432,
    disabledFeatures: [
      'server:domain',
    ],
  },
  {
    key: 'redshift',
    name: 'Redshift',
    defaultDatabase: 'postgres',
    defaultPort: 5432,
    disabledFeatures: [
      'server:domain',
    ],
  },
  {
    key: 'sqlserver',
    name: 'Microsoft SQL Server',
    defaultPort: 1433,
  },
  {
    key: 'sqlite',
    name: 'SQLite',
    defaultDatabase: ':memory:',
    disabledFeatures: [
      'server:ssl',
      'server:host',
      'server:port',
      'server:socketPath',
      'server:user',
      'server:password',
      'server:schema',
      'server:domain',
      'server:ssh',
      'cancelQuery',
    ],
  },
  {
    key: 'cassandra',
    name: 'Cassandra',
    defaultPort: 9042,
    disabledFeatures: [
      'server:ssl',
      'server:socketPath',
      'server:schema',
      'server:domain',
      'scriptCreateTable',
      'cancelQuery',
    ],
  },
];

export default {
  mysql,
  mariadb: mysql,
  postgresql,
  redshift: postgresql,
  sqlserver,
  sqlite,
  cassandra,
};
<|endoftext|>


<commit_before>module.exports = function(HAPnode, config, functions)
{
    var Accessory       = HAPnode.Accessory;
    var Service         = HAPnode.Service;
    var Characteristic  = HAPnode.Characteristic;
    var uuid            = HAPnode.uuid;
    var debug           = HAPnode.debug;

    var module  = {};

    module.newDevice = function(device)
    {
        var Lightbulb = {
            powerOn: (parseInt(device.status) === 1)?true:false,

            setPower: function(state)
            {
                // if (on)
                // {
                //     binaryState     = 1;
                //     Lightbulb.powerOn  = true;
                // }
                // else
                // {
                //     binaryState     = 0;
                //     Lightbulb.powerOn  = false;
                // }

                debug("Making request for device %s", device.name);

                var service = 'urn:upnp-org:serviceId:SwitchPower1',
                    action = 'SetTarget',
                    value = parseInt(state);
                functions.executeAction({
                  action: action,
                  serviceId: service,
                  newTargetValue: value,
                  DeviceNum: device.id
                }).then(function(response){
                  debug("Light Power set");
                  debug(response);
                })

                // return HAPnode.request({method:'GET',uri:"http://"+config.veraIP+":3480/data_request?id=lu_action&output_format=xml&DeviceNum=" + device.id + "&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=" + binaryState, resolveWithFullResponse: true}).then(function (res)
                // {
                //     if (res.statusCode === 200)
                //     {
                //         status = (Lightbulb.powerOn)?'On':'Off';
                //         debug("The %s has been turned %s", device.name, status);
                //     }
                //     else
                //     {
                //         debug("Error while turning the %s on/off %s", device.name);
                //     }
                // }).catch(function (err) {
                //     HAPnode.debug("Request error:"+err);
                // });
            },
            getStatus: function()
            {
                debug("Making request for device %s", device.name);
                status = parseInt(functions.getVariable(device.id, 'status'));
                debug("LEVEL IS ", status)
                return status;
            },
            identify: function()
            {
                debug("Identify the light %s", device.name);
            }
        };

        var light = new Accessory(device.name, uuid.generate('device:Lightbulb:'+config.cardinality+':'+device.id));

        light.username  = functions.genMac('device:'+config.cardinality+':'+device.id);
        light.pincode   = config.pincode;
        light.deviceid  = device.id;

        light
            .getService(Service.AccessoryInformation)
            .setCharacteristic(Characteristic.Manufacturer, "Oltica")
            .setCharacteristic(Characteristic.Model, "Rev-1")
            .setCharacteristic(Characteristic.SerialNumber, "A1S2NASF88EW");

        light.on('identify', function(paired, callback) {
            Lightbulb.identify();
            callback(); // success
        });

        light
            .addService(Service.Lightbulb, device.name)
            .getCharacteristic(Characteristic.On)
            .on('set', function(value, callback) {
                Lightbulb.setPower(value);
                callback();
            });

        light
            .getService(Service.Lightbulb)
            .getCharacteristic(Characteristic.On)
            .on('get', function(callback) {
                var err = null;
                callback(err, Lightbulb.getStatus());

            });

        return light;
    };

    return module;
};
<commit_msg>resolving switch power, setting state to 1/0<commit_after>module.exports = function(HAPnode, config, functions)
{
    var Accessory       = HAPnode.Accessory;
    var Service         = HAPnode.Service;
    var Characteristic  = HAPnode.Characteristic;
    var uuid            = HAPnode.uuid;
    var debug           = HAPnode.debug;

    var module  = {};

    module.newDevice = function(device)
    {
        var Lightbulb = {
            powerOn: (parseInt(device.status) === 1)?true:false,

            setPower: function(state)
            {
                state = state ? 1:0;
                debug("Making request for device %s", device.name);

                var service = 'urn:upnp-org:serviceId:SwitchPower1',
                    action = 'SetTarget',
                    value = state;
                functions.executeAction({
                  action: action,
                  serviceId: service,
                  newTargetValue: value,
                  DeviceNum: device.id
                }).then(function(response){
                  debug("Light Power set");
                  debug(response);
                })

                // return HAPnode.request({method:'GET',uri:"http://"+config.veraIP+":3480/data_request?id=lu_action&output_format=xml&DeviceNum=" + device.id + "&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=" + binaryState, resolveWithFullResponse: true}).then(function (res)
                // {
                //     if (res.statusCode === 200)
                //     {
                //         status = (Lightbulb.powerOn)?'On':'Off';
                //         debug("The %s has been turned %s", device.name, status);
                //     }
                //     else
                //     {
                //         debug("Error while turning the %s on/off %s", device.name);
                //     }
                // }).catch(function (err) {
                //     HAPnode.debug("Request error:"+err);
                // });
            },
            getStatus: function()
            {
                debug("Making request for device %s", device.name);
                status = parseInt(functions.getVariable(device.id, 'status'));
                debug("LEVEL IS ", status)
                return status;
            },
            identify: function()
            {
                debug("Identify the light %s", device.name);
            }
        };

        var light = new Accessory(device.name, uuid.generate('device:Lightbulb:'+config.cardinality+':'+device.id));

        light.username  = functions.genMac('device:'+config.cardinality+':'+device.id);
        light.pincode   = config.pincode;
        light.deviceid  = device.id;

        light
            .getService(Service.AccessoryInformation)
            .setCharacteristic(Characteristic.Manufacturer, "Oltica")
            .setCharacteristic(Characteristic.Model, "Rev-1")
            .setCharacteristic(Characteristic.SerialNumber, "A1S2NASF88EW");

        light.on('identify', function(paired, callback) {
            Lightbulb.identify();
            callback(); // success
        });

        light
            .addService(Service.Lightbulb, device.name)
            .getCharacteristic(Characteristic.On)
            .on('set', function(value, callback) {
                Lightbulb.setPower(value);
                callback();
            });

        light
            .getService(Service.Lightbulb)
            .getCharacteristic(Characteristic.On)
            .on('get', function(callback) {
                var err = null;
                callback(err, Lightbulb.getStatus());

            });

        return light;
    };

    return module;
};
<|endoftext|>


<commit_before>'use strict';

module.exports = ({ Plugin, types: t }) => {

  const removeReferenceVisitor = {
    ReferencedIdentifier(path) {
      if (!this.bindingsToReplace[path.node.name]) {
        return;
      }

      const { replacement, markReplaced, scope } = this.bindingsToReplace[path.node.name];

      if ((t.isClass(replacement) || t.isFunction(replacement))
          && scope !== path.scope) {
        return;
      }

      if (path.find(({ node }) => node === replacement)) {
        return;
      }

      t.toExpression(replacement);

      // This changes `function.name` but all the other minifier
      // do it :/
      if (t.isFunction(replacement)) {
        replacement.id = null;
      }

      path.replaceWith(replacement);
      markReplaced();
    },
  };

  const main = {
    // remove side effectless statement
    ExpressionStatement(path) {
      if (path.get('expression').isPure() && !path.isCompletionRecord()) {
        if (!path.parentPath.isBlockStatement()) {
          path.replaceWith(t.emptyStatement());
        } else {
          path.remove();
        }
      }
    },

    // Remove bindings with no references.
    Scope(path) {
      if (path.isProgram()) {
        return;
      }

      const { scope } = path;
      const bindingsToReplace = Object.create(null);

      for (let name in scope.bindings) {
        let binding = scope.bindings[name];

        if (!binding.referenced && binding.kind !== 'param' && binding.kind !== 'module') {
          if (binding.path.isVariableDeclarator()) {

            // Can't remove if in a for in statement `for (var x in wat)`.
            if (binding.path.parentPath.parentPath && binding.path.parentPath.parentPath.isForInStatement()) {
              continue;
            }

            if (binding.path.node.init && !scope.isPure(binding.path.node.init)) {
              if (binding.path.parentPath.node.declarations.length === 1) {
                binding.path.parentPath.replaceWith(binding.path.node.init);
                scope.removeBinding(name);
              }
              continue;
            }
          } else if (!scope.isPure(binding.path.node)) {
            continue;
          } else if (binding.path.isFunctionExpression()) {
            // `bar(function foo() {})` foo is not referenced but it's used.
            continue;
          }
          scope.removeBinding(name);
          binding.path.remove();
        } else if (binding.constant) {
          if (binding.path.isFunctionDeclaration() ||
              (binding.path.isVariableDeclarator() && binding.path.get('init').isFunction())) {
                const fun = binding.path.isFunctionDeclaration() ? binding.path : binding.path.get('init');
                let allInside = true;
                for (let ref of binding.referencePaths) {
                  if (!ref.find(p => p.node === fun.node)) {
                    allInside = false;
                    break;
                  }
                }

                if (allInside) {
                  scope.removeBinding(name);
                  binding.path.remove();
                  continue;
                }
          }

          if (binding.references === 1 && binding.kind !== 'param' && binding.kind !== 'module' && binding.constant) {
            let replacement = binding.path.node;
            if (t.isVariableDeclarator(replacement)) {
              replacement = replacement.init;
            }
            if (!replacement) {
              continue;
            }

            if (!scope.isPure(replacement, true)) {
              continue;
            }

            bindingsToReplace[name] = {
              scope,
              replacement,
              markReplaced() {
                scope.removeBinding(name);
                if (binding.path.node) {
                  binding.path.remove();
                }
              },
            };
          }
        }
      }
      if (Object.keys(bindingsToReplace).length) {
        path.traverse(removeReferenceVisitor, {bindingsToReplace});
      }
    },

    // Remove unreachable code.
    BlockStatement(path) {
      const paths = path.get('body');

      let purge = false;

      for (let i = 0; i < paths.length; i++) {
        const p = paths[i];

        if (!purge && p.isCompletionStatement()) {
          purge = true;
          continue;
        }

        if (purge && !p.isFunctionDeclaration()) {
          p.remove();
        }
      }
    },

    // Double check unreachable code and remove return statements that
    // have no semantic meaning
    ReturnStatement(path) {
      const { node } = path;
      if (!path.inList) {
        return;
      }

      // Not last in it's block? (See BlockStatement visitor)
      if (path.container.length - 1 !== path.key &&
          !path.getSibling(path.key + 1).isFunctionDeclaration()
      ) {
        // This is probably a new oppurtinity by some other transform
        // let's call the block visitor on this again before proceeding.
        path.parentPath.pushContext(path.context);
        path.parentPath.visit();
        path.parentPath.popContext();

        return;
      }

      if (node.argument) {
        return;
      }

      let noNext = true;
      let parentPath = path.parentPath;
      while (parentPath && !parentPath.isFunction() && noNext) {
        const nextPath = parentPath.getSibling(parentPath.key + 1);
        if (nextPath.node) {
          if (nextPath.isReturnStatement()) {
            nextPath.pushContext(path.context);
            nextPath.visit();
            nextPath.popContext();
            if (parentPath.getSibling(parentPath.key + 1).node) {
              noNext = false;
              break;
            }
          } else {
            noNext = false;
            break;
          }
        }

        parentPath = parentPath.parentPath;
      }

      if (noNext) {
        path.remove();
      }
    },

    ConditionalExpression(path) {
      const { node } = path;
      const evaluateTest = path.get('test').evaluateTruthy();
      if (evaluateTest === true) {
        path.replaceWith(node.consequent);
      } else if (evaluateTest === false) {
        path.replaceWith(node.alternate);
      }
    },

    IfStatement: {
      exit(path) {
        const { node } = path;
        let { consequent, alternate, test } = node;

        const evaluateTest = path.get('test').evaluateTruthy();

        // we can check if a test will be truthy 100% and if so then we can inline
        // the consequent and completely ignore the alternate
        //
        //   if (true) { foo; } -> { foo; }
        //   if ("foo") { foo; } -> { foo; }
        //
        if (evaluateTest === true) {
          path.replaceWithMultiple(toStatements(consequent));
          return;
        }

        // we can check if a test will be falsy 100% and if so we can inline the
        // alternate if there is one and completely remove the consequent
        //
        //   if ("") { bar; } else { foo; } -> { foo; }
        //   if ("") { bar; } ->
        //
        if (evaluateTest === false) {
          if (alternate) {
            path.replaceWithMultiple(toStatements(alternate));
            return;
          } else {
            path.remove();
          }
        }

        // remove alternate blocks that are empty
        //
        //   if (foo) { foo; } else {} -> if (foo) { foo; }
        //
        if (t.isBlockStatement(alternate) && !alternate.body.length) {
          alternate = node.alternate = null;
        }

        // if the consequent block is empty turn alternate blocks into a consequent
        // and flip the test
        //
        //   if (foo) {} else { bar; } -> if (!foo) { bar; }
        //

        if (t.isBlockStatement(consequent) && !consequent.body.length &&
            t.isBlockStatement(alternate) && alternate.body.length
        ) {
          node.consequent = node.alternate;
          node.alternate = null;
          node.test = t.unaryExpression('!', test, true);
        }
      },
    },

    // Join assignment and definition when in sequence.
    // var x; x = 1; -> var x = 1;
    AssignmentExpression(path) {
      if (!path.get('left').isIdentifier() ||
          !path.parentPath.isExpressionStatement()
      ) {
        return;
      }

      const prev = path.parentPath.getSibling(path.parentPath.key - 1);
      if (!(prev && prev.isVariableDeclaration())) {
        return;
      }

      const declars = prev.node.declarations;
      if (declars.length !== 1 || declars[0].init ||
          declars[0].id.name !== path.get('left').node.name
      ) {
        return;
      }
      declars[0].init = path.node.right;
      path.remove();
    },
  };

  return {
    visitor: {
      Program(path) {
        // We need to run this plugin in isolation.
        path.traverse(main, {});
      },
    },
  };

  function toStatements(node) {
    if (t.isBlockStatement(node)) {
      let hasBlockScoped = false;

      for (let i = 0; i < node.body.length; i++) {
        let bodyNode = node.body[i];
        if (t.isBlockScoped(bodyNode)) {
          hasBlockScoped = true;
        }
      }

      if (!hasBlockScoped) {
        return node.body;
      }
    }
    return node;
  }
};
<commit_msg>Fix infinite recursion bug<commit_after>'use strict';

const returnSeen = Symbol('returnSeen');

module.exports = ({ Plugin, types: t }) => {

  const removeReferenceVisitor = {
    ReferencedIdentifier(path) {
      if (!this.bindingsToReplace[path.node.name]) {
        return;
      }

      const { replacement, markReplaced, scope } = this.bindingsToReplace[path.node.name];

      if ((t.isClass(replacement) || t.isFunction(replacement))
          && scope !== path.scope) {
        return;
      }

      if (path.find(({ node }) => node === replacement)) {
        return;
      }

      t.toExpression(replacement);

      // This changes `function.name` but all the other minifier
      // do it :/
      if (t.isFunction(replacement)) {
        replacement.id = null;
      }

      path.replaceWith(replacement);
      markReplaced();
    },
  };

  const main = {
    // remove side effectless statement
    ExpressionStatement(path) {
      if (path.get('expression').isPure() && !path.isCompletionRecord()) {
        if (!path.parentPath.isBlockStatement()) {
          path.replaceWith(t.emptyStatement());
        } else {
          path.remove();
        }
      }
    },

    // Remove bindings with no references.
    Scope(path) {
      if (path.isProgram()) {
        return;
      }

      const { scope } = path;
      const bindingsToReplace = Object.create(null);

      for (let name in scope.bindings) {
        let binding = scope.bindings[name];

        if (!binding.referenced && binding.kind !== 'param' && binding.kind !== 'module') {
          if (binding.path.isVariableDeclarator()) {

            // Can't remove if in a for in statement `for (var x in wat)`.
            if (binding.path.parentPath.parentPath && binding.path.parentPath.parentPath.isForInStatement()) {
              continue;
            }

            if (binding.path.node.init && !scope.isPure(binding.path.node.init)) {
              if (binding.path.parentPath.node.declarations.length === 1) {
                binding.path.parentPath.replaceWith(binding.path.node.init);
                scope.removeBinding(name);
              }
              continue;
            }
          } else if (!scope.isPure(binding.path.node)) {
            continue;
          } else if (binding.path.isFunctionExpression()) {
            // `bar(function foo() {})` foo is not referenced but it's used.
            continue;
          }
          scope.removeBinding(name);
          binding.path.remove();
        } else if (binding.constant) {
          if (binding.path.isFunctionDeclaration() ||
              (binding.path.isVariableDeclarator() && binding.path.get('init').isFunction())) {
                const fun = binding.path.isFunctionDeclaration() ? binding.path : binding.path.get('init');
                let allInside = true;
                for (let ref of binding.referencePaths) {
                  if (!ref.find(p => p.node === fun.node)) {
                    allInside = false;
                    break;
                  }
                }

                if (allInside) {
                  scope.removeBinding(name);
                  binding.path.remove();
                  continue;
                }
          }

          if (binding.references === 1 && binding.kind !== 'param' && binding.kind !== 'module' && binding.constant) {
            let replacement = binding.path.node;
            if (t.isVariableDeclarator(replacement)) {
              replacement = replacement.init;
            }
            if (!replacement) {
              continue;
            }

            if (!scope.isPure(replacement, true)) {
              continue;
            }

            bindingsToReplace[name] = {
              scope,
              replacement,
              markReplaced() {
                scope.removeBinding(name);
                if (binding.path.node) {
                  binding.path.remove();
                }
              },
            };
          }
        }
      }
      if (Object.keys(bindingsToReplace).length) {
        path.traverse(removeReferenceVisitor, {bindingsToReplace});
      }
    },

    // Remove unreachable code.
    BlockStatement(path) {
      const paths = path.get('body');

      let purge = false;

      for (let i = 0; i < paths.length; i++) {
        const p = paths[i];

        if (!purge && p.isCompletionStatement()) {
          purge = true;
          continue;
        }

        if (purge && !p.isFunctionDeclaration()) {
          p.remove();
        }
      }
    },

    // Double check unreachable code and remove return statements that
    // have no semantic meaning
    ReturnStatement(path) {
      const { node } = path;
      if (node[returnSeen] || !path.inList) {
        return;
      }

      node[returnSeen] = true;

      // Not last in it's block? (See BlockStatement visitor)
      if (path.container.length - 1 !== path.key &&
          !path.getSibling(path.key + 1).isFunctionDeclaration()
      ) {
        // This is probably a new oppurtinity by some other transform
        // let's call the block visitor on this again before proceeding.
        path.parentPath.pushContext(path.context);
        path.parentPath.visit();
        path.parentPath.popContext();

        return;
      }

      if (node.argument) {
        return;
      }

      let noNext = true;
      let parentPath = path.parentPath;
      while (parentPath && !parentPath.isFunction() && noNext) {
        const nextPath = parentPath.getSibling(parentPath.key + 1);
        if (nextPath.node) {
          if (nextPath.isReturnStatement()) {
            nextPath.pushContext(path.context);
            nextPath.visit();
            nextPath.popContext();
            if (parentPath.getSibling(parentPath.key + 1).node) {
              noNext = false;
              break;
            }
          } else {
            noNext = false;
            break;
          }
        }

        parentPath = parentPath.parentPath;
      }

      if (noNext) {
        path.remove();
      }
    },

    ConditionalExpression(path) {
      const { node } = path;
      const evaluateTest = path.get('test').evaluateTruthy();
      if (evaluateTest === true) {
        path.replaceWith(node.consequent);
      } else if (evaluateTest === false) {
        path.replaceWith(node.alternate);
      }
    },

    IfStatement: {
      exit(path) {
        const { node } = path;
        let { consequent, alternate, test } = node;

        const evaluateTest = path.get('test').evaluateTruthy();

        // we can check if a test will be truthy 100% and if so then we can inline
        // the consequent and completely ignore the alternate
        //
        //   if (true) { foo; } -> { foo; }
        //   if ("foo") { foo; } -> { foo; }
        //
        if (evaluateTest === true) {
          path.replaceWithMultiple(toStatements(consequent));
          return;
        }

        // we can check if a test will be falsy 100% and if so we can inline the
        // alternate if there is one and completely remove the consequent
        //
        //   if ("") { bar; } else { foo; } -> { foo; }
        //   if ("") { bar; } ->
        //
        if (evaluateTest === false) {
          if (alternate) {
            path.replaceWithMultiple(toStatements(alternate));
            return;
          } else {
            path.remove();
          }
        }

        // remove alternate blocks that are empty
        //
        //   if (foo) { foo; } else {} -> if (foo) { foo; }
        //
        if (t.isBlockStatement(alternate) && !alternate.body.length) {
          alternate = node.alternate = null;
        }

        // if the consequent block is empty turn alternate blocks into a consequent
        // and flip the test
        //
        //   if (foo) {} else { bar; } -> if (!foo) { bar; }
        //

        if (t.isBlockStatement(consequent) && !consequent.body.length &&
            t.isBlockStatement(alternate) && alternate.body.length
        ) {
          node.consequent = node.alternate;
          node.alternate = null;
          node.test = t.unaryExpression('!', test, true);
        }
      },
    },

    // Join assignment and definition when in sequence.
    // var x; x = 1; -> var x = 1;
    AssignmentExpression(path) {
      if (!path.get('left').isIdentifier() ||
          !path.parentPath.isExpressionStatement()
      ) {
        return;
      }

      const prev = path.parentPath.getSibling(path.parentPath.key - 1);
      if (!(prev && prev.isVariableDeclaration())) {
        return;
      }

      const declars = prev.node.declarations;
      if (declars.length !== 1 || declars[0].init ||
          declars[0].id.name !== path.get('left').node.name
      ) {
        return;
      }
      declars[0].init = path.node.right;
      path.remove();
    },
  };

  return {
    visitor: {
      Program(path) {
        // We need to run this plugin in isolation.
        path.traverse(main, {});
      },
    },
  };

  function toStatements(node) {
    if (t.isBlockStatement(node)) {
      let hasBlockScoped = false;

      for (let i = 0; i < node.body.length; i++) {
        let bodyNode = node.body[i];
        if (t.isBlockScoped(bodyNode)) {
          hasBlockScoped = true;
        }
      }

      if (!hasBlockScoped) {
        return node.body;
      }
    }
    return node;
  }
};
<|endoftext|>