mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-02 03:38:16 +08:00
🐛 fix(query-editor): 修复多数据源大查询限流失效
- SQL限流:抽取查询自动限流工具,修复 SELECT 判断大小写不一致导致限制未生效 - 方言适配:按 Oracle/Dameng、SQL Server、MySQL/PostgreSQL 等方言分别注入行数限制 - 自定义驱动:支持 custom 连接根据 driver 解析 Oracle、PostgreSQL、SQL Server 等方言 - MongoDB修复:修正 db.collection.find() 解析边界,并对 find/只读 aggregate 下推 limit - Oracle优化:DSN 增加 PREFETCH_ROWS 和 LOB FETCH 参数,减少大结果集拉取开销 - 测试覆盖:补充 SQL 方言矩阵、MongoDB 限流和 Oracle DSN 参数测试 Refs #424
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { convertMongoShellToJsonCommand } from './mongodb';
|
||||
import { applyMongoQueryAutoLimit, convertMongoShellToJsonCommand } from './mongodb';
|
||||
|
||||
const parseCommand = (command: string | undefined) => JSON.parse(command || '{}');
|
||||
|
||||
describe('convertMongoShellToJsonCommand', () => {
|
||||
it('converts show dbs shell shortcut to listDatabases command', () => {
|
||||
@@ -16,4 +18,105 @@ describe('convertMongoShellToJsonCommand', () => {
|
||||
command: JSON.stringify({ listCollections: 1, filter: {}, nameOnly: true }),
|
||||
});
|
||||
});
|
||||
|
||||
it('converts find shell commands without adding implicit limit', () => {
|
||||
const result = convertMongoShellToJsonCommand('db.users.find({ active: true })');
|
||||
|
||||
expect(result.recognized).toBe(true);
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
find: 'users',
|
||||
filter: { active: true },
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps explicit find limit values from shell commands', () => {
|
||||
const result = convertMongoShellToJsonCommand('db.users.find({}).limit(10)');
|
||||
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
find: 'users',
|
||||
filter: {},
|
||||
limit: 10,
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps explicit zero limit values from shell commands', () => {
|
||||
const result = convertMongoShellToJsonCommand('db.users.find({}).limit(0)');
|
||||
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
find: 'users',
|
||||
filter: {},
|
||||
limit: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyMongoQueryAutoLimit', () => {
|
||||
it('adds limit to raw Mongo find commands', () => {
|
||||
const result = applyMongoQueryAutoLimit('{"find":"users","filter":{}}', 500);
|
||||
|
||||
expect(result.applied).toBe(true);
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
find: 'users',
|
||||
filter: {},
|
||||
limit: 500,
|
||||
});
|
||||
});
|
||||
|
||||
it('adds limit after shell find conversion', () => {
|
||||
const shell = convertMongoShellToJsonCommand('db.users.find({ active: true })');
|
||||
const result = applyMongoQueryAutoLimit(shell.command || '', 500);
|
||||
|
||||
expect(result.applied).toBe(true);
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
find: 'users',
|
||||
filter: { active: true },
|
||||
limit: 500,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not replace explicit find limits', () => {
|
||||
const result = applyMongoQueryAutoLimit('{"find":"users","filter":{},"limit":10}', 500);
|
||||
|
||||
expect(result.applied).toBe(false);
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
find: 'users',
|
||||
filter: {},
|
||||
limit: 10,
|
||||
});
|
||||
});
|
||||
|
||||
it('adds $limit to read-only aggregate pipelines', () => {
|
||||
const result = applyMongoQueryAutoLimit('{"aggregate":"users","pipeline":[{"$match":{"active":true}}],"cursor":{}}', 500);
|
||||
|
||||
expect(result.applied).toBe(true);
|
||||
expect(parseCommand(result.command)).toEqual({
|
||||
aggregate: 'users',
|
||||
pipeline: [
|
||||
{ $match: { active: true } },
|
||||
{ $limit: 500 },
|
||||
],
|
||||
cursor: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('does not add another aggregate $limit', () => {
|
||||
const command = '{"aggregate":"users","pipeline":[{"$limit":10}],"cursor":{}}';
|
||||
const result = applyMongoQueryAutoLimit(command, 500);
|
||||
|
||||
expect(result.applied).toBe(false);
|
||||
expect(result.command).toBe(command);
|
||||
});
|
||||
|
||||
it('does not alter aggregate write pipelines', () => {
|
||||
const command = '{"aggregate":"users","pipeline":[{"$match":{}},{"$out":"tmp_users"}],"cursor":{}}';
|
||||
const result = applyMongoQueryAutoLimit(command, 500);
|
||||
|
||||
expect(result.applied).toBe(false);
|
||||
expect(result.command).toBe(command);
|
||||
});
|
||||
|
||||
it('does not limit non-read or invalid commands', () => {
|
||||
expect(applyMongoQueryAutoLimit('{"count":"users","query":{}}', 500).applied).toBe(false);
|
||||
expect(applyMongoQueryAutoLimit('db.users.find({})', 500).applied).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user