<commit_before>'use strict';

var Utils = require('../../utils')
  , DataTypes = require('../../data-types')
  , SqlString = require('../../sql-string')
  , Transaction = require('../../transaction');

var MySqlQueryGenerator = Utils._.extend(
  Utils._.clone(require('../abstract/query-generator')),
  Utils._.clone(require('../mysql/query-generator'))
);

var hashToWhereConditions = MySqlQueryGenerator.hashToWhereConditions;

module.exports = (function() {
  var QueryGenerator = {
    options: {},
    dialect: 'sqlite',

    createSchema: function() {
      var query = "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
      return Utils._.template(query)({});
    },

    dropSchema: function(tableName, options) {
      return this.dropTableQuery(tableName, options);
    },

    showSchemasQuery: function() {
      return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
    },

    createTableQuery: function(tableName, attributes, options) {
      options = options || {};

      var query = 'CREATE TABLE IF NOT EXISTS <%= table %> (<%= attributes%>)'
        , primaryKeys = []
        , needsMultiplePrimaryKeys = (Utils._.values(attributes).filter(function(definition) {
                    return Utils._.includes(definition, 'PRIMARY KEY');
                  }).length > 1)
        , attrStr = []
        , modifierLastIndex = -1;

      for (var attr in attributes) {
        if (attributes.hasOwnProperty(attr)) {
          var dataType = attributes[attr];

          if (Utils._.includes(dataType, 'AUTOINCREMENT')) {
            dataType = dataType.replace(/BIGINT/, 'INTEGER');
          }

          // SQLite thinks that certain modifiers should come before the length declaration,
          // whereas other dialects want them after, see http://www.sqlite.org/lang_createtable.html.

          // Start by finding the index of the last of the modifiers
          ['UNSIGNED', 'BINARY', 'ZEROFILL'].forEach(function (modifier) {
            var tmpIndex = dataType.indexOf(modifier);

            if (tmpIndex > modifierLastIndex) {
              modifierLastIndex = tmpIndex + modifier.length;
            }
          });

          if (modifierLastIndex) {
            // If a modifier was found, and a lenght declaration is given before the modifier, move the length
            var length = dataType.match(/\(\s*\d+(\s*,\s*\d)?\s*\)/);
            if (length && length.index < modifierLastIndex) {
              dataType = dataType.replace(length[0], '');

              // Since the legnth was placed before the modifier, removing the legnth has changed the index
              if (length.index < modifierLastIndex) {
                modifierLastIndex -= length[0].length;
              }
              dataType = Utils._.insert(dataType, modifierLastIndex, length[0]).trim();
            }

            modifierLastIndex = -1;
          }

          var dataTypeString = dataType;
          if (Utils._.includes(dataType, 'PRIMARY KEY')) {
            if (Utils._.includes(dataType, 'INTEGER')) {
              dataTypeString = 'INTEGER PRIMARY KEY'; // Only INTEGER is allowed for primary key, see https://github.com/sequelize/sequelize/issues/969 (no lenght, unsigned etc)
            }

            if (needsMultiplePrimaryKeys) {
              primaryKeys.push(attr);
              dataTypeString = dataType.replace(/PRIMARY KEY/, 'NOT NULL');
            }
          }
          attrStr.push(this.quoteIdentifier(attr) + " " + dataTypeString);
        }
      }

      var values = {
        table: this.quoteTable(tableName),
        attributes: attrStr.join(", "),
        charset: (options.charset ? "DEFAULT CHARSET=" + options.charset : "")
      }
      , pkString = primaryKeys.map(function(pk) { return this.quoteIdentifier(pk); }.bind(this)).join(", ");

      if (!!options.uniqueKeys) {
        Utils._.each(options.uniqueKeys, function(columns) {
          values.attributes += ", UNIQUE (" + columns.fields.join(', ') + ")";
        });
      }

      if (pkString.length > 0) {
        values.attributes += ", PRIMARY KEY (" + pkString + ")";
      }

      var sql = Utils._.template(query, values).trim() + ";";
      return this.replaceBooleanDefaults(sql);
    },

    booleanValue: function(value){
      return !!value ? 1 : 0;
    },

    uniqueConstraintMapping: {
      code: 'SQLITE_CONSTRAINT',
      map: function(str) {
        var match = str.match(/columns (.*?) are/);
        if (match === null || match.length < 2) {
          return false;
        }

        return match[1].split(', ');
      }
    },

    addLimitAndOffset: function(options, query){
      query = query || "";
      if (options.offset && !options.limit) {
        query += " LIMIT " + options.offset + ", " + 10000000000000;
      } else if (options.limit) {
        if (options.offset) {
          query += " LIMIT " + options.offset + ", " + options.limit;
        } else {
          query += " LIMIT " + options.limit;
        }
      }
      return query;
    },

    addColumnQuery: function() {
      var sql = MySqlQueryGenerator.addColumnQuery.apply(this, arguments);
      return this.replaceBooleanDefaults(sql);
    },

    showTablesQuery: function() {
      return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
    },

    bulkInsertQuery: function(tableName, attrValueHashes, options) {
      var query = "INSERT<%= ignoreDuplicates %> INTO <%= table %> (<%= attributes %>) VALUES <%= tuples %>;"
        , tuples = []
        , allAttributes = [];

      Utils._.forEach(attrValueHashes, function(attrValueHash, i) {
        Utils._.forOwn(attrValueHash, function(value, key, hash) {
          if (allAttributes.indexOf(key) === -1) allAttributes.push(key);
        });
      });

      Utils._.forEach(attrValueHashes, function(attrValueHash, i) {
        tuples.push("(" +
          allAttributes.map(function (key) {
            return this.escape(attrValueHash[key]);
          }.bind(this)).join(",") +
        ")");
      }.bind(this));

      var replacements  = {
        ignoreDuplicates: options && options.ignoreDuplicates ? ' OR IGNORE' : '',
        table: this.quoteTable(tableName),
        attributes: allAttributes.map(function(attr) {
                      return this.quoteIdentifier(attr);
                    }.bind(this)).join(","),
        tuples: tuples
      };

      return Utils._.template(query)(replacements);
    },

    updateQuery: function(tableName, attrValueHash, where, options) {
      attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull, options);

      var query  = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %>"
        , values = [];

      for (var key in attrValueHash) {
        var value = attrValueHash[key];
        values.push(this.quoteIdentifier(key) + "=" + this.escape(value));
      }

      var replacements = {
        table: this.quoteTable(tableName),
        values: values.join(","),
        where: this.getWhereConditions(where)
      };

      return Utils._.template(query)(replacements);
    },

    deleteQuery: function(tableName, where, options) {
      options = options || {};

      var query = "DELETE FROM <%= table %> WHERE <%= where %>";
      var replacements = {
        table: this.quoteTable(tableName),
        where: this.getWhereConditions(where)
      };

      return Utils._.template(query)(replacements);
    },

    attributesToSQL: function(attributes) {
      var result = {};

      for (var name in attributes) {
        var dataType = attributes[name];

        if (Utils._.isObject(dataType)) {
          var template     = "<%= type %>"
            , replacements = { type: dataType.type };

          if (dataType.type.toString() === DataTypes.ENUM.toString()) {
            replacements.type = "TEXT";

            if (!(Array.isArray(dataType.values) && (dataType.values.length > 0))) {
              throw new Error('Values for ENUM haven\'t been defined.');
            }
          }

          if (dataType.hasOwnProperty('allowNull') && !dataType.allowNull && !dataType.primaryKey) {
            template += " NOT NULL";
          }

          if (Utils.defaultValueSchemable(dataType.defaultValue)) {
            // TODO thoroughly check that DataTypes.NOW will properly
            // get populated on all databases as DEFAULT value
            // i.e. mysql requires: DEFAULT CURRENT_TIMESTAMP
            template += " DEFAULT <%= defaultValue %>";
            replacements.defaultValue = this.escape(dataType.defaultValue);
          }

          if (dataType.unique === true) {
            template += " UNIQUE";
          }

          if (dataType.primaryKey) {
            template += " PRIMARY KEY";

            if (dataType.autoIncrement) {
              template += ' AUTOINCREMENT';
            }
          }

          if(dataType.references) {
            template += " REFERENCES <%= referencesTable %> (<%= referencesKey %>)";
            replacements.referencesTable = this.quoteTable(dataType.references);

            if(dataType.referencesKey) {
              replacements.referencesKey = this.quoteIdentifier(dataType.referencesKey);
            } else {
              replacements.referencesKey = this.quoteIdentifier('id');
            }

            if(dataType.onDelete) {
              template += " ON DELETE <%= onDeleteAction %>";
              replacements.onDeleteAction = dataType.onDelete.toUpperCase();
            }

            if(dataType.onUpdate) {
              template += " ON UPDATE <%= onUpdateAction %>";
              replacements.onUpdateAction = dataType.onUpdate.toUpperCase();
            }

          }

          result[name] = Utils._.template(template)(replacements);
        } else {
          result[name] = dataType;
        }
      }

      return result;
    },

    findAutoIncrementField: function(factory) {
      var fields = [];

      for (var name in factory.attributes) {
        if (factory.attributes.hasOwnProperty(name)) {
          var definition = factory.attributes[name];
          if (definition && definition.autoIncrement) {
            fields.push(name);
          }
        }
      }

      return fields;
    },

    showIndexQuery: function(tableName) {
      var sql = "PRAGMA INDEX_LIST(<%= tableName %>)";
      return Utils._.template(sql, { tableName: tableName });
    },

    removeIndexQuery: function(tableName, indexNameOrAttributes) {
      var sql       = "DROP INDEX IF EXISTS <%= indexName %>"
        , indexName = indexNameOrAttributes;

      if (typeof indexName !== 'string') {
        indexName = Utils._.underscored(tableName + '_' + indexNameOrAttributes.join('_'));
      }

      return Utils._.template(sql, { tableName: tableName, indexName: indexName });
    },

    describeTableQuery: function(tableName, schema, schemaDelimiter) {
      var options = {};
      options.schema = schema;
      options.schemaDelimiter = schemaDelimiter;
      options.quoted = false;

      var sql = "PRAGMA TABLE_INFO(<%= tableName %>);";
      return Utils._.template(sql, { tableName: this.addSchema({tableName: tableName, options: options})});
    },

    removeColumnQuery: function(tableName, attributes) {
      attributes = this.attributesToSQL(attributes);

      var backupTableName = tableName + "_backup";
      var query = [
        this.createTableQuery(backupTableName, attributes).replace('CREATE TABLE', 'CREATE TEMPORARY TABLE'),
        "INSERT INTO <%= tableName %>_backup SELECT <%= attributeNames %> FROM <%= tableName %>;",
        "DROP TABLE <%= tableName %>;",
        this.createTableQuery(tableName, attributes),
        "INSERT INTO <%= tableName %> SELECT <%= attributeNames %> FROM <%= tableName %>_backup;",
        "DROP TABLE <%= tableName %>_backup;"
      ].join("");

      return Utils._.template(query, {
        tableName: tableName,
        attributeNames: Utils._.keys(attributes).join(', ')
      });
    },

    renameColumnQuery: function(tableName, attrNameBefore, attrNameAfter, attributes) {
      attributes = this.attributesToSQL(attributes);

      var backupTableName = tableName + "_backup";
      var query = [
        this.createTableQuery(backupTableName, attributes).replace('CREATE TABLE', 'CREATE TEMPORARY TABLE'),
        "INSERT INTO <%= tableName %>_backup SELECT <%= attributeNamesImport %> FROM <%= tableName %>;",
        "DROP TABLE <%= tableName %>;",
        this.createTableQuery(tableName, attributes),
        "INSERT INTO <%= tableName %> SELECT <%= attributeNamesExport %> FROM <%= tableName %>_backup;",
        "DROP TABLE <%= tableName %>_backup;"
      ].join("");

      return Utils._.template(query, {
        tableName: tableName,
        attributeNamesImport: Utils._.keys(attributes).map(function(attr) {
          return (attrNameAfter === attr) ? '`' + attrNameBefore + '` AS `' + attr + '`' : '`' + attr + '`'
        }.bind(this)).join(', '),
        attributeNamesExport: Utils._.keys(attributes).map(function(attr) {
          return '`' + attr + '`'
        }.bind(this)).join(', ')
      });
    },

    startTransactionQuery: function() {
      return "BEGIN TRANSACTION;";
    },

    setAutocommitQuery: function() {
      return "-- SQLite does not support SET autocommit.";
    },

    setIsolationLevelQuery: function(value) {
      switch (value) {
        case Transaction.ISOLATION_LEVELS.REPEATABLE_READ:
          return "-- SQLite is not able to choose the isolation level REPEATABLE READ.";
        case Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED:
          return "PRAGMA read_uncommitted = ON;";
        case Transaction.ISOLATION_LEVELS.READ_COMMITTED:
          return "PRAGMA read_uncommitted = OFF;";
        case Transaction.ISOLATION_LEVELS.SERIALIZABLE:
          return "-- SQLite's default isolation level is SERIALIZABLE. Nothing to do.";
        default:
          throw new Error('Unknown isolation level: ' + value);
      }
    },

    replaceBooleanDefaults: function(sql) {
      return sql.replace(/DEFAULT '?false'?/g, "DEFAULT 0").replace(/DEFAULT '?true'?/g, "DEFAULT 1");
    },

    quoteIdentifier: function(identifier, force) {
      if (identifier === '*') return identifier;
      return Utils.addTicks(identifier, "`");
    },

        /**
     * Generates an SQL query that returns all foreign keys of a table.
     *
     * @param  {String} tableName  The name of the table.
     * @param  {String} schemaName The name of the schema.
     * @return {String}            The generated sql query.
     */
    getForeignKeysQuery: function(tableName, schemaName) {
      var sql = "PRAGMA foreign_key_list(<%= tableName %>)";
      return Utils._.template(sql, { tableName: tableName });
    }
  };

  return Utils._.extend({}, MySqlQueryGenerator, QueryGenerator);
})();
<commit_msg>Using quoteIdentifier() to wrap attribute names<commit_after>'use strict';

