dbgate-api 4.4.1 → 4.4.5-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env-portal +11 -1
- package/package.json +8 -8
- package/src/controllers/archive.js +21 -16
- package/src/controllers/config.js +11 -4
- package/src/controllers/connections.js +39 -7
- package/src/controllers/databaseConnections.js +34 -23
- package/src/controllers/files.js +11 -11
- package/src/controllers/jsldata.js +4 -4
- package/src/controllers/metadata.js +4 -4
- package/src/controllers/plugins.js +9 -9
- package/src/controllers/queryHistory.js +2 -2
- package/src/controllers/runners.js +23 -15
- package/src/controllers/serverConnections.js +12 -9
- package/src/controllers/sessions.js +14 -7
- package/src/currentVersion.js +2 -2
- package/src/index.js +1 -1
- package/src/main.js +57 -40
- package/src/nativeModules.js +11 -3
- package/src/nativeModulesContent.js +1 -1
- package/src/proc/databaseConnectionProcess.js +41 -2
- package/src/shell/generateDeploySql.js +14 -2
- package/src/utility/DatastoreProxy.js +8 -1
- package/src/utility/directories.js +10 -0
- package/src/utility/platformInfo.js +5 -3
- package/src/utility/processArgs.js +8 -6
- package/src/utility/socket.js +20 -10
- package/src/utility/useController.js +26 -9
|
@@ -12,7 +12,7 @@ const _ = require('lodash');
|
|
|
12
12
|
const packagedPluginsContent = require('../packagedPluginsContent');
|
|
13
13
|
|
|
14
14
|
module.exports = {
|
|
15
|
-
script_meta:
|
|
15
|
+
script_meta: true,
|
|
16
16
|
async script({ packageName }) {
|
|
17
17
|
const packagedContent = packagedPluginsContent();
|
|
18
18
|
|
|
@@ -30,7 +30,7 @@ module.exports = {
|
|
|
30
30
|
return data;
|
|
31
31
|
},
|
|
32
32
|
|
|
33
|
-
search_meta:
|
|
33
|
+
search_meta: true,
|
|
34
34
|
async search({ filter }) {
|
|
35
35
|
// DOCS: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get-v1search
|
|
36
36
|
const resp = await axios.default.get(
|
|
@@ -40,7 +40,7 @@ module.exports = {
|
|
|
40
40
|
return (objects || []).map(x => x.package);
|
|
41
41
|
},
|
|
42
42
|
|
|
43
|
-
info_meta:
|
|
43
|
+
info_meta: true,
|
|
44
44
|
async info({ packageName }) {
|
|
45
45
|
try {
|
|
46
46
|
const infoResp = await axios.default.get(`https://registry.npmjs.org/${packageName}`);
|
|
@@ -63,7 +63,7 @@ module.exports = {
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
|
|
66
|
-
installed_meta:
|
|
66
|
+
installed_meta: true,
|
|
67
67
|
async installed() {
|
|
68
68
|
const packagedContent = packagedPluginsContent();
|
|
69
69
|
|
|
@@ -107,7 +107,7 @@ module.exports = {
|
|
|
107
107
|
// await fs.writeFile(path.join(datadir(), 'removed-plugins'), this.removedPlugins.join('\n'));
|
|
108
108
|
// },
|
|
109
109
|
|
|
110
|
-
install_meta:
|
|
110
|
+
install_meta: true,
|
|
111
111
|
async install({ packageName }) {
|
|
112
112
|
if (!hasPermission(`plugins/install`)) return;
|
|
113
113
|
const dir = path.join(pluginsdir(), packageName);
|
|
@@ -120,7 +120,7 @@ module.exports = {
|
|
|
120
120
|
// await this.saveRemovePlugins();
|
|
121
121
|
},
|
|
122
122
|
|
|
123
|
-
uninstall_meta:
|
|
123
|
+
uninstall_meta: true,
|
|
124
124
|
async uninstall({ packageName }) {
|
|
125
125
|
if (!hasPermission(`plugins/install`)) return;
|
|
126
126
|
const dir = path.join(pluginsdir(), packageName);
|
|
@@ -130,7 +130,7 @@ module.exports = {
|
|
|
130
130
|
await this.saveRemovePlugins();
|
|
131
131
|
},
|
|
132
132
|
|
|
133
|
-
upgrade_meta:
|
|
133
|
+
upgrade_meta: true,
|
|
134
134
|
async upgrade({ packageName }) {
|
|
135
135
|
if (!hasPermission(`plugins/install`)) return;
|
|
136
136
|
const dir = path.join(pluginsdir(), packageName);
|
|
@@ -143,13 +143,13 @@ module.exports = {
|
|
|
143
143
|
socket.emitChanged(`installed-plugins-changed`);
|
|
144
144
|
},
|
|
145
145
|
|
|
146
|
-
command_meta:
|
|
146
|
+
command_meta: true,
|
|
147
147
|
async command({ packageName, command, args }) {
|
|
148
148
|
const content = requirePlugin(packageName);
|
|
149
149
|
return content.commands[command](args);
|
|
150
150
|
},
|
|
151
151
|
|
|
152
|
-
authTypes_meta:
|
|
152
|
+
authTypes_meta: true,
|
|
153
153
|
async authTypes({ engine }) {
|
|
154
154
|
const packageName = extractPackageName(engine);
|
|
155
155
|
const content = requirePlugin(packageName);
|
|
@@ -34,7 +34,7 @@ function readCore(reader, skip, limit, filter) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
module.exports = {
|
|
37
|
-
read_meta:
|
|
37
|
+
read_meta: true,
|
|
38
38
|
async read({ skip, limit, filter }) {
|
|
39
39
|
const fileName = path.join(datadir(), 'query-history.jsonl');
|
|
40
40
|
// @ts-ignore
|
|
@@ -44,7 +44,7 @@ module.exports = {
|
|
|
44
44
|
return res;
|
|
45
45
|
},
|
|
46
46
|
|
|
47
|
-
write_meta:
|
|
47
|
+
write_meta: true,
|
|
48
48
|
async write({ data }) {
|
|
49
49
|
const fileName = path.join(datadir(), 'query-history.jsonl');
|
|
50
50
|
await fs.appendFile(fileName, JSON.stringify(data) + '\n');
|
|
@@ -8,6 +8,7 @@ const { fork } = require('child_process');
|
|
|
8
8
|
const { rundir, uploadsdir, pluginsdir, getPluginBackendPath, packagedPluginList } = require('../utility/directories');
|
|
9
9
|
const { extractShellApiPlugins, extractShellApiFunctionName } = require('dbgate-tools');
|
|
10
10
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
11
|
+
const processArgs = require('../utility/processArgs');
|
|
11
12
|
|
|
12
13
|
function extractPlugins(script) {
|
|
13
14
|
const requireRegex = /\s*\/\/\s*@require\s+([^\s]+)\s*\n/g;
|
|
@@ -98,15 +99,22 @@ module.exports = {
|
|
|
98
99
|
const pluginNames = _.union(fs.readdirSync(pluginsdir()), packagedPluginList);
|
|
99
100
|
console.log(`RUNNING SCRIPT ${scriptFile}`);
|
|
100
101
|
// const subprocess = fork(scriptFile, ['--checkParent', '--max-old-space-size=8192'], {
|
|
101
|
-
const subprocess = fork(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
...
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
const subprocess = fork(
|
|
103
|
+
scriptFile,
|
|
104
|
+
[
|
|
105
|
+
'--checkParent', // ...process.argv.slice(3)
|
|
106
|
+
...processArgs.getPassArgs(),
|
|
107
|
+
],
|
|
108
|
+
{
|
|
109
|
+
cwd: directory,
|
|
110
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
111
|
+
env: {
|
|
112
|
+
...process.env,
|
|
113
|
+
DBGATE_API: global['API_PACKAGE'] || global['dbgateApiModulePath'] || process.argv[1],
|
|
114
|
+
..._.fromPairs(pluginNames.map(name => [`PLUGIN_${_.camelCase(name)}`, getPluginBackendPath(name)])),
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
);
|
|
110
118
|
const pipeDispatcher = severity => data =>
|
|
111
119
|
this.dispatchMessage(runid, { severity, message: data.toString().trim() });
|
|
112
120
|
|
|
@@ -136,21 +144,21 @@ module.exports = {
|
|
|
136
144
|
if (handleProcessCommunication(message, subprocess)) return;
|
|
137
145
|
this[`handle_${msgtype}`](runid, message);
|
|
138
146
|
});
|
|
139
|
-
return newOpened;
|
|
147
|
+
return _.pick(newOpened, ['runid']);
|
|
140
148
|
},
|
|
141
149
|
|
|
142
|
-
start_meta:
|
|
150
|
+
start_meta: true,
|
|
143
151
|
async start({ script }) {
|
|
144
152
|
const runid = uuidv1();
|
|
145
153
|
return this.startCore(runid, scriptTemplate(script, false));
|
|
146
154
|
},
|
|
147
155
|
|
|
148
|
-
getNodeScript_meta:
|
|
156
|
+
getNodeScript_meta: true,
|
|
149
157
|
async getNodeScript({ script }) {
|
|
150
158
|
return scriptTemplate(script, true);
|
|
151
159
|
},
|
|
152
160
|
|
|
153
|
-
cancel_meta:
|
|
161
|
+
cancel_meta: true,
|
|
154
162
|
async cancel({ runid }) {
|
|
155
163
|
const runner = this.opened.find(x => x.runid == runid);
|
|
156
164
|
if (!runner) {
|
|
@@ -160,7 +168,7 @@ module.exports = {
|
|
|
160
168
|
return { state: 'ok' };
|
|
161
169
|
},
|
|
162
170
|
|
|
163
|
-
files_meta:
|
|
171
|
+
files_meta: true,
|
|
164
172
|
async files({ runid }) {
|
|
165
173
|
const directory = path.join(rundir(), runid);
|
|
166
174
|
const files = await fs.readdir(directory);
|
|
@@ -176,7 +184,7 @@ module.exports = {
|
|
|
176
184
|
return res;
|
|
177
185
|
},
|
|
178
186
|
|
|
179
|
-
loadReader_meta:
|
|
187
|
+
loadReader_meta: true,
|
|
180
188
|
async loadReader({ functionName, props }) {
|
|
181
189
|
const promise = new Promise((resolve, reject) => {
|
|
182
190
|
const runid = uuidv1();
|
|
@@ -6,6 +6,7 @@ const AsyncLock = require('async-lock');
|
|
|
6
6
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
7
7
|
const lock = new AsyncLock();
|
|
8
8
|
const config = require('./config');
|
|
9
|
+
const processArgs = require('../utility/processArgs');
|
|
9
10
|
|
|
10
11
|
module.exports = {
|
|
11
12
|
opened: [],
|
|
@@ -37,10 +38,12 @@ module.exports = {
|
|
|
37
38
|
const existing = this.opened.find(x => x.conid == conid);
|
|
38
39
|
if (existing) return existing;
|
|
39
40
|
const connection = await connections.get({ conid });
|
|
40
|
-
const subprocess = fork(process.argv[1], [
|
|
41
|
+
const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
|
|
42
|
+
'--is-forked-api',
|
|
41
43
|
'--start-process',
|
|
42
44
|
'serverConnectionProcess',
|
|
43
|
-
...
|
|
45
|
+
...processArgs.getPassArgs(),
|
|
46
|
+
// ...process.argv.slice(3),
|
|
44
47
|
]);
|
|
45
48
|
const newOpened = {
|
|
46
49
|
conid,
|
|
@@ -86,25 +89,25 @@ module.exports = {
|
|
|
86
89
|
}
|
|
87
90
|
},
|
|
88
91
|
|
|
89
|
-
disconnect_meta:
|
|
92
|
+
disconnect_meta: true,
|
|
90
93
|
async disconnect({ conid }) {
|
|
91
94
|
await this.close(conid, true);
|
|
92
95
|
return { status: 'ok' };
|
|
93
96
|
},
|
|
94
97
|
|
|
95
|
-
listDatabases_meta:
|
|
98
|
+
listDatabases_meta: true,
|
|
96
99
|
async listDatabases({ conid }) {
|
|
97
100
|
const opened = await this.ensureOpened(conid);
|
|
98
101
|
return opened.databases;
|
|
99
102
|
},
|
|
100
103
|
|
|
101
|
-
version_meta:
|
|
104
|
+
version_meta: true,
|
|
102
105
|
async version({ conid }) {
|
|
103
106
|
const opened = await this.ensureOpened(conid);
|
|
104
107
|
return opened.version;
|
|
105
108
|
},
|
|
106
109
|
|
|
107
|
-
serverStatus_meta:
|
|
110
|
+
serverStatus_meta: true,
|
|
108
111
|
async serverStatus() {
|
|
109
112
|
return {
|
|
110
113
|
...this.closed,
|
|
@@ -112,7 +115,7 @@ module.exports = {
|
|
|
112
115
|
};
|
|
113
116
|
},
|
|
114
117
|
|
|
115
|
-
ping_meta:
|
|
118
|
+
ping_meta: true,
|
|
116
119
|
async ping({ connections }) {
|
|
117
120
|
await Promise.all(
|
|
118
121
|
_.uniq(connections).map(async conid => {
|
|
@@ -128,7 +131,7 @@ module.exports = {
|
|
|
128
131
|
return { status: 'ok' };
|
|
129
132
|
},
|
|
130
133
|
|
|
131
|
-
refresh_meta:
|
|
134
|
+
refresh_meta: true,
|
|
132
135
|
async refresh({ conid, keepOpen }) {
|
|
133
136
|
if (!keepOpen) this.close(conid);
|
|
134
137
|
|
|
@@ -136,7 +139,7 @@ module.exports = {
|
|
|
136
139
|
return { status: 'ok' };
|
|
137
140
|
},
|
|
138
141
|
|
|
139
|
-
createDatabase_meta:
|
|
142
|
+
createDatabase_meta: true,
|
|
140
143
|
async createDatabase({ conid, name }) {
|
|
141
144
|
const opened = await this.ensureOpened(conid);
|
|
142
145
|
opened.subprocess.send({ msgtype: 'createDatabase', name });
|
|
@@ -5,6 +5,7 @@ const socket = require('../utility/socket');
|
|
|
5
5
|
const { fork } = require('child_process');
|
|
6
6
|
const jsldata = require('./jsldata');
|
|
7
7
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
8
|
+
const processArgs = require('../utility/processArgs');
|
|
8
9
|
|
|
9
10
|
module.exports = {
|
|
10
11
|
/** @type {import('dbgate-types').OpenedSession[]} */
|
|
@@ -61,11 +62,17 @@ module.exports = {
|
|
|
61
62
|
|
|
62
63
|
handle_ping() {},
|
|
63
64
|
|
|
64
|
-
create_meta:
|
|
65
|
+
create_meta: true,
|
|
65
66
|
async create({ conid, database }) {
|
|
66
67
|
const sesid = uuidv1();
|
|
67
68
|
const connection = await connections.get({ conid });
|
|
68
|
-
const subprocess = fork(process.argv[1], [
|
|
69
|
+
const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
|
|
70
|
+
'--is-forked-api',
|
|
71
|
+
'--start-process',
|
|
72
|
+
'sessionProcess',
|
|
73
|
+
...processArgs.getPassArgs(),
|
|
74
|
+
// ...process.argv.slice(3),
|
|
75
|
+
]);
|
|
69
76
|
const newOpened = {
|
|
70
77
|
conid,
|
|
71
78
|
database,
|
|
@@ -81,10 +88,10 @@ module.exports = {
|
|
|
81
88
|
this[`handle_${msgtype}`](sesid, message);
|
|
82
89
|
});
|
|
83
90
|
subprocess.send({ msgtype: 'connect', ...connection, database });
|
|
84
|
-
return newOpened;
|
|
91
|
+
return _.pick(newOpened, ['conid', 'database', 'sesid']);
|
|
85
92
|
},
|
|
86
93
|
|
|
87
|
-
executeQuery_meta:
|
|
94
|
+
executeQuery_meta: true,
|
|
88
95
|
async executeQuery({ sesid, sql }) {
|
|
89
96
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
90
97
|
if (!session) {
|
|
@@ -98,7 +105,7 @@ module.exports = {
|
|
|
98
105
|
return { state: 'ok' };
|
|
99
106
|
},
|
|
100
107
|
|
|
101
|
-
// cancel_meta:
|
|
108
|
+
// cancel_meta: true,
|
|
102
109
|
// async cancel({ sesid }) {
|
|
103
110
|
// const session = this.opened.find((x) => x.sesid == sesid);
|
|
104
111
|
// if (!session) {
|
|
@@ -108,7 +115,7 @@ module.exports = {
|
|
|
108
115
|
// return { state: 'ok' };
|
|
109
116
|
// },
|
|
110
117
|
|
|
111
|
-
kill_meta:
|
|
118
|
+
kill_meta: true,
|
|
112
119
|
async kill({ sesid }) {
|
|
113
120
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
114
121
|
if (!session) {
|
|
@@ -119,7 +126,7 @@ module.exports = {
|
|
|
119
126
|
return { state: 'ok' };
|
|
120
127
|
},
|
|
121
128
|
|
|
122
|
-
// runCommand_meta:
|
|
129
|
+
// runCommand_meta: true,
|
|
123
130
|
// async runCommand({ conid, database, sql }) {
|
|
124
131
|
// console.log(`Running SQL command , conid=${conid}, database=${database}, sql=${sql}`);
|
|
125
132
|
// const opened = await this.ensureOpened(conid, database);
|
package/src/currentVersion.js
CHANGED
package/src/index.js
CHANGED
|
@@ -8,7 +8,7 @@ if (processArgs.startProcess) {
|
|
|
8
8
|
const proc = require('./proc');
|
|
9
9
|
const module = proc[processArgs.startProcess];
|
|
10
10
|
module.start();
|
|
11
|
-
} else if (!
|
|
11
|
+
} else if (!processArgs.checkParent && !global['API_PACKAGE'] && !global['dbgateApiModulePath']) {
|
|
12
12
|
const main = require('./main');
|
|
13
13
|
|
|
14
14
|
main.start();
|
package/src/main.js
CHANGED
|
@@ -4,12 +4,8 @@ const bodyParser = require('body-parser');
|
|
|
4
4
|
const fileUpload = require('express-fileupload');
|
|
5
5
|
const http = require('http');
|
|
6
6
|
const cors = require('cors');
|
|
7
|
-
const io = require('socket.io');
|
|
8
|
-
const fs = require('fs');
|
|
9
7
|
const getPort = require('get-port');
|
|
10
|
-
const childProcessChecker = require('./utility/childProcessChecker');
|
|
11
8
|
const path = require('path');
|
|
12
|
-
const crypto = require('crypto');
|
|
13
9
|
|
|
14
10
|
const useController = require('./utility/useController');
|
|
15
11
|
const socket = require('./utility/socket');
|
|
@@ -31,10 +27,7 @@ const queryHistory = require('./controllers/queryHistory');
|
|
|
31
27
|
|
|
32
28
|
const { rundir } = require('./utility/directories');
|
|
33
29
|
const platformInfo = require('./utility/platformInfo');
|
|
34
|
-
const processArgs = require('./utility/processArgs');
|
|
35
|
-
const timingSafeCheckToken = require('./utility/timingSafeCheckToken');
|
|
36
30
|
|
|
37
|
-
let authorization = null;
|
|
38
31
|
let checkLocalhostOrigin = null;
|
|
39
32
|
|
|
40
33
|
function start() {
|
|
@@ -43,7 +36,6 @@ function start() {
|
|
|
43
36
|
const app = express();
|
|
44
37
|
|
|
45
38
|
const server = http.createServer(app);
|
|
46
|
-
socket.set(io(server));
|
|
47
39
|
|
|
48
40
|
if (process.env.LOGIN && process.env.PASSWORD) {
|
|
49
41
|
app.use(
|
|
@@ -58,9 +50,6 @@ function start() {
|
|
|
58
50
|
}
|
|
59
51
|
|
|
60
52
|
app.use(function (req, res, next) {
|
|
61
|
-
if (authorization && !timingSafeCheckToken(req.headers.authorization, authorization)) {
|
|
62
|
-
return res.status(403).json({ error: 'Not authorized!' });
|
|
63
|
-
}
|
|
64
53
|
if (checkLocalhostOrigin) {
|
|
65
54
|
if (
|
|
66
55
|
req.headers.origin &&
|
|
@@ -81,6 +70,20 @@ function start() {
|
|
|
81
70
|
});
|
|
82
71
|
|
|
83
72
|
app.use(cors());
|
|
73
|
+
|
|
74
|
+
app.get('/stream', async function (req, res) {
|
|
75
|
+
res.set({
|
|
76
|
+
'Cache-Control': 'no-cache',
|
|
77
|
+
'Content-Type': 'text/event-stream',
|
|
78
|
+
Connection: 'keep-alive',
|
|
79
|
+
});
|
|
80
|
+
res.flushHeaders();
|
|
81
|
+
|
|
82
|
+
// Tell the client to retry every 10 seconds if connectivity is lost
|
|
83
|
+
res.write('retry: 10000\n\n');
|
|
84
|
+
socket.setSseResponse(res);
|
|
85
|
+
});
|
|
86
|
+
|
|
84
87
|
app.use(bodyParser.json({ limit: '50mb' }));
|
|
85
88
|
|
|
86
89
|
app.use(
|
|
@@ -90,20 +93,7 @@ function start() {
|
|
|
90
93
|
})
|
|
91
94
|
);
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
useController(app, '/server-connections', serverConnections);
|
|
95
|
-
useController(app, '/database-connections', databaseConnections);
|
|
96
|
-
useController(app, '/metadata', metadata);
|
|
97
|
-
useController(app, '/sessions', sessions);
|
|
98
|
-
useController(app, '/runners', runners);
|
|
99
|
-
useController(app, '/jsldata', jsldata);
|
|
100
|
-
useController(app, '/config', config);
|
|
101
|
-
useController(app, '/archive', archive);
|
|
102
|
-
useController(app, '/uploads', uploads);
|
|
103
|
-
useController(app, '/plugins', plugins);
|
|
104
|
-
useController(app, '/files', files);
|
|
105
|
-
useController(app, '/scheduler', scheduler);
|
|
106
|
-
useController(app, '/query-history', queryHistory);
|
|
96
|
+
useAllControllers(app, null);
|
|
107
97
|
|
|
108
98
|
// if (process.env.PAGES_DIRECTORY) {
|
|
109
99
|
// app.use('/pages', express.static(process.env.PAGES_DIRECTORY));
|
|
@@ -122,19 +112,7 @@ function start() {
|
|
|
122
112
|
}
|
|
123
113
|
}
|
|
124
114
|
|
|
125
|
-
if (
|
|
126
|
-
childProcessChecker();
|
|
127
|
-
|
|
128
|
-
authorization = crypto.randomBytes(32).toString('hex');
|
|
129
|
-
|
|
130
|
-
getPort().then(port => {
|
|
131
|
-
checkLocalhostOrigin = `localhost:${port}`;
|
|
132
|
-
server.listen(port, () => {
|
|
133
|
-
console.log(`DbGate API listening on port ${port}`);
|
|
134
|
-
process.send({ msgtype: 'listening', port, authorization });
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
} else if (platformInfo.isNpmDist) {
|
|
115
|
+
if (platformInfo.isNpmDist) {
|
|
138
116
|
app.use(express.static(path.join(__dirname, '../../dbgate-web/public')));
|
|
139
117
|
getPort({ port: 5000 }).then(port => {
|
|
140
118
|
server.listen(port, () => {
|
|
@@ -142,8 +120,47 @@ function start() {
|
|
|
142
120
|
});
|
|
143
121
|
});
|
|
144
122
|
} else {
|
|
145
|
-
|
|
123
|
+
const port = process.env.PORT || 3000;
|
|
124
|
+
console.log('DbGate API listening on port', port);
|
|
125
|
+
server.listen(port);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function shutdown() {
|
|
129
|
+
console.log('\nShutting down DbGate API server');
|
|
130
|
+
server.close(() => {
|
|
131
|
+
console.log('Server shut down, terminating');
|
|
132
|
+
process.exit(0);
|
|
133
|
+
});
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
console.log('Server close timeout, terminating');
|
|
136
|
+
process.exit(0);
|
|
137
|
+
}, 1000);
|
|
146
138
|
}
|
|
139
|
+
|
|
140
|
+
process.on('SIGINT', shutdown);
|
|
141
|
+
process.on('SIGTERM', shutdown);
|
|
142
|
+
process.on('SIGBREAK', shutdown);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function useAllControllers(app, electron) {
|
|
146
|
+
useController(app, electron, '/connections', connections);
|
|
147
|
+
useController(app, electron, '/server-connections', serverConnections);
|
|
148
|
+
useController(app, electron, '/database-connections', databaseConnections);
|
|
149
|
+
useController(app, electron, '/metadata', metadata);
|
|
150
|
+
useController(app, electron, '/sessions', sessions);
|
|
151
|
+
useController(app, electron, '/runners', runners);
|
|
152
|
+
useController(app, electron, '/jsldata', jsldata);
|
|
153
|
+
useController(app, electron, '/config', config);
|
|
154
|
+
useController(app, electron, '/archive', archive);
|
|
155
|
+
useController(app, electron, '/uploads', uploads);
|
|
156
|
+
useController(app, electron, '/plugins', plugins);
|
|
157
|
+
useController(app, electron, '/files', files);
|
|
158
|
+
useController(app, electron, '/scheduler', scheduler);
|
|
159
|
+
useController(app, electron, '/query-history', queryHistory);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function initializeElectronSender(electronSender) {
|
|
163
|
+
socket.setElectronSender(electronSender);
|
|
147
164
|
}
|
|
148
165
|
|
|
149
|
-
module.exports = { start };
|
|
166
|
+
module.exports = { start, useAllControllers, initializeElectronSender };
|
package/src/nativeModules.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
const argIndex = process.argv.indexOf('--native-modules');
|
|
2
|
-
const redirectFile = argIndex > 0 ? process.argv[argIndex + 1] : null;
|
|
2
|
+
const redirectFile = global['NATIVE_MODULES'] || (argIndex > 0 ? process.argv[argIndex + 1] : null);
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
function requireDynamic(file) {
|
|
5
|
+
try {
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
return __non_webpack_require__(redirectFile);
|
|
8
|
+
} catch (err) {
|
|
9
|
+
return require(redirectFile);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = redirectFile ? requireDynamic(redirectFile) : require('./nativeModulesContent');
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
// this file is generated automatically by script fillNativeModules.js, do not edit it manually
|
|
3
3
|
const content = {};
|
|
4
4
|
|
|
5
|
-
content['better-sqlite3
|
|
5
|
+
content['better-sqlite3'] = () => require('better-sqlite3');
|
|
6
6
|
|
|
7
7
|
module.exports = content;
|
|
@@ -6,10 +6,12 @@ const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
|
6
6
|
const connectUtility = require('../utility/connectUtility');
|
|
7
7
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
8
8
|
const { SqlGenerator } = require('dbgate-tools');
|
|
9
|
+
const generateDeploySql = require('../shell/generateDeploySql');
|
|
9
10
|
|
|
10
11
|
let systemConnection;
|
|
11
12
|
let storedConnection;
|
|
12
13
|
let afterConnectCallbacks = [];
|
|
14
|
+
let afterAnalyseCallbacks = [];
|
|
13
15
|
let analysedStructure = null;
|
|
14
16
|
let lastPing = null;
|
|
15
17
|
let lastStatus = null;
|
|
@@ -42,14 +44,18 @@ async function handleFullRefresh() {
|
|
|
42
44
|
process.send({ msgtype: 'structure', structure: analysedStructure });
|
|
43
45
|
process.send({ msgtype: 'structureTime', analysedTime });
|
|
44
46
|
setStatusName('ok');
|
|
47
|
+
|
|
45
48
|
loadingModel = false;
|
|
49
|
+
resolveAnalysedPromises();
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
async function handleIncrementalRefresh(forceSend) {
|
|
49
53
|
loadingModel = true;
|
|
50
54
|
const driver = requireEngineDriver(storedConnection);
|
|
51
55
|
setStatusName('checkStructure');
|
|
52
|
-
const newStructure = await checkedAsyncCall(
|
|
56
|
+
const newStructure = await checkedAsyncCall(
|
|
57
|
+
driver.analyseIncremental(systemConnection, analysedStructure, serverVersion)
|
|
58
|
+
);
|
|
53
59
|
analysedTime = new Date().getTime();
|
|
54
60
|
if (newStructure != null) {
|
|
55
61
|
analysedStructure = newStructure;
|
|
@@ -62,6 +68,7 @@ async function handleIncrementalRefresh(forceSend) {
|
|
|
62
68
|
process.send({ msgtype: 'structureTime', analysedTime });
|
|
63
69
|
setStatusName('ok');
|
|
64
70
|
loadingModel = false;
|
|
71
|
+
resolveAnalysedPromises();
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
function handleSyncModel() {
|
|
@@ -123,6 +130,20 @@ function waitConnected() {
|
|
|
123
130
|
});
|
|
124
131
|
}
|
|
125
132
|
|
|
133
|
+
function waitStructure() {
|
|
134
|
+
if (analysedStructure) return Promise.resolve();
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
afterAnalyseCallbacks.push([resolve, reject]);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function resolveAnalysedPromises() {
|
|
141
|
+
for (const [resolve] of afterAnalyseCallbacks) {
|
|
142
|
+
resolve();
|
|
143
|
+
}
|
|
144
|
+
afterAnalyseCallbacks = [];
|
|
145
|
+
}
|
|
146
|
+
|
|
126
147
|
async function handleRunScript({ msgid, sql }) {
|
|
127
148
|
await waitConnected();
|
|
128
149
|
const driver = requireEngineDriver(storedConnection);
|
|
@@ -168,7 +189,7 @@ async function handleUpdateCollection({ msgid, changeSet }) {
|
|
|
168
189
|
}
|
|
169
190
|
|
|
170
191
|
async function handleSqlPreview({ msgid, objects, options }) {
|
|
171
|
-
await
|
|
192
|
+
await waitStructure();
|
|
172
193
|
const driver = requireEngineDriver(storedConnection);
|
|
173
194
|
|
|
174
195
|
try {
|
|
@@ -188,6 +209,22 @@ async function handleSqlPreview({ msgid, objects, options }) {
|
|
|
188
209
|
}
|
|
189
210
|
}
|
|
190
211
|
|
|
212
|
+
async function handleGenerateDeploySql({ msgid, modelFolder }) {
|
|
213
|
+
await waitStructure();
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
const res = await generateDeploySql({
|
|
217
|
+
systemConnection,
|
|
218
|
+
connection: storedConnection,
|
|
219
|
+
analysedStructure,
|
|
220
|
+
modelFolder,
|
|
221
|
+
});
|
|
222
|
+
process.send({ ...res, msgtype: 'response', msgid });
|
|
223
|
+
} catch (err) {
|
|
224
|
+
process.send({ msgtype: 'response', msgid, isError: true, errorMessage: err.message });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
191
228
|
// async function handleRunCommand({ msgid, sql }) {
|
|
192
229
|
// await waitConnected();
|
|
193
230
|
// const driver = engines(storedConnection);
|
|
@@ -208,6 +245,7 @@ const messageHandlers = {
|
|
|
208
245
|
sqlPreview: handleSqlPreview,
|
|
209
246
|
ping: handlePing,
|
|
210
247
|
syncModel: handleSyncModel,
|
|
248
|
+
generateDeploySql: handleGenerateDeploySql,
|
|
211
249
|
// runCommand: handleRunCommand,
|
|
212
250
|
};
|
|
213
251
|
|
|
@@ -232,6 +270,7 @@ function start() {
|
|
|
232
270
|
try {
|
|
233
271
|
await handleMessage(message);
|
|
234
272
|
} catch (e) {
|
|
273
|
+
console.error('Error in DB connection', e);
|
|
235
274
|
process.send({ msgtype: 'error', error: e.message });
|
|
236
275
|
}
|
|
237
276
|
});
|
|
@@ -5,6 +5,7 @@ const {
|
|
|
5
5
|
databaseInfoFromYamlModel,
|
|
6
6
|
extendDatabaseInfo,
|
|
7
7
|
modelCompareDbDiffOptions,
|
|
8
|
+
enrichWithPreloadedRows,
|
|
8
9
|
} = require('dbgate-tools');
|
|
9
10
|
const importDbModel = require('../utility/importDbModel');
|
|
10
11
|
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
@@ -19,8 +20,9 @@ async function generateDeploySql({
|
|
|
19
20
|
loadedDbModel = undefined,
|
|
20
21
|
}) {
|
|
21
22
|
if (!driver) driver = requireEngineDriver(connection);
|
|
23
|
+
|
|
24
|
+
const pool = systemConnection || (await connectUtility(driver, connection));
|
|
22
25
|
if (!analysedStructure) {
|
|
23
|
-
const pool = systemConnection || (await connectUtility(driver, connection));
|
|
24
26
|
analysedStructure = await driver.analyseFull(pool);
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -39,10 +41,20 @@ async function generateDeploySql({
|
|
|
39
41
|
noRenameColumn: true,
|
|
40
42
|
};
|
|
41
43
|
const currentModelPaired = matchPairedObjects(deployedModel, currentModel, opts);
|
|
44
|
+
const currentModelPairedPreloaded = await enrichWithPreloadedRows(deployedModel, currentModelPaired, pool, driver);
|
|
45
|
+
|
|
46
|
+
// console.log('currentModelPairedPreloaded', currentModelPairedPreloaded.tables[0]);
|
|
42
47
|
// console.log('deployedModel', deployedModel.tables[0]);
|
|
43
48
|
// console.log('currentModel', currentModel.tables[0]);
|
|
44
49
|
// console.log('currentModelPaired', currentModelPaired.tables[0]);
|
|
45
|
-
const res = getAlterDatabaseScript(
|
|
50
|
+
const res = getAlterDatabaseScript(
|
|
51
|
+
currentModelPairedPreloaded,
|
|
52
|
+
deployedModel,
|
|
53
|
+
opts,
|
|
54
|
+
currentModelPairedPreloaded,
|
|
55
|
+
deployedModel,
|
|
56
|
+
driver
|
|
57
|
+
);
|
|
46
58
|
return res;
|
|
47
59
|
}
|
|
48
60
|
|