dbgate-api 4.6.3 → 4.7.0

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dbgate-api",
3
3
  "main": "src/index.js",
4
- "version": "4.6.3",
4
+ "version": "4.7.0",
5
5
  "homepage": "https://dbgate.org/",
6
6
  "repository": {
7
7
  "type": "git",
@@ -25,9 +25,9 @@
25
25
  "compare-versions": "^3.6.0",
26
26
  "cors": "^2.8.5",
27
27
  "cross-env": "^6.0.3",
28
- "dbgate-query-splitter": "^4.6.3",
29
- "dbgate-sqltree": "^4.6.3",
30
- "dbgate-tools": "^4.6.3",
28
+ "dbgate-query-splitter": "^4.7.0",
29
+ "dbgate-sqltree": "^4.7.0",
30
+ "dbgate-tools": "^4.7.0",
31
31
  "diff": "^5.0.0",
32
32
  "diff2html": "^3.4.13",
33
33
  "eslint": "^6.8.0",
@@ -63,7 +63,7 @@
63
63
  "devDependencies": {
64
64
  "@types/fs-extra": "^9.0.11",
65
65
  "@types/lodash": "^4.14.149",
66
- "dbgate-types": "^4.6.3",
66
+ "dbgate-types": "^4.7.0",
67
67
  "env-cmd": "^10.1.0",
68
68
  "node-loader": "^1.0.2",
69
69
  "nodemon": "^2.0.2",
@@ -21,6 +21,7 @@ module.exports = {
21
21
  const name = await this.getNewAppFolder({ name: folder });
22
22
  await fs.mkdir(path.join(appdir(), name));
23
23
  socket.emitChanged('app-folders-changed');
24
+ this.emitChangedDbApp(folder);
24
25
  return name;
25
26
  },
26
27
 
@@ -93,6 +94,8 @@ module.exports = {
93
94
  if (!folder) throw new Error('Missing folder parameter');
94
95
  await fs.rmdir(path.join(appdir(), folder), { recursive: true });
95
96
  socket.emitChanged(`app-folders-changed`);
97
+ socket.emitChanged(`app-files-changed-${folder}`);
98
+ socket.emitChanged('used-apps-changed');
96
99
  },
97
100
 
98
101
  async getNewAppFolder({ name }) {
@@ -141,6 +141,13 @@ module.exports = {
141
141
  });
142
142
  },
143
143
 
144
+ saveText_meta: true,
145
+ async saveText({ folder, file, text }) {
146
+ await fs.writeFile(path.join(resolveArchiveFolder(folder), `${file}.jsonl`), text);
147
+ socket.emitChanged(`archive-files-changed-${folder}`);
148
+ return true;
149
+ },
150
+
144
151
  async getNewArchiveFolder({ database }) {
145
152
  const isLink = database.endsWith(database);
146
153
  const name = isLink ? database.slice(0, -5) : database;
@@ -62,9 +62,10 @@ module.exports = {
62
62
  delete this.requests[msgid];
63
63
  },
64
64
  handle_status(conid, database, { status }) {
65
+ // console.log('HANDLE SET STATUS', status);
65
66
  const existing = this.opened.find(x => x.conid == conid && x.database == database);
66
67
  if (!existing) return;
67
- if (existing.status == status) return;
68
+ if (existing.status && status && existing.status.counter > status.counter) return;
68
69
  existing.status = status;
69
70
  socket.emitChanged(`database-status-changed-${conid}-${database}`);
70
71
  },
@@ -1,6 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const lineReader = require('line-reader');
3
3
  const _ = require('lodash');
4
+ const { __ } = require('lodash/fp');
4
5
  const DatastoreProxy = require('../utility/DatastoreProxy');
5
6
  const { saveFreeTableData } = require('../utility/freeTableStorage');
6
7
  const getJslFileName = require('../utility/getJslFileName');
@@ -10,7 +11,10 @@ const socket = require('../utility/socket');
10
11
  function readFirstLine(file) {
11
12
  return new Promise((resolve, reject) => {
12
13
  lineReader.open(file, (err, reader) => {
13
- if (err) reject(err);
14
+ if (err) {
15
+ reject(err);
16
+ return;
17
+ }
14
18
  if (reader.hasNextLine()) {
15
19
  reader.nextLine((err, line) => {
16
20
  if (err) reject(err);
@@ -108,7 +112,16 @@ module.exports = {
108
112
  async getInfo({ jslid }) {
109
113
  const file = getJslFileName(jslid);
110
114
  const firstLine = await readFirstLine(file);
111
- if (firstLine) return JSON.parse(firstLine);
115
+ if (firstLine) {
116
+ const parsed = JSON.parse(firstLine);
117
+ if (parsed.__isStreamHeader) {
118
+ return parsed;
119
+ }
120
+ return {
121
+ __isStreamHeader: true,
122
+ __isDynamicStructure: true,
123
+ };
124
+ }
112
125
  return null;
113
126
  },
114
127
 
@@ -132,7 +145,7 @@ module.exports = {
132
145
  },
133
146
 
134
147
  async notifyChangedStats(stats) {
135
- console.log('SENDING STATS', JSON.stringify(stats));
148
+ // console.log('SENDING STATS', JSON.stringify(stats));
136
149
  const datastore = this.datastores[stats.jslid];
137
150
  if (datastore) await datastore.notifyChanged();
138
151
  socket.emit(`jsldata-stats-${stats.jslid}`, stats);
@@ -151,4 +164,10 @@ module.exports = {
151
164
  saveFreeTableData(getJslFileName(jslid), data);
152
165
  return true;
153
166
  },
167
+
168
+ saveText_meta: true,
169
+ async saveText({ jslid, text }) {
170
+ await fs.promises.writeFile(getJslFileName(jslid), text);
171
+ return true;
172
+ },
154
173
  };
@@ -48,7 +48,7 @@ module.exports = {
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');
51
- socket.emitChanged('query-history-changed');
51
+ socket.emit('query-history-changed');
52
52
  return 'OK';
53
53
  },
54
54
  };
@@ -1,5 +1,5 @@
1
1
 
2
2
  module.exports = {
3
- version: '4.6.3',
4
- buildTime: '2022-02-07T20:42:15.958Z'
3
+ version: '4.7.0',
4
+ buildTime: '2022-02-21T18:54:46.663Z'
5
5
  };
@@ -18,6 +18,12 @@ let lastStatus = null;
18
18
  let analysedTime = 0;
19
19
  let serverVersion;
20
20
 
21
+ let statusCounter = 0;
22
+ function getStatusCounter() {
23
+ statusCounter += 1;
24
+ return statusCounter;
25
+ }
26
+
21
27
  async function checkedAsyncCall(promise) {
22
28
  try {
23
29
  const res = await promise;
@@ -79,7 +85,7 @@ function handleSyncModel() {
79
85
  function setStatus(status) {
80
86
  const statusString = stableStringify(status);
81
87
  if (lastStatus != statusString) {
82
- process.send({ msgtype: 'status', status });
88
+ process.send({ msgtype: 'status', status: { ...status, counter: getStatusCounter() } });
83
89
  lastStatus = statusString;
84
90
  }
85
91
  }
@@ -2,12 +2,17 @@ const EnsureStreamHeaderStream = require('../utility/EnsureStreamHeaderStream');
2
2
 
3
3
  function copyStream(input, output) {
4
4
  return new Promise((resolve, reject) => {
5
- const ensureHeader = new EnsureStreamHeaderStream();
6
5
  const finisher = output['finisher'] || output;
7
6
  finisher.on('finish', resolve);
8
7
  finisher.on('error', reject);
9
- input.pipe(ensureHeader);
10
- ensureHeader.pipe(output);
8
+
9
+ if (output.requireFixedStructure) {
10
+ const ensureHeader = new EnsureStreamHeaderStream();
11
+ input.pipe(ensureHeader);
12
+ ensureHeader.pipe(output);
13
+ } else {
14
+ input.pipe(output);
15
+ }
11
16
  });
12
17
  }
13
18
 
@@ -11,10 +11,7 @@ class StringifyStream extends stream.Transform {
11
11
  let skip = false;
12
12
 
13
13
  if (!this.wasHeader) {
14
- skip =
15
- chunk.__isStreamHeader ||
16
- // TODO remove isArray test
17
- Array.isArray(chunk.columns);
14
+ skip = chunk.__isStreamHeader;
18
15
  this.wasHeader = true;
19
16
  }
20
17
  if (!skip) {
@@ -12,14 +12,14 @@ class ParseStream extends stream.Transform {
12
12
  _transform(chunk, encoding, done) {
13
13
  const obj = JSON.parse(chunk);
14
14
  if (!this.wasHeader) {
15
- if (
16
- !obj.__isStreamHeader &&
17
- // TODO remove isArray test
18
- !Array.isArray(obj.columns)
19
- ) {
20
- this.push({ columns: Object.keys(obj).map(columnName => ({ columnName })) });
15
+ if (!obj.__isStreamHeader) {
16
+ this.push({
17
+ __isStreamHeader: true,
18
+ __isDynamicStructure: true,
19
+ // columns: Object.keys(obj).map(columnName => ({ columnName })),
20
+ });
21
21
  }
22
-
22
+
23
23
  this.wasHeader = true;
24
24
  }
25
25
  if (!this.limitRows || this.rowsWritten < this.limitRows) {
@@ -10,11 +10,7 @@ class StringifyStream extends stream.Transform {
10
10
  _transform(chunk, encoding, done) {
11
11
  let skip = false;
12
12
  if (!this.wasHeader) {
13
- skip =
14
- (chunk.__isStreamHeader ||
15
- // TODO remove isArray test
16
- Array.isArray(chunk.columns)) &&
17
- !this.header;
13
+ skip = (chunk.__isStreamHeader && !this.header) || (chunk.__isStreamHeader && chunk.__isDynamicStructure);
18
14
  this.wasHeader = true;
19
15
  }
20
16
  if (!skip) {
@@ -14,11 +14,7 @@ class SqlizeStream extends stream.Transform {
14
14
  _transform(chunk, encoding, done) {
15
15
  let skip = false;
16
16
  if (!this.wasHeader) {
17
- if (
18
- chunk.__isStreamHeader ||
19
- // TODO remove isArray test
20
- Array.isArray(chunk.columns)
21
- ) {
17
+ if (chunk.__isStreamHeader) {
22
18
  skip = true;
23
19
  this.tableName = chunk.pureName;
24
20
  if (chunk.engine) {
@@ -13,11 +13,7 @@ class EnsureStreamHeaderStream extends stream.Transform {
13
13
  return;
14
14
  }
15
15
 
16
- if (
17
- !chunk.__isStreamHeader &&
18
- // TODO remove isArray test
19
- !Array.isArray(chunk.columns)
20
- ) {
16
+ if (!chunk.__isStreamHeader) {
21
17
  this.push({
22
18
  __isStreamHeader: true,
23
19
  __isComputedStructure: true,
@@ -27,6 +27,7 @@ class JsonLinesDatastore {
27
27
  this.reader = null;
28
28
  this.readedDataRowCount = 0;
29
29
  this.readedSchemaRow = false;
30
+ // this.firstRowToBeReturned = null;
30
31
  this.notifyChangedCallback = null;
31
32
  this.currentFilter = null;
32
33
  }
@@ -37,6 +38,7 @@ class JsonLinesDatastore {
37
38
  this.reader = null;
38
39
  this.readedDataRowCount = 0;
39
40
  this.readedSchemaRow = false;
41
+ // this.firstRowToBeReturned = null;
40
42
  this.currentFilter = null;
41
43
  reader.close(() => {});
42
44
  }
@@ -61,6 +63,11 @@ class JsonLinesDatastore {
61
63
  }
62
64
 
63
65
  async _readLine(parse) {
66
+ // if (this.firstRowToBeReturned) {
67
+ // const res = this.firstRowToBeReturned;
68
+ // this.firstRowToBeReturned = null;
69
+ // return res;
70
+ // }
64
71
  for (;;) {
65
72
  const line = await fetchNextLineFromReader(this.reader);
66
73
  if (!line) {
@@ -70,7 +77,11 @@ class JsonLinesDatastore {
70
77
 
71
78
  if (!this.readedSchemaRow) {
72
79
  this.readedSchemaRow = true;
73
- return true;
80
+ const parsedLine = JSON.parse(line);
81
+ if (parsedLine.__isStreamHeader) {
82
+ // skip to next line
83
+ continue;
84
+ }
74
85
  }
75
86
  if (this.currentFilter) {
76
87
  const parsedLine = JSON.parse(line);
@@ -130,11 +141,21 @@ class JsonLinesDatastore {
130
141
  this.reader = reader;
131
142
  this.currentFilter = filter;
132
143
  }
133
- if (!this.readedSchemaRow) {
134
- await this._readLine(false); // skip structure
135
- }
144
+ // if (!this.readedSchemaRow) {
145
+ // const line = await this._readLine(true); // skip structure
146
+ // if (!line.__isStreamHeader) {
147
+ // // line contains data
148
+ // this.firstRowToBeReturned = line;
149
+ // }
150
+ // }
136
151
  while (this.readedDataRowCount < offset) {
137
- await this._readLine(false);
152
+ const line = await this._readLine(false);
153
+ if (line == null) break;
154
+ // if (this.firstRowToBeReturned) {
155
+ // this.firstRowToBeReturned = null;
156
+ // } else {
157
+ // await this._readLine(false);
158
+ // }
138
159
  }
139
160
  }
140
161
 
@@ -148,7 +169,6 @@ class JsonLinesDatastore {
148
169
  res.push(line);
149
170
  }
150
171
  });
151
- // console.log('RETURN', res.length);
152
172
  return res;
153
173
  }
154
174
  }
@@ -23,7 +23,8 @@ module.exports = {
23
23
  }
24
24
  },
25
25
  emitChanged(key) {
26
- this.emit('clean-cache', key);
27
- this.emit(key);
26
+ // console.log('EMIT CHANGED', key);
27
+ this.emit('changed-cache', key);
28
+ // this.emit(key);
28
29
  },
29
30
  };
package/webpack.config.js CHANGED
@@ -10,16 +10,16 @@ var config = {
10
10
  target: 'node',
11
11
  node: {
12
12
  __dirname: false,
13
- },
13
+ },
14
14
  output: {
15
15
  path: path.resolve(__dirname, 'dist'),
16
16
  filename: 'bundle.js',
17
17
  libraryTarget: 'commonjs2',
18
18
  },
19
19
 
20
- // optimization: {
21
- // minimize: false,
22
- // },
20
+ // optimization: {
21
+ // minimize: false,
22
+ // },
23
23
 
24
24
  module: {
25
25
  rules: [
@@ -45,6 +45,9 @@ var config = {
45
45
  },
46
46
  }),
47
47
  ],
48
+ externals: {
49
+ 'better-sqlite3': 'commonjs better-sqlite3',
50
+ },
48
51
  };
49
52
 
50
53
  module.exports = config;