Fix/filter by array field (#1813)
* test: filter by association array field * fix: match operator in pg * chore: cast
This commit is contained in:
parent
b3d4e47ef3
commit
7b550ce5aa
@ -5,9 +5,7 @@ import { Collection } from '../../collection';
|
|||||||
describe('find with associations', () => {
|
describe('find with associations', () => {
|
||||||
let db: Database;
|
let db: Database;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
db = mockDatabase({
|
db = mockDatabase();
|
||||||
tablePrefix: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
await db.clean({ drop: true });
|
await db.clean({ drop: true });
|
||||||
});
|
});
|
||||||
@ -16,6 +14,80 @@ describe('find with associations', () => {
|
|||||||
await db.close();
|
await db.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should filter by association array field', async () => {
|
||||||
|
const User = db.collection({
|
||||||
|
name: 'users',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'posts',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const Post = db.collection({
|
||||||
|
name: 'posts',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'array',
|
||||||
|
name: 'tags',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'title',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.sync();
|
||||||
|
|
||||||
|
await User.repository.create({
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
name: 'u1',
|
||||||
|
posts: [
|
||||||
|
{
|
||||||
|
tags: ['t1'],
|
||||||
|
title: 'u1p1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const posts = await Post.repository.find({
|
||||||
|
filter: {
|
||||||
|
tags: {
|
||||||
|
$match: ['t1'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(posts.length).toEqual(1);
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
$and: [
|
||||||
|
{
|
||||||
|
posts: {
|
||||||
|
tags: {
|
||||||
|
$match: ['t1'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const results = await User.repository.find({
|
||||||
|
filter,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(results[0].get('name')).toEqual('u1');
|
||||||
|
});
|
||||||
|
|
||||||
it('should filter by association field', async () => {
|
it('should filter by association field', async () => {
|
||||||
const User = db.collection({
|
const User = db.collection({
|
||||||
name: 'users',
|
name: 'users',
|
||||||
|
@ -11,6 +11,11 @@ const escape = (value, ctx) => {
|
|||||||
return sequelize.escape(value);
|
return sequelize.escape(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getQueryInterface = (ctx) => {
|
||||||
|
const sequelize = ctx.db.sequelize;
|
||||||
|
return sequelize.getQueryInterface();
|
||||||
|
};
|
||||||
|
|
||||||
const sqliteExistQuery = (value, ctx) => {
|
const sqliteExistQuery = (value, ctx) => {
|
||||||
const fieldName = getFieldName(ctx);
|
const fieldName = getFieldName(ctx);
|
||||||
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`;
|
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`;
|
||||||
@ -45,10 +50,9 @@ export default {
|
|||||||
const fieldName = getFieldName(ctx);
|
const fieldName = getFieldName(ctx);
|
||||||
|
|
||||||
if (isPg(ctx)) {
|
if (isPg(ctx)) {
|
||||||
return {
|
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`;
|
||||||
[Op.contained]: value,
|
const queryValue = escape(JSON.stringify(value), ctx);
|
||||||
[Op.contains]: value,
|
return Sequelize.literal(`${name} @> ${queryValue}::JSONB AND ${name} <@ ${queryValue}::JSONB`);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value = escape(JSON.stringify(value.sort()), ctx);
|
value = escape(JSON.stringify(value.sort()), ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user