<commit_before>const fs     = require("fs")
    , path   = require("path")
    , moment = require("moment")

var Utils          = require("./utils")
  , Migration      = require("./migration")
  , DataTypes      = require("./data-types")

module.exports = (function() {
  var Migrator = function(sequelize, options) {
    this.sequelize = sequelize
    this.options   = Utils._.extend({
      path: __dirname + '/../migrations',
      from: null,
      to: null,
      logging: true
    }, options || {})
  }

  Object.defineProperty(Migrator.prototype, "queryInterface", {
    get: function() {
      return this.sequelize.getQueryInterface()
    }
  })

  Migrator.prototype.migrate = function(options) {
    var self = this

    options = Utils._.extend({
      method: 'up'
    }, options || {})

    return new Utils.CustomEventEmitter(function(emitter) {
      self.getUndoneMigrations(function(err, migrations) {
        if(err) {
          emitter.emit('failure', err)
        } else {
          var chainer = new Utils.QueryChainer

          if(options.method == 'down')
            migrations.reverse()

          migrations.forEach(function(migration) {
            chainer.add(migration, 'execute', [options], {
              before: function(migration) {
                if(self.options.logging)
                  console.log('Executing migration: ' + migration.filename)
              },
              after: function(migration) {
                if(self.options.logging)
                  console.log('Executed migration: ' + migration.filename)
              },
              success: function(migration, callback) {
                saveSuccessfulMigration.call(self, migrations[0], migration, callback)
              }
            })
          })

          chainer
            .runSerially({ skipOnError: true })
            .success(function() { emitter.emit('success', null) })
            .error(function(err) { emitter.emit('failure', err) })
        }
      })
    }).run()
  }

  Migrator.prototype.getUndoneMigrations = function(callback)  {
    var self = this

    var filterFrom = function(migrations, from, callback, options) {
      var result = migrations.filter(function(migration) { return migration.isAfter(from, options) })
      callback && callback(null, result)
    }
    var filterTo = function(migrations, to, callback, options) {
      var result = migrations.filter(function(migration) { return migration.isBefore(to, options) })
      callback && callback(null, result)
    }

    var migrationFiles = fs.readdirSync(this.options.path)

    var migrations = migrationFiles.map(function(file) {
      return new Migration(self, self.options.path + '/' + file)
    })

    migrations = migrations.sort(function(a,b){
      return parseInt(a.filename.split('-')[0]) - parseInt(b.filename.split('-')[0])
    })

    if(this.options.from) {
      filterFrom(migrations, this.options.from, function(err, migrations) {
        if(self.options.to)
          filterTo(migrations, self.options.to, callback)
        else
          callback && callback(null, migrations)
      })
    } else {
      getLastMigrationIdFromDatabase.call(this).success(function(lastMigrationId) {
        if(lastMigrationId) {
          filterFrom(migrations, lastMigrationId, function(err, migrations) {
            if(self.options.to)
              filterTo(migrations, self.options.to, callback)
            else
              callback && callback(null, migrations)
          }, { withoutEqual: true })
        } else {
          if(self.options.to)
            filterTo(migrations, self.options.to, callback)
          else
            callback && callback(null, migrations)
        }
      }).error(function(err) {
        callback && callback(err, null)
      })
    }
  }

  Migrator.prototype.findOrCreateSequelizeMetaModel = function(syncOptions) {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var storedModel   = self.sequelize.modelFactoryManager.getModel('SequelizeMeta')
        , SequelizeMeta = storedModel

      if(!storedModel) {
        SequelizeMeta = self.sequelize.define('SequelizeMeta', {
          from: DataTypes.STRING,
          to:   DataTypes.STRING
        })
      }

      // force sync when model has newly created or if syncOptions are passed
      if(!storedModel || syncOptions) {
        SequelizeMeta
          .sync(syncOptions || {})
          .success(function() { emitter.emit('success', SequelizeMeta) })
          .error(function(err) { emitter.emit('failure', err) })
      } else {
        emitter.emit('success', SequelizeMeta)
      }
    }).run()
  }

  // private

  var getLastMigrationFromDatabase = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
        SequelizeMeta.find({ order: 'id DESC' }).success(function(meta) {
          emitter.emit('success', meta ? meta : null)
        }).error(function(err) { emitter.emit('failure', err) })
      }).error(function(err) { emitter.emit(err) })
    }).run()
  }

  var getLastMigrationIdFromDatabase = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      getLastMigrationFromDatabase.call(self)
        .success(function(meta) {
          emitter.emit('success', meta ? meta.to : null)
        })
        .error(function(err) {
          emitter.emit('failure', err)
        })
    }).run()
  }

  var getFormattedDateString = function(s) {
    var result = null

    try {
      result = s.match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/).slice(1, 6).join('-')
    } catch(e) {
      throw new Error(s + ' is no valid migration timestamp format! Use YYYYMMDDHHmmss!')
    }

    return result
  }

  var stringToDate = function(s) {
    return moment(getFormattedDateString(s), "YYYYMMDDHHmmss")
  }

  var saveSuccessfulMigration = function(from, to, callback) {
    var self = this

    self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
      SequelizeMeta
        .create({ from: from.migrationId, to: to.migrationId })
        .success(callback)
    })
  }

  return Migrator
})()<commit_msg>delete SequelizeMeta database entry after undoing a migration<commit_after>const fs     = require("fs")
    , path   = require("path")
    , moment = require("moment")

var Utils          = require("./utils")
  , Migration      = require("./migration")
  , DataTypes      = require("./data-types")

