mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 22:36:01 +00:00
Connection to MognoDB legacy
This commit is contained in:
@@ -42,6 +42,7 @@
|
|||||||
"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",
|
||||||
|
"mongodb-old": "npm:mongodb@^6.16.0",
|
||||||
"@mongosh/browser-runtime-electron": "^3.16.4",
|
"@mongosh/browser-runtime-electron": "^3.16.4",
|
||||||
"@mongosh/service-provider-node-driver": "^3.10.2"
|
"@mongosh/service-provider-node-driver": "^3.10.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const { EventEmitter } = require('events');
|
const { EventEmitter } = require('events');
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
const driverBase = require('../frontend/driver');
|
const driverBases = require('../frontend/drivers');
|
||||||
const Analyser = require('./Analyser');
|
const Analyser = require('./Analyser');
|
||||||
const isPromise = require('is-promise');
|
const isPromise = require('is-promise');
|
||||||
const { MongoClient, ObjectId, AbstractCursor, Long } = require('mongodb');
|
const mongodb = require('mongodb');
|
||||||
|
const oldmongodb = require('mongodb-old');
|
||||||
|
const { ObjectId } = require('mongodb');
|
||||||
|
// { MongoClient, ObjectId, AbstractCursor, Long }
|
||||||
const { EJSON } = require('bson');
|
const { EJSON } = require('bson');
|
||||||
const { serializeJsTypesForJsonStringify, deserializeJsTypesFromJsonParse, getLogger } = require('dbgate-tools');
|
const { serializeJsTypesForJsonStringify, deserializeJsTypesFromJsonParse, getLogger } = require('dbgate-tools');
|
||||||
const createBulkInsertStream = require('./createBulkInsertStream');
|
const createBulkInsertStream = require('./createBulkInsertStream');
|
||||||
@@ -18,7 +21,8 @@ let isProApp;
|
|||||||
|
|
||||||
const logger = getLogger('mongoDriver');
|
const logger = getLogger('mongoDriver');
|
||||||
|
|
||||||
function serializeMongoData(row) {
|
function serializeMongoData(row, driverBase) {
|
||||||
|
const { Long } = driverBase.useLegacyDriver ? oldmongodb : mongodb;
|
||||||
return EJSON.serialize(
|
return EJSON.serialize(
|
||||||
serializeJsTypesForJsonStringify(row, (value) => {
|
serializeJsTypesForJsonStringify(row, (value) => {
|
||||||
if (value instanceof Long) {
|
if (value instanceof Long) {
|
||||||
@@ -33,10 +37,10 @@ function serializeMongoData(row) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readCursor(cursor, options) {
|
async function readCursor(cursor, options, driverBase) {
|
||||||
options.recordset({ __isDynamicStructure: true });
|
options.recordset({ __isDynamicStructure: true });
|
||||||
await cursor.forEach((row) => {
|
await cursor.forEach((row) => {
|
||||||
options.row(serializeMongoData(row));
|
options.row(serializeMongoData(row, driverBase));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +90,8 @@ async function getScriptableDb(dbhan) {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/** @type {import('dbgate-types').EngineDriver<MongoClient, import('mongodb').Db>} */
|
/** @type {import('dbgate-types').EngineDriver<import('mongodb').MongoClient, import('mongodb').Db>} */
|
||||||
const driver = {
|
const drivers = driverBases.map((driverBase) => ({
|
||||||
...driverBase,
|
...driverBase,
|
||||||
analyserClass: Analyser,
|
analyserClass: Analyser,
|
||||||
async connect({ server, port, user, password, database, useDatabaseUrl, databaseUrl, ssl, useSshTunnel }) {
|
async connect({ server, port, user, password, database, useDatabaseUrl, databaseUrl, ssl, useSshTunnel }) {
|
||||||
@@ -120,6 +124,8 @@ const driver = {
|
|||||||
options.tlsInsecure = !ssl.rejectUnauthorized;
|
options.tlsInsecure = !ssl.rejectUnauthorized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { MongoClient } = driverBase.useLegacyDriver ? oldmongodb : mongodb;
|
||||||
|
|
||||||
const client = new MongoClient(mongoUrl, options);
|
const client = new MongoClient(mongoUrl, options);
|
||||||
await client.connect();
|
await client.connect();
|
||||||
return {
|
return {
|
||||||
@@ -314,8 +320,10 @@ const driver = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { AbstractCursor } = driverBase.useLegacyDriver ? oldmongodb : mongodb;
|
||||||
|
|
||||||
if (exprValue instanceof AbstractCursor) {
|
if (exprValue instanceof AbstractCursor) {
|
||||||
await readCursor(exprValue, options);
|
await readCursor(exprValue, options, driverBase);
|
||||||
} else if (isPromise(exprValue)) {
|
} else if (isPromise(exprValue)) {
|
||||||
try {
|
try {
|
||||||
const resValue = await exprValue;
|
const resValue = await exprValue;
|
||||||
@@ -427,7 +435,7 @@ const driver = {
|
|||||||
const cursorStream = exprValue.stream();
|
const cursorStream = exprValue.stream();
|
||||||
|
|
||||||
cursorStream.on('data', (row) => {
|
cursorStream.on('data', (row) => {
|
||||||
pass.write(serializeMongoData(row));
|
pass.write(serializeMongoData(row, driverBase));
|
||||||
});
|
});
|
||||||
|
|
||||||
// propagate error
|
// propagate error
|
||||||
@@ -487,10 +495,12 @@ const driver = {
|
|||||||
let cursor = await collection.aggregate(deserializeMongoData(convertToMongoAggregate(options.aggregate)));
|
let cursor = await collection.aggregate(deserializeMongoData(convertToMongoAggregate(options.aggregate)));
|
||||||
const rows = await cursor.toArray();
|
const rows = await cursor.toArray();
|
||||||
return {
|
return {
|
||||||
rows: rows.map(serializeMongoData).map((x) => ({
|
rows: rows
|
||||||
...x._id,
|
.map((row) => serializeMongoData(row, driverBase))
|
||||||
..._.omit(x, ['_id']),
|
.map((x) => ({
|
||||||
})),
|
...x._id,
|
||||||
|
..._.omit(x, ['_id']),
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// console.log('options.condition', JSON.stringify(options.condition, undefined, 2));
|
// console.log('options.condition', JSON.stringify(options.condition, undefined, 2));
|
||||||
@@ -500,7 +510,7 @@ const driver = {
|
|||||||
if (options.limit) cursor = cursor.limit(options.limit);
|
if (options.limit) cursor = cursor.limit(options.limit);
|
||||||
const rows = await cursor.toArray();
|
const rows = await cursor.toArray();
|
||||||
return {
|
return {
|
||||||
rows: rows.map(serializeMongoData),
|
rows: rows.map((row) => serializeMongoData(row, driverBase)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -613,10 +623,12 @@ const driver = {
|
|||||||
]);
|
]);
|
||||||
const rows = await cursor.toArray();
|
const rows = await cursor.toArray();
|
||||||
return _.uniqBy(
|
return _.uniqBy(
|
||||||
rows.map(serializeMongoData).map(({ _id }) => {
|
rows
|
||||||
if (_.isArray(_id) || _.isPlainObject(_id)) return { value: null };
|
.map((row) => serializeMongoData(row, driverBase))
|
||||||
return { value: _id };
|
.map(({ _id }) => {
|
||||||
}),
|
if (_.isArray(_id) || _.isPlainObject(_id)) return { value: null };
|
||||||
|
return { value: _id };
|
||||||
|
}),
|
||||||
(x) => x.value
|
(x) => x.value
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -753,10 +765,10 @@ const driver = {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
};
|
}));
|
||||||
|
|
||||||
driver.initialize = (dbgateEnv) => {
|
drivers.initialize = (dbgateEnv) => {
|
||||||
isProApp = dbgateEnv.isProApp;
|
isProApp = dbgateEnv.isProApp;
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = drivers;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
const driver = require('./driver');
|
const drivers = require('./drivers');
|
||||||
const {
|
const {
|
||||||
formatProfilerEntry,
|
formatProfilerEntry,
|
||||||
extractProfileTimestamp,
|
extractProfileTimestamp,
|
||||||
@@ -7,13 +7,13 @@ const {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
packageName: 'dbgate-plugin-mongo',
|
packageName: 'dbgate-plugin-mongo',
|
||||||
drivers: [driver],
|
drivers,
|
||||||
functions: {
|
functions: {
|
||||||
formatProfilerEntry,
|
formatProfilerEntry,
|
||||||
extractProfileTimestamp,
|
extractProfileTimestamp,
|
||||||
aggregateProfileChartEntry,
|
aggregateProfileChartEntry,
|
||||||
},
|
},
|
||||||
initialize(dbgateEnv) {
|
initialize(dbgateEnv) {
|
||||||
driver.initialize(dbgateEnv);
|
drivers.initialize(dbgateEnv);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ function jsonStringifyWithObjectId(obj) {
|
|||||||
return JSON.stringify(obj, mongoReplacer, 2)
|
return JSON.stringify(obj, mongoReplacer, 2)
|
||||||
.replace(/\{\s*\"\$oid\"\s*\:\s*\"([0-9a-f]+)\"\s*\}/g, (m, id) => `ObjectId("${id}")`)
|
.replace(/\{\s*\"\$oid\"\s*\:\s*\"([0-9a-f]+)\"\s*\}/g, (m, id) => `ObjectId("${id}")`)
|
||||||
.replace(/\{\s*\"\$bigint\"\s*\:\s*\"([0-9]+)\"\s*\}/g, (m, num) => `${num}n`)
|
.replace(/\{\s*\"\$bigint\"\s*\:\s*\"([0-9]+)\"\s*\}/g, (m, num) => `${num}n`)
|
||||||
.replace(/\{\s*"\$binary"\s*:\s*\{\s*"base64"\s*:\s*"([^"]+)"(?:\s*,\s*"subType"\s*:\s*"([0-9a-fA-F]{2})")?\s*\}\s*\}/g, (m, base64, subType) => {
|
.replace(
|
||||||
return `BinData(${parseInt(subType || "00", 16)}, "${base64}")`;
|
/\{\s*"\$binary"\s*:\s*\{\s*"base64"\s*:\s*"([^"]+)"(?:\s*,\s*"subType"\s*:\s*"([0-9a-fA-F]{2})")?\s*\}\s*\}/g,
|
||||||
});
|
(m, base64, subType) => {
|
||||||
|
return `BinData(${parseInt(subType || '00', 16)}, "${base64}")`;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import('dbgate-types').SqlDialect} */
|
/** @type {import('dbgate-types').SqlDialect} */
|
||||||
@@ -34,7 +37,7 @@ const dialect = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @type {import('dbgate-types').EngineDriver} */
|
/** @type {import('dbgate-types').EngineDriver} */
|
||||||
const driver = {
|
const mongoDriverBase = {
|
||||||
...driverBase,
|
...driverBase,
|
||||||
dumperClass: Dumper,
|
dumperClass: Dumper,
|
||||||
databaseEngineTypes: ['document'],
|
databaseEngineTypes: ['document'],
|
||||||
@@ -193,4 +196,16 @@ const driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
const mongoDriver = {
|
||||||
|
...mongoDriverBase,
|
||||||
|
};
|
||||||
|
|
||||||
|
const legacyMongoDriver = {
|
||||||
|
...mongoDriverBase,
|
||||||
|
engine: 'mongo-legacy@dbgate-plugin-mongo',
|
||||||
|
title: 'MongoDB 4 - Legacy',
|
||||||
|
premiumOnly: true,
|
||||||
|
useLegacyDriver: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = [mongoDriver, legacyMongoDriver];
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import driver from './driver';
|
import drivers from './drivers';
|
||||||
import { formatProfilerEntry, extractProfileTimestamp, aggregateProfileChartEntry } from './profilerFunctions';
|
import { formatProfilerEntry, extractProfileTimestamp, aggregateProfileChartEntry } from './profilerFunctions';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
packageName: 'dbgate-plugin-mongo',
|
packageName: 'dbgate-plugin-mongo',
|
||||||
drivers: [driver],
|
drivers,
|
||||||
functions: {
|
functions: {
|
||||||
formatProfilerEntry,
|
formatProfilerEntry,
|
||||||
extractProfileTimestamp,
|
extractProfileTimestamp,
|
||||||
|
|||||||
23
yarn.lock
23
yarn.lock
@@ -2669,6 +2669,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
sparse-bitfield "^3.0.3"
|
sparse-bitfield "^3.0.3"
|
||||||
|
|
||||||
|
"@mongodb-js/saslprep@^1.3.0":
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.3.2.tgz#51e5cad2f24b8759702d9cc185da0a3ef3784bad"
|
||||||
|
integrity sha512-QgA5AySqB27cGTXBFmnpifAi7HxoGUeezwo6p9dI03MuDB6Pp33zgclqVb6oVK3j6I9Vesg0+oojW2XxB59SGg==
|
||||||
|
dependencies:
|
||||||
|
sparse-bitfield "^3.0.3"
|
||||||
|
|
||||||
"@mongodb-js/socksv5@^0.0.10":
|
"@mongodb-js/socksv5@^0.0.10":
|
||||||
version "0.0.10"
|
version "0.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/@mongodb-js/socksv5/-/socksv5-0.0.10.tgz#d734c9799a5d011caaf43788e16925aca90712d8"
|
resolved "https://registry.yarnpkg.com/@mongodb-js/socksv5/-/socksv5-0.0.10.tgz#d734c9799a5d011caaf43788e16925aca90712d8"
|
||||||
@@ -6159,6 +6166,11 @@ dbgate-query-splitter@^4.11.7:
|
|||||||
resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.7.tgz#f9d53b3ceafbd76355152677b87ae453598b4a88"
|
resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.7.tgz#f9d53b3ceafbd76355152677b87ae453598b4a88"
|
||||||
integrity sha512-2J0Gc2hyZrHnrLBpI6Tw8MvP7V01eTj+SMHLeG9ggVf6Y8JB/6JBK5kPwhz77SwZw/InhpaweCUBoHFCJUv/kg==
|
integrity sha512-2J0Gc2hyZrHnrLBpI6Tw8MvP7V01eTj+SMHLeG9ggVf6Y8JB/6JBK5kPwhz77SwZw/InhpaweCUBoHFCJUv/kg==
|
||||||
|
|
||||||
|
dbgate-query-splitter@^4.11.9:
|
||||||
|
version "4.11.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.9.tgz#1461ec652caf6b44d7b94109610f497695c4aef6"
|
||||||
|
integrity sha512-WaN9VFgmIpIvpNDUFNV1P0m7TimCAk2Itgk4lKndxC+ixhersHfLfGcea5gcKS1ie8+SRoKlFsfe/MIehvOA9A==
|
||||||
|
|
||||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
@@ -10685,7 +10697,7 @@ mongodb-connection-string-url@^3.0.0:
|
|||||||
"@types/whatwg-url" "^11.0.2"
|
"@types/whatwg-url" "^11.0.2"
|
||||||
whatwg-url "^13.0.0"
|
whatwg-url "^13.0.0"
|
||||||
|
|
||||||
mongodb-connection-string-url@^3.0.1:
|
mongodb-connection-string-url@^3.0.1, mongodb-connection-string-url@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz#e223089dfa0a5fa9bf505f8aedcbc67b077b33e7"
|
resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz#e223089dfa0a5fa9bf505f8aedcbc67b077b33e7"
|
||||||
integrity sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==
|
integrity sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==
|
||||||
@@ -10698,6 +10710,15 @@ mongodb-ns@^2.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/mongodb-ns/-/mongodb-ns-2.4.2.tgz#481592316d3a2be68accbba3aca2cb660eb6da1d"
|
resolved "https://registry.yarnpkg.com/mongodb-ns/-/mongodb-ns-2.4.2.tgz#481592316d3a2be68accbba3aca2cb660eb6da1d"
|
||||||
integrity sha512-gYJjEYG4v4a1WSXgUf81OBoBRlj+Z1SlnQVO392fC/4a1CN7CLWDITajZWPFTPh/yRozYk6sHHtZwZmQhodBEA==
|
integrity sha512-gYJjEYG4v4a1WSXgUf81OBoBRlj+Z1SlnQVO392fC/4a1CN7CLWDITajZWPFTPh/yRozYk6sHHtZwZmQhodBEA==
|
||||||
|
|
||||||
|
"mongodb-old@npm:mongodb@^6.16.0":
|
||||||
|
version "6.21.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.21.0.tgz#f83355905900f2e7a912593f0315d5e2e0bda576"
|
||||||
|
integrity sha512-URyb/VXMjJ4da46OeSXg+puO39XH9DeQpWCslifrRn9JWugy0D+DvvBvkm2WxmHe61O/H19JM66p1z7RHVkZ6A==
|
||||||
|
dependencies:
|
||||||
|
"@mongodb-js/saslprep" "^1.3.0"
|
||||||
|
bson "^6.10.4"
|
||||||
|
mongodb-connection-string-url "^3.0.2"
|
||||||
|
|
||||||
mongodb-redact@^1.1.5:
|
mongodb-redact@^1.1.5:
|
||||||
version "1.1.8"
|
version "1.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/mongodb-redact/-/mongodb-redact-1.1.8.tgz#47323bd7fcdb033d75ccf539e4fa3685fa5221c5"
|
resolved "https://registry.yarnpkg.com/mongodb-redact/-/mongodb-redact-1.1.8.tgz#47323bd7fcdb033d75ccf539e4fa3685fa5221c5"
|
||||||
|
|||||||
Reference in New Issue
Block a user