var Utils = require('../../utils')
  , DataTypes = require('../../data-types')
  , SqlString = require('../../sql-string')
  , Transaction = require('../../transaction');

var MySqlQueryGenerator = Utils._.extend(
  Utils._.clone(require('../abstract/query-generator')),
  Utils._.clone(require('../mysql/query-generator'))
);

var hashToWhereConditions = MySqlQueryGenerator.hashToWhereConditions;

module.exports = (function() {
  var QueryGenerator = {
    options: {},
    dialect: 'sqlite',

    createSchema: function() {
      var query = "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
      return Utils._.template(query)({});
    },

    dropSchema: function(tableName, options) {
      return this.dropTableQuery(tableName, options);
    },

    showSchemasQuery: function() {
      return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
    },

    createTableQuery: function(tableName, attributes, options) {
      options = options || {};

      var query = 'CREATE TABLE IF NOT EXISTS <%= table %> (<%= attributes%>)'
        , primaryKeys = []
        , needsMultiplePrimaryKeys = (Utils._.values(attributes).filter(function(definition) {
                    return Utils._.includes(definition, 'PRIMARY KEY');
                  }).length > 1)
        , attrStr = []
        , modifierLastIndex = -1;

      for (var attr in attributes) {
        if (attributes.hasOwnProperty(attr)) {
          var dataType = attributes[attr];

          if (Utils._.includes(dataType, 'AUTOINCREMENT')) {
            dataType = dataType.replace(/BIGINT/, 'INTEGER');
          }

          // SQLite thinks that certain modifiers should come before the length declaration,
          // whereas other dialects want them after, see http://www.sqlite.org/lang_createtable.html.

          // Start by finding the index of the last of the modifiers
          ['UNSIGNED', 'BINARY', 'ZEROFILL'].forEach(function (modifier) {
            var tmpIndex = dataType.indexOf(modifier);

            if (tmpIndex > modifierLastIndex) {
              modifierLastIndex = tmpIndex + modifier.length;
            }
          });

          if (modifierLastIndex) {
            // If a modifier was found, and a lenght declaration is given before the modifier, move the length
            var length = dataType.match(/\(\s*\d+(\s*,\s*\d)?\s*\)/);
            if (length && length.index < modifierLastIndex) {
              dataType = dataType.replace(length[0], '');

              // Since the legnth was placed before the modifier, removing the legnth has changed the index
              if (length.index < modifierLastIndex) {
                modifierLastIndex -= length[0].length;
              }
              dataType = Utils._.insert(dataType, modifierLastIndex, length[0]).trim();
            }

            modifierLastIndex = -1;
          }

          var dataTypeString = dataType;
          if (Utils._.includes(dataType, 'PRIMARY KEY')) {
            if (Utils._.includes(dataType, 'INTEGER')) {
              dataTypeString = 'INTEGER PRIMARY KEY'; // Only INTEGER is allowed for primary key, see https://github.com/sequelize/sequelize/issues/969 (no lenght, unsigned etc)
            }

            if (needsMultiplePrimaryKeys) {
              primaryKeys.push(attr);
              dataTypeString = dataType.replace(/PRIMARY KEY/, 'NOT NULL');
            }
          }
          attrStr.push(this.quoteIdentifier(attr) + " " + dataTypeString);
        }
      }

      var values = {
        table: this.quoteTable(tableName),
        attributes: attrStr.join(", "),
        charset: (options.charset ? "DEFAULT CHARSET=" + options.charset : "")
      }
      , pkString = primaryKeys.map(function(pk) { return this.quoteIdentifier(pk); }.bind(this)).join(", ");

      if (!!options.uniqueKeys) {
        Utils._.each(options.uniqueKeys, function(columns) {
          values.attributes += ", UNIQUE (" + columns.fields.join(', ') + ")";
        });
      }

      if (pkString.length > 0) {
        values.attributes += ", PRIMARY KEY (" + pkString + ")";
      }

      var sql = Utils._.template(query, values).trim() + ";";
      return this.replaceBooleanDefaults(sql);
    },

    booleanValue: function(value){
      return !!value ? 1 : 0;
    },

    uniqueConstraintMapping: {
      code: 'SQLITE_CONSTRAINT',
      map: function(str) {
        var match = str.match(/columns (.*?) are/);
        if (match === null || match.length < 2) {
          return false;
        }

        return match[1].split(', ');
      }
    },

    addLimitAndOffset: function(options, query){
      query = query || "";
      if (options.offset && !options.limit) {
        query += " LIMIT " + options.offset + ", " + 10000000000000;
      } else if (options.limit) {
        if (options.offset) {
          query += " LIMIT " + options.offset + ", " + options.limit;
        } else {
          query += " LIMIT " + options.limit;
        }
      }
      return query;
    },

    addColumnQuery: function() {
      var sql = MySqlQueryGenerator.addColumnQuery.apply(this, arguments);
      return this.replaceBooleanDefaults(sql);
    },

    showTablesQuery: function() {
      return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
    },

    bulkInsertQuery: function(tableName, attrValueHashes, options) {
      var query = "INSERT<%= ignoreDuplicates %> INTO <%= table %> (<%= attributes %>) VALUES <%= tuples %>;"
        , tuples = []
        , allAttributes = [];

      Utils._.forEach(attrValueHashes, function(attrValueHash, i) {
        Utils._.forOwn(attrValueHash, function(value, key, hash) {
          if (allAttributes.indexOf(key) === -1) allAttributes.push(key);
        });
      });

      Utils._.forEach(attrValueHashes, function(attrValueHash, i) {
        tuples.push("(" +
          allAttributes.map(function (key) {
            return this.escape(attrValueHash[key]);
          }.bind(this)).join(",") +
        ")");
      }.bind(this));

      var replacements  = {
        ignoreDuplicates: options && options.ignoreDuplicates ? ' OR IGNORE' : '',
        table: this.quoteTable(tableName),
        attributes: allAttributes.map(function(attr) {
                      return this.quoteIdentifier(attr);
                    }.bind(this)).join(","),
        tuples: tuples
      };

      return Utils._.template(query)(replacements);
    },

    updateQuery: function(tableName, attrValueHash, where, options) {
      attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull, options);

      var query  = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %>"
        , values = [];

      for (var key in attrValueHash) {
        var value = attrValueHash[key];
        values.push(this.quoteIdentifier(key) + "=" + this.escape(value));
      }

      var replacements = {
        table: this.quoteTable(tableName),
        values: values.join(","),
        where: this.getWhereConditions(where)
      };

      return Utils._.template(query)(replacements);
    },

    deleteQuery: function(tableName, where, options) {
      options = options || {};

      var query = "DELETE FROM <%= table %> WHERE <%= where %>";
      var replacements = {
        table: this.quoteTable(tableName),
        where: this.getWhereConditions(where)
      };

      return Utils._.template(query)(replacements);
    },

    attributesToSQL: function(attributes) {
      var result = {};

      for (var name in attributes) {
        var dataType = attributes[name];

        if (Utils._.isObject(dataType)) {
          var template     = "<%= type %>"
            , replacements = { type: dataType.type };

          if (dataType.type.toString() === DataTypes.ENUM.toString()) {
            replacements.type = "TEXT";

            if (!(Array.isArray(dataType.values) && (dataType.values.length > 0))) {
              throw new Error('Values for ENUM haven\'t been defined.');
            }
          }

          if (dataType.hasOwnProperty('allowNull') && !dataType.allowNull && !dataType.primaryKey) {
            template += " NOT NULL";
          }

          if (Utils.defaultValueSchemable(dataType.defaultValue)) {
            // TODO thoroughly check that DataTypes.NOW will properly
            // get populated on all databases as DEFAULT value
            // i.e. mysql requires: DEFAULT CURRENT_TIMESTAMP
            template += " DEFAULT <%= defaultValue %>";
            replacements.defaultValue = this.escape(dataType.defaultValue);
          }

          if (dataType.unique === true) {
            template += " UNIQUE";
          }

          if (dataType.primaryKey) {
            template += " PRIMARY KEY";

            if (dataType.autoIncrement) {
              template += ' AUTOINCREMENT';
            }
          }

          if(dataType.references) {
            template += " REFERENCES <%= referencesTable %> (<%= referencesKey %>)";
            replacements.referencesTable = this.quoteTable(dataType.references);

            if(dataType.referencesKey) {
              replacements.referencesKey = this.quoteIdentifier(dataType.referencesKey);
            } else {
              replacements.referencesKey = this.quoteIdentifier('id');
            }

            if(dataType.onDelete) {
              template += " ON DELETE <%= onDeleteAction %>";
              replacements.onDeleteAction = dataType.onDelete.toUpperCase();
            }

            if(dataType.onUpdate) {
              template += " ON UPDATE <%= onUpdateAction %>";
              replacements.onUpdateAction = dataType.onUpdate.toUpperCase();
            }

          }

          result[name] = Utils._.template(template)(replacements);
        } else {
          result[name] = dataType;
        }
      }

      return result;
    },

    findAutoIncrementField: function(factory) {
      var fields = [];

      for (var name in factory.attributes) {
        if (factory.attributes.hasOwnProperty(name)) {
          var definition = factory.attributes[name];
          if (definition && definition.autoIncrement) {
            fields.push(name);
          }
        }
      }

      return fields;
    },

    showIndexQuery: function(tableName) {
      var sql = "PRAGMA INDEX_LIST(<%= tableName %>)";
      return Utils._.template(sql, { tableName: tableName });
    },

    removeIndexQuery: function(tableName, indexNameOrAttributes) {
      var sql       = "DROP INDEX IF EXISTS <%= indexName %>"
        , indexName = indexNameOrAttributes;

      if (typeof indexName !== 'string') {
        indexName = Utils._.underscored(tableName + '_' + indexNameOrAttributes.join('_'));
      }

      return Utils._.template(sql, { tableName: tableName, indexName: indexName });
    },

    describeTableQuery: function(tableName, schema, schemaDelimiter) {
      var options = {};
      options.schema = schema;
      options.schemaDelimiter = schemaDelimiter;
      options.quoted = false;

      var sql = "PRAGMA TABLE_INFO(<%= tableName %>);";
      return Utils._.template(sql, { tableName: this.addSchema({tableName: tableName, options: options})});
    },

    removeColumnQuery: function(tableName, attributes) {
      attributes = this.attributesToSQL(attributes);

      var backupTableName = tableName + "_backup";
      var query = [
        this.createTableQuery(backupTableName, attributes).replace('CREATE TABLE', 'CREATE TEMPORARY TABLE'),
        "INSERT INTO <%= tableName %>_backup SELECT <%= attributeNames %> FROM <%= tableName %>;",
        "DROP TABLE <%= tableName %>;",
        this.createTableQuery(tableName, attributes),
        "INSERT INTO <%= tableName %> SELECT <%= attributeNames %> FROM <%= tableName %>_backup;",
        "DROP TABLE <%= tableName %>_backup;"
      ].join("");

      return Utils._.template(query, {
        tableName: tableName,
        attributeNames: Utils._.keys(attributes).join(', ')
      });
    },

    renameColumnQuery: function(tableName, attrNameBefore, attrNameAfter, attributes) {
      attributes = this.attributesToSQL(attributes);

      var backupTableName = tableName + "_backup";
      var query = [
        this.createTableQuery(backupTableName, attributes).replace('CREATE TABLE', 'CREATE TEMPORARY TABLE'),
        "INSERT INTO <%= tableName %>_backup SELECT <%= attributeNamesImport %> FROM <%= tableName %>;",
        "DROP TABLE <%= tableName %>;",
        this.createTableQuery(tableName, attributes),
        "INSERT INTO <%= tableName %> SELECT <%= attributeNamesExport %> FROM <%= tableName %>_backup;",
        "DROP TABLE <%= tableName %>_backup;"
      ].join("");

      return Utils._.template(query, {
        tableName: tableName,
        attributeNamesImport: Utils._.keys(attributes).map(function(attr) {
            return (attrNameAfter === attr) ? this.quoteIdentifier(attrNameBefore) + ' AS ' + this.quoteIdentifier(attr) : this.quoteIdentifier(attr);
        }.bind(this)).join(', '),
        attributeNamesExport: Utils._.keys(attributes).map(function(attr) {
            return this.quoteIdentifier(attr);
        }.bind(this)).join(', ')
      });
    },

    startTransactionQuery: function() {
      return "BEGIN TRANSACTION;";
    },

    setAutocommitQuery: function() {
      return "-- SQLite does not support SET autocommit.";
    },

    setIsolationLevelQuery: function(value) {
      switch (value) {
        case Transaction.ISOLATION_LEVELS.REPEATABLE_READ:
          return "-- SQLite is not able to choose the isolation level REPEATABLE READ.";
        case Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED:
          return "PRAGMA read_uncommitted = ON;";
        case Transaction.ISOLATION_LEVELS.READ_COMMITTED:
          return "PRAGMA read_uncommitted = OFF;";
        case Transaction.ISOLATION_LEVELS.SERIALIZABLE:
          return "-- SQLite's default isolation level is SERIALIZABLE. Nothing to do.";
        default:
          throw new Error('Unknown isolation level: ' + value);
      }
    },

    replaceBooleanDefaults: function(sql) {
      return sql.replace(/DEFAULT '?false'?/g, "DEFAULT 0").replace(/DEFAULT '?true'?/g, "DEFAULT 1");
    },

    quoteIdentifier: function(identifier, force) {
      if (identifier === '*') return identifier;
      return Utils.addTicks(identifier, "`");
    },

        /**
     * Generates an SQL query that returns all foreign keys of a table.
     *
     * @param  {String} tableName  The name of the table.
     * @param  {String} schemaName The name of the schema.
     * @return {String}            The generated sql query.
     */
    getForeignKeysQuery: function(tableName, schemaName) {
      var sql = "PRAGMA foreign_key_list(<%= tableName %>)";
      return Utils._.template(sql, { tableName: tableName });
    }
  };

  return Utils._.extend({}, MySqlQueryGenerator, QueryGenerator);
})();
<|endoftext|>


