fix: array $noneOf with null (#220)
* fix: array $noneOf with null * fix: mysql test
This commit is contained in:
parent
5233d00373
commit
534a6e43ee
@ -26,14 +26,14 @@ describe('array field operator', function () {
|
|||||||
|
|
||||||
t1 = await Test.repository.create({
|
t1 = await Test.repository.create({
|
||||||
values: {
|
values: {
|
||||||
selected: [1, 2, 'a', 'b'],
|
selected: ['1', '2', 'a', 'b'],
|
||||||
name: 't1',
|
name: 't1',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
t2 = await Test.repository.create({
|
t2 = await Test.repository.create({
|
||||||
values: {
|
values: {
|
||||||
selected: [11, 22, 'aa', 'bb', 'cc'],
|
selected: ['11', '22', 'aa', 'bb', 'cc'],
|
||||||
name: 't2',
|
name: 't2',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -133,7 +133,7 @@ describe('array field operator', function () {
|
|||||||
test('$match', async () => {
|
test('$match', async () => {
|
||||||
const filter1 = await Test.repository.find({
|
const filter1 = await Test.repository.find({
|
||||||
filter: {
|
filter: {
|
||||||
'selected.$match': [2, 1, 'a', 'b'],
|
'selected.$match': ['2', '1', 'a', 'b'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ describe('array field operator', function () {
|
|||||||
filter: {
|
filter: {
|
||||||
$and: [
|
$and: [
|
||||||
{
|
{
|
||||||
selected: { $match: [2, 1, 'a', 'b'] },
|
selected: { $match: ['2', '1', 'a', 'b'] },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -159,7 +159,7 @@ describe('array field operator', function () {
|
|||||||
test('$notMatch', async () => {
|
test('$notMatch', async () => {
|
||||||
const filter2 = await Test.repository.find({
|
const filter2 = await Test.repository.find({
|
||||||
filter: {
|
filter: {
|
||||||
'selected.$notMatch': [1, 2, 'a', 'b'],
|
'selected.$notMatch': ['1', '2', 'a', 'b'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -193,6 +193,16 @@ describe('array field operator', function () {
|
|||||||
expect(filter3[0].get('name')).toEqual(t2.get('name'));
|
expect(filter3[0].get('name')).toEqual(t2.get('name'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('$anyOf with multiple items', async () => {
|
||||||
|
const filter3 = await Test.repository.find({
|
||||||
|
filter: {
|
||||||
|
'selected.$anyOf': ['aa', 'a', '1'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(filter3.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
test('$noneOf', async () => {
|
test('$noneOf', async () => {
|
||||||
const filter = await Test.repository.find({
|
const filter = await Test.repository.find({
|
||||||
filter: {
|
filter: {
|
||||||
@ -204,6 +214,24 @@ describe('array field operator', function () {
|
|||||||
expect(filter[0].get('name')).toEqual(t1.get('name'));
|
expect(filter[0].get('name')).toEqual(t1.get('name'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('$noneOf with null', async () => {
|
||||||
|
const t3 = await Test.repository.create({
|
||||||
|
values: {
|
||||||
|
name: 't3',
|
||||||
|
selected: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const filter = await Test.repository.find({
|
||||||
|
filter: {
|
||||||
|
'selected.$noneOf': ['a', 'aa', '1'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(filter.length).toEqual(1);
|
||||||
|
expect(filter[0].get('name')).toEqual(t3.get('name'));
|
||||||
|
});
|
||||||
|
|
||||||
test('$empty', async () => {
|
test('$empty', async () => {
|
||||||
const t3 = await Test.repository.create({
|
const t3 = await Test.repository.create({
|
||||||
values: {
|
values: {
|
||||||
|
@ -12,6 +12,7 @@ export class ArrayField extends Field {
|
|||||||
|
|
||||||
sortValue(model) {
|
sortValue(model) {
|
||||||
const oldValue = model.get(this.options.name);
|
const oldValue = model.get(this.options.name);
|
||||||
|
|
||||||
if (oldValue) {
|
if (oldValue) {
|
||||||
const newValue = oldValue.sort();
|
const newValue = oldValue.sort();
|
||||||
model.set(this.options.name, newValue);
|
model.set(this.options.name, newValue);
|
||||||
|
@ -81,9 +81,12 @@ export default {
|
|||||||
const fieldName = getFieldName(ctx);
|
const fieldName = getFieldName(ctx);
|
||||||
|
|
||||||
if (isPg(ctx)) {
|
if (isPg(ctx)) {
|
||||||
const queryValue = JSON.stringify(value).replace("'", "''");
|
return Sequelize.literal(
|
||||||
|
`${fieldName} ?| ${escape(
|
||||||
return Sequelize.literal(`${fieldName} @> ${escape(queryValue, ctx)}::JSONB`);
|
value.map((i) => `${i}`),
|
||||||
|
ctx,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMySQL(ctx)) {
|
if (isMySQL(ctx)) {
|
||||||
@ -98,23 +101,29 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
$noneOf(value, ctx) {
|
$noneOf(value, ctx) {
|
||||||
|
let where;
|
||||||
|
|
||||||
if (isPg(ctx)) {
|
if (isPg(ctx)) {
|
||||||
const fieldName = getFieldName(ctx);
|
const fieldName = getFieldName(ctx);
|
||||||
// pg single quote
|
// pg single quote
|
||||||
const queryValue = JSON.stringify(value).replace("'", "''");
|
where = Sequelize.literal(
|
||||||
return Sequelize.literal(`not (${fieldName} @> ${escape(queryValue, ctx)}::JSONB)`);
|
`not (${fieldName} ?| ${escape(
|
||||||
}
|
value.map((i) => `${i}`),
|
||||||
|
ctx,
|
||||||
if (isMySQL(ctx)) {
|
)})`,
|
||||||
|
);
|
||||||
|
} else if (isMySQL(ctx)) {
|
||||||
const fieldName = getFieldName(ctx);
|
const fieldName = getFieldName(ctx);
|
||||||
value = escape(JSON.stringify(value), ctx);
|
value = escape(JSON.stringify(value), ctx);
|
||||||
return Sequelize.literal(`NOT JSON_OVERLAPS(${fieldName}, ${value})`);
|
where = Sequelize.literal(`NOT JSON_OVERLAPS(${fieldName}, ${value})`);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
const subQuery = sqliteExistQuery(value, ctx);
|
const subQuery = sqliteExistQuery(value, ctx);
|
||||||
|
|
||||||
|
where = Sequelize.literal(`not ${subQuery}`);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[Op.and]: [Sequelize.literal(`not ${subQuery}`)],
|
[Op.or]: [where, { [Op.is]: null }],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user