2020-11-16 13:23:28 +00:00
|
|
|
|
2022-12-21 13:17:50 +00:00
|
|
|
const Myt = require('./myt');
|
2022-12-21 12:34:17 +00:00
|
|
|
const Command = require('./lib/command');
|
2020-11-14 01:38:56 +00:00
|
|
|
const fs = require('fs-extra');
|
2021-10-14 08:34:40 +00:00
|
|
|
const nodegit = require('nodegit');
|
2022-12-21 12:34:17 +00:00
|
|
|
const ExporterEngine = require('./lib/exporter-engine');
|
2022-12-21 13:17:50 +00:00
|
|
|
|
2022-12-21 12:34:17 +00:00
|
|
|
class Pull extends Command {
|
|
|
|
static usage = {
|
|
|
|
description: 'Incorporate database routine changes into workspace',
|
|
|
|
params: {
|
|
|
|
force: 'Do it even if there are local changes',
|
|
|
|
checkout: 'Move to same database commit before pull',
|
|
|
|
update: 'Update all routines',
|
|
|
|
sums: 'Save SHA sums of all objects'
|
|
|
|
},
|
|
|
|
operand: 'remote'
|
|
|
|
};
|
|
|
|
|
|
|
|
static localOpts = {
|
|
|
|
alias: {
|
|
|
|
force: 'f',
|
|
|
|
checkout: 'c',
|
|
|
|
update: 'u',
|
|
|
|
sums: 's'
|
|
|
|
},
|
|
|
|
boolean: [
|
|
|
|
'force',
|
|
|
|
'checkout',
|
|
|
|
'update',
|
|
|
|
'sums'
|
|
|
|
]
|
|
|
|
};
|
2021-10-22 14:11:03 +00:00
|
|
|
|
2022-12-21 13:17:50 +00:00
|
|
|
async run(myt, opts) {
|
|
|
|
const conn = await myt.dbConnect();
|
|
|
|
const repo = await myt.openRepo();
|
2021-10-22 14:11:03 +00:00
|
|
|
|
|
|
|
if (!opts.force) {
|
|
|
|
async function hasChanges(diff) {
|
|
|
|
if (diff)
|
|
|
|
for (const patch of await diff.patches()) {
|
|
|
|
const match = patch
|
|
|
|
.newFile()
|
|
|
|
.path()
|
|
|
|
.match(/^routines\/(.+)\.sql$/);
|
|
|
|
if (match) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for unstaged changes
|
|
|
|
|
2022-12-21 13:17:50 +00:00
|
|
|
const unstagedDiff = await myt.getUnstaged(repo);
|
2021-10-22 14:11:03 +00:00
|
|
|
|
|
|
|
if (await hasChanges(unstagedDiff))
|
|
|
|
throw new Error('You have unstaged changes, save them before pull');
|
|
|
|
|
|
|
|
// Check for staged changes
|
|
|
|
|
2022-12-21 13:17:50 +00:00
|
|
|
const stagedDiff = await myt.getStaged(repo);
|
2021-10-22 14:11:03 +00:00
|
|
|
|
|
|
|
if (await hasChanges(stagedDiff))
|
|
|
|
throw new Error('You have staged changes, save them before pull');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Checkout to remote commit
|
|
|
|
|
|
|
|
if (opts.checkout) {
|
2022-12-21 13:17:50 +00:00
|
|
|
const version = await myt.fetchDbVersion();
|
2021-10-22 14:11:03 +00:00
|
|
|
|
|
|
|
if (version && version.gitCommit) {
|
|
|
|
const now = parseInt(new Date().toJSON());
|
2022-12-21 13:17:50 +00:00
|
|
|
const branchName = `myt-pull_${now}`;
|
2021-10-22 14:11:03 +00:00
|
|
|
console.log(`Creating branch '${branchName}' from database commit.`);
|
|
|
|
const commit = await repo.getCommit(version.gitCommit);
|
|
|
|
const branch = await nodegit.Branch.create(repo,
|
2022-12-21 13:17:50 +00:00
|
|
|
`myt-pull_${now}`, commit, () => {});
|
2021-10-22 14:11:03 +00:00
|
|
|
await repo.checkoutBranch(branch);
|
|
|
|
}
|
2021-10-14 08:34:40 +00:00
|
|
|
}
|
2020-12-02 07:35:26 +00:00
|
|
|
|
2021-10-22 14:11:03 +00:00
|
|
|
// Export routines to SQL files
|
|
|
|
|
|
|
|
console.log(`Incorporating routine changes.`);
|
|
|
|
|
2022-12-21 13:17:50 +00:00
|
|
|
const engine = new ExporterEngine(conn, opts.mytDir);
|
2022-02-02 04:05:31 +00:00
|
|
|
await engine.init();
|
|
|
|
const shaSums = engine.shaSums;
|
2020-12-02 07:35:26 +00:00
|
|
|
|
2022-12-21 12:34:17 +00:00
|
|
|
const routinesDir = opts.routinesDir;
|
|
|
|
if (!await fs.pathExists(routinesDir))
|
|
|
|
await fs.mkdir(routinesDir);
|
2020-12-19 01:06:06 +00:00
|
|
|
|
2021-10-23 13:20:35 +00:00
|
|
|
// Delete old schemas
|
|
|
|
|
2022-12-21 12:34:17 +00:00
|
|
|
const schemas = await fs.readdir(routinesDir);
|
2020-12-19 01:06:06 +00:00
|
|
|
for (const schema of schemas) {
|
|
|
|
if (opts.schemas.indexOf(schema) == -1)
|
2022-12-21 12:34:17 +00:00
|
|
|
await fs.remove(`${routinesDir}/${schema}`, {recursive: true});
|
2020-12-19 01:06:06 +00:00
|
|
|
}
|
2020-12-02 07:35:26 +00:00
|
|
|
|
2022-02-02 04:05:31 +00:00
|
|
|
for (const schema in shaSums) {
|
2022-12-21 12:34:17 +00:00
|
|
|
if (!await fs.pathExists(`${routinesDir}/${schema}`))
|
2022-04-30 00:06:56 +00:00
|
|
|
engine.deleteSchemaSums(schema);
|
2022-02-02 04:05:31 +00:00
|
|
|
}
|
|
|
|
|
2021-10-23 13:20:35 +00:00
|
|
|
// Export objects to SQL files
|
2021-10-22 14:11:03 +00:00
|
|
|
|
2020-12-02 07:35:26 +00:00
|
|
|
for (const schema of opts.schemas) {
|
2022-12-21 12:34:17 +00:00
|
|
|
let schemaDir = `${routinesDir}/${schema}`;
|
2020-12-02 07:35:26 +00:00
|
|
|
if (!await fs.pathExists(schemaDir))
|
|
|
|
await fs.mkdir(schemaDir);
|
2022-04-30 00:06:56 +00:00
|
|
|
|
|
|
|
for (const exporter of engine.exporters)
|
2022-12-21 12:34:17 +00:00
|
|
|
await exporter.export(routinesDir,
|
2022-04-30 00:33:41 +00:00
|
|
|
schema, opts.update, opts.sums);
|
2020-12-02 07:35:26 +00:00
|
|
|
}
|
2021-10-22 14:11:03 +00:00
|
|
|
|
2022-04-30 00:06:56 +00:00
|
|
|
await engine.refreshPullDate();
|
|
|
|
await engine.saveInfo();
|
2020-11-14 01:38:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 07:35:26 +00:00
|
|
|
module.exports = Pull;
|
2020-11-14 01:38:56 +00:00
|
|
|
|
2020-12-02 07:35:26 +00:00
|
|
|
if (require.main === module)
|
2022-12-21 13:17:50 +00:00
|
|
|
new Myt().run(Pull);
|