update.js 3.65 KB
const path = require('path');
const shelljs = require('shelljs');
const _ = require('lodash');
const fs = require('fs');
const ynLib = require('yoho-node-lib');
const config = require('../../config');
const argv = require('optimist').argv

ynLib.global(config);

const logger = global.yoho.logger;
const {SqlHelper} = require('../../utils');
const migrations = require('../../migrations');
const migrationPath = path.join(__dirname, '../../migrations');
const migrationTablName = '__migrations';
const scriptPath = path.join(__dirname, '../../scripts');
const env_script = process.env.npm_config_script || argv.script;
const mysqlCli = new SqlHelper();
let script_file = '';
if (env_script) {
    script_file = process.env.npm_config_file || argv.file;

    if (!script_file) {
        console.error('请输入保存的文件名');
        return;
    }
}

const initMargration = () => {
    return mysqlCli.execute(`create database if not exists ${config.mysql.database};`).then(() => {
        return mysqlCli.changeDatabase(config.mysql.database).then(() => {
            return mysqlCli.execute(`create table if not exists ${migrationTablName} (
                id int(10) unsigned not null auto_increment,
                migration_name varchar(50) not null,
                migration_time timestamp not null DEFAULT CURRENT_TIMESTAMP,
                primary key (id)
            ) DEFAULT CHARSET=utf8;`);
        });
    });
};
const removeComment = (scripts) => {
    const regComment1 = /\/\*(\n|.)*?\*\//g;
    const regComment2 = /#.*?(\n|$)/g;
    const regComment3 = /--.*?(\n|$)/g;

    return scripts
        .replace(regComment1, '')
        .replace(regComment2, '')
        .replace(regComment3, '');
};
const getSql = (migras) => {
    let scripts = '';
    let migrationsSqls = [];

    _.each(migras, m => {
        scripts += removeComment(fs.readFileSync(`${migrationPath}/${m}.sql`, 'utf8'));
    });
    migrationsSqls = _.filter(_.split(scripts, 'GO;'), script => _.trim(script));
    return migrationsSqls;
}
const getMigrationLogSql = (migras) => {
    return _.map(migras, m => {
        return `insert ${migrationTablName} (migration_name) values ('${m}');\r\n`;
    });
}
const script = (migras, sqls) => {
    let migrationsSqls = getSql(migras);
    let insertSqls = getMigrationLogSql(migras);
    let scripts = _.join(_.concat(migrationsSqls, insertSqls), '');

    shelljs.exec(`mkdir -p ${scriptPath}`); // 创建页面目录

    fs.writeFileSync(path.join(scriptPath, `${script_file}.sql`), scripts, {
        encoding: 'utf8'
    });

    return Promise.resolve();
};
const update = (migras) => {
    let migrationsSqls = getSql(migras);

    return mysqlCli.transaction(migrationsSqls).then(() => {
        let insertSqls = getMigrationLogSql(migras);

        return mysqlCli.transaction(insertSqls);
    }, () => {
        return Promise.reject();
    });
}
const migration = (migras) => {
    if (migras.length) {
        return env_script ? script(migras) : update(migras)
    }
    logger.warn('无更新记录');
    return Promise.resolve();
};


initMargration().then(() => {
    let sqlIn = _.join(_.map(migrations, m => {
        return `'${m}'`;
    }), ',');

    mysqlCli
        .query(`select * from ${migrationTablName} where migration_name in (${sqlIn})`)
        .then(result => {
            let migras = _.filter(migrations,
                m => _.every(result,
                    r => m.indexOf(r.migration_name) < 0));

            migration(migras).then(() => {
                logger.info('migration ok!');
                process.exit();
            }, () => {
                logger.error('migration error!');
                process.exit();
            });
        });
});