fix: postgres array operator (#200)

This commit is contained in:
ChengLei Shao 2022-02-20 10:33:26 +08:00 committed by GitHub
parent e56b2b7bf6
commit 351bb88245
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 11 deletions

View File

@ -1,7 +1,7 @@
import { mockDatabase } from '../index'; import { mockDatabase } from '../index';
import Database from '../../database'; import Database from '../../database';
describe.skip('array field operator', function () { describe('array field operator', function () {
let db: Database; let db: Database;
let Test; let Test;
@ -119,6 +119,7 @@ describe.skip('array field operator', function () {
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
expect(result[0].get('name')).toEqual('u0'); expect(result[0].get('name')).toEqual('u0');
result = await User.repository.find({ result = await User.repository.find({
filter: { filter: {
'posts.tags.$anyOf': ['t1'], 'posts.tags.$anyOf': ['t1'],

View File

@ -52,9 +52,8 @@ const isMySQL = (ctx) => {
export default { export default {
$match(value, ctx) { $match(value, ctx) {
value = escape(JSON.stringify(value.sort()), ctx);
const fieldName = getFieldName(ctx); const fieldName = getFieldName(ctx);
if (isPg(ctx)) { if (isPg(ctx)) {
return { return {
[Op.contained]: value, [Op.contained]: value,
@ -62,6 +61,8 @@ export default {
}; };
} }
value = escape(JSON.stringify(value.sort()), ctx);
if (isMySQL(ctx)) { if (isMySQL(ctx)) {
return Sequelize.literal(`JSON_CONTAINS(${fieldName}, ${value}) AND JSON_CONTAINS(${value}, ${fieldName})`); return Sequelize.literal(`JSON_CONTAINS(${fieldName}, ${value}) AND JSON_CONTAINS(${value}, ${fieldName})`);
} }
@ -76,9 +77,7 @@ export default {
value = escape(JSON.stringify(value), ctx); value = escape(JSON.stringify(value), ctx);
if (isPg(ctx)) { if (isPg(ctx)) {
return Sequelize.literal( return Sequelize.literal(`not (${fieldName} <@ ${value}::JSONB and ${fieldName} @> ${value}::JSONB)`);
`not (${fieldName} <@ ${escape(value, ctx)}::JSONB and ${fieldName} @> ${value}::JSONB)`,
);
} }
if (isMySQL(ctx)) { if (isMySQL(ctx)) {
@ -89,17 +88,18 @@ export default {
}; };
}, },
// TODO sql injection
$anyOf(value, ctx) { $anyOf(value, ctx) {
const fieldName = getFieldName(ctx);
if (isPg(ctx)) { if (isPg(ctx)) {
return { const queryValue = JSON.stringify(value).replace("'", "''");
[Op.contains]: value,
}; return Sequelize.literal(`${fieldName} @> ${escape(queryValue, ctx)}::JSONB`);
} }
if (isMySQL(ctx)) { if (isMySQL(ctx)) {
const fieldName = getFieldName(ctx);
value = escape(JSON.stringify(value), ctx); value = escape(JSON.stringify(value), ctx);
return Sequelize.literal(`JSON_OVERLAPS(${fieldName}, ${value})`); return Sequelize.literal(`JSON_OVERLAPS(${fieldName}, ${value})`);
} }