feat(infra): add not-condition to orm (#9466)
This commit is contained in:
@@ -102,6 +102,61 @@ describe('ORM entity CRUD', () => {
|
|||||||
expect(user2).toEqual(user);
|
expect(user2).toEqual(user);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should be able to filter with nullable condition', t => {
|
||||||
|
const { client } = t;
|
||||||
|
|
||||||
|
client.users.create({
|
||||||
|
name: 'u1',
|
||||||
|
email: 'e1@example.com',
|
||||||
|
});
|
||||||
|
|
||||||
|
client.users.create({
|
||||||
|
name: 'u2',
|
||||||
|
});
|
||||||
|
|
||||||
|
const users = client.users.find({
|
||||||
|
email: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(users).toHaveLength(1);
|
||||||
|
expect(users[0].email).toBeFalsy();
|
||||||
|
|
||||||
|
const users2 = client.users.find({
|
||||||
|
email: {
|
||||||
|
not: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(users2).toHaveLength(1);
|
||||||
|
expect(users2[0].email).toEqual('e1@example.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should be able to filter with `not` condition', t => {
|
||||||
|
const { client } = t;
|
||||||
|
|
||||||
|
client.users.create({
|
||||||
|
name: 'u1',
|
||||||
|
email: 'e1@example.com',
|
||||||
|
});
|
||||||
|
|
||||||
|
const users = client.users.find({
|
||||||
|
email: {
|
||||||
|
not: 'e1@example.com',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(users).toHaveLength(0);
|
||||||
|
|
||||||
|
const users2 = client.users.find({
|
||||||
|
name: {
|
||||||
|
not: 'u2',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(users2).toHaveLength(1);
|
||||||
|
expect(users2[0].name).toEqual('u1');
|
||||||
|
});
|
||||||
|
|
||||||
test('should be able to update entity', t => {
|
test('should be able to update entity', t => {
|
||||||
const { client } = t;
|
const { client } = t;
|
||||||
|
|
||||||
|
|||||||
@@ -152,9 +152,26 @@ export class MemoryTableAdapter implements TableAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private match(record: any, where: WhereCondition) {
|
private match(record: any, where: WhereCondition) {
|
||||||
return Array.isArray(where)
|
if (Array.isArray(where)) {
|
||||||
? where.every(c => record[c.field] === c.value)
|
return where.every(c => {
|
||||||
: where.byKey === record[this.keyField];
|
const value = record[c.field] || null;
|
||||||
|
const condition = c.value;
|
||||||
|
|
||||||
|
if (typeof condition === 'object') {
|
||||||
|
if (condition === null) {
|
||||||
|
return value === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('not' in condition) {
|
||||||
|
return value !== condition.not;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value === condition;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return where.byKey === record[this.keyField];
|
||||||
}
|
}
|
||||||
|
|
||||||
private dispatch(key: string, data: any) {
|
private dispatch(key: string, data: any) {
|
||||||
|
|||||||
@@ -4,9 +4,17 @@ export interface TableAdapterOptions extends TableOptions {
|
|||||||
keyField: string;
|
keyField: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type WhereEqCondition = {
|
type OrmPrimitiveValues = string | number | boolean | null;
|
||||||
|
|
||||||
|
type SimpleCondition =
|
||||||
|
| OrmPrimitiveValues
|
||||||
|
| {
|
||||||
|
not: OrmPrimitiveValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WhereSimpleCondition = {
|
||||||
field: string;
|
field: string;
|
||||||
value: any;
|
value: SimpleCondition;
|
||||||
};
|
};
|
||||||
|
|
||||||
type WhereByKeyCondition = {
|
type WhereByKeyCondition = {
|
||||||
@@ -14,8 +22,8 @@ type WhereByKeyCondition = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// currently only support eq condition
|
// currently only support eq condition
|
||||||
// TODO(@forehalo): on the way [gt, gte, lt, lte, in, notIn, like, notLike, isNull, isNotNull, And, Or]
|
// TODO(@forehalo): on the way [gt, gte, lt, lte, in, notIn, like, notLike, Or]
|
||||||
export type WhereCondition = WhereEqCondition[] | WhereByKeyCondition;
|
export type WhereCondition = Array<WhereSimpleCondition> | WhereByKeyCondition;
|
||||||
export type Select = '*' | 'key' | string[];
|
export type Select = '*' | 'key' | string[];
|
||||||
|
|
||||||
export type InsertQuery = {
|
export type InsertQuery = {
|
||||||
|
|||||||
@@ -226,7 +226,22 @@ export class YjsTableAdapter implements TableAdapter {
|
|||||||
(Array.isArray(where)
|
(Array.isArray(where)
|
||||||
? where.length === 0
|
? where.length === 0
|
||||||
? false
|
? false
|
||||||
: where.every(c => this.field(record, c.field) === c.value)
|
: where.every(c => {
|
||||||
|
const field = this.field(record, c.field);
|
||||||
|
const condition = c.value;
|
||||||
|
|
||||||
|
if (typeof condition === 'object') {
|
||||||
|
if (condition === null) {
|
||||||
|
return field === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('not' in condition) {
|
||||||
|
return field !== condition.not;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return field === condition;
|
||||||
|
})
|
||||||
: where.byKey === this.keyof(record))
|
: where.byKey === this.keyof(record))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -242,7 +257,14 @@ export class YjsTableAdapter implements TableAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private field(ty: AbstractType<any>, field: string) {
|
private field(ty: AbstractType<any>, field: string) {
|
||||||
return YMap.prototype.get.call(ty, field);
|
const val = YMap.prototype.get.call(ty, field);
|
||||||
|
|
||||||
|
// only handle null will make the day easier
|
||||||
|
if (val === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setField(ty: AbstractType<any>, field: string, value: any) {
|
private setField(ty: AbstractType<any>, field: string, value: any) {
|
||||||
|
|||||||
@@ -116,7 +116,10 @@ export type FindEntityInput<T extends TableSchemaBuilder> = Pretty<
|
|||||||
T,
|
T,
|
||||||
{
|
{
|
||||||
[key in TableDefinedFieldNames<T>]?: key extends keyof TableDefinedEntity<T>
|
[key in TableDefinedFieldNames<T>]?: key extends keyof TableDefinedEntity<T>
|
||||||
? TableDefinedEntity<T>[key]
|
?
|
||||||
|
| TableDefinedEntity<T>[key]
|
||||||
|
| { not: TableDefinedEntity<T>[key] | null }
|
||||||
|
| null
|
||||||
: never;
|
: never;
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user