@based/db 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/darwin_aarch64/include/selva/db.h +3 -0
- package/dist/lib/darwin_aarch64/include/selva/fields.h +1 -2
- package/dist/lib/darwin_aarch64/include/selva/history.h +16 -1
- package/dist/lib/darwin_aarch64/include/selva/types.h +4 -0
- package/dist/lib/darwin_aarch64/libnode-v20.11.1.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v20.18.1.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.13.0.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +3 -0
- package/dist/lib/linux_aarch64/include/selva/fields.h +1 -2
- package/dist/lib/linux_aarch64/include/selva/history.h +16 -1
- package/dist/lib/linux_aarch64/include/selva/types.h +4 -0
- package/dist/lib/linux_aarch64/libnode-v20.11.1.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v20.18.1.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v22.13.0.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +3 -0
- package/dist/lib/linux_x86_64/include/selva/fields.h +1 -2
- package/dist/lib/linux_x86_64/include/selva/history.h +16 -1
- package/dist/lib/linux_x86_64/include/selva/types.h +4 -0
- package/dist/lib/linux_x86_64/libnode-v20.11.1.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v20.18.1.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v22.13.0.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/crc32.js +0 -276
- package/dist/src/client/modify/ModifyRes.d.ts +4 -2
- package/dist/src/client/modify/ModifyRes.js +11 -6
- package/dist/src/client/modify/alias.js +2 -2
- package/dist/src/client/modify/cardinality.js +6 -1
- package/dist/src/client/modify/create.js +8 -9
- package/dist/src/client/modify/references/reference.js +14 -7
- package/dist/src/client/modify/references/references.js +10 -4
- package/dist/src/client/modify/string.js +2 -2
- package/dist/src/client/modify/text.js +1 -1
- package/dist/src/client/modify/types.d.ts +3 -1
- package/dist/src/client/modify/types.js +2 -0
- package/dist/src/client/modify/update.js +1 -1
- package/dist/src/client/operations.d.ts +2 -2
- package/dist/src/client/operations.js +19 -3
- package/dist/src/client/query/BasedDbQuery.d.ts +4 -3
- package/dist/src/client/query/BasedDbQuery.js +14 -6
- package/dist/src/client/query/BasedIterable.js +3 -10
- package/dist/src/client/query/display.d.ts +6 -0
- package/dist/src/client/query/display.js +52 -1
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +9 -8
- package/dist/src/client/query/filter/createReferenceFilter.js +5 -4
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +6 -10
- package/dist/src/client/query/filter/toBuffer.js +1 -6
- package/dist/src/client/query/include/props.js +14 -6
- package/dist/src/client/query/include/utils.js +2 -2
- package/dist/src/client/query/include/walk.js +1 -7
- package/dist/src/client/query/queryDef.d.ts +1 -1
- package/dist/src/client/query/queryDef.js +4 -3
- package/dist/src/client/query/registerQuery.js +1 -0
- package/dist/src/client/query/search/index.js +12 -6
- package/dist/src/client/query/sort.js +7 -6
- package/dist/src/client/query/thresholds.d.ts +0 -1
- package/dist/src/client/query/thresholds.js +0 -8
- package/dist/src/client/query/toBuffer.js +0 -3
- package/dist/src/client/query/types.d.ts +2 -0
- package/dist/src/client/query/validation.d.ts +32 -0
- package/dist/src/client/query/validation.js +237 -114
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +17 -2
- package/dist/src/native.d.ts +2 -0
- package/dist/src/native.js +6 -0
- package/dist/src/server/index.d.ts +8 -6
- package/dist/src/server/index.js +56 -30
- package/dist/src/server/migrate/index.js +10 -2
- package/dist/src/server/migrate/worker.js +1 -1
- package/dist/src/server/schema/typeDef.js +35 -25
- package/dist/src/server/schema/types.d.ts +10 -5
- package/dist/src/server/schema/types.js +1 -1
- package/package.json +5 -3
|
@@ -3,14 +3,19 @@ import { setCursor } from '../setCursor.js';
|
|
|
3
3
|
import { DELETE, RANGE_ERR } from '../types.js';
|
|
4
4
|
import { getEdgeSize, writeEdges } from './edge.js';
|
|
5
5
|
import { dbUpdateFromUpsert } from './references.js';
|
|
6
|
-
function writeRef(id, ctx, schema, def, parentId, modifyOp, hasEdges) {
|
|
6
|
+
function writeRef(id, ctx, schema, def, parentId, modifyOp, hasEdges, isTmpId) {
|
|
7
7
|
if (ctx.len + 16 > ctx.max) {
|
|
8
8
|
return RANGE_ERR;
|
|
9
9
|
}
|
|
10
10
|
ctx.markNodeDirty(ctx.db.schemaTypesParsed[def.inverseTypeName], id);
|
|
11
11
|
setCursor(ctx, schema, def.prop, def.typeIndex, parentId, modifyOp);
|
|
12
12
|
ctx.buf[ctx.len++] = modifyOp;
|
|
13
|
-
|
|
13
|
+
if (isTmpId) {
|
|
14
|
+
ctx.buf[ctx.len++] = hasEdges ? 2 : 3;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
ctx.buf[ctx.len++] = hasEdges ? 1 : 0;
|
|
18
|
+
}
|
|
14
19
|
ctx.buf[ctx.len++] = id;
|
|
15
20
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
16
21
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
@@ -18,20 +23,22 @@ function writeRef(id, ctx, schema, def, parentId, modifyOp, hasEdges) {
|
|
|
18
23
|
}
|
|
19
24
|
function singleReferenceEdges(ref, ctx, schema, def, parentId, modifyOp) {
|
|
20
25
|
let id = ref.id;
|
|
26
|
+
let isTmpId;
|
|
21
27
|
if (typeof id !== 'number') {
|
|
22
28
|
if (id instanceof ModifyState) {
|
|
23
29
|
if (id.error) {
|
|
24
30
|
return id.error;
|
|
25
31
|
}
|
|
32
|
+
isTmpId = !id.resolved;
|
|
26
33
|
id = id.tmpId;
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
if (id > 0) {
|
|
30
37
|
const edgesLen = def.edgesTotalLen || getEdgeSize(def, ref);
|
|
31
38
|
if (edgesLen === 0) {
|
|
32
|
-
return writeRef(id, ctx, schema, def, parentId, modifyOp, false);
|
|
39
|
+
return writeRef(id, ctx, schema, def, parentId, modifyOp, false, isTmpId);
|
|
33
40
|
}
|
|
34
|
-
let err = writeRef(id, ctx, schema, def, parentId, modifyOp, true);
|
|
41
|
+
let err = writeRef(id, ctx, schema, def, parentId, modifyOp, true, isTmpId);
|
|
35
42
|
if (err) {
|
|
36
43
|
return err;
|
|
37
44
|
}
|
|
@@ -63,20 +70,20 @@ export function writeReference(value, ctx, schema, def, res, modifyOp) {
|
|
|
63
70
|
ctx.buf[ctx.len++] = DELETE;
|
|
64
71
|
}
|
|
65
72
|
else if (typeof value === 'number') {
|
|
66
|
-
return writeRef(value, ctx, schema, def, res.tmpId, modifyOp, false);
|
|
73
|
+
return writeRef(value, ctx, schema, def, res.tmpId, modifyOp, false, false);
|
|
67
74
|
}
|
|
68
75
|
else if (value instanceof ModifyState) {
|
|
69
76
|
if (value.error) {
|
|
70
77
|
return value.error;
|
|
71
78
|
}
|
|
72
|
-
return writeRef(value.tmpId, ctx, schema, def, res.tmpId, modifyOp, false);
|
|
79
|
+
return writeRef(value.tmpId, ctx, schema, def, res.tmpId, modifyOp, false, !value.resolved);
|
|
73
80
|
}
|
|
74
81
|
else if (typeof value === 'object' && value !== null) {
|
|
75
82
|
if (def.edges) {
|
|
76
83
|
return singleReferenceEdges(value, ctx, schema, def, res.tmpId, modifyOp);
|
|
77
84
|
}
|
|
78
85
|
else if (typeof value.id === 'number') {
|
|
79
|
-
return writeRef(value.id, ctx, schema, def, res.tmpId, modifyOp, false);
|
|
86
|
+
return writeRef(value.id, ctx, schema, def, res.tmpId, modifyOp, false, false);
|
|
80
87
|
}
|
|
81
88
|
else if (typeof value.upsert === 'object' && value.upsert !== null) {
|
|
82
89
|
dbUpdateFromUpsert(ctx, schema, def, res, ctx.db.upsert(def.inverseTypeName, value.upsert));
|
|
@@ -130,12 +130,14 @@ function appendRefs(def, ctx, modifyOp, refs, op, remaining) {
|
|
|
130
130
|
const ref = refs[i];
|
|
131
131
|
let id;
|
|
132
132
|
let index;
|
|
133
|
+
let isTmpId;
|
|
133
134
|
if (typeof ref === 'object') {
|
|
134
135
|
if (ref instanceof ModifyState) {
|
|
135
136
|
if (ref.error) {
|
|
136
137
|
return ref.error;
|
|
137
138
|
}
|
|
138
139
|
id = ref.tmpId;
|
|
140
|
+
isTmpId = !ref.resolved;
|
|
139
141
|
}
|
|
140
142
|
else if (ref.id instanceof ModifyState) {
|
|
141
143
|
if (ref.id.error) {
|
|
@@ -143,6 +145,7 @@ function appendRefs(def, ctx, modifyOp, refs, op, remaining) {
|
|
|
143
145
|
}
|
|
144
146
|
id = ref.id.tmpId;
|
|
145
147
|
index = ref.$index;
|
|
148
|
+
isTmpId = !ref.id.resolved;
|
|
146
149
|
}
|
|
147
150
|
else if (ref.id > 0) {
|
|
148
151
|
id = ref.id;
|
|
@@ -163,7 +166,7 @@ function appendRefs(def, ctx, modifyOp, refs, op, remaining) {
|
|
|
163
166
|
if (ctx.len + 9 > ctx.max) {
|
|
164
167
|
return RANGE_ERR;
|
|
165
168
|
}
|
|
166
|
-
ctx.buf[ctx.len++] = 1;
|
|
169
|
+
ctx.buf[ctx.len++] = isTmpId ? 5 : 1;
|
|
167
170
|
ctx.buf[ctx.len++] = id;
|
|
168
171
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
169
172
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
@@ -173,7 +176,7 @@ function appendRefs(def, ctx, modifyOp, refs, op, remaining) {
|
|
|
173
176
|
if (ctx.len + 13 > ctx.max) {
|
|
174
177
|
return RANGE_ERR;
|
|
175
178
|
}
|
|
176
|
-
ctx.buf[ctx.len++] = 2;
|
|
179
|
+
ctx.buf[ctx.len++] = isTmpId ? 6 : 2;
|
|
177
180
|
ctx.buf[ctx.len++] = id;
|
|
178
181
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
179
182
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
@@ -202,7 +205,7 @@ function appendRefs(def, ctx, modifyOp, refs, op, remaining) {
|
|
|
202
205
|
if (ctx.len + 5 > ctx.max) {
|
|
203
206
|
return RANGE_ERR;
|
|
204
207
|
}
|
|
205
|
-
ctx.buf[ctx.len++] = 0;
|
|
208
|
+
ctx.buf[ctx.len++] = isTmpId ? 4 : 0;
|
|
206
209
|
ctx.buf[ctx.len++] = id;
|
|
207
210
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
208
211
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
@@ -212,7 +215,7 @@ function appendRefs(def, ctx, modifyOp, refs, op, remaining) {
|
|
|
212
215
|
if (ctx.len + 9 > ctx.max) {
|
|
213
216
|
return RANGE_ERR;
|
|
214
217
|
}
|
|
215
|
-
ctx.buf[ctx.len++] = 3;
|
|
218
|
+
ctx.buf[ctx.len++] = isTmpId ? 7 : 3;
|
|
216
219
|
ctx.buf[ctx.len++] = id;
|
|
217
220
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
218
221
|
ctx.buf[ctx.len++] = id >>>= 8;
|
|
@@ -255,6 +258,9 @@ function putRefs(def, ctx, modifyOp, refs, op) {
|
|
|
255
258
|
if (ref.error) {
|
|
256
259
|
return ref.error;
|
|
257
260
|
}
|
|
261
|
+
if (!ref.resolved) {
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
258
264
|
ref = ref.tmpId;
|
|
259
265
|
ctx.buf[ctx.len++] = ref;
|
|
260
266
|
ctx.buf[ctx.len++] = ref >>>= 8;
|
|
@@ -29,8 +29,8 @@ export function writeString(lang, value, ctx, def, t, parentId, modifyOp) {
|
|
|
29
29
|
return RANGE_ERR;
|
|
30
30
|
}
|
|
31
31
|
if (modifyOp === CREATE) {
|
|
32
|
-
def.
|
|
33
|
-
ctx.
|
|
32
|
+
def.seperateSort.bufferTmp[t.prop] = 2;
|
|
33
|
+
ctx.hasSortField++;
|
|
34
34
|
}
|
|
35
35
|
setCursor(ctx, def, t.prop, t.typeIndex, parentId, modifyOp);
|
|
36
36
|
// TODO if buffer check if second byte is zero or one
|
|
@@ -3,7 +3,7 @@ import { writeString } from './string.js';
|
|
|
3
3
|
export function writeText(value, ctx, def, t, res, modifyOp) {
|
|
4
4
|
// todo proper fallback as well
|
|
5
5
|
if (value && typeof value !== 'object') {
|
|
6
|
-
const err = writeString(res.
|
|
6
|
+
const err = writeString(res.locale ?? langCodesMap.get('en'), value, ctx, def, t, res.tmpId, modifyOp);
|
|
7
7
|
}
|
|
8
8
|
else {
|
|
9
9
|
for (const lang in value) {
|
|
@@ -8,6 +8,8 @@ export declare const RANGE_ERR = 1;
|
|
|
8
8
|
export declare const INCREMENT = 12;
|
|
9
9
|
export declare const DECREMENT = 13;
|
|
10
10
|
export declare const EXPIRE = 14;
|
|
11
|
+
export declare const ADD_EMPTY_SORT_TEXT = 15;
|
|
12
|
+
export declare const ADD_EMPTY_SORT = 7;
|
|
11
13
|
export declare const SWITCH_TYPE = 2;
|
|
12
14
|
export declare const SWITCH_FIELD = 0;
|
|
13
15
|
export declare const SWITCH_ID_CREATE = 9;
|
|
@@ -16,6 +18,6 @@ export type ModifyErr = typeof RANGE_ERR | ModifyError | void;
|
|
|
16
18
|
export type ModifyOp = typeof CREATE | typeof UPDATE | typeof INCREMENT | typeof EXPIRE;
|
|
17
19
|
export type ModifyOpts = {
|
|
18
20
|
unsafe?: boolean;
|
|
19
|
-
|
|
21
|
+
locale?: LangName;
|
|
20
22
|
overwrite?: boolean;
|
|
21
23
|
};
|
|
@@ -6,6 +6,8 @@ export const RANGE_ERR = 1;
|
|
|
6
6
|
export const INCREMENT = 12;
|
|
7
7
|
export const DECREMENT = 13;
|
|
8
8
|
export const EXPIRE = 14;
|
|
9
|
+
export const ADD_EMPTY_SORT_TEXT = 15;
|
|
10
|
+
export const ADD_EMPTY_SORT = 7;
|
|
9
11
|
export const SWITCH_TYPE = 2;
|
|
10
12
|
export const SWITCH_FIELD = 0;
|
|
11
13
|
export const SWITCH_ID_CREATE = 9;
|
|
@@ -59,7 +59,7 @@ export const update = (db, type, id, obj, opts) => {
|
|
|
59
59
|
}
|
|
60
60
|
const ctx = db.modifyCtx;
|
|
61
61
|
const pos = ctx.len;
|
|
62
|
-
const res = new ModifyState(def.id, id, db, getSubscriptionMarkers(db, def.id, id, false), opts);
|
|
62
|
+
const res = new ModifyState(def.id, id, db, getSubscriptionMarkers(db, def.id, id, false), opts, true);
|
|
63
63
|
const err = appendUpdate(ctx, def, obj, res, opts?.overwrite);
|
|
64
64
|
if (err) {
|
|
65
65
|
ctx.prefix0 = -1; // force a new cursor
|
|
@@ -6,7 +6,7 @@ export declare class ModifyCtx {
|
|
|
6
6
|
len: number;
|
|
7
7
|
id: number;
|
|
8
8
|
lastMain: number;
|
|
9
|
-
|
|
9
|
+
hasSortField: number;
|
|
10
10
|
queue: Map<(payload: any) => void, ModifyState>;
|
|
11
11
|
ctx: {
|
|
12
12
|
offsets?: Record<number, number>;
|
|
@@ -25,7 +25,7 @@ export declare class ModifyCtx {
|
|
|
25
25
|
markNodeDirty(schema: SchemaTypeDef, nodeId: number): void;
|
|
26
26
|
markTypeDirty(schema: SchemaTypeDef): void;
|
|
27
27
|
updateMax(): void;
|
|
28
|
-
getData(): Buffer;
|
|
28
|
+
getData(lastIds: Record<number, number>): Buffer;
|
|
29
29
|
}
|
|
30
30
|
export declare const flushBuffer: (db: DbClient) => Promise<void>;
|
|
31
31
|
export declare const startDrain: (db: DbClient) => void;
|
|
@@ -9,7 +9,7 @@ export class ModifyCtx {
|
|
|
9
9
|
len = 0;
|
|
10
10
|
id = -1;
|
|
11
11
|
lastMain = -1;
|
|
12
|
-
|
|
12
|
+
hasSortField = -1;
|
|
13
13
|
queue = new Map();
|
|
14
14
|
ctx = {}; // maybe make this different?
|
|
15
15
|
payload;
|
|
@@ -47,7 +47,7 @@ export class ModifyCtx {
|
|
|
47
47
|
this.dirtyTypes.size * 10 -
|
|
48
48
|
this.dirtyRanges.size * 8;
|
|
49
49
|
}
|
|
50
|
-
getData() {
|
|
50
|
+
getData(lastIds) {
|
|
51
51
|
const rangesSize = this.dirtyRanges.size;
|
|
52
52
|
const typesSize = this.dirtyTypes.size;
|
|
53
53
|
const data = this.buf.subarray(0, this.len + 4 + 2 + typesSize * 10 + rangesSize * 8);
|
|
@@ -56,6 +56,7 @@ export class ModifyCtx {
|
|
|
56
56
|
i += 2;
|
|
57
57
|
for (const [id, startId] of this.dirtyTypes) {
|
|
58
58
|
const lastId = this.db.schemaTypesParsedById[id].lastId;
|
|
59
|
+
lastIds[id] = lastId;
|
|
59
60
|
data.writeUint16LE(id, i);
|
|
60
61
|
i += 2;
|
|
61
62
|
data.writeUint32LE(startId, i);
|
|
@@ -76,11 +77,26 @@ export const flushBuffer = (db) => {
|
|
|
76
77
|
let flushPromise;
|
|
77
78
|
if (ctx.len) {
|
|
78
79
|
const d = Date.now();
|
|
79
|
-
const
|
|
80
|
+
const lastIds = {};
|
|
81
|
+
const data = ctx.getData(lastIds);
|
|
80
82
|
const resCtx = ctx.ctx;
|
|
81
83
|
const queue = ctx.queue;
|
|
82
84
|
flushPromise = db.hooks.flushModify(data).then(({ offsets }) => {
|
|
83
85
|
resCtx.offsets = offsets;
|
|
86
|
+
for (const typeId in lastIds) {
|
|
87
|
+
if (typeId in offsets) {
|
|
88
|
+
const lastId = lastIds[typeId] + offsets[typeId];
|
|
89
|
+
const def = db.schemaTypesParsedById[typeId];
|
|
90
|
+
const delta = lastId - def.lastId;
|
|
91
|
+
if (delta > 0) {
|
|
92
|
+
def.lastId += delta;
|
|
93
|
+
def.total += delta;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.warn('no offset returned, very wrong');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
84
100
|
db.writeTime += Date.now() - d;
|
|
85
101
|
if (queue.size) {
|
|
86
102
|
flushPromise.then(() => {
|
|
@@ -19,7 +19,7 @@ export declare class QueryBranch<T> {
|
|
|
19
19
|
search(query: ArrayBufferView, field: string, opts?: Omit<FilterOpts, 'lowerCase'>): T;
|
|
20
20
|
or(fn: FilterBranchFn): T;
|
|
21
21
|
or(field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts): T;
|
|
22
|
-
range(offset: number, limit
|
|
22
|
+
range(offset: number, limit?: number): T;
|
|
23
23
|
include(...fields: (string | BranchInclude | string[])[]): T;
|
|
24
24
|
}
|
|
25
25
|
export declare class BasedDbReferenceQuery extends QueryBranch<BasedDbReferenceQuery> {
|
|
@@ -31,12 +31,13 @@ declare class GetPromise extends Promise<BasedQueryResponse> {
|
|
|
31
31
|
}
|
|
32
32
|
export declare class BasedDbQuery extends QueryBranch<BasedDbQuery> {
|
|
33
33
|
#private;
|
|
34
|
-
|
|
34
|
+
skipValidation: boolean;
|
|
35
|
+
constructor(db: DbClient, type: string, id?: QueryByAliasObj | number | Uint32Array | (QueryByAliasObj | number)[], skipValidation?: boolean);
|
|
35
36
|
id: number;
|
|
36
37
|
get(): GetPromise;
|
|
37
38
|
buffer: Buffer;
|
|
38
39
|
register(): void;
|
|
39
|
-
|
|
40
|
+
locale(locale: LangName): this;
|
|
40
41
|
subscribe(onData: OnData, onError?: OnError): import("./subscription/types.js").OnClose;
|
|
41
42
|
_getSync(dbCtxExternal: any): BasedQueryResponse;
|
|
42
43
|
toBuffer(): Buffer;
|
|
@@ -9,6 +9,8 @@ import { subscribe } from './subscription/index.js';
|
|
|
9
9
|
import { registerQuery } from './registerQuery.js';
|
|
10
10
|
import { langCodesMap } from '@based/schema';
|
|
11
11
|
import { convertFilter } from './filter/convertFilter.js';
|
|
12
|
+
import { validateLocale, validateRange } from './validation.js';
|
|
13
|
+
import { DEF_RANGE_PROP_LIMIT } from './thresholds.js';
|
|
12
14
|
export class QueryBranch {
|
|
13
15
|
db;
|
|
14
16
|
def;
|
|
@@ -106,7 +108,13 @@ export class QueryBranch {
|
|
|
106
108
|
// @ts-ignore
|
|
107
109
|
return this;
|
|
108
110
|
}
|
|
109
|
-
range(offset, limit) {
|
|
111
|
+
range(offset, limit = DEF_RANGE_PROP_LIMIT) {
|
|
112
|
+
if (validateRange(this.def, offset, limit)) {
|
|
113
|
+
this.def.range.offset = 0;
|
|
114
|
+
this.def.range.limit = DEF_RANGE_PROP_LIMIT;
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
110
118
|
this.def.range.offset = offset;
|
|
111
119
|
this.def.range.limit = limit;
|
|
112
120
|
// @ts-ignore
|
|
@@ -172,7 +180,8 @@ class GetPromise extends Promise {
|
|
|
172
180
|
}
|
|
173
181
|
}
|
|
174
182
|
export class BasedDbQuery extends QueryBranch {
|
|
175
|
-
|
|
183
|
+
skipValidation = false;
|
|
184
|
+
constructor(db, type, id, skipValidation) {
|
|
176
185
|
const target = {
|
|
177
186
|
type,
|
|
178
187
|
};
|
|
@@ -185,15 +194,13 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
185
194
|
// TODO ADD MULTI ALIAS
|
|
186
195
|
// @ts-ignore
|
|
187
196
|
target.ids = id;
|
|
188
|
-
// target.ids = new Uint32Array(id)
|
|
189
|
-
// target.ids.sort()
|
|
190
197
|
}
|
|
191
198
|
else {
|
|
192
199
|
target.id = id;
|
|
193
200
|
}
|
|
194
201
|
}
|
|
195
202
|
}
|
|
196
|
-
const def = createQueryDef(db, QueryDefType.Root, target);
|
|
203
|
+
const def = createQueryDef(db, QueryDefType.Root, target, skipValidation);
|
|
197
204
|
super(db, def);
|
|
198
205
|
}
|
|
199
206
|
#getInternal = async (resolve, reject) => {
|
|
@@ -226,7 +233,8 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
226
233
|
register() {
|
|
227
234
|
registerQuery(this);
|
|
228
235
|
}
|
|
229
|
-
|
|
236
|
+
locale(locale) {
|
|
237
|
+
validateLocale(this.def, locale);
|
|
230
238
|
this.def.lang = langCodesMap.get(locale) ?? 0;
|
|
231
239
|
return this;
|
|
232
240
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { inspect } from 'node:util';
|
|
2
2
|
import picocolors from 'picocolors';
|
|
3
3
|
import { debug, resultToObject, readAllFields } from './query.js';
|
|
4
|
-
import { size, time, inspectData } from './display.js';
|
|
4
|
+
import { size, time, inspectData, defHasId, displayTarget } from './display.js';
|
|
5
5
|
import { readFloatLE, readUint32 } from '../bitWise.js';
|
|
6
6
|
export { time, size, inspectData };
|
|
7
7
|
export class BasedQueryResponse {
|
|
@@ -21,15 +21,8 @@ export class BasedQueryResponse {
|
|
|
21
21
|
return this.result.length;
|
|
22
22
|
}
|
|
23
23
|
[inspect.custom](depth) {
|
|
24
|
-
const hasId =
|
|
25
|
-
const target =
|
|
26
|
-
? this.def.schema.type +
|
|
27
|
-
':' +
|
|
28
|
-
('alias' in this.def.target
|
|
29
|
-
? inspect(this.def.target.alias)
|
|
30
|
-
: // @ts-ignore
|
|
31
|
-
this.def.target.id)
|
|
32
|
-
: this.def.schema.type;
|
|
24
|
+
const hasId = defHasId(this.def);
|
|
25
|
+
const target = displayTarget(this.def);
|
|
33
26
|
let str = '';
|
|
34
27
|
str += '\n execTime: ' + time(this.execTime);
|
|
35
28
|
str += '\n size: ' + size(this.result.byteLength);
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { QueryDef } from './types.js';
|
|
2
|
+
import { TypeIndex } from '../../server/schema/types.js';
|
|
2
3
|
import { BasedQueryResponse } from './BasedIterable.js';
|
|
3
4
|
export declare const size: (size: number) => string;
|
|
4
5
|
export declare const time: (time: number) => string;
|
|
6
|
+
export declare const prettyPrintVal: (v: any, type: TypeIndex) => string;
|
|
7
|
+
export declare const parseUint8Array: (p: any) => any;
|
|
8
|
+
export declare const safeStringify: (p: any, nr?: number) => string;
|
|
5
9
|
export declare const inspectData: (q: BasedQueryResponse, def: QueryDef, level: number, top: boolean, depth: number, hasId?: boolean) => string;
|
|
10
|
+
export declare const defHasId: (def: QueryDef) => boolean;
|
|
11
|
+
export declare const displayTarget: (def: QueryDef) => string;
|
|
@@ -34,7 +34,7 @@ export const time = (time) => {
|
|
|
34
34
|
return picocolors.green(str);
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
const prettyPrintVal = (v, type) => {
|
|
37
|
+
export const prettyPrintVal = (v, type) => {
|
|
38
38
|
if (type === BINARY) {
|
|
39
39
|
const nr = 12;
|
|
40
40
|
const isLarger = v.length > nr;
|
|
@@ -72,6 +72,37 @@ const prettyPrintVal = (v, type) => {
|
|
|
72
72
|
}
|
|
73
73
|
return v;
|
|
74
74
|
};
|
|
75
|
+
export const parseUint8Array = (p) => {
|
|
76
|
+
if (ArrayBuffer.isView(p)) {
|
|
77
|
+
const x = [];
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
for (let i = 0; i < p.length; i++) {
|
|
80
|
+
x[i] = p[i];
|
|
81
|
+
}
|
|
82
|
+
p = x;
|
|
83
|
+
return p;
|
|
84
|
+
}
|
|
85
|
+
return p;
|
|
86
|
+
};
|
|
87
|
+
export const safeStringify = (p, nr = 30) => {
|
|
88
|
+
var v;
|
|
89
|
+
try {
|
|
90
|
+
p = parseUint8Array(p);
|
|
91
|
+
if (typeof p === 'object') {
|
|
92
|
+
for (const key in p) {
|
|
93
|
+
p[key] = parseUint8Array(p[key]);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
v = JSON.stringify(p).replace(/"/g, '').slice(0, nr);
|
|
97
|
+
if (v.length === nr) {
|
|
98
|
+
v += '...';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
v = '';
|
|
103
|
+
}
|
|
104
|
+
return v;
|
|
105
|
+
};
|
|
75
106
|
const inspectObject = (object, q, path, level, isLast, isFirst, isObject, depth) => {
|
|
76
107
|
const prefix = ''.padEnd(level, ' ');
|
|
77
108
|
let str = '';
|
|
@@ -253,4 +284,24 @@ export const inspectData = (q, def, level, top, depth, hasId = false) => {
|
|
|
253
284
|
}
|
|
254
285
|
return str;
|
|
255
286
|
};
|
|
287
|
+
export const defHasId = (def) => {
|
|
288
|
+
return 'id' in def.target || 'alias' in def.target;
|
|
289
|
+
};
|
|
290
|
+
export const displayTarget = (def) => {
|
|
291
|
+
// ids
|
|
292
|
+
const hasId = defHasId(def);
|
|
293
|
+
const hasIds = 'ids' in def.target;
|
|
294
|
+
const target = hasId || hasIds
|
|
295
|
+
? def.schema.type +
|
|
296
|
+
':' +
|
|
297
|
+
(hasIds
|
|
298
|
+
? // @ts-ignore
|
|
299
|
+
`ids(${def.target?.ids?.length ?? 0})`
|
|
300
|
+
: 'alias' in def.target
|
|
301
|
+
? safeStringify(def.target.alias, 30)
|
|
302
|
+
: // @ts-ignore
|
|
303
|
+
def.target.id)
|
|
304
|
+
: def.schema.type;
|
|
305
|
+
return target;
|
|
306
|
+
};
|
|
256
307
|
//# sourceMappingURL=display.js.map
|
|
@@ -70,10 +70,11 @@ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
|
|
|
70
70
|
prop.typeIndex === REFERENCES && ctx.operation === EQUAL
|
|
71
71
|
? MODE_AND_FIXED
|
|
72
72
|
: MODE_OR_FIXED;
|
|
73
|
-
buf.
|
|
74
|
-
buf.writeUInt16LE(
|
|
75
|
-
buf
|
|
76
|
-
buf[7] =
|
|
73
|
+
buf[2] = prop.typeIndex;
|
|
74
|
+
buf.writeUInt16LE(size, 3);
|
|
75
|
+
buf.writeUInt16LE(start, 5);
|
|
76
|
+
buf[7] = ctx.operation;
|
|
77
|
+
// buf[7] = prop.typeIndex
|
|
77
78
|
buf.writeUInt16LE(len, 8);
|
|
78
79
|
if (sort) {
|
|
79
80
|
value = new Uint32Array(value.map((v) => parseFilterValue(prop, v)));
|
|
@@ -93,10 +94,10 @@ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
|
|
|
93
94
|
buf = Buffer.allocUnsafe(8 + size);
|
|
94
95
|
buf[0] = ctx.type;
|
|
95
96
|
buf[1] = MODE_DEFAULT;
|
|
96
|
-
buf.
|
|
97
|
-
buf.writeUInt16LE(
|
|
98
|
-
buf
|
|
99
|
-
buf[7] =
|
|
97
|
+
buf[2] = prop.typeIndex;
|
|
98
|
+
buf.writeUInt16LE(size, 3);
|
|
99
|
+
buf.writeUInt16LE(start, 5);
|
|
100
|
+
buf[7] = ctx.operation;
|
|
100
101
|
writeFixed(prop, buf, parseFilterValue(prop, value), size, 8);
|
|
101
102
|
}
|
|
102
103
|
return buf;
|
|
@@ -5,10 +5,11 @@ export const createReferenceFilter = (prop, ctx, value) => {
|
|
|
5
5
|
buf = Buffer.allocUnsafe(11 + len * 8);
|
|
6
6
|
buf[0] = ctx.type;
|
|
7
7
|
buf[1] = MODE_REFERENCE;
|
|
8
|
-
buf.
|
|
9
|
-
buf.writeUInt16LE(
|
|
10
|
-
buf
|
|
11
|
-
buf[7] =
|
|
8
|
+
buf[2] = prop.typeIndex;
|
|
9
|
+
buf.writeUInt16LE(8, 3);
|
|
10
|
+
buf.writeUInt16LE(len, 5);
|
|
11
|
+
buf[7] = ctx.operation;
|
|
12
|
+
// buf[7] = prop.typeIndex
|
|
12
13
|
// REF TYPE (only 1 exists now...)
|
|
13
14
|
buf[8] = 0;
|
|
14
15
|
buf.writeUInt16LE(prop.inverseTypeId, 9);
|
|
@@ -40,7 +40,7 @@ const parseValue = (value, prop, ctx, lang) => {
|
|
|
40
40
|
// @ts-ignore
|
|
41
41
|
val = Buffer.concat([val, Buffer.from([ctx.opts.score ?? 2])]);
|
|
42
42
|
}
|
|
43
|
-
// @ts-ignore
|
|
43
|
+
// @ts-ignore
|
|
44
44
|
return val;
|
|
45
45
|
};
|
|
46
46
|
export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
@@ -70,7 +70,6 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
|
70
70
|
else {
|
|
71
71
|
val = parseValue(value, prop, ctx, lang);
|
|
72
72
|
}
|
|
73
|
-
// -------------------- PUT VARIABLES HERE
|
|
74
73
|
if (ctx.operation === EQUAL ||
|
|
75
74
|
ctx.operation === HAS ||
|
|
76
75
|
ctx.operation === LIKE ||
|
|
@@ -98,9 +97,6 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
|
98
97
|
buf = writeVarFilter(mode, val, ctx, prop, prop.start, prop.len);
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
|
-
else {
|
|
102
|
-
console.log('OP NOT SUPPORTED YET =>', ctx);
|
|
103
|
-
}
|
|
104
100
|
return buf;
|
|
105
101
|
};
|
|
106
102
|
function writeVarFilter(mode, val, ctx, prop, start, len) {
|
|
@@ -108,11 +104,11 @@ function writeVarFilter(mode, val, ctx, prop, start, len) {
|
|
|
108
104
|
const buf = Buffer.allocUnsafe(12 + size);
|
|
109
105
|
buf[0] = ctx.type;
|
|
110
106
|
buf[1] = mode;
|
|
111
|
-
buf.
|
|
112
|
-
buf.
|
|
113
|
-
buf.
|
|
114
|
-
buf
|
|
115
|
-
buf[11] =
|
|
107
|
+
buf[2] = prop.typeIndex;
|
|
108
|
+
buf.writeUInt16LE(start, 3);
|
|
109
|
+
buf.writeUint16LE(len, 5);
|
|
110
|
+
buf.writeUint32LE(size, 7);
|
|
111
|
+
buf[11] = ctx.operation;
|
|
116
112
|
// need to pas LANG FROM QUERY
|
|
117
113
|
// need to set on 12 if TEXT
|
|
118
114
|
buf.set(Buffer.from(val), 12);
|
|
@@ -9,20 +9,15 @@ import { META_EDGE, META_OR_BRANCH, META_REFERENCE } from './types.js';
|
|
|
9
9
|
// [meta = 254] [field] [typeId 2] [size 2]
|
|
10
10
|
// -------------------------------------------
|
|
11
11
|
// conditions normal
|
|
12
|
-
// field, [size 2]
|
|
13
|
-
// [or = 0] [size 2] [start 2], [op] [typeIndex], value[size]
|
|
14
12
|
// -------------------------------------------
|
|
15
13
|
// conditions or fixed
|
|
16
|
-
// field, [size 2]
|
|
17
|
-
// [or = 1] [size 2] [start 2] [op] [typeIndex], [repeat 2], value[size] value[size] value[size]
|
|
18
14
|
// -------------------------------------------
|
|
19
15
|
// conditions or variable
|
|
20
|
-
// field, [size 2]
|
|
21
|
-
// [or = 2] [size 2] [start 2], [op] [typeIndex], [size 2], value[size], [size 2], value[size]
|
|
22
16
|
// -------------------------------------------
|
|
23
17
|
const writeConditions = (result, k, offset, conditions) => {
|
|
24
18
|
let lastWritten = offset;
|
|
25
19
|
result[lastWritten] = k;
|
|
20
|
+
// result[lasWritten + 1] = typeIndex
|
|
26
21
|
lastWritten++;
|
|
27
22
|
const sizeIndex = lastWritten;
|
|
28
23
|
lastWritten += 2;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REFERENCE, REFERENCES, } from '../../../server/schema/types.js';
|
|
1
|
+
import { REFERENCE, REFERENCES, TEXT, } from '../../../server/schema/types.js';
|
|
2
2
|
export const getAll = (props) => {
|
|
3
3
|
const fields = [];
|
|
4
4
|
for (const key in props) {
|
|
@@ -50,13 +50,21 @@ export const includeProp = (def, prop) => {
|
|
|
50
50
|
if (!prop || prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES) {
|
|
51
51
|
return false;
|
|
52
52
|
}
|
|
53
|
-
if (prop.
|
|
54
|
-
def.include.
|
|
53
|
+
if (prop.typeIndex === TEXT) {
|
|
54
|
+
if (!def.include.langTextFields.has(prop.prop)) {
|
|
55
|
+
def.include.langTextFields.set(prop.prop, { def: prop, codes: new Set() });
|
|
56
|
+
}
|
|
57
|
+
def.include.langTextFields.get(prop.prop).codes.add(def.lang ?? 0);
|
|
55
58
|
}
|
|
56
59
|
else {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
if (prop.separate) {
|
|
61
|
+
def.include.props.set(prop.prop, prop);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
def.include.main.len += prop.len;
|
|
65
|
+
def.include.main.include[prop.start] = [0, prop];
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
return false;
|
|
62
70
|
};
|
|
@@ -19,7 +19,7 @@ const createRefQueryDef = (db, def, t) => {
|
|
|
19
19
|
: QueryDefType.References, {
|
|
20
20
|
type: t.inverseTypeName,
|
|
21
21
|
propDef: t,
|
|
22
|
-
});
|
|
22
|
+
}, def.skipValidation);
|
|
23
23
|
defRef.lang = def.lang;
|
|
24
24
|
def.references.set(t.prop, defRef);
|
|
25
25
|
return defRef;
|
|
@@ -33,7 +33,7 @@ export const createOrGetRefQueryDef = (db, def, t) => {
|
|
|
33
33
|
export const createOrGetEdgeRefQueryDef = (db, def, t) => {
|
|
34
34
|
def.edges ??= createQueryDef(db, QueryDefType.Edge, {
|
|
35
35
|
ref: t,
|
|
36
|
-
});
|
|
36
|
+
}, def.skipValidation);
|
|
37
37
|
def.edges.props ??= {};
|
|
38
38
|
def.edges.props[t.name] = t;
|
|
39
39
|
const refDef = createOrGetRefQueryDef(db, def.edges, t);
|
|
@@ -16,7 +16,7 @@ export const walkDefs = (db, def, f) => {
|
|
|
16
16
|
if (!def.edges) {
|
|
17
17
|
def.edges = createQueryDef(db, QueryDefType.Edge, {
|
|
18
18
|
ref: def.target.propDef,
|
|
19
|
-
});
|
|
19
|
+
}, def.skipValidation);
|
|
20
20
|
def.edges.lang = def.lang;
|
|
21
21
|
}
|
|
22
22
|
const edgeProp = def.edges.props[p];
|
|
@@ -82,12 +82,6 @@ export const walkDefs = (db, def, f) => {
|
|
|
82
82
|
includeAllProps(refDef);
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
else if (prop.typeIndex === TEXT) {
|
|
86
|
-
if (!def.include.langTextFields.has(prop.prop)) {
|
|
87
|
-
def.include.langTextFields.set(prop.prop, { def: prop, codes: new Set() });
|
|
88
|
-
}
|
|
89
|
-
def.include.langTextFields.get(prop.prop).codes.add(def.lang ?? 0);
|
|
90
|
-
}
|
|
91
85
|
else {
|
|
92
86
|
includeProp(def, prop);
|
|
93
87
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { DbClient } from '../index.js';
|
|
2
2
|
import { QueryDef, QueryDefType, QueryTarget } from './types.js';
|
|
3
|
-
export declare const createQueryDef: (db: DbClient, type: QueryDefType, target: QueryTarget) => QueryDef;
|
|
3
|
+
export declare const createQueryDef: (db: DbClient, type: QueryDefType, target: QueryTarget, skipValidation: boolean) => QueryDef;
|