From fca00ed248c0d4add98d26ecdbd8b395d598b677 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Wed, 8 Dec 2021 21:19:46 +0100 Subject: [PATCH] suport mongo ObjectId in data editor --- .../web/src/datagrid/InplaceEditor.svelte | 10 +++- .../web/src/jsonview/CollectionJsonRow.svelte | 2 +- .../dbgate-plugin-mongo/src/backend/driver.js | 20 ++++---- .../src/frontend/driver.js | 50 ++++++++----------- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/packages/web/src/datagrid/InplaceEditor.svelte b/packages/web/src/datagrid/InplaceEditor.svelte index e39d20da..6208225b 100644 --- a/packages/web/src/datagrid/InplaceEditor.svelte +++ b/packages/web/src/datagrid/InplaceEditor.svelte @@ -1,6 +1,7 @@ @@ -28,7 +36,7 @@ export let onSetValue; export let width; export let cellValue; - export let fillParent=false; + export let fillParent = false; let domEditor; diff --git a/packages/web/src/jsonview/CollectionJsonRow.svelte b/packages/web/src/jsonview/CollectionJsonRow.svelte index c0daca2d..2967da3c 100644 --- a/packages/web/src/jsonview/CollectionJsonRow.svelte +++ b/packages/web/src/jsonview/CollectionJsonRow.svelte @@ -4,7 +4,7 @@ showModal(EditJsonModal, { json: rowData, onSave: value => { - if (rowData._id && value._id != rowData._id) { + if (grider.getRowStatus(rowIndex).status != 'inserted' && rowData._id && value._id != rowData._id) { showModal(ErrorMessageModal, { message: '_id attribute cannot be changed' }); return false; } diff --git a/plugins/dbgate-plugin-mongo/src/backend/driver.js b/plugins/dbgate-plugin-mongo/src/backend/driver.js index 99a6160b..6c3b2809 100644 --- a/plugins/dbgate-plugin-mongo/src/backend/driver.js +++ b/plugins/dbgate-plugin-mongo/src/backend/driver.js @@ -21,7 +21,7 @@ function readCursor(cursor, options) { }); } -function convertCondition(condition) { +function convertObjectId(condition) { return _.cloneDeepWith(condition, (x) => { if (x && x.$oid) return ObjectId(x.$oid); }); @@ -205,11 +205,11 @@ const driver = { try { const collection = pool.__getDatabase().collection(options.pureName); if (options.countDocuments) { - const count = await collection.countDocuments(convertCondition(options.condition) || {}); + const count = await collection.countDocuments(convertObjectId(options.condition) || {}); return { count }; } else { // console.log('options.condition', JSON.stringify(options.condition, undefined, 2)); - let cursor = await collection.find(convertCondition(options.condition) || {}); + let cursor = await collection.find(convertObjectId(options.condition) || {}); if (options.sort) cursor = cursor.sort(options.sort); if (options.skip) cursor = cursor.skip(options.skip); if (options.limit) cursor = cursor.limit(options.limit); @@ -235,7 +235,7 @@ const driver = { ...insert.document, ...insert.fields, }; - const resdoc = await collection.insert(document); + const resdoc = await collection.insert(convertObjectId(document)); res.inserted.push(resdoc._id); } for (const update of changeSet.updates) { @@ -245,24 +245,24 @@ const driver = { ...update.document, ...update.fields, }; - const doc = await collection.findOne(convertCondition(update.condition)); + const doc = await collection.findOne(convertObjectId(update.condition)); if (doc) { - const resdoc = await collection.replaceOne(convertCondition(update.condition), { - ...document, + const resdoc = await collection.replaceOne(convertObjectId(update.condition), { + ...convertObjectId(document), _id: doc._id, }); res.replaced.push(resdoc._id); } } else { - const resdoc = await collection.updateOne(convertCondition(update.condition), { - $set: update.fields, + const resdoc = await collection.updateOne(convertObjectId(update.condition), { + $set: convertObjectId(update.fields), }); res.updated.push(resdoc._id); } } for (const del of changeSet.deletes) { const collection = db.collection(del.pureName); - const resdoc = await collection.deleteOne(convertCondition(del.condition)); + const resdoc = await collection.deleteOne(convertObjectId(del.condition)); res.deleted.push(resdoc._id); } return res; diff --git a/plugins/dbgate-plugin-mongo/src/frontend/driver.js b/plugins/dbgate-plugin-mongo/src/frontend/driver.js index 1ccf067f..ac23a53b 100644 --- a/plugins/dbgate-plugin-mongo/src/frontend/driver.js +++ b/plugins/dbgate-plugin-mongo/src/frontend/driver.js @@ -3,11 +3,11 @@ const { driverBase } = global.DBGATE_TOOLS; const Dumper = require('./Dumper'); const { mongoSplitterOptions } = require('dbgate-query-splitter/lib/options'); -function getConditionPreview(condition) { - if (condition && condition._id && condition._id.$oid) { - return `{ _id: ObjectId('${condition._id.$oid}') }`; - } - return JSON.stringify(condition); +function jsonStringifyWithObjectId(obj) { + return JSON.stringify(obj, undefined, 2).replace( + /\{\s*\"\$oid\"\s*\:\s*\"([0-9a-f]+)\"\s*\}/g, + (m, id) => `ObjectId("${id}")` + ); } /** @type {import('dbgate-types').SqlDialect} */ @@ -47,37 +47,29 @@ const driver = { getCollectionUpdateScript(changeSet) { let res = ''; for (const insert of changeSet.inserts) { - res += `db.${insert.pureName}.insert(${JSON.stringify( - { - ...insert.document, - ...insert.fields, - }, - undefined, - 2 - )});\n`; + res += `db.${insert.pureName}.insert(${jsonStringifyWithObjectId({ + ...insert.document, + ...insert.fields, + })});\n`; } for (const update of changeSet.updates) { if (update.document) { - res += `db.${update.pureName}.replaceOne(${getConditionPreview(update.condition)}, ${JSON.stringify( - { - ...update.document, - ...update.fields, - }, - undefined, - 2 - )});\n`; + res += `db.${update.pureName}.replaceOne(${jsonStringifyWithObjectId( + update.condition + )}, ${jsonStringifyWithObjectId({ + ...update.document, + ...update.fields, + })});\n`; } else { - res += `db.${update.pureName}.updateOne(${getConditionPreview(update.condition)}, ${JSON.stringify( - { - $set: update.fields, - }, - undefined, - 2 - )});\n`; + res += `db.${update.pureName}.updateOne(${jsonStringifyWithObjectId( + update.condition + )}, ${jsonStringifyWithObjectId({ + $set: update.fields, + })});\n`; } } for (const del of changeSet.deletes) { - res += `db.${del.pureName}.deleteOne(${getConditionPreview(del.condition)});\n`; + res += `db.${del.pureName}.deleteOne(${jsonStringifyWithObjectId(del.condition)});\n`; } return res; },