All files / lib/mssql Migrate.js

76.47% Statements 26/34
37.5% Branches 3/8
84.62% Functions 11/13
76.47% Lines 26/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91          1x 1x                     1x 1x 1x       1x 1x         1x 1x 1x 1x             1x 1x 1x         5x 5x         5x 5x   5x                       1x 1x       1x     1x 1x     1x                   1x  
/**
 * @author David Menger
 */
'use strict';
 
const migrate = require('migrate');
const mssql = require('mssql');
 
class Migrate {
 
    /**
     *
     * @param {Promise<mssql.ConnectionPool>} pool
     * @param {string} migrationsPath
     * @param {string} tableName
     */
    constructor (pool, migrationsPath, tableName = 'migrations') {
        this._pool = pool;
        this._tableName = tableName;
        this._migrationsPath = migrationsPath;
    }
 
    load (cb) {
        this._load()
            .then((set) => cb(null, set))
            .catch((e) => cb(e));
    }
 
    async _load () {
        const cp = await this._pool;
        try {
            const r = cp.request();
            const res = await r.query(`SELECT TOP 1 data FROM ${this._tableName} WHERE id=1`);
            const [item = null] = res.recordset;
            if (!item) {
                return { lastRun: null, migrations: [] };
            }
            return JSON.parse(item.data);
        } catch (e) {
            const r = cp.request();
            await r.query(`CREATE TABLE ${this._tableName} (id int, data text)`);
            return { lastRun: null, migrations: [] };
        }
    }
 
    save (set, cb) {
        this._save(set)
            .then(() => cb())
            .catch((e) => cb(e));
    }
 
    async _save (set) {
        const cp = await this._pool;
        const r = cp.request();
 
        await r
            .input('data', mssql.Text, JSON.stringify(set))
            .query(`MERGE INTO ${this._tableName} AS target
                USING (SELECT 1 as id) AS source (id)
                ON source.id = target.id
                WHEN MATCHED THEN
                    UPDATE SET data = @data
                WHEN NOT MATCHED THEN
                    INSERT (id, data) VALUES (1, @data);`);
    }
 
    migrate () {
        return new Promise((resolve, reject) => {
            migrate.load({
                stateStore: this,
                migrationsDirectory: this._migrationsPath
            }, (err, set) => {
                Iif (err) {
                    reject(err);
                } else {
                    set.up((er) => {
                        Iif (er) {
                            reject(er);
                        } else {
                            resolve();
                        }
                    });
                }
            });
        });
    }
 
}
 
module.exports = Migrate;