Skip to content

Commit

Permalink
feat(minato): optimize $.object, fix sqlite json unquote (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hieuzest authored May 7, 2024
1 parent 728b4d8 commit 72ea137
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
11 changes: 9 additions & 2 deletions packages/core/src/selection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineProperty, Dict, filterKeys, mapValues } from 'cosmokit'
import { defineProperty, Dict, filterKeys } from 'cosmokit'
import { Driver } from './driver.ts'
import { Eval, executeEval } from './eval.ts'
import { Model } from './model.ts'
Expand Down Expand Up @@ -119,7 +119,14 @@ class Executable<S = any, T = any> {
})
return Object.fromEntries(entries)
} else {
return mapValues(fields, field => this.resolveField(field))
const entries = Object.entries(fields).flatMap(([key, field]) => {
const expr = this.resolveField(field)
if (expr['$object']) {
return Object.entries(expr['$object']).map(([key2, expr2]) => [`${key}.${key2}`, expr2])
}
return [[key, expr]]
})
return Object.fromEntries(entries)
}
}

Expand Down
6 changes: 4 additions & 2 deletions packages/sqlite/src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ export class SQLiteBuilder extends Builder {
}

protected encode(value: string, encoded: boolean, pure: boolean = false, type?: Type) {
return encoded ? super.encode(value, encoded, pure, type) : value
return encoded ? super.encode(value, encoded, pure, type)
: (encoded === this.isEncoded() && !pure) ? value
: this.asEncoded(`(${value} ->> '$')`, pure ? undefined : false)
}

protected createAggr(expr: any, aggr: (value: string) => string, nonaggr?: (value: string) => string) {
Expand All @@ -83,6 +85,6 @@ export class SQLiteBuilder extends Builder {
}

protected transformJsonField(obj: string, path: string) {
return this.asEncoded(`json_extract(${obj}, '$${path}')`, false)
return this.asEncoded(`(${obj} -> '$${path}')`, true)
}
}
33 changes: 33 additions & 0 deletions packages/tests/src/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,39 @@ namespace JsonTests {
])
})

it('project in json with nested object', async () => {
const res = await database.select('bar')
.project({
'obj.num': row => row.obj.x,
'obj.str': row => row.obj.y,
'obj.str2': row => row.obj.z,
'obj.obj': row => row.obj.o,
'obj.a': row => row.obj.o.a,
})
.execute()

expect(res).to.deep.equal([
{ obj: { a: 1, num: 1, obj: { a: 1, b: '1' }, str: 'a', str2: '1' } },
{ obj: { a: 2, num: 2, obj: { a: 2, b: '2' }, str: 'b', str2: '2' } },
{ obj: { a: 3, num: 3, obj: { a: 3, b: '3' }, str: 'c', str2: '3' } },
])
})

it('$.object on row', async () => {
const res = await database.select('foo')
.project({
obj: row => $.object(row),
})
.orderBy(row => row.obj.id)
.execute()

expect(res).to.deep.equal([
{ obj: { id: 1, value: 0 } },
{ obj: { id: 2, value: 2 } },
{ obj: { id: 3, value: 2 } },
])
})

it('$.object on cell', async () => {
const res = await database.join(['foo', 'bar'], (foo, bar) => $.eq(foo.id, bar.pid))
.groupBy('bar', {
Expand Down

0 comments on commit 72ea137

Please sign in to comment.