<commit_before>var terminalOpen = false;
var gitHubOpen = false;
var urlCopied = false;
var terminalRightPlace = false;
var gitCloneCommand = false;
var moduleOneComplete = false;
moduleOnePicture.src = "assets/images/desktop.png";

var openTerminal = function (){
  if (terminalOpen === false){
    terminalOpen = true;
    document.getElementById("moduleOneOutput").innerHTML = "You open a terminal!";
    moduleOnePicture.src = "assets/images/openTerminal.png";
  } else {
    document.getElementById("moduleOneOutput").innerHTML = "You already have a terminal open!";
  }
}
 var openGitHub = function(){
  if (gitHubOpen === false){
    gitHubOpen = true;
    document.getElementById("moduleOneOutput").innerHTML = "You open the internet!";
    moduleOnePicture.src = "assets/images/openGitHub.png";
  } else {
    document.getElementById("moduleOneOutput").innerHTML = "You've already opened the internet!";
  }
 }

 var copyURL = function(){
  if ((gitHubOpen === true) && (urlCopied === false)){
    urlCopied = true;
    document.getElementById("moduleOneOutput").innerHTML = "You copy the URL";
    moduleOnePicture.src = "assets/images/copyURL.png";
  } else {
    document.getElementById("moduleOneOutput").innerHTML = "You've already copied the URL!";
  }
 }

