execute query from shell

This commit is contained in:
Jan Prochazka
2020-12-08 18:51:00 +01:00
parent e0c91214fd
commit f8ee3b92cf
7 changed files with 97 additions and 8 deletions

View File

@@ -0,0 +1,19 @@
const goSplit = require('../utility/goSplit');
const requireEngineDriver = require('../utility/requireEngineDriver');
async function executeQuery({ connection, sql }) {
console.log(`Execute query ${sql}`);
const driver = requireEngineDriver(connection);
const pool = await driver.connect(connection);
console.log(`Connected.`);
for (const sqlItem of goSplit(sql)) {
console.log('Executing query', sqlItem);
await driver.query(pool, sqlItem);
}
console.log(`Query finished`);
}
module.exports = executeQuery;

View File

@@ -15,6 +15,8 @@ const finalizer = require('./finalizer');
const registerPlugins = require('./registerPlugins'); const registerPlugins = require('./registerPlugins');
const requirePlugin = require('./requirePlugin'); const requirePlugin = require('./requirePlugin');
const download = require('./download'); const download = require('./download');
const executeQuery = require('./executeQuery');
const loadFile = require('./loadFile');
const dbgateApi = { const dbgateApi = {
queryReader, queryReader,
@@ -32,7 +34,8 @@ const dbgateApi = {
collectorWriter, collectorWriter,
finalizer, finalizer,
registerPlugins, registerPlugins,
download, executeQuery,
loadFile,
}; };
requirePlugin.initialize(dbgateApi); requirePlugin.initialize(dbgateApi);

View File

@@ -0,0 +1,10 @@
const fs = require('fs-extra');
const path = require('path');
const { filesdir } = require('../utility/directories');
async function loadFile(file) {
const text = await fs.readFile(path.join(filesdir(), file), { encoding: 'utf-8' });
return text;
}
module.exports = loadFile;

View File

@@ -18,6 +18,15 @@ export function extractShellApiPlugins(functionName, props): string[] {
return res; return res;
} }
export function extractPackageName(name): string {
if (!name) return null;
const nsMatch = name.match(/^([^@]+)@([^@]+)/);
if (nsMatch) {
return nsMatch[2];
}
return null;
}
export function extractShellApiFunctionName(functionName) { export function extractShellApiFunctionName(functionName) {
const nsMatch = functionName.match(/^([^@]+)@([^@]+)/); const nsMatch = functionName.match(/^([^@]+)@([^@]+)/);
if (nsMatch) { if (nsMatch) {

View File

@@ -5,20 +5,23 @@ import { DropDownMenuItem } from '../modals/DropDownMenu';
import { AppObjectCore } from './AppObjectCore'; import { AppObjectCore } from './AppObjectCore';
import useNewQuery from '../query/useNewQuery'; import useNewQuery from '../query/useNewQuery';
import { openNewTab } from '../utility/common'; import { openNewTab } from '../utility/common';
import { useSetOpenedTabs } from '../utility/globalState'; import { useCurrentDatabase, useSetOpenedTabs } from '../utility/globalState';
import ScriptWriter from '../impexp/ScriptWriter';
import { extractPackageName } from 'dbgate-tools';
function Menu({ data }) { function Menu({ data, menuExt = null }) {
const handleDelete = () => { const handleDelete = () => {
axios.post('files/delete', data); axios.post('files/delete', data);
}; };
return ( return (
<> <>
<DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem> <DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>
{menuExt}
</> </>
); );
} }
export function SavedFileAppObjectBase({ data, commonProps, format, icon, onLoad }) { export function SavedFileAppObjectBase({ data, commonProps, format, icon, onLoad, menuExt = null }) {
const { file, folder } = data; const { file, folder } = data;
const onClick = async () => { const onClick = async () => {
@@ -26,12 +29,48 @@ export function SavedFileAppObjectBase({ data, commonProps, format, icon, onLoad
onLoad(resp.data); onLoad(resp.data);
}; };
return <AppObjectCore {...commonProps} data={data} title={file} icon={icon} onClick={onClick} Menu={Menu} />; return (
<AppObjectCore
{...commonProps}
data={data}
title={file}
icon={icon}
onClick={onClick}
Menu={menuExt ? (props) => <Menu {...props} menuExt={menuExt} /> : Menu}
/>
);
} }
export function SavedSqlFileAppObject({ data, commonProps }) { export function SavedSqlFileAppObject({ data, commonProps }) {
const { file, folder } = data; const { file, folder } = data;
const newQuery = useNewQuery(); const newQuery = useNewQuery();
const currentDatabase = useCurrentDatabase();
const setOpenedTabs = useSetOpenedTabs();
const connection = _.get(currentDatabase, 'connection');
const database = _.get(currentDatabase, 'name');
const handleGenerateExecute = () => {
const script = new ScriptWriter();
const conn = {
..._.omit(connection, ['displayName', '_id']),
database,
};
script.put(`const sql = await dbgateApi.loadFile('${folder}/${file}');`)
script.put(`await dbgateApi.executeQuery({ sql, connection: ${JSON.stringify(conn)} });`)
// @ts-ignore
script.requirePackage(extractPackageName(conn.engine));
openNewTab(
setOpenedTabs,
{
title: 'Shell',
icon: 'img shell',
tabComponent: 'ShellTab',
},
script.getScript()
);
};
return ( return (
<SavedFileAppObjectBase <SavedFileAppObjectBase
@@ -39,6 +78,11 @@ export function SavedSqlFileAppObject({ data, commonProps }) {
commonProps={commonProps} commonProps={commonProps}
format="text" format="text"
icon="img sql-file" icon="img sql-file"
menuExt={
connection && database ? (
<DropDownMenuItem onClick={handleGenerateExecute}>Generate shell execute</DropDownMenuItem>
) : null
}
onLoad={(data) => { onLoad={(data) => {
newQuery({ newQuery({
title: file, title: file,

View File

@@ -2,7 +2,7 @@ import _ from 'lodash';
import { extractShellApiFunctionName, extractShellApiPlugins } from 'dbgate-tools'; import { extractShellApiFunctionName, extractShellApiPlugins } from 'dbgate-tools';
export default class ScriptWriter { export default class ScriptWriter {
constructor(varCount) { constructor(varCount = '0') {
this.s = ''; this.s = '';
this.packageNames = []; this.packageNames = [];
// this.engines = []; // this.engines = [];
@@ -24,6 +24,10 @@ export default class ScriptWriter {
this.packageNames.push(...extractShellApiPlugins(functionName, props)); this.packageNames.push(...extractShellApiPlugins(functionName, props));
} }
requirePackage(packageName) {
this.packageNames.push(packageName);
}
copyStream(sourceVar, targetVar) { copyStream(sourceVar, targetVar) {
this.put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar});`); this.put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar});`);
} }
@@ -32,7 +36,7 @@ export default class ScriptWriter {
this.put(`// ${s}`); this.put(`// ${s}`);
} }
getScript(extensions, schedule) { getScript(schedule = null) {
const packageNames = this.packageNames; const packageNames = this.packageNames;
let prefix = _.uniq(packageNames) let prefix = _.uniq(packageNames)
.map((packageName) => `// @require ${packageName}\n`) .map((packageName) => `// @require ${packageName}\n`)

View File

@@ -182,7 +182,7 @@ export default async function createImpExpScript(extensions, values, addEditorIn
script.comment('@ImportExportConfigurator'); script.comment('@ImportExportConfigurator');
script.comment(JSON.stringify(values)); script.comment(JSON.stringify(values));
} }
return script.getScript(extensions, values.schedule); return script.getScript(values.schedule);
} }
export function getActionOptions(extensions, source, values, targetDbinfo) { export function getActionOptions(extensions, source, values, targetDbinfo) {