feat: basic mongosh support

This commit is contained in:
Pavel
2025-07-23 04:40:52 +02:00
parent 082d0aa02f
commit b8e50737d2
4 changed files with 2096 additions and 180 deletions

2
.nvmrc
View File

@@ -1 +1 @@
v21.7.3 v24.4.1

View File

@@ -41,7 +41,9 @@
"dbgate-tools": "^6.0.0-alpha.1", "dbgate-tools": "^6.0.0-alpha.1",
"is-promise": "^4.0.0", "is-promise": "^4.0.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mongodb": "^6.3.0" "mongodb": "^6.3.0",
"@mongosh/browser-runtime-electron": "^3.16.4",
"@mongosh/service-provider-node-driver": "^3.10.2"
}, },
"optionalDependencies": { "optionalDependencies": {
"mongodb-client-encryption": "^6.1.1" "mongodb-client-encryption": "^6.1.1"

View File

@@ -5,6 +5,8 @@ const driverBase = require('../frontend/driver');
const Analyser = require('./Analyser'); const Analyser = require('./Analyser');
const { MongoClient, ObjectId, AbstractCursor, Long } = require('mongodb'); const { MongoClient, ObjectId, AbstractCursor, Long } = require('mongodb');
const { EJSON } = require('bson'); const { EJSON } = require('bson');
const { NodeDriverServiceProvider } = require('@mongosh/service-provider-node-driver');
const { ElectronRuntime } = require('@mongosh/browser-runtime-electron');
const { serializeJsTypesForJsonStringify, deserializeJsTypesFromJsonParse } = require('dbgate-tools'); const { serializeJsTypesForJsonStringify, deserializeJsTypesFromJsonParse } = require('dbgate-tools');
const createBulkInsertStream = require('./createBulkInsertStream'); const createBulkInsertStream = require('./createBulkInsertStream');
const { const {
@@ -55,7 +57,7 @@ async function getScriptableDb(dbhan) {
return db; return db;
} }
/** @type {import('dbgate-types').EngineDriver} */ /** @type {import('dbgate-types').EngineDriver<MongoClient>} */
const driver = { const driver = {
...driverBase, ...driverBase,
analyserClass: Analyser, analyserClass: Analyser,
@@ -135,23 +137,13 @@ const driver = {
// saveScriptToDatabase({ conid: connection._id, database: name }, `db.createCollection('${newCollection}')`); // saveScriptToDatabase({ conid: connection._id, database: name }, `db.createCollection('${newCollection}')`);
}, },
async stream(dbhan, sql, options) { async stream(dbhan, sql, options) {
let func;
try {
func = eval(`(db,ObjectId) => ${sql}`);
} catch (err) {
options.info({
message: 'Error compiling expression: ' + err.message,
time: new Date(),
severity: 'error',
});
options.done();
return;
}
const db = await getScriptableDb(dbhan);
let exprValue; let exprValue;
try { try {
exprValue = func(db, ObjectId.createFromHexString); const connectionString = dbhan.client.s.url;
const serviceProvider = await NodeDriverServiceProvider.connect(connectionString);
const runtime = new ElectronRuntime(serviceProvider);
exprValue = await runtime.evaluate(sql);
} catch (err) { } catch (err) {
options.info({ options.info({
message: 'Error evaluating expression: ' + err.message, message: 'Error evaluating expression: ' + err.message,
@@ -162,45 +154,19 @@ const driver = {
return; return;
} }
if (exprValue instanceof AbstractCursor) { console.log(exprValue);
await readCursor(exprValue, options);
} else if (isPromise(exprValue)) {
try {
const resValue = await exprValue;
options.info({ if (exprValue.type === 'Document') {
message: 'Command succesfully executed',
time: new Date(),
severity: 'info',
});
try {
options.info({
message: `Result: ${JSON.stringify(resValue)}`,
time: new Date(),
severity: 'info',
});
} catch (err) {
options.info({
message: `Result: ${resValue}`,
time: new Date(),
severity: 'info',
});
}
const arrayRes = findArrayResult(resValue);
if (arrayRes) {
options.recordset({ __isDynamicStructure: true }); options.recordset({ __isDynamicStructure: true });
for (const row of arrayRes) { options.row(exprValue.printable);
options.row(row); } else if (exprValue.type === 'Cursor' || exprValue.type === 'AggregationCursor') {
} options.recordset({ __isDynamicStructure: true });
} for (const doc of exprValue.printable.documents) {
} catch (err) { options.row(doc);
options.info({
message: 'Error when running command: ' + err.message,
time: new Date(),
severity: 'error',
});
} }
} else {
options.recordset({ __isDynamicStructure: true });
options.row(exprValue.printable);
} }
options.done(); options.done();

2198
yarn.lock

File diff suppressed because it is too large Load Diff