var navigateTerminal = function (){
  if ((terminalRightPlace === false) && (terminalOpen === true)){
    terminalRightPlace = true;
    document.getElementById("moduleOneOutput").innerHTML = "Nice! you moved to where you want the file!";
    moduleOnePicture.src = "assets/images/navigateTerminal.png";
  } else if (terminalOpen === false){
    document.getElementById("moduleOneOutput").innerHTML = "Try opening the terminal first!";
  }
  else {
    document.getElementById("moduleOneOutput").innerHTML = "I mean....you already went somewhere, but its cool that you changed your mind. ";
  }
}

var enterGitCloneCommand = function (){
  if ((terminalOpen === true) && (urlCopied === true) && (terminalRightPlace === true)){
     document.getElementById("moduleOneOutput").innerHTML = "Awesome! You got everything just right! You're now the pround owner of a local copy of your repository!";
     moduleOnePicture.src = "assets/images/typeGitClone.png";
     moduleOneComplete = true;
  } else if ((terminalOpen === false) && (urlCopied === true) && (terminalRightPlace === true)){
     document.getElementById("moduleOneOutput").innerHTML = "Your terminal isn't open. Try doing that first.";
  } else if ((terminalOpen === true) && (urlCopied === true) && (terminalRightPlace === false)){
     document.getElementById("moduleOneOutput").innerHTML = "Your terminal is open, and you have your URL. But, you don't have your terminal navigated to where you want it. Try doing that first.";
  } else if ((terminalOpen === true) && (urlCopied === false) && (terminalRightPlace === true)){
     document.getElementById("moduleOneOutput").innerHTML = "You haven't gotten the URL for your repository yet. Go do that, and try again!";
  } else if ((terminalOpen === false) && (urlCopied === false) && (terminalRightPlace === false)){
     document.getElementById("moduleOneOutput").innerHTML = "You haven't done anything yet. Try opening the terminal, and getting the URL for your repository";
  }
  else {
    document.getElementById("moduleOneOutput").innerHTML = "Not ever the devs know whats going on or how you got here. Here there be dragons. Godspeed, foolish mortal.";
  }
}

var reset = function () {
  terminalOpen = false;
  gitHubOpen = false;
  urlCopied = false;
  terminalRightPlace = false;
  gitCloneCommand = false;
  document.getElementById("moduleOneOutput").innerHTML = "You behold your desktop. What do you do?";
  moduleOnePicture.src = "assets/images/desktop.png";
}

<commit_msg>fixed logic gaps<commit_after>var terminalOpen = false;
var gitHubOpen = false;
var urlCopied = false;
var terminalRightPlace = false;
var gitCloneCommand = false;
var moduleOneComplete = false;
moduleOnePicture.src = "assets/images/desktop.png";

var openTerminal = function (){
  if (terminalOpen === false){
    terminalOpen = true;
    document.getElementById("moduleOneOutput").innerHTML = "You open a terminal!";
    moduleOnePicture.src = "assets/images/openTerminal.png";
  } else {
    document.getElementById("moduleOneOutput").innerHTML = "You already have a terminal open!";
  }
}
 var openGitHub = function(){
  if (gitHubOpen === false){
    gitHubOpen = true;
    document.getElementById("moduleOneOutput").innerHTML = "You open the internet!";
    moduleOnePicture.src = "assets/images/openGitHub.png";
  } else {
    document.getElementById("moduleOneOutput").innerHTML = "You've already opened the internet!";
  }
 }

 var copyURL = function(){
  if ((gitHubOpen === true) && (urlCopied === false)){
    urlCopied = true;
    document.getElementById("moduleOneOutput").innerHTML = "You copy the URL";
    moduleOnePicture.src = "assets/images/copyURL.png";
  } else if ((gitHubOpen=== false) && (urlCopied === false)){
    document.getElementById("moduleOneOutput").innerHTML = "Open GitHub first";
  } else if (urlCopied=== true){
    document.getElementById("moduleOneOutput").innerHTML = "You've already copied the URL!";
  }
 }

var navigateTerminal = function (){
  if ((terminalRightPlace === false) && (terminalOpen === true)){
    terminalRightPlace = true;
    document.getElementById("moduleOneOutput").innerHTML = "Nice! you moved to where you want the file!";
    moduleOnePicture.src = "assets/images/navigateTerminal.png";
  } else if (terminalOpen === false){
    document.getElementById("moduleOneOutput").innerHTML = "Try opening the terminal first!";
  }
  else {
    document.getElementById("moduleOneOutput").innerHTML = "I mean....you already went somewhere, but its cool that you changed your mind. ";
  }
}

var enterGitCloneCommand = function (){
  if ((terminalOpen === true) && (urlCopied === true) && (terminalRightPlace === true)){
     document.getElementById("moduleOneOutput").innerHTML = "Awesome! You got everything just right! You're now the pround owner of a local copy of your repository!";
     moduleOnePicture.src = "assets/images/typeGitClone.png";
     moduleOneComplete = true;
  } else if ((terminalOpen === true) && (urlCopied === false) && (terminalRightPlace === false)){
     document.getElementById("moduleOneOutput").innerHTML = "Your terminal is open. Now get your URL and pick where to put the file";
  } else if ((terminalOpen === true) && (urlCopied === true) && (terminalRightPlace === false)){
     document.getElementById("moduleOneOutput").innerHTML = "Your terminal is open, and you have your URL. But, you don't have your terminal navigated to where you want it. Try doing that first.";
  } else if ((terminalOpen === true) && (urlCopied === false) && (terminalRightPlace === true)){
     document.getElementById("moduleOneOutput").innerHTML = "You haven't gotten the URL for your repository yet. Go do that, and try again!";
  } else if ((terminalOpen === false) && (urlCopied === false) && (terminalRightPlace === false)){
     document.getElementById("moduleOneOutput").innerHTML = "You haven't done anything yet. Try opening the terminal, and getting the URL for your repository";
  }else if ((terminalOpen === false) && (urlCopied === true) && (terminalRightPlace === false)){
     document.getElementById("moduleOneOutput").innerHTML = "You haven't opened the terminal, yet. Do that first. ";
  }
  else {
    document.getElementById("moduleOneOutput").innerHTML = "Not ever the devs know whats going on or how you got here. Here there be dragons. Godspeed, foolish mortal.";
  }
}

var reset = function () {
  terminalOpen = false;
  gitHubOpen = false;
  urlCopied = false;
  terminalRightPlace = false;
  gitCloneCommand = false;
  document.getElementById("moduleOneOutput").innerHTML = "You behold your desktop. What do you do?";
  moduleOnePicture.src = "assets/images/desktop.png";
}

<|endoftext|>


