mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 06:06:01 +00:00
Connection to MognoDB legacy
This commit is contained in:
211
plugins/dbgate-plugin-mongo/src/frontend/drivers.js
Normal file
211
plugins/dbgate-plugin-mongo/src/frontend/drivers.js
Normal file
@@ -0,0 +1,211 @@
|
||||
const { driverBase } = global.DBGATE_PACKAGES['dbgate-tools'];
|
||||
const { convertToMongoCondition, convertToMongoSort } = require('./convertToMongoCondition');
|
||||
const Dumper = require('./Dumper');
|
||||
const { mongoSplitterOptions } = require('dbgate-query-splitter/lib/options');
|
||||
const _pickBy = require('lodash/pickBy');
|
||||
const _fromPairs = require('lodash/fromPairs');
|
||||
|
||||
function mongoReplacer(key, value) {
|
||||
if (typeof value === 'bigint') {
|
||||
return { $bigint: value.toString() };
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function jsonStringifyWithObjectId(obj) {
|
||||
return JSON.stringify(obj, mongoReplacer, 2)
|
||||
.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*"\$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} */
|
||||
const dialect = {
|
||||
limitSelect: true,
|
||||
rangeSelect: true,
|
||||
offsetFetchRangeSyntax: true,
|
||||
stringEscapeChar: "'",
|
||||
fallbackDataType: 'nvarchar(max)',
|
||||
quoteIdentifier(s) {
|
||||
return `[${s}]`;
|
||||
},
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').EngineDriver} */
|
||||
const mongoDriverBase = {
|
||||
...driverBase,
|
||||
dumperClass: Dumper,
|
||||
databaseEngineTypes: ['document'],
|
||||
dialect,
|
||||
engine: 'mongo@dbgate-plugin-mongo',
|
||||
title: 'MongoDB',
|
||||
editorMode: 'javascript',
|
||||
defaultPort: 27017,
|
||||
supportsDatabaseUrl: true,
|
||||
supportsServerSummary: true,
|
||||
// temporatily disable MongoDB profiler support
|
||||
supportsDatabaseProfiler: false,
|
||||
profilerFormatterFunction: 'formatProfilerEntry@dbgate-plugin-mongo',
|
||||
profilerTimestampFunction: 'extractProfileTimestamp@dbgate-plugin-mongo',
|
||||
profilerChartAggregateFunction: 'aggregateProfileChartEntry@dbgate-plugin-mongo',
|
||||
profilerChartMeasures: [
|
||||
{ label: 'Req count/s', field: 'countPerSec' },
|
||||
{ label: 'Avg duration', field: 'avgDuration' },
|
||||
{ label: 'Max duration', field: 'maxDuration' },
|
||||
],
|
||||
databaseUrlPlaceholder: 'e.g. mongodb://username:password@mongodb.mydomain.net/dbname',
|
||||
collectionSingularLabel: 'collection',
|
||||
collectionPluralLabel: 'collections',
|
||||
|
||||
getQuerySplitterOptions: () => mongoSplitterOptions,
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (field == 'useDatabaseUrl') return true;
|
||||
if (values.useDatabaseUrl) {
|
||||
return ['databaseUrl', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field);
|
||||
}
|
||||
return ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field);
|
||||
},
|
||||
|
||||
importExportArgs: [
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'createStringId',
|
||||
label: 'Create string _id attribute',
|
||||
apiName: 'createStringId',
|
||||
direction: 'target',
|
||||
},
|
||||
],
|
||||
|
||||
newCollectionFormParams: [
|
||||
{
|
||||
type: 'text',
|
||||
label: 'Collection name',
|
||||
name: 'name',
|
||||
focused: true,
|
||||
},
|
||||
],
|
||||
|
||||
getCollectionUpdateScript(changeSet, collectionInfo) {
|
||||
let res = '';
|
||||
for (const insert of changeSet.inserts) {
|
||||
res += `db.getCollection('${insert.pureName}').insertOne(${jsonStringifyWithObjectId({
|
||||
...insert.document,
|
||||
...insert.fields,
|
||||
})});\n`;
|
||||
}
|
||||
for (const update of changeSet.updates) {
|
||||
if (update.document) {
|
||||
res += `db.getCollection('${update.pureName}').replaceOne(${jsonStringifyWithObjectId(
|
||||
update.condition
|
||||
)}, ${jsonStringifyWithObjectId({
|
||||
...update.document,
|
||||
...update.fields,
|
||||
})});\n`;
|
||||
} else {
|
||||
const set = _pickBy(update.fields, (v, k) => v !== undefined);
|
||||
const unset = _fromPairs(
|
||||
Object.keys(update.fields)
|
||||
.filter((k) => update.fields[k] === undefined)
|
||||
.map((k) => [k, ''])
|
||||
);
|
||||
const updates = {};
|
||||
if (!_.isEmpty(set)) updates.$set = set;
|
||||
if (!_.isEmpty(unset)) updates.$unset = unset;
|
||||
|
||||
res += `db.getCollection('${update.pureName}').updateOne(${jsonStringifyWithObjectId(
|
||||
update.condition
|
||||
)}, ${jsonStringifyWithObjectId(updates)});\n`;
|
||||
}
|
||||
}
|
||||
for (const del of changeSet.deletes) {
|
||||
res += `db.getCollection('${del.pureName}').deleteOne(${jsonStringifyWithObjectId(del.condition)});\n`;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
getFilterBehaviour(dataType, standardFilterBehaviours) {
|
||||
return standardFilterBehaviours.mongoFilterBehaviour;
|
||||
},
|
||||
|
||||
getCollectionExportQueryScript(collection, condition, sort) {
|
||||
return `db.getCollection('${collection}')
|
||||
.find(${jsonStringifyWithObjectId(convertToMongoCondition(condition) || {})})
|
||||
.sort(${JSON.stringify(convertToMongoSort(sort) || {})})`;
|
||||
},
|
||||
getCollectionExportQueryJson(collection, condition, sort) {
|
||||
return {
|
||||
collection,
|
||||
condition: convertToMongoCondition(condition) || {},
|
||||
sort: convertToMongoSort(sort) || {},
|
||||
};
|
||||
},
|
||||
|
||||
dataEditorTypesBehaviour: {
|
||||
parseJsonNull: true,
|
||||
parseJsonBoolean: true,
|
||||
parseNumber: true,
|
||||
parseJsonArray: true,
|
||||
parseJsonObject: true,
|
||||
parseObjectIdAsDollar: true,
|
||||
parseDateAsDollar: true,
|
||||
parseHexAsBuffer: true,
|
||||
|
||||
explicitDataType: true,
|
||||
supportNumberType: true,
|
||||
supportStringType: true,
|
||||
supportBooleanType: true,
|
||||
supportDateType: true,
|
||||
supportJsonType: true,
|
||||
supportObjectIdType: true,
|
||||
supportNullType: true,
|
||||
|
||||
supportFieldRemoval: true,
|
||||
},
|
||||
|
||||
getScriptTemplates(objectTypeField) {
|
||||
switch (objectTypeField) {
|
||||
case 'collections':
|
||||
return [
|
||||
{
|
||||
label: 'JS: dropCollection()',
|
||||
scriptTemplate: 'dropCollection',
|
||||
},
|
||||
{
|
||||
label: 'JS: find()',
|
||||
scriptTemplate: 'findCollection',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
|
||||
async getScriptTemplateContent(scriptTemplate, props) {
|
||||
switch (scriptTemplate) {
|
||||
case 'dropCollection':
|
||||
return `db.getCollection('${props.pureName}').drop();`;
|
||||
case 'findCollection':
|
||||
return `db.getCollection('${props.pureName}').find();`;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const mongoDriver = {
|
||||
...mongoDriverBase,
|
||||
};
|
||||
|
||||
const legacyMongoDriver = {
|
||||
...mongoDriverBase,
|
||||
engine: 'mongo-legacy@dbgate-plugin-mongo',
|
||||
title: 'MongoDB 4 - Legacy',
|
||||
premiumOnly: true,
|
||||
useLegacyDriver: true,
|
||||
};
|
||||
|
||||
module.exports = [mongoDriver, legacyMongoDriver];
|
||||
Reference in New Issue
Block a user