myt/lib/exporter.js

87 lines
2.5 KiB
JavaScript

const ejs = require('ejs');
const fs = require('fs-extra');
const SqlString = require('sqlstring');
module.exports = class Exporter {
constructor(objectType, replace) {
Object.assign(this, {
objectType,
replace
});
}
async init() {
const templateDir = `${__dirname}/../exporters/${this.objectType}`;
this.sql = await fs.readFile(`${templateDir}.sql`, 'utf8');
const templateFile = await fs.readFile(`${templateDir}.ejs`, 'utf8');
this.template = ejs.compile(templateFile);
this.attrs = require(`${templateDir}.js`);
}
async query(conn, schema, name) {
const ops = [];
function addOp(col, value) {
ops.push(conn.format('?? = ?', [col, value]));
}
if (schema)
addOp(this.attrs.schemaCol, schema);
if (name)
addOp(this.attrs.nameCol, name);
const filter = {
toSqlString() {
return ops.join(' AND ');
}
}
const [res] = await conn.query(this.sql, [filter]);
return res;
}
format(params) {
const {attrs} = this;
params = Object.assign({}, attrs.defaults, params)
const data = {params};
if (attrs.formatter)
attrs.formatter(params);
if (attrs.escapeCols)
for (const escapeCol of attrs.escapeCols) {
if (params[escapeCol])
params[escapeCol] = SqlString.escape(params[escapeCol])
}
const split = params.definer.split('@');
data.definer =
SqlString.escapeId(split[0], true) + '@' +
SqlString.escapeId(split[1], true);
data.name =
SqlString.escapeId(params.schema, true) + '.' +
SqlString.escapeId(params.name, true);
const objectType = this.objectType.toUpperCase();
const delimiter = '$$';
const replace = `CREATE OR REPLACE`;
let create;
if (this.replace) {
create = `DELIMITER ${delimiter}\n${replace}`
} else {
create =
`DROP ${objectType} IF EXISTS ${data.name};\n`
+`DELIMITER ${delimiter}\n`
+`CREATE`;
}
data.createOrReplace = `${replace} DEFINER=${data.definer}`
data.begin = `${create} DEFINER=${data.definer}`;
data.typeAndName = `${objectType} ${data.name}`;
data.end = `${delimiter}\nDELIMITER ;`;
return this.template(data);
}
}