<commit_before>//
// new SortingTable( 'my_table', {
//   zebra: true,                        // Stripe the table, also on initialize
//   details: false,                     // Has details every other row
//   paginator: false,                   // Pass a paginator object
//   onSorted: function(){},             // Callback to run after sort
//   dont_sort_class: 'nosort',          // Class name on th's that don't sort
//   forward_sort_class: 'forward_sort', // Class applied to forward sort th's
//   reverse_sort_class: 'reverse_sort'  // Class applied to reverse sort th's
// });
//
// The above were the defaults.  The regexes in load_conversions test a cell
// begin sorted for a match, then use that conversion for all elements on that
// column.
//
// Requires mootools Class, Array, Function, Element, Element.Selectors,
// Element.Event, and you should probably get Window.DomReady if you're smart.
//

var SortingTable = new Class({

  Implements: [Options, Events],

  options: {
    zebra: true,
    details: false,
    paginator: false,
    onSorted: $empty,
    dont_sort_class: 'nosort',
    forward_sort_class: 'forward_sort',
    reverse_sort_class: 'reverse_sort'
  },

  initialize: function( table, options ) {
    this.table = $(table);
    this.setOptions(options);

    this.tbody = this.table.getElement('tbody');
    if (this.options.zebra) {
      SortingTable.stripe_table(this.tbody.getChildren());
    }

    this.headers = this.table.getElement('thead').getElements('th');
    this.headers.each(function( header, index ) {
      if (header.hasClass( this.options.dont_sort_class )) { return }
      header.store( 'column', index )
      header.addEvent( 'mousedown', function(evt){
        this.sort_by_header( evt.target );
        if ( this.options.paginator) this.options.paginator.to_page( 1 );
      }.bind( this ) );
    }, this);

    this.load_conversions();
  },

  sort_by_header: function( header ){
    var rows = [];

    var before = this.tbody.getPrevious();
    this.tbody.dispose();

    var trs = this.tbody.getChildren();
    while ( row = trs.shift() ) {
      row = { row: row.dispose() };
      if ( this.options.details ) {
        row.detail = trs.shift().dispose();
      }
      rows.unshift( row );
    }

    if ( this.sort_column >= 0 &&
         this.sort_column == header.retrieve('column') ) {
      // They were pulled off in reverse
      if ( header.hasClass( this.options.reverse_sort_class ) ) {
        header.removeClass( this.options.reverse_sort_class );
        header.addClass( this.options.forward_sort_class );
      } else {
        header.removeClass( this.options.forward_sort_class );
        header.addClass( this.options.reverse_sort_class );
      }
    } else {
      this.headers.each(function(h){
        h.removeClass( this.options.forward_sort_class );
        h.removeClass( this.options.reverse_sort_class );
      }, this);
      this.sort_column = header.retrieve('column');
      if (header.retrieve('conversion_function')) {
        this.conversion_matcher = header.retrieve('conversion_matcher');
        this.conversion_function = header.retrieve('conversion_function');
      } else {
        this.conversion_function = false;
        rows.some(function(row){
          var to_match = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          if (to_match == '') return false;
          this.conversions.some(function(conversion){
            if (conversion.matcher.test( to_match )){
              this.conversion_matcher = conversion.matcher;
              this.conversion_function = conversion.conversion_function;
              return true;
            }
            return false;
          }, this);
          return !!(this.conversion_function);
        }, this);
        header.store('conversion_function', this.conversion_function );
        header.store('conversion_matcher', this.conversion_matcher );
      }
      header.addClass( this.options.forward_sort_class );
      rows.each(function(row){
        var compare_value = this.conversion_function( row );
        row.toString = function(){
          return compare_value;
        };
      }, this);
      rows.sort();
    }

    var index = 0;
    while ( row = rows.shift() ) {
      this.tbody.appendChild(row.row);
      if (row.detail) this.tbody.appendChild(row.detail);
      if ( this.options.zebra ) {
        row.row.className = row.row.className.replace( this.removeAltClassRe, '$1').clean();
        if (row.detail)
          row.detail.className = row.detail.className.replace( this.removeAltClassRe, '$1').clean();
        if (index % 2) {
          row.row.addClass( 'alt' );
          if (row.detail) row.detail.addClass( 'alt' );
        }
      }
      index++;
    }
   this.tbody.inject(before, 'after');
   this.fireEvent('sorted', this);
  },

  load_conversions: function() {
    this.conversions = $A([
      // 1.75 MB, 301 GB, 34 KB, 8 TB
      { matcher: /([0-9.]{1,8}).*([KMGT]{1})B/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = this.conversion_matcher.exec( cell );
          if (!cell) { return '0' }
          if (cell[2] == 'M') {
            sort_val = '1';
          } else if (cell[2] == 'G') {
            sort_val = '2';
          } else if (cell[2] == 'T') {
            sort_val = '3';
          } else {
            sort_val = '0';
          }
          var i = cell[1].indexOf('.')
          if (i == -1) {
            post = '00'
          } else {
            var dec = cell[1].split('.');
            cell[1] = dec[0];
            post = dec[1].concat('00'.substr(0,2-dec[1].length));
          }
          return sort_val.concat('00000000'.substr(0,2-cell[1].length).concat(cell[1])).concat(post);
        }
      },
      // 1 day ago, 4 days ago, 38 years ago, 1 month ago
      { matcher: /(\d{1,2}) (.{3,6}) ago/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = this.conversion_matcher.exec( cell );
          if (!cell) { return '0' }
          var sort_val;
          if (cell[2].indexOf('month') != -1) {
            sort_val = '1';
          } else if (cell[2].indexOf('year') != -1) {
            sort_val = '2';
          } else {
            sort_val = '0';
          }
          return sort_val.concat('00'.substr(0,2-cell[1].length).concat(cell[1]));
        }
      },
      // Currency, or floating point with precision up to .00
      { matcher:  /^[^\d]?((\d+|,\d{3})*(\.\d{1,2})?)$/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = parseFloat(cell.replace(/^[^\d]/, "").replace(/,/g, ""));
          if (isNaN(cell)) { cell = 0; }
          cell = Math.round((cell * 100)).toString();
          return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
        }
      },
      // YYYY-MM-DD, YYYY-m-d
      { matcher: /(\d{4})-(\d{1,2})-(\d{1,2})/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = this.conversion_matcher.exec( cell );
          return cell[1]+
                 '00'.substr(0,2-cell[2].length).concat(cell[2])+
                 '00'.substr(0,2-cell[3].length).concat(cell[3]);
        }
      },
      // Numbers
      { matcher: /^\d+$/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
        }
      },
      // Fallback
      { matcher: /.*/,
        conversion_function: function( row ) {
          return $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
        }
      }
    ]);
  }

});

SortingTable.removeAltClassRe = new RegExp('(^|\\s)alt(?:\\s|$)');
SortingTable.implement({ removeAltClassRe: SortingTable.removeAltClassRe });

SortingTable.stripe_table = function ( tr_elements  ) {
  var counter = 0;
  tr_elements.each( function( tr ) {
    if ( !tr.hasClass('collapsed') ) counter++;
    tr.className = tr.className.replace( this.removeAltClassRe, '$1').clean();
    if (counter % 2) tr.addClass( 'alt' );
  });
}
<commit_msg>Handle empty date cells as the lowest possible value.  Resolves Issue #6<commit_after>//
// new SortingTable( 'my_table', {
//   zebra: true,                        // Stripe the table, also on initialize
//   details: false,                     // Has details every other row
//   paginator: false,                   // Pass a paginator object
//   onSorted: function(){},             // Callback to run after sort
//   dont_sort_class: 'nosort',          // Class name on th's that don't sort
//   forward_sort_class: 'forward_sort', // Class applied to forward sort th's
//   reverse_sort_class: 'reverse_sort'  // Class applied to reverse sort th's
// });
//
// The above were the defaults.  The regexes in load_conversions test a cell
// begin sorted for a match, then use that conversion for all elements on that
// column.
//
// Requires mootools Class, Array, Function, Element, Element.Selectors,
// Element.Event, and you should probably get Window.DomReady if you're smart.
//

