mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-18 23:07:02 +08:00
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);
|
||||
});
|
||||
|
||||
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 => {
|
||||
const { client } = t;
|
||||
|
||||
|
||||
@@ -152,9 +152,26 @@ export class MemoryTableAdapter implements TableAdapter {
|
||||
}
|
||||
|
||||
private match(record: any, where: WhereCondition) {
|
||||
return Array.isArray(where)
|
||||
? where.every(c => record[c.field] === c.value)
|
||||
: where.byKey === record[this.keyField];
|
||||
if (Array.isArray(where)) {
|
||||
return where.every(c => {
|
||||
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) {
|
||||
|
||||
@@ -4,9 +4,17 @@ export interface TableAdapterOptions extends TableOptions {
|
||||
keyField: string;
|
||||
}
|
||||
|
||||
type WhereEqCondition = {
|
||||
type OrmPrimitiveValues = string | number | boolean | null;
|
||||
|
||||
type SimpleCondition =
|
||||
| OrmPrimitiveValues
|
||||
| {
|
||||
not: OrmPrimitiveValues;
|
||||
};
|
||||
|
||||
type WhereSimpleCondition = {
|
||||
field: string;
|
||||
value: any;
|
||||
value: SimpleCondition;
|
||||
};
|
||||
|
||||
type WhereByKeyCondition = {
|
||||
@@ -14,8 +22,8 @@ type WhereByKeyCondition = {
|
||||
};
|
||||
|
||||
// currently only support eq condition
|
||||
// TODO(@forehalo): on the way [gt, gte, lt, lte, in, notIn, like, notLike, isNull, isNotNull, And, Or]
|
||||
export type WhereCondition = WhereEqCondition[] | WhereByKeyCondition;
|
||||
// TODO(@forehalo): on the way [gt, gte, lt, lte, in, notIn, like, notLike, Or]
|
||||
export type WhereCondition = Array<WhereSimpleCondition> | WhereByKeyCondition;
|
||||
export type Select = '*' | 'key' | string[];
|
||||
|
||||
export type InsertQuery = {
|
||||
|
||||
@@ -226,7 +226,22 @@ export class YjsTableAdapter implements TableAdapter {
|
||||
(Array.isArray(where)
|
||||
? where.length === 0
|
||||
? 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))
|
||||
);
|
||||
}
|
||||
@@ -242,7 +257,14 @@ export class YjsTableAdapter implements TableAdapter {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -116,7 +116,10 @@ export type FindEntityInput<T extends TableSchemaBuilder> = Pretty<
|
||||
T,
|
||||
{
|
||||
[key in TableDefinedFieldNames<T>]?: key extends keyof TableDefinedEntity<T>
|
||||
? TableDefinedEntity<T>[key]
|
||||
?
|
||||
| TableDefinedEntity<T>[key]
|
||||
| { not: TableDefinedEntity<T>[key] | null }
|
||||
| null
|
||||
: never;
|
||||
}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user