$size query (#9591)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2025-07-23 18:15:34 +05:00
committed by GitHub
parent 679a3df09f
commit 3ff80a095c
17 changed files with 274 additions and 47 deletions
+12
View File
@@ -15,6 +15,7 @@
import core, {
type AccountUuid,
type AnyAttribute,
type Arr,
type AttachedDoc,
type Class,
@@ -43,6 +44,10 @@ export function createClass (_class: Ref<Class<Obj>>, attributes: Data<Class<Obj
return txFactory.createTxCreateDoc(core.class.Class, core.space.Model, attributes, _class)
}
export function createAttribute (attribute: Data<AnyAttribute>): TxCreateDoc<Doc> {
return txFactory.createTxCreateDoc(core.class.Attribute, core.space.Model, attribute)
}
/**
* @public
*/
@@ -115,6 +120,13 @@ export function genMinModel (): TxCUD<Doc>[] {
txes.push(
createClass(core.class.Doc, { label: 'Doc' as IntlString, extends: core.class.Obj, kind: ClassifierKind.CLASS })
)
txes.push(
createClass(core.class.Attribute, {
label: 'Attribute' as IntlString,
extends: core.class.Doc,
kind: ClassifierKind.CLASS
})
)
txes.push(
createClass(core.class.Relation, {
label: 'Relation' as IntlString,
+17 -1
View File
@@ -154,7 +154,8 @@ describe('postgres operations', () => {
await operations.createDoc(taskPlugin.class.Task, '' as Ref<Space>, {
name: `my-task-${i}`,
description: `${i * i}`,
rate: 20 + i
rate: 20 + i,
arr: new Array(i).fill(i)
})
}
@@ -169,6 +170,21 @@ describe('postgres operations', () => {
const third = await client.findAll<Task>(taskPlugin.class.Task, { rate: { $in: [25, 26, 27, 28] } })
expect(third.length).toEqual(4)
const size = await client.findAll<Task>(taskPlugin.class.Task, { arr: { $size: 5 } })
expect(size.length).toEqual(1)
const sizeGt = await client.findAll<Task>(taskPlugin.class.Task, { arr: { $size: { $gt: 45 } } })
expect(sizeGt.length).toEqual(4)
const sizeGte = await client.findAll<Task>(taskPlugin.class.Task, { arr: { $size: { $gte: 45 } } })
expect(sizeGte.length).toEqual(5)
const sizeLt = await client.findAll<Task>(taskPlugin.class.Task, { arr: { $size: { $lt: 45 } } })
expect(sizeLt.length).toEqual(45)
const sizeLte = await client.findAll<Task>(taskPlugin.class.Task, { arr: { $size: { $lte: 45 } } })
expect(sizeLte.length).toEqual(46)
})
it('check update', async () => {
+11 -2
View File
@@ -1,4 +1,4 @@
import {
import core, {
type AttachedDoc,
type Class,
ClassifierKind,
@@ -11,7 +11,7 @@ import {
type Tx
} from '@hcengineering/core'
import { type IntlString, plugin, type Plugin } from '@hcengineering/platform'
import { createClass } from './minmodel'
import { createAttribute, createClass } from './minmodel'
export interface TaskComment extends AttachedDoc {
message: string
@@ -107,6 +107,15 @@ export function createTaskModel (txes: Tx[]): void {
kind: ClassifierKind.CLASS,
label: 'Comment' as IntlString,
domain: 'test-task' as Domain
}),
createAttribute({
attributeOf: taskPlugin.class.Task,
name: 'arr',
type: {
_class: core.class.ArrOf,
label: 'arr' as IntlString,
type: core.class.TypeNumber
}
})
)
}
+25
View File
@@ -1263,6 +1263,31 @@ abstract class PostgresAdapterBase implements DbAdapter {
res.push(`${tkey} @> ${vars.addArray(val, valType)}`)
}
break
case '$size': {
let v = val
let op = '='
if (typeof val === 'object') {
if (val.$gt !== undefined) {
v = val.$gt
op = '>'
} else if (val.$gte !== undefined) {
v = val.$gte
op = '>='
} else if (val.$lt !== undefined) {
v = val.$lt
op = '<'
} else if (val.$lte !== undefined) {
v = val.$lte
op = '<='
}
}
if (type === 'dataArray') {
res.push(`coalesce(jsonb_array_length(${tkey}), 0) ${op} ${vars.add(v, '::integer')}`)
} else {
res.push(`array_length(${tkey}, 1) ${op} ${vars.add(v, '::integer')}`)
}
break
}
default:
nonOperator[operator] = value[operator]
break