var SortingTable = new Class({

  Implements: [Options, Events],

  options: {
    zebra: true,
    details: false,
    paginator: false,
    onSorted: $empty,
    dont_sort_class: 'nosort',
    forward_sort_class: 'forward_sort',
    reverse_sort_class: 'reverse_sort'
  },

  initialize: function( table, options ) {
    this.table = $(table);
    this.setOptions(options);

    this.tbody = this.table.getElement('tbody');
    if (this.options.zebra) {
      SortingTable.stripe_table(this.tbody.getChildren());
    }

    this.headers = this.table.getElement('thead').getElements('th');
    this.headers.each(function( header, index ) {
      if (header.hasClass( this.options.dont_sort_class )) { return }
      header.store( 'column', index )
      header.addEvent( 'mousedown', function(evt){
        this.sort_by_header( evt.target );
        if ( this.options.paginator) this.options.paginator.to_page( 1 );
      }.bind( this ) );
    }, this);

    this.load_conversions();
  },

  sort_by_header: function( header ){
    var rows = [];

    var before = this.tbody.getPrevious();
    this.tbody.dispose();

    var trs = this.tbody.getChildren();
    while ( row = trs.shift() ) {
      row = { row: row.dispose() };
      if ( this.options.details ) {
        row.detail = trs.shift().dispose();
      }
      rows.unshift( row );
    }

    if ( this.sort_column >= 0 &&
         this.sort_column == header.retrieve('column') ) {
      // They were pulled off in reverse
      if ( header.hasClass( this.options.reverse_sort_class ) ) {
        header.removeClass( this.options.reverse_sort_class );
        header.addClass( this.options.forward_sort_class );
      } else {
        header.removeClass( this.options.forward_sort_class );
        header.addClass( this.options.reverse_sort_class );
      }
    } else {
      this.headers.each(function(h){
        h.removeClass( this.options.forward_sort_class );
        h.removeClass( this.options.reverse_sort_class );
      }, this);
      this.sort_column = header.retrieve('column');
      if (header.retrieve('conversion_function')) {
        this.conversion_matcher = header.retrieve('conversion_matcher');
        this.conversion_function = header.retrieve('conversion_function');
      } else {
        this.conversion_function = false;
        rows.some(function(row){
          var to_match = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          if (to_match == '') return false;
          this.conversions.some(function(conversion){
            if (conversion.matcher.test( to_match )){
              this.conversion_matcher = conversion.matcher;
              this.conversion_function = conversion.conversion_function;
              return true;
            }
            return false;
          }, this);
          return !!(this.conversion_function);
        }, this);
        header.store('conversion_function', this.conversion_function );
        header.store('conversion_matcher', this.conversion_matcher );
      }
      header.addClass( this.options.forward_sort_class );
      rows.each(function(row){
        var compare_value = this.conversion_function( row );
        row.toString = function(){
          return compare_value;
        };
      }, this);
      rows.sort();
    }

    var index = 0;
    while ( row = rows.shift() ) {
      this.tbody.appendChild(row.row);
      if (row.detail) this.tbody.appendChild(row.detail);
      if ( this.options.zebra ) {
        row.row.className = row.row.className.replace( this.removeAltClassRe, '$1').clean();
        if (row.detail)
          row.detail.className = row.detail.className.replace( this.removeAltClassRe, '$1').clean();
        if (index % 2) {
          row.row.addClass( 'alt' );
          if (row.detail) row.detail.addClass( 'alt' );
        }
      }
      index++;
    }
   this.tbody.inject(before, 'after');
   this.fireEvent('sorted', this);
  },

  load_conversions: function() {
    this.conversions = $A([
      // 1.75 MB, 301 GB, 34 KB, 8 TB
      { matcher: /([0-9.]{1,8}).*([KMGT]{1})B/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = this.conversion_matcher.exec( cell );
          if (!cell) { return '0' }
          if (cell[2] == 'M') {
            sort_val = '1';
          } else if (cell[2] == 'G') {
            sort_val = '2';
          } else if (cell[2] == 'T') {
            sort_val = '3';
          } else {
            sort_val = '0';
          }
          var i = cell[1].indexOf('.')
          if (i == -1) {
            post = '00'
          } else {
            var dec = cell[1].split('.');
            cell[1] = dec[0];
            post = dec[1].concat('00'.substr(0,2-dec[1].length));
          }
          return sort_val.concat('00000000'.substr(0,2-cell[1].length).concat(cell[1])).concat(post);
        }
      },
      // 1 day ago, 4 days ago, 38 years ago, 1 month ago
      { matcher: /(\d{1,2}) (.{3,6}) ago/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = this.conversion_matcher.exec( cell );
          if (!cell) { return '0' }
          var sort_val;
          if (cell[2].indexOf('month') != -1) {
            sort_val = '1';
          } else if (cell[2].indexOf('year') != -1) {
            sort_val = '2';
          } else {
            sort_val = '0';
          }
          return sort_val.concat('00'.substr(0,2-cell[1].length).concat(cell[1]));
        }
      },
      // Currency, or floating point with precision up to .00
      { matcher:  /^[^\d]?((\d+|,\d{3})*(\.\d{1,2})?)$/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          cell = parseFloat(cell.replace(/^[^\d]/, "").replace(/,/g, ""));
          if (isNaN(cell)) { cell = 0; }
          cell = Math.round((cell * 100)).toString();
          return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
        }
      },
      // YYYY-MM-DD, YYYY-m-d
      { matcher: /(\d{4})-(\d{1,2})-(\d{1,2})/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          if (cell && cell.length > 0) {
            cell = this.conversion_matcher.exec( cell );
            return cell[1]+
                   '00'.substr(0,2-cell[2].length).concat(cell[2])+
                   '00'.substr(0,2-cell[3].length).concat(cell[3]);
          } else {
            return '';
          }
        }
      },
      // Numbers
      { matcher: /^\d+$/,
        conversion_function: function( row ) {
          var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
          return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
        }
      },
      // Fallback
      { matcher: /.*/,
        conversion_function: function( row ) {
          return $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
        }
      }
    ]);
  }

});

SortingTable.removeAltClassRe = new RegExp('(^|\\s)alt(?:\\s|$)');
SortingTable.implement({ removeAltClassRe: SortingTable.removeAltClassRe });

SortingTable.stripe_table = function ( tr_elements  ) {
  var counter = 0;
  tr_elements.each( function( tr ) {
    if ( !tr.hasClass('collapsed') ) counter++;
    tr.className = tr.className.replace( this.removeAltClassRe, '$1').clean();
    if (counter % 2) tr.addClass( 'alt' );
  });
}
<|endoftext|>


<commit_before>"use strict";