module.exports = (function() {
  var Migrator = function(sequelize, options) {
    this.sequelize = sequelize
    this.options   = Utils._.extend({
      path: __dirname + '/../migrations',
      from: null,
      to: null,
      logging: true
    }, options || {})
  }

  Object.defineProperty(Migrator.prototype, "queryInterface", {
    get: function() {
      return this.sequelize.getQueryInterface()
    }
  })

  Migrator.prototype.migrate = function(options) {
    var self = this

    options = Utils._.extend({
      method: 'up'
    }, options || {})

    return new Utils.CustomEventEmitter(function(emitter) {
      self.getUndoneMigrations(function(err, migrations) {
        if(err) {
          emitter.emit('failure', err)
        } else {
          var chainer = new Utils.QueryChainer
            , from    = migrations[0]

          if(options.method == 'down') {
            migrations.reverse()
            from = migrations[0]
          }

          migrations.forEach(function(migration) {
            chainer.add(migration, 'execute', [options], {
              before: function(migration) {
                if(self.options.logging)
                  console.log('Executing migration: ' + migration.filename)
              },
              after: function(migration) {
                if(self.options.logging)
                  console.log('Executed migration: ' + migration.filename)
              },
              success: function(migration, callback) {
                if(options.method == 'down')
                  deleteUndoneMigration.call(self, from, migration, callback)
                else
                  saveSuccessfulMigration.call(self, from, migration, callback)
              }
            })
          })

          chainer
            .runSerially({ skipOnError: true })
            .success(function() { emitter.emit('success', null) })
            .error(function(err) { emitter.emit('failure', err) })
        }
      })
    }).run()
  }

  Migrator.prototype.getUndoneMigrations = function(callback)  {
    var self = this

    var filterFrom = function(migrations, from, callback, options) {
      var result = migrations.filter(function(migration) { return migration.isAfter(from, options) })
      callback && callback(null, result)
    }
    var filterTo = function(migrations, to, callback, options) {
      var result = migrations.filter(function(migration) { return migration.isBefore(to, options) })
      callback && callback(null, result)
    }

    var migrationFiles = fs.readdirSync(this.options.path)

    var migrations = migrationFiles.map(function(file) {
      return new Migration(self, self.options.path + '/' + file)
    })

    migrations = migrations.sort(function(a,b){
      return parseInt(a.filename.split('-')[0]) - parseInt(b.filename.split('-')[0])
    })

    if(this.options.from) {
      filterFrom(migrations, this.options.from, function(err, migrations) {
        if(self.options.to)
          filterTo(migrations, self.options.to, callback)
        else
          callback && callback(null, migrations)
      })
    } else {
      getLastMigrationIdFromDatabase.call(this).success(function(lastMigrationId) {
        if(lastMigrationId) {
          filterFrom(migrations, lastMigrationId, function(err, migrations) {
            if(self.options.to)
              filterTo(migrations, self.options.to, callback)
            else
              callback && callback(null, migrations)
          }, { withoutEqual: true })
        } else {
          if(self.options.to)
            filterTo(migrations, self.options.to, callback)
          else
            callback && callback(null, migrations)
        }
      }).error(function(err) {
        callback && callback(err, null)
      })
    }
  }

  Migrator.prototype.findOrCreateSequelizeMetaModel = function(syncOptions) {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      var storedModel   = self.sequelize.modelFactoryManager.getModel('SequelizeMeta')
        , SequelizeMeta = storedModel

      if(!storedModel) {
        SequelizeMeta = self.sequelize.define('SequelizeMeta', {
          from: DataTypes.STRING,
          to:   DataTypes.STRING
        })
      }

      // force sync when model has newly created or if syncOptions are passed
      if(!storedModel || syncOptions) {
        SequelizeMeta
          .sync(syncOptions || {})
          .success(function() { emitter.emit('success', SequelizeMeta) })
          .error(function(err) { emitter.emit('failure', err) })
      } else {
        emitter.emit('success', SequelizeMeta)
      }
    }).run()
  }

  // private

  var getLastMigrationFromDatabase = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
        SequelizeMeta.find({ order: 'id DESC' }).success(function(meta) {
          emitter.emit('success', meta ? meta : null)
        }).error(function(err) { emitter.emit('failure', err) })
      }).error(function(err) { emitter.emit(err) })
    }).run()
  }

  var getLastMigrationIdFromDatabase = function() {
    var self = this

    return new Utils.CustomEventEmitter(function(emitter) {
      getLastMigrationFromDatabase.call(self)
        .success(function(meta) {
          emitter.emit('success', meta ? meta.to : null)
        })
        .error(function(err) {
          emitter.emit('failure', err)
        })
    }).run()
  }

  var getFormattedDateString = function(s) {
    var result = null

    try {
      result = s.match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/).slice(1, 6).join('-')
    } catch(e) {
      throw new Error(s + ' is no valid migration timestamp format! Use YYYYMMDDHHmmss!')
    }

    return result
  }

  var stringToDate = function(s) {
    return moment(getFormattedDateString(s), "YYYYMMDDHHmmss")
  }

  var saveSuccessfulMigration = function(from, to, callback) {
    var self = this

    self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
      SequelizeMeta
        .create({ from: from.migrationId, to: to.migrationId })
        .success(callback)
    })
  }

  var deleteUndoneMigration = function(from, to, callback) {
    var self = this

    self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
      SequelizeMeta
        .find({ from: from.migrationId, to: to.migrationId })
        .success(function(meta) {
          meta.destroy().success(callback)
        })
    })
  }

  return Migrator
})()
{'fraction_non_alphanumeric': 0.12992065913945683, 'fraction_numerical': 0.0017546536466280134, 'mean_word_length': 2.3961139896373056, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1251693', 'n_tokens_mistral': 3863, 'n_tokens_neox': 3835, 'n_words': 701}