precise work with mongoid

This commit is contained in:
Jan Prochazka 2021-12-07 21:29:31 +01:00
parent c113266095
commit 6bd48ca29f
8 changed files with 25 additions and 34 deletions

View File

@ -8,6 +8,7 @@ export function getFilterValueExpression(value, dataType) {
if (isTypeDateTime(dataType)) return moment(value).format('YYYY-MM-DD HH:mm:ss'); if (isTypeDateTime(dataType)) return moment(value).format('YYYY-MM-DD HH:mm:ss');
if (value === true) return 'TRUE'; if (value === true) return 'TRUE';
if (value === false) return 'FALSE'; if (value === false) return 'FALSE';
if (value.$oid) return `ObjectId("${value.$oid}")`;
return `="${value}"`; return `="${value}"`;
} }

View File

@ -28,16 +28,12 @@ const numberTestCondition = () => value => ({
], ],
}); });
const idRegex = /[('"]([0-9a-f]{24})['")]/;
const objectIdTestCondition = () => value => ({ const objectIdTestCondition = () => value => ({
$or: [ $or: [
{ {
__placeholder__: { __placeholder__: { $oid: value.match(idRegex)[1] },
$regex: `.*${value}.*`,
$options: 'i',
},
},
{
__placeholder__: { $oid: value },
}, },
], ],
}); });
@ -78,7 +74,7 @@ const createParser = () => {
.map(Number) .map(Number)
.desc('number'), .desc('number'),
objectid: () => token(P.regexp(/[0-9a-f]{24}/)).desc('ObjectId'), objectid: () => token(P.regexp(/ObjectId\(['"]?[0-9a-f]{24}['"]?\)/)).desc('ObjectId'),
noQuotedString: () => P.regexp(/[^\s^,^'^"]+/).desc('string unquoted'), noQuotedString: () => P.regexp(/[^\s^,^'^"]+/).desc('string unquoted'),

View File

@ -124,6 +124,8 @@
{:else} {:else}
<span class="null">({value.data.length} bytes)</span> <span class="null">({value.data.length} bytes)</span>
{/if} {/if}
{:else if value.$oid}
<span class="value">ObjectId("{value.$oid}")</span>
{:else if _.isPlainObject(value)} {:else if _.isPlainObject(value)}
<span class="null" title={JSON.stringify(value, undefined, 2)}>(JSON)</span> <span class="null" title={JSON.stringify(value, undefined, 2)}>(JSON)</span>
{:else if _.isArray(value)} {:else if _.isArray(value)}

View File

@ -67,6 +67,7 @@ export function countColumnSizes(grider: Grider, columns, containerWidth, displa
const value = row[uqName]; const value = row[uqName];
let text = value; let text = value;
if (_.isArray(value)) text = `[${value.length} items]`; if (_.isArray(value)) text = `[${value.length} items]`;
else if (value?.$oid) text = `ObjectId("${value.$oid}")`;
const width = context.measureText(text).width + 8; const width = context.measureText(text).width + 8;
// console.log('colName', colName, text, width); // console.log('colName', colName, text, width);
columnSizes.putSizeOverride(colIndex, width); columnSizes.putSizeOverride(colIndex, width);

View File

@ -4,7 +4,7 @@
showModal(EditJsonModal, { showModal(EditJsonModal, {
json: rowData, json: rowData,
onSave: value => { onSave: value => {
if (value._id != rowData._id) { if (rowData._id && value._id != rowData._id) {
showModal(ErrorMessageModal, { message: '_id attribute cannot be changed' }); showModal(ErrorMessageModal, { message: '_id attribute cannot be changed' });
return false; return false;
} }

View File

@ -71,6 +71,7 @@ export function extractRowCopiedValue(row, col) {
if (value === undefined) value = _.get(row, col); if (value === undefined) value = _.get(row, col);
if (value === null) return '(NULL)'; if (value === null) return '(NULL)';
if (value === undefined) return '(NoField)'; if (value === undefined) return '(NoField)';
if (value && value.$oid) return `ObjectId("${value.$oid}")`;
if (value && value.type == 'Buffer' && _.isArray(value.data)) return arrayToHexString(value.data); if (value && value.type == 'Buffer' && _.isArray(value.data)) return arrayToHexString(value.data);
if (_.isPlainObject(value) || _.isArray(value)) return JSON.stringify(value); if (_.isPlainObject(value) || _.isArray(value)) return JSON.stringify(value);
return value; return value;

View File

@ -8,28 +8,20 @@ const ObjectId = require('mongodb').ObjectId;
const Cursor = require('mongodb').Cursor; const Cursor = require('mongodb').Cursor;
const createBulkInsertStream = require('./createBulkInsertStream'); const createBulkInsertStream = require('./createBulkInsertStream');
function transformMongoData(row) {
return _.mapValues(row, (v) => (v && v.constructor && v.constructor.name == 'ObjectID' ? { $oid: v.toString() } : v));
}
function readCursor(cursor, options) { function readCursor(cursor, options) {
return new Promise((resolve) => { return new Promise((resolve) => {
options.recordset({ __isDynamicStructure: true }); options.recordset({ __isDynamicStructure: true });
cursor.on('data', (data) => options.row(data)); cursor.on('data', (data) => options.row(transformMongoData(data)));
cursor.on('end', () => resolve()); cursor.on('end', () => resolve());
}); });
} }
const mongoIdRegex = /^[0-9a-f]{24}$/; function convertCondition(condition) {
function convertConditionInternal(condition) {
if (condition && _.isString(condition._id) && condition._id.match(mongoIdRegex)) {
return {
_id: {
$in: [condition._id, ObjectId(condition._id)],
},
};
}
return condition;
}
function convertConditionUser(condition) {
return _.cloneDeepWith(condition, (x) => { return _.cloneDeepWith(condition, (x) => {
if (x && x.$oid) return ObjectId(x.$oid); if (x && x.$oid) return ObjectId(x.$oid);
}); });
@ -213,16 +205,16 @@ const driver = {
try { try {
const collection = pool.__getDatabase().collection(options.pureName); const collection = pool.__getDatabase().collection(options.pureName);
if (options.countDocuments) { if (options.countDocuments) {
const count = await collection.countDocuments(convertConditionUser(options.condition) || {}); const count = await collection.countDocuments(convertCondition(options.condition) || {});
return { count }; return { count };
} else { } else {
// console.log('options.condition', JSON.stringify(options.condition, undefined, 2)); // console.log('options.condition', JSON.stringify(options.condition, undefined, 2));
let cursor = await collection.find(convertConditionUser(options.condition) || {}); let cursor = await collection.find(convertCondition(options.condition) || {});
if (options.sort) cursor = cursor.sort(options.sort); if (options.sort) cursor = cursor.sort(options.sort);
if (options.skip) cursor = cursor.skip(options.skip); if (options.skip) cursor = cursor.skip(options.skip);
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 { rows }; return { rows: rows.map(transformMongoData) };
} }
} catch (err) { } catch (err) {
return { errorMessage: err.message }; return { errorMessage: err.message };
@ -253,16 +245,16 @@ const driver = {
...update.document, ...update.document,
...update.fields, ...update.fields,
}; };
const doc = await collection.findOne(convertConditionInternal(update.condition)); const doc = await collection.findOne(convertCondition(update.condition));
if (doc) { if (doc) {
const resdoc = await collection.replaceOne(convertConditionInternal(update.condition), { const resdoc = await collection.replaceOne(convertCondition(update.condition), {
...document, ...document,
_id: doc._id, _id: doc._id,
}); });
res.replaced.push(resdoc._id); res.replaced.push(resdoc._id);
} }
} else { } else {
const resdoc = await collection.updateOne(convertConditionInternal(update.condition), { const resdoc = await collection.updateOne(convertCondition(update.condition), {
$set: update.fields, $set: update.fields,
}); });
res.updated.push(resdoc._id); res.updated.push(resdoc._id);
@ -270,7 +262,7 @@ const driver = {
} }
for (const del of changeSet.deletes) { for (const del of changeSet.deletes) {
const collection = db.collection(del.pureName); const collection = db.collection(del.pureName);
const resdoc = await collection.deleteOne(convertConditionInternal(del.condition)); const resdoc = await collection.deleteOne(convertCondition(del.condition));
res.deleted.push(resdoc._id); res.deleted.push(resdoc._id);
} }
return res; return res;

View File

@ -3,11 +3,9 @@ const { driverBase } = global.DBGATE_TOOLS;
const Dumper = require('./Dumper'); const Dumper = require('./Dumper');
const { mongoSplitterOptions } = require('dbgate-query-splitter/lib/options'); const { mongoSplitterOptions } = require('dbgate-query-splitter/lib/options');
const mongoIdRegex = /^[0-9a-f]{24}$/;
function getConditionPreview(condition) { function getConditionPreview(condition) {
if (condition && _isString(condition._id) && condition._id.match(mongoIdRegex)) { if (condition && condition._id && condition._id.$oid) {
return `{ _id: { $in: ['${condition._id}', ObjectId('${condition._id}')] } }`; return `{ _id: ObjectId('${condition._id.$oid}') }`;
} }
return JSON.stringify(condition); return JSON.stringify(condition);
} }