(function() {

	/**
	 * A simple buffer to abstract data types away
	 *
	 * @constructor
	 * @param {Array.<number>=} arr
	 */
	function Buffer(arr) {
		this.buffer = arr ? arr : [];

	}
	Object.defineProperty(Buffer.prototype, 'length', {get: function() { return this.buffer.length; },
	                               		   			   enumerable : false});
	/**
	 * @param {Array.<number>} arr
	 */
	Buffer.prototype.appendArray = function(arr) {
		this.buffer.push.apply(this.buffer, arr);
	};

	/**
	 * @param {number} idx
	 * @param {number} num
	 */
	Buffer.prototype.writeShort = function(idx, num) {
		this.buffer[idx] = num & 255;
		this.buffer[idx + 1] = (num >> 8) & 255;
	};

	/**
	 * @param {number} idx
	 * @param {number} num
	 */
	Buffer.prototype.writeInt = function(idx, num) {
		this.buffer[idx] = num & 255;
		this.buffer[idx + 1] = (num >> 8) & 255;
		this.buffer[idx + 2] = (num >> 16) & 255;
		this.buffer[idx + 3] = (num >> 24) & 255;
	};

	/**
	 * @param {number} idx
	 * @param {number} num
	 */
	Buffer.prototype.writeLong = function(idx, num) {
		this.buffer[idx] = num & 255;
		this.buffer[idx + 1] = (num >> 8) & 255;
		this.buffer[idx + 2] = (num >> 16) & 255;
		this.buffer[idx + 3] = (num >> 24) & 255;
		this.buffer[idx + 4] = 0;
		this.buffer[idx + 5] = 0;
		this.buffer[idx + 6] = 0;
		this.buffer[idx + 7] = 0;
	};

	/**
	 * @param {number} idx
	 * @param {string} str
	 */
	Buffer.prototype.writeString = function(idx, str) {
		for (var i=0; i < str.length; ++i) {
			this.buffer[idx + i] = str.charCodeAt(i) & 255;
		}
	};

	/**
	 * @param {number} idx
	 * @param {Buffer} buf
	 */
	Buffer.prototype.writeBuffer = function(idx, buf) {
		for (var i=0; i < buf.length; ++i) {
			this.buffer[idx + i] = buf.buffer[i];
		}
	};

	Buffer.prototype.toString = function() {
		var str = '';
		for (var i=0; i < this.buffer.length; ++i) {
			var numStr = this.buffer[i].toString(16);
			str += '%' + (numStr.length == 1 ? '0' + numStr : numStr);
		}
		return str;
	};

	/**
	 * @constructor
	 * @param {string} id
	 */
	function Chunk(id) {
		this.id = id;
		this.data = new Buffer();
	};

	Chunk.prototype.getBuffer = function() {
		var buffer = new Buffer();
		buffer.writeString(0, this.id);
		buffer.writeInt(4, this.data.length);
		buffer.writeBuffer(8, this.data);
		return buffer;
	};

	/**
	 * @constructor
 	 * @param {string} type
	 */
	function List(type) {
		this.type = type;
		this.elements = [];
	};

	List.prototype.getBuffer = function() {
		var buffer = new Buffer();
		buffer.writeString(0, 'LIST');
		buffer.writeString(8, this.type);

		var len = 4;
		for (var i=0; i < this.elements.length; ++i) {
			var buf = this.elements[i].getBuffer();
			buffer.writeBuffer(len + 8, buf);
			len += buf.length;
		}

		buffer.writeInt(4, len);
		return buffer;
	};

	/**
	 * @constructor
	 */
	function AVIJS() {
		this.settings = {
			width: 5,
			height: 5,
			framesPerSecond: 20
		};

		this.streams = [];
	};

	AVIJS.prototype.getBuffer = function() {
		var buffer = new Buffer();
		buffer.writeString(0, 'RIFF');
		buffer.writeString(8, 'AVI ');
		var len = 4;
		var frames = 0;
		for (var i=0; i < this.streams.length; ++i) {
			frames += this.streams[i].frames.length;
		}

		var hdrl = new List('hdrl');
		var avih = new Chunk('avih');
		avih.data.writeInt(0, 66665);
		avih.data.writeInt(4, 0); // MaxBytesPerSec
		avih.data.writeInt(8, 1); // Padding (in bytes)
		avih.data.writeInt(12, 0); // Flags
		avih.data.writeInt(16, frames); // Total Frames
		avih.data.writeInt(20, 0); // Initial Frames
		avih.data.writeInt(24, this.streams.length); // Total Streams
		avih.data.writeInt(28, 0); // Suggested Buffer size
		avih.data.writeInt(32, this.settings.width); // pixel width
		avih.data.writeInt(36, this.settings.height); // pixel height
		avih.data.writeInt(40, 0); // Reserved int[4]
		avih.data.writeInt(44, 0);
		avih.data.writeInt(48, 0);
		avih.data.writeInt(52, 0);
		hdrl.elements.push(avih);

		for (var i=0; i < this.streams.length; ++i) {
			hdrl.elements.push(this.streams[i].getHeaderBuffer());
		}
		var hdrlBuf = hdrl.getBuffer();
		buffer.writeBuffer(8 + len, hdrlBuf);
		len += hdrlBuf.length;

		var movi = new List('movi');
		for (var i=0; i < this.streams.length; ++i) {
			movi.elements.push(this.streams[i].getDataBuffer(i));
		}

		var moviBuf = movi.getBuffer();
		buffer.writeBuffer(8 + len, moviBuf);
		len += moviBuf.length;

		buffer.writeInt(4, len);
		return buffer.toString();
	};

	/**
	 * @constructor
 	 * @param {number} fps
	 */
	AVIJS.Stream = function(fps, width, height) {
		this.fps = fps;
		this.width = width;
		this.height = height;
		this.frames = [];
	};

	AVIJS.Stream.prototype.addFrame = function(imgData) {
		var frame = [];
		for (var i=0; i < imgData.length; i += 4) {
			frame.push(imgData[i], imgData[i+1], imgData[i+2],0);
		}
		this.frames.push(frame);
	};

	AVIJS.Stream.prototype.getHeaderBuffer = function() {
		var list = new List('strl');
		var strh = new Chunk('strh');
		strh.data.writeString(0, 'vids'); // fourCC
		strh.data.writeString(4, 'DIB '); // Uncompressed
		strh.data.writeInt(8, 0); // Flags
		strh.data.writeShort(12, 1); // Priority
		strh.data.writeShort(14, 0); // Language
		strh.data.writeInt(16, 0); // Initial frames
		strh.data.writeInt(20, 1); // Scale
		strh.data.writeInt(24, this.fps); // Rate
		strh.data.writeInt(28, 0); // Startdelay
		strh.data.writeInt(32, 0); // Length
		strh.data.writeInt(36, 0); // suggested buffer size
		strh.data.writeInt(40, -1); // quality
		strh.data.writeInt(44, 0); // sampleSize
		strh.data.writeInt(48, 0); // Rect left
		strh.data.writeInt(52, 0); // Rect top
		strh.data.writeInt(56, this.width); // Rect width
		strh.data.writeInt(60, this.height); // Rect height
		list.elements.push(strh);

		var strf = new Chunk('strf');
		strf.data.writeLong(0, this.width); // width
		strf.data.writeLong(8, this.height); // height
		strf.data.writeShort(16, 1); // planes
		strf.data.writeShort(18, 32); // bits per pixel
		strf.data.writeInt(20, 0); // compression
		strf.data.writeInt(24, 0); // image size
		strf.data.writeLong(28, 0); // x pixels per meter
		strf.data.writeLong(36, 0); // y pixels per meter
		strf.data.writeInt(44, 0); // colortable used
		strf.data.writeInt(48, 0); // colortable important
		list.elements.push(strf);

		return list;
	};

	AVIJS.Stream.prototype.getDataBuffer = function(idx) {
		var chk = new Chunk((idx < 10 ? '0' + idx : idx) + 'db');
		for (var i=0; i < this.frames.length; ++i) {
			chk.data.appendArray(this.frames[i]);
		}
		return chk;
	};

	window['AVIJS'] = AVIJS;
})();<commit_msg>Fixed a few data type mistakes.<commit_after>"use strict";

(function() {

	/**
	 * A simple buffer to abstract data types away
	 *
	 * @constructor
	 * @param {Array.<number>=} arr
	 */
	function Buffer(arr) {
		this.buffer = arr ? arr : [];

	}
	Object.defineProperty(Buffer.prototype, 'length', {get: function() { return this.buffer.length; },
	                               		   			   enumerable : false});
	/**
	 * @param {Array.<number>} arr
	 */
	Buffer.prototype.appendArray = function(arr) {
		this.buffer.push.apply(this.buffer, arr);
	};

	/**
	 * @param {number} idx
	 * @param {number} num
	 */
	Buffer.prototype.writeShort = function(idx, num) {
		this.buffer[idx] = num & 255;
		this.buffer[idx + 1] = (num >> 8) & 255;
	};

	/**
	 * @param {number} idx
	 * @param {number} num
	 */
	Buffer.prototype.writeInt = function(idx, num) {
		this.buffer[idx] = num & 255;
		this.buffer[idx + 1] = (num >> 8) & 255;
		this.buffer[idx + 2] = (num >> 16) & 255;
		this.buffer[idx + 3] = (num >> 24) & 255;
	};

	/**
	 * @param {number} idx
	 * @param {string} str
	 */
	Buffer.prototype.writeString = function(idx, str) {
		for (var i=0; i < str.length; ++i) {
			this.buffer[idx + i] = str.charCodeAt(i) & 255;
		}
	};

	/**
	 * @param {number} idx
	 * @param {Buffer} buf
	 */
	Buffer.prototype.writeBuffer = function(idx, buf) {
		for (var i=0; i < buf.length; ++i) {
			this.buffer[idx + i] = buf.buffer[i];
		}
	};

	Buffer.prototype.toString = function() {
		var str = '';
		for (var i=0; i < this.buffer.length; ++i) {
			var numStr = this.buffer[i].toString(16);
			str += '%' + (numStr.length == 1 ? '0' + numStr : numStr);
		}
		return str;
	};

	/**
	 * @constructor
	 * @param {string} id
	 */
	function Chunk(id) {
		this.id = id;
		this.data = new Buffer();
	};

	Chunk.prototype.getBuffer = function() {
		var buffer = new Buffer();
		buffer.writeString(0, this.id);
		buffer.writeInt(4, this.data.length);
		buffer.writeBuffer(8, this.data);
		return buffer;
	};

	/**
	 * @constructor
 	 * @param {string} type
	 */
	function List(type) {
		this.type = type;
		this.elements = [];
	};

	List.prototype.getBuffer = function() {
		var buffer = new Buffer();
		buffer.writeString(0, 'LIST');
		buffer.writeString(8, this.type);

		var len = 4;
		for (var i=0; i < this.elements.length; ++i) {
			var buf = this.elements[i].getBuffer();
			buffer.writeBuffer(len + 8, buf);
			len += buf.length;
		}

		buffer.writeInt(4, len);
		return buffer;
	};

	/**
	 * @constructor
	 */
	function AVIJS() {
		this.settings = {
			width: 5,
			height: 5,
			framesPerSecond: 20
		};

		this.streams = [];
	};

	AVIJS.prototype.getBuffer = function() {
		var buffer = new Buffer();
		buffer.writeString(0, 'RIFF');
		buffer.writeString(8, 'AVI ');
		var len = 4;
		var frames = 0;
		for (var i=0; i < this.streams.length; ++i) {
			frames += this.streams[i].frames.length;
		}

		var hdrl = new List('hdrl');
		var avih = new Chunk('avih');
		avih.data.writeInt(0, 66665);
		avih.data.writeInt(4, 0); // MaxBytesPerSec
		avih.data.writeInt(8, 1); // Padding (in bytes)
		avih.data.writeInt(12, 0); // Flags
		avih.data.writeInt(16, frames); // Total Frames
		avih.data.writeInt(20, 0); // Initial Frames
		avih.data.writeInt(24, this.streams.length); // Total Streams
		avih.data.writeInt(28, 0); // Suggested Buffer size
		avih.data.writeInt(32, this.settings.width); // pixel width
		avih.data.writeInt(36, this.settings.height); // pixel height
		avih.data.writeInt(40, 0); // Reserved int[4]
		avih.data.writeInt(44, 0);
		avih.data.writeInt(48, 0);
		avih.data.writeInt(52, 0);
		hdrl.elements.push(avih);

		for (var i=0; i < this.streams.length; ++i) {
			hdrl.elements.push(this.streams[i].getHeaderBuffer());
		}
		var hdrlBuf = hdrl.getBuffer();
		buffer.writeBuffer(8 + len, hdrlBuf);
		len += hdrlBuf.length;

		var movi = new List('movi');
		for (var i=0; i < this.streams.length; ++i) {
			movi.elements.push(this.streams[i].getDataBuffer(i));
		}

		var moviBuf = movi.getBuffer();
		buffer.writeBuffer(8 + len, moviBuf);
		len += moviBuf.length;

		buffer.writeInt(4, len);
		return buffer.toString();
	};

	/**
	 * @constructor
 	 * @param {number} fps
	 */
	AVIJS.Stream = function(fps, width, height) {
		this.fps = fps;
		this.width = width;
		this.height = height;
		this.frames = [];
	};

	AVIJS.Stream.prototype.addFrame = function(imgData) {
		var frame = [];
		for (var i=0; i < imgData.length; i += 4) {
			frame.push(imgData[i], imgData[i+1], imgData[i+2],0);
		}
		this.frames.push(frame);
	};

	AVIJS.Stream.prototype.getHeaderBuffer = function() {
		var list = new List('strl');
		var strh = new Chunk('strh');
		strh.data.writeString(0, 'vids'); // fourCC
		strh.data.writeString(4, 'DIB '); // Uncompressed
		strh.data.writeInt(8, 0); // Flags
		strh.data.writeShort(12, 1); // Priority
		strh.data.writeShort(14, 0); // Language
		strh.data.writeInt(16, 0); // Initial frames
		strh.data.writeInt(20, 1); // Scale
		strh.data.writeInt(24, this.fps); // Rate
		strh.data.writeInt(28, 0); // Startdelay
		strh.data.writeInt(32, 0); // Length
		strh.data.writeInt(36, 0); // suggested buffer size
		strh.data.writeInt(40, -1); // quality
		strh.data.writeInt(44, 0); // sampleSize
		strh.data.writeShort(48, 0); // Rect left
		strh.data.writeShort(50, 0); // Rect top
		strh.data.writeShort(52, this.width); // Rect width
		strh.data.writeShort(54, this.height); // Rect height
		list.elements.push(strh);

		var strf = new Chunk('strf');
		strf.data.writeInt(0, 40); // struct size
		strf.data.writeInt(4, this.width); // width
		strf.data.writeInt(8, this.height); // height
		strf.data.writeShort(12, 1); // planes
		strf.data.writeShort(14, 32); // bits per pixel
		strf.data.writeInt(16, 0); // compression
		strf.data.writeInt(20, 0); // image size
		strf.data.writeInt(24, 0); // x pixels per meter
		strf.data.writeInt(28, 0); // y pixels per meter
		strf.data.writeInt(32, 0); // colortable used
		strf.data.writeInt(36, 0); // colortable important
		list.elements.push(strf);

		return list;
	};

	AVIJS.Stream.prototype.getDataBuffer = function(idx) {
		var chk = new Chunk((idx < 10 ? '0' + idx : idx) + 'db');
		for (var i=0; i < this.frames.length; ++i) {
			chk.data.appendArray(this.frames[i]);
		}
		return chk;
	};

	window['AVIJS'] = AVIJS;
})();<|endoftext|>


