From 81fbed7a7f3bfd73a4d15e459be2e7854f7263ad Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 16 Sep 2021 12:43:51 +0200 Subject: [PATCH] #166 filter by mongo ObjectID --- packages/filterparser/src/mongoParser.ts | 20 +++++++++++++++- .../datagrid/CollectionDataGridCore.svelte | 3 +-- .../dbgate-plugin-mongo/src/backend/driver.js | 23 +++++++++++++------ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/filterparser/src/mongoParser.ts b/packages/filterparser/src/mongoParser.ts index 454d7438..f40f907d 100644 --- a/packages/filterparser/src/mongoParser.ts +++ b/packages/filterparser/src/mongoParser.ts @@ -28,6 +28,20 @@ const numberTestCondition = () => value => ({ ], }); +const objectIdTestCondition = () => value => ({ + $or: [ + { + __placeholder__: { + $regex: `.*${value}.*`, + $options: 'i', + }, + }, + { + __placeholder__: { $oid: value }, + }, + ], +}); + const testCondition = (operator, value) => () => ({ __placeholder__: { [operator]: value, @@ -64,9 +78,12 @@ const createParser = () => { .map(Number) .desc('number'), + objectid: () => token(P.regexp(/[0-9a-f]{24}/)).desc('ObjectId'), + noQuotedString: () => P.regexp(/[^\s^,^'^"]+/).desc('string unquoted'), - value: r => P.alt(r.string1, r.string2, r.number, r.noQuotedString), + value: r => P.alt(r.objectid, r.string1, r.string2, r.number, r.noQuotedString), + valueTestObjectId: r => r.objectid.map(objectIdTestCondition()), valueTestNum: r => r.number.map(numberTestCondition()), valueTest: r => r.value.map(regexCondition('.*#VALUE#.*')), @@ -108,6 +125,7 @@ const createParser = () => { r.startsWithNot, r.endsWithNot, r.containsNot, + r.valueTestObjectId, r.valueTestNum, r.valueTest ).trim(whitespace), diff --git a/packages/web/src/datagrid/CollectionDataGridCore.svelte b/packages/web/src/datagrid/CollectionDataGridCore.svelte index eae2313f..06bff26d 100644 --- a/packages/web/src/datagrid/CollectionDataGridCore.svelte +++ b/packages/web/src/datagrid/CollectionDataGridCore.svelte @@ -26,6 +26,7 @@ if (!filters[uniqueName]) continue; try { const ast = parseFilter(filters[uniqueName], 'mongo'); + // console.log('AST', ast); const cond = _.cloneDeepWith(ast, expr => { if (expr.__placeholder__) { return { @@ -112,7 +113,6 @@ return response.data.count; } - { + if (x && x.$oid) return ObjectId(x.$oid); + }); +} + function findArrayResult(resValue) { if (!_.isPlainObject(resValue)) return null; const arrays = _.values(resValue).filter((x) => _.isArray(x)); @@ -191,10 +197,11 @@ const driver = { try { const collection = pool.__getDatabase().collection(options.pureName); if (options.countDocuments) { - const count = await collection.countDocuments(options.condition || {}); + const count = await collection.countDocuments(convertConditionUser(options.condition) || {}); return { count }; } else { - let cursor = await collection.find(options.condition || {}); + // console.log('options.condition', JSON.stringify(options.condition, undefined, 2)); + let cursor = await collection.find(convertConditionUser(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); @@ -230,22 +237,24 @@ const driver = { ...update.document, ...update.fields, }; - const doc = await collection.findOne(convertCondition(update.condition)); + const doc = await collection.findOne(convertConditionInternal(update.condition)); if (doc) { - const resdoc = await collection.replaceOne(convertCondition(update.condition), { + const resdoc = await collection.replaceOne(convertConditionInternal(update.condition), { ...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(convertConditionInternal(update.condition), { + $set: 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(convertConditionInternal(del.condition)); res.deleted.push(resdoc._id); } return res;