123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- 'use strict';
- exports.__esModule = true;
- var _omit2 = require('lodash/omit');
- var _omit3 = _interopRequireDefault(_omit2);
- var _map2 = require('lodash/map');
- var _map3 = _interopRequireDefault(_map2);
- var _identity2 = require('lodash/identity');
- var _identity3 = _interopRequireDefault(_identity2);
- var _find2 = require('lodash/find');
- var _find3 = _interopRequireDefault(_find2);
- var _uniqueId2 = require('lodash/uniqueId');
- var _uniqueId3 = _interopRequireDefault(_uniqueId2);
- var _assign2 = require('lodash/assign');
- var _assign3 = _interopRequireDefault(_assign2);
- var _bluebird = require('bluebird');
- var _bluebird2 = _interopRequireDefault(_bluebird);
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
- // So altering the schema in SQLite3 is a major pain.
- // We have our own object to deal with the renaming and altering the types
- // for sqlite3 things.
- function SQLite3_DDL(client, tableCompiler, pragma, connection) {
- this.client = client;
- this.tableCompiler = tableCompiler;
- this.pragma = pragma;
- this.tableName = this.tableCompiler.tableNameRaw;
- this.alteredName = (0, _uniqueId3.default)('_knex_temp_alter');
- this.connection = connection;
- }
- // SQLite3_DDL
- //
- // All of the SQLite3 specific DDL helpers for renaming/dropping
- // columns and changing datatypes.
- // -------
- (0, _assign3.default)(SQLite3_DDL.prototype, {
- getColumn: _bluebird2.default.method(function (column) {
- var currentCol = (0, _find3.default)(this.pragma, { name: column });
- if (!currentCol) throw new Error('The column ' + column + ' is not in the ' + this.tableName + ' table');
- return currentCol;
- }),
- getTableSql: function getTableSql() {
- return this.trx.raw('SELECT name, sql FROM sqlite_master WHERE type="table" AND name="' + this.tableName + '"');
- },
- renameTable: _bluebird2.default.method(function () {
- return this.trx.raw('ALTER TABLE "' + this.tableName + '" RENAME TO "' + this.alteredName + '"');
- }),
- dropOriginal: function dropOriginal() {
- return this.trx.raw('DROP TABLE "' + this.tableName + '"');
- },
- dropTempTable: function dropTempTable() {
- return this.trx.raw('DROP TABLE "' + this.alteredName + '"');
- },
- copyData: function copyData() {
- return this.trx.raw('SELECT * FROM "' + this.tableName + '"').bind(this).then(this.insertChunked(20, this.alteredName));
- },
- reinsertData: function reinsertData(iterator) {
- return function () {
- return this.trx.raw('SELECT * FROM "' + this.alteredName + '"').bind(this).then(this.insertChunked(20, this.tableName, iterator));
- };
- },
- insertChunked: function insertChunked(amount, target, iterator) {
- iterator = iterator || _identity3.default;
- return function (result) {
- var batch = [];
- var ddl = this;
- return _bluebird2.default.reduce(result, function (memo, row) {
- memo++;
- batch.push(row);
- if (memo % 20 === 0 || memo === result.length) {
- return ddl.trx.queryBuilder().table(target).insert((0, _map3.default)(batch, iterator)).then(function () {
- batch = [];
- }).thenReturn(memo);
- }
- return memo;
- }, 0);
- };
- },
- createTempTable: function createTempTable(createTable) {
- return function () {
- return this.trx.raw(createTable.sql.replace(this.tableName, this.alteredName));
- };
- },
- _doReplace: function _doReplace(sql, from, to) {
- var matched = sql.match(/^CREATE TABLE (\S+) \((.*)\)/);
- var tableName = matched[1];
- var defs = matched[2];
- if (!defs) {
- throw new Error('No column definitions in this statement!');
- }
- var parens = 0,
- args = [],
- ptr = 0;
- var i = 0;
- var x = defs.length;
- for (i = 0; i < x; i++) {
- switch (defs[i]) {
- case '(':
- parens++;
- break;
- case ')':
- parens--;
- break;
- case ',':
- if (parens === 0) {
- args.push(defs.slice(ptr, i));
- ptr = i + 1;
- }
- break;
- case ' ':
- if (ptr === i) {
- ptr = i + 1;
- }
- break;
- }
- }
- args.push(defs.slice(ptr, i));
- args = args.map(function (item) {
- var split = item.split(' ');
- if (split[0] === from) {
- // column definition
- if (to) {
- split[0] = to;
- return split.join(' ');
- }
- return ''; // for deletions
- }
- // skip constraint name
- var idx = /constraint/i.test(split[0]) ? 2 : 0;
- // primary key and unique constraints have one or more
- // columns from this table listed between (); replace
- // one if it matches
- if (/primary|unique/i.test(split[idx])) {
- return item.replace(/\(.*\)/, function (columns) {
- return columns.replace(from, to);
- });
- }
- // foreign keys have one or more columns from this table
- // listed between (); replace one if it matches
- // foreign keys also have a 'references' clause
- // which may reference THIS table; if it does, replace
- // column references in that too!
- if (/foreign/.test(split[idx])) {
- split = item.split(/ references /i);
- // the quoted column names save us from having to do anything
- // other than a straight replace here
- split[0] = split[0].replace(from, to);
- if (split[1].slice(0, tableName.length) === tableName) {
- split[1] = split[1].replace(/\(.*\)/, function (columns) {
- return columns.replace(from, to);
- });
- }
- return split.join(' references ');
- }
- return item;
- });
- return sql.replace(/\(.*\)/, function () {
- return '(' + args.join(', ') + ')';
- }).replace(/,\s*([,)])/, '$1');
- },
- // Boy, this is quite a method.
- renameColumn: _bluebird2.default.method(function (from, to) {
- var _this = this;
- return this.client.transaction(function (trx) {
- _this.trx = trx;
- return _this.getColumn(from).bind(_this).then(_this.getTableSql).then(function (sql) {
- var a = this.client.wrapIdentifier(from);
- var b = this.client.wrapIdentifier(to);
- var createTable = sql[0];
- var newSql = this._doReplace(createTable.sql, a, b);
- if (sql === newSql) {
- throw new Error('Unable to find the column to change');
- }
- return _bluebird2.default.bind(this).then(this.createTempTable(createTable)).then(this.copyData).then(this.dropOriginal).then(function () {
- return this.trx.raw(newSql);
- }).then(this.reinsertData(function (row) {
- row[to] = row[from];
- return (0, _omit3.default)(row, from);
- })).then(this.dropTempTable);
- });
- }, { connection: this.connection });
- }),
- dropColumn: _bluebird2.default.method(function (column) {
- var _this2 = this;
- return this.client.transaction(function (trx) {
- _this2.trx = trx;
- return _this2.getColumn(column).bind(_this2).then(_this2.getTableSql).then(function (sql) {
- var createTable = sql[0];
- var a = this.client.wrapIdentifier(column);
- var newSql = this._doReplace(createTable.sql, a, '');
- if (sql === newSql) {
- throw new Error('Unable to find the column to change');
- }
- return _bluebird2.default.bind(this).then(this.createTempTable(createTable)).then(this.copyData).then(this.dropOriginal).then(function () {
- return this.trx.raw(newSql);
- }).then(this.reinsertData(function (row) {
- return (0, _omit3.default)(row, column);
- })).then(this.dropTempTable);
- });
- }, { connection: this.connection });
- })
- });
- exports.default = SQLite3_DDL;
- module.exports = exports['default'];
|