<commit_before>'use strict';

var KnockoutComponent = require( 'br/knockout/KnockoutComponent' );
var ServiceRegistry = require( 'br/ServiceRegistry' );

// Blades
var OSInfoBlade = require( 'dashboard/osinfo/OsinfoViewModel' );
var BrjsvctViewBlade = require( 'dashboard/brjsvct/BrjsvctViewModel' );
var BrjsVersionsViewBlade = require( 'dashboard/brjsversions/BrjsversionsViewModel' );
var PopularcommandsViewBlade = require( 'dashboard/popularcommands/PopularcommandsViewModel' );
var AvgfilesinappViewBlade = require( 'dashboard/avgfilesinapp/AvgfilesinappViewModel' );
var AverageBundlesetDuration = require( 'dashboard/avgbundlesetduration/AverageBundlesetDurationViewModel' );
var ActivitylogViewBlade = require( 'dashboard/activitylog/ActivitylogViewModel' );

var App = function() {
  var StatsService = require( 'statservice/Service' );
  var statService = new StatsService();
  ServiceRegistry.registerService( 'stat.service', statService );

  this._statsEl = document.getElementById("stats");

  this._addBladeToUI( OSInfoBlade, 'dashboard.osinfo.view-template' );
  this._addBladeToUI( BrjsvctViewBlade, 'dashboard.brjsvct.view-template' );
  this._addBladeToUI( BrjsVersionsViewBlade, 'dashboard.brjsversions.view-template' );
  this._addBladeToUI( PopularcommandsViewBlade, 'dashboard.popularcommands.view-template' );
  this._addBladeToUI( AvgfilesinappViewBlade, 'dashboard.avgfilesinapp.view-template' );
  this._addBladeToUI( AverageBundlesetDuration, 'dashboard.avgbundlesetduration.view-template' );

  this._addBladeToUI( ActivitylogViewBlade, 'dashboard.activitylog.view-template' );
};

App.prototype._addBladeToUI = function( BladeDefinition, viewId ) {
  var blade = new BladeDefinition();
  var component = new KnockoutComponent( viewId, blade );
  this._statsEl.appendChild( component.getElement() );
};

module.exports = App;
<commit_msg>google charts library check-hack<commit_after>'use strict';

var KnockoutComponent = require( 'br/knockout/KnockoutComponent' );
var ServiceRegistry = require( 'br/ServiceRegistry' );

// Blades
var OSInfoBlade = require( 'dashboard/osinfo/OsinfoViewModel' );
var BrjsvctViewBlade = require( 'dashboard/brjsvct/BrjsvctViewModel' );
var BrjsVersionsViewBlade = require( 'dashboard/brjsversions/BrjsversionsViewModel' );
var PopularcommandsViewBlade = require( 'dashboard/popularcommands/PopularcommandsViewModel' );
var AvgfilesinappViewBlade = require( 'dashboard/avgfilesinapp/AvgfilesinappViewModel' );
var AverageBundlesetDuration = require( 'dashboard/avgbundlesetduration/AverageBundlesetDurationViewModel' );
var ActivitylogViewBlade = require( 'dashboard/activitylog/ActivitylogViewModel' );

var App = function() {
  var StatsService = require( 'statservice/Service' );
  var statService = new StatsService();
  ServiceRegistry.registerService( 'stat.service', statService );

  this._statsEl = document.getElementById("stats");

  // Hack: Keen uses Google charts and we're occasionally seeing
  // a problem where the google library hasn't yet loaded.
  var waitForGoogle = setInterval( function() {
    if( typeof google !== 'undefined' ) {
      this._addBlades();
      clearInterval( waitForGoogle );
    }
  }.bind( this ), 200 );
};

App.prototype._addBlades = function() {
  this._addBladeToUI( OSInfoBlade, 'dashboard.osinfo.view-template' );
  this._addBladeToUI( BrjsvctViewBlade, 'dashboard.brjsvct.view-template' );
  this._addBladeToUI( BrjsVersionsViewBlade, 'dashboard.brjsversions.view-template' );
  this._addBladeToUI( PopularcommandsViewBlade, 'dashboard.popularcommands.view-template' );
  this._addBladeToUI( AvgfilesinappViewBlade, 'dashboard.avgfilesinapp.view-template' );
  this._addBladeToUI( AverageBundlesetDuration, 'dashboard.avgbundlesetduration.view-template' );

  this._addBladeToUI( ActivitylogViewBlade, 'dashboard.activitylog.view-template' );
};

App.prototype._addBladeToUI = function( BladeDefinition, viewId ) {
  var blade = new BladeDefinition();
  var component = new KnockoutComponent( viewId, blade );
  this._statsEl.appendChild( component.getElement() );
};

module.exports = App;
<|endoftext|>


<commit_before>import React from 'react'
import styled from 'styled-components'

import { Intro, CheckboxTree } from './components'
import data from './data/data.json'
import github from './assets/github.svg'

const Section = styled.section`
  display: flex;
  flex-direction: column;
  width: 80%;
  max-width: 64rem;
  height: 100vh;
  margin: 0 auto;
`

const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  flex: 1;
  margin-top: 2rem;
  overflow: auto;
`

const Footer = styled.div`
  align-self: center;
  margin: 2rem;
`

export const App = () => (

      <Wrapper>
        <Intro />
        <CheckboxTree data={data} />
      </Wrapper>

)
<commit_msg>Remove redundant role<commit_after>import React from 'react'
import styled from 'styled-components'

import { Intro, CheckboxTree } from './components'
import data from './data/data.json'
import github from './assets/github.svg'

const Section = styled.section`
  display: flex;
  flex-direction: column;
  width: 80%;
  max-width: 64rem;
  height: 100vh;
  margin: 0 auto;
`

const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  flex: 1;
  margin-top: 2rem;
  overflow: auto;
`

const Footer = styled.div`
  align-self: center;
  margin: 2rem;
`

export const App = () => (

      <Wrapper>
        <Intro />
        <CheckboxTree data={data} />
      </Wrapper>

)
<|endoftext|>