mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-29 20:23:59 +00:00
mongo condition refactor
This commit is contained in:
@@ -39,13 +39,15 @@ export const datetimeFilterBehaviour: FilterBehaviour = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const mongoFilterBehaviour: FilterBehaviour = {
|
export const mongoFilterBehaviour: FilterBehaviour = {
|
||||||
compilerType: 'mongoCondition',
|
compilerType: 'sqlTree',
|
||||||
supportEquals: true,
|
supportEquals: true,
|
||||||
supportArrayTesting: true,
|
supportArrayTesting: true,
|
||||||
supportNumberLikeComparison: true,
|
supportNumberLikeComparison: true,
|
||||||
supportStringInclusion: true,
|
supportStringInclusion: true,
|
||||||
supportBooleanValues: true,
|
supportBooleanValues: true,
|
||||||
supportExistsTesting: true,
|
supportExistsTesting: true,
|
||||||
|
|
||||||
|
allowStringToken: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const evalFilterBehaviour: FilterBehaviour = {
|
export const evalFilterBehaviour: FilterBehaviour = {
|
||||||
|
|||||||
@@ -33,11 +33,18 @@
|
|||||||
const ast = parseFilter(filters[uniqueName], filterBehaviour);
|
const ast = parseFilter(filters[uniqueName], filterBehaviour);
|
||||||
// console.log('AST', ast);
|
// console.log('AST', ast);
|
||||||
const cond = _.cloneDeepWith(ast, expr => {
|
const cond = _.cloneDeepWith(ast, expr => {
|
||||||
if (expr.__placeholder__) {
|
if (expr.exprType == 'placeholder') {
|
||||||
return {
|
return {
|
||||||
[uniqueName]: expr.__placeholder__,
|
exprType: 'column',
|
||||||
|
columnName: uniqueName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (expr.__placeholder__) {
|
||||||
|
// return {
|
||||||
|
// [uniqueName]: expr.__placeholder__,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
conditions.push(cond);
|
conditions.push(cond);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -47,7 +54,8 @@
|
|||||||
|
|
||||||
return conditions.length > 0
|
return conditions.length > 0
|
||||||
? {
|
? {
|
||||||
$and: conditions,
|
conditionType: 'and',
|
||||||
|
conditions,
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const MongoClient = require('mongodb').MongoClient;
|
|||||||
const ObjectId = require('mongodb').ObjectId;
|
const ObjectId = require('mongodb').ObjectId;
|
||||||
const AbstractCursor = require('mongodb').AbstractCursor;
|
const AbstractCursor = require('mongodb').AbstractCursor;
|
||||||
const createBulkInsertStream = require('./createBulkInsertStream');
|
const createBulkInsertStream = require('./createBulkInsertStream');
|
||||||
|
const { convertToMongoCondition } = require('../frontend/convertToMongoCondition');
|
||||||
|
|
||||||
function transformMongoData(row) {
|
function transformMongoData(row) {
|
||||||
return _.cloneDeepWith(row, (x) => {
|
return _.cloneDeepWith(row, (x) => {
|
||||||
@@ -269,10 +270,13 @@ const driver = {
|
|||||||
return res.databases;
|
return res.databases;
|
||||||
},
|
},
|
||||||
async readCollection(pool, options) {
|
async readCollection(pool, options) {
|
||||||
|
const mongoCondition = convertToMongoCondition(options.condition);
|
||||||
|
console.log('******************* mongoCondition *****************')
|
||||||
|
console.log(JSON.stringify(mongoCondition, undefined, 2));
|
||||||
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(convertObjectId(options.condition) || {});
|
const count = await collection.countDocuments(convertObjectId(mongoCondition) || {});
|
||||||
return { count };
|
return { count };
|
||||||
} else if (options.aggregate) {
|
} else if (options.aggregate) {
|
||||||
let cursor = await collection.aggregate(convertObjectId(options.aggregate));
|
let cursor = await collection.aggregate(convertObjectId(options.aggregate));
|
||||||
@@ -280,7 +284,7 @@ const driver = {
|
|||||||
return { rows: rows.map(transformMongoData) };
|
return { rows: rows.map(transformMongoData) };
|
||||||
} 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(convertObjectId(options.condition) || {});
|
let cursor = await collection.find(convertObjectId(mongoCondition) || {});
|
||||||
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);
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
function convertLeftOperandToMongoColumn(left) {
|
||||||
|
if (left.exprType == 'placeholder') return '__placeholder__';
|
||||||
|
if (left.exprType == 'column') return left.columnName;
|
||||||
|
throw new Error(`Unknown left operand type ${left.exprType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertRightOperandToMongoValue(right) {
|
||||||
|
if (right.exprType == 'value') return right.value;
|
||||||
|
throw new Error(`Unknown right operand type ${right.exprType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToMongoCondition(filter) {
|
||||||
|
if (!filter) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (filter.conditionType) {
|
||||||
|
case 'and':
|
||||||
|
return {
|
||||||
|
$and: filter.conditions.map((x) => convertToMongoCondition(x)),
|
||||||
|
};
|
||||||
|
case 'or':
|
||||||
|
return {
|
||||||
|
$or: filter.conditions.map((x) => convertToMongoCondition(x)),
|
||||||
|
};
|
||||||
|
case 'binary':
|
||||||
|
switch (filter.operator) {
|
||||||
|
case '=':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$eq: convertRightOperandToMongoValue(filter.right),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
case '!=':
|
||||||
|
case '<>':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$ne: convertRightOperandToMongoValue(filter.right),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
case '<':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$lt: convertRightOperandToMongoValue(filter.right),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
case '<=':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$lte: convertRightOperandToMongoValue(filter.right),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
case '>':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$gt: convertRightOperandToMongoValue(filter.right),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
case '>=':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$gte: convertRightOperandToMongoValue(filter.right),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'isNull':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.expr)]: {
|
||||||
|
$exists: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'isNotNull':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.expr)]: {
|
||||||
|
$exists: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'not':
|
||||||
|
return {
|
||||||
|
$not: convertToMongoCondition(filter.condition),
|
||||||
|
};
|
||||||
|
case 'like':
|
||||||
|
return {
|
||||||
|
[convertLeftOperandToMongoColumn(filter.left)]: {
|
||||||
|
$regex: `${convertRightOperandToMongoValue(filter.right)}`.replace(/%/g, '.*'),
|
||||||
|
$options: 'i',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown condition type ${filter.conditionType}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
convertToMongoCondition,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user