@naturalcycles/db-lib 10.13.0 → 10.15.0
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.
|
@@ -77,7 +77,7 @@ export class InMemoryDB {
|
|
|
77
77
|
async saveBatch(_table, rows, opt = {}) {
|
|
78
78
|
const table = this.cfg.tablesPrefix + _table;
|
|
79
79
|
this.data[table] ||= {};
|
|
80
|
-
|
|
80
|
+
for (const r of rows) {
|
|
81
81
|
if (!r.id) {
|
|
82
82
|
this.cfg.logger.warn({ rows });
|
|
83
83
|
throw new Error(`InMemoryDB doesn't support id auto-generation in saveBatch, row without id was given`);
|
|
@@ -92,7 +92,7 @@ export class InMemoryDB {
|
|
|
92
92
|
// 1. Not store values "by reference" (avoid mutation bugs)
|
|
93
93
|
// 2. Simulate real DB that would do something like that in a transport layer anyway
|
|
94
94
|
this.data[table][r.id] = JSON.parse(JSON.stringify(r), bufferReviver);
|
|
95
|
-
}
|
|
95
|
+
}
|
|
96
96
|
}
|
|
97
97
|
async deleteByQuery(q, _opt) {
|
|
98
98
|
const table = this.cfg.tablesPrefix + q.table;
|
|
@@ -106,12 +106,12 @@ export class InMemoryDB {
|
|
|
106
106
|
if (!this.data[table])
|
|
107
107
|
return 0;
|
|
108
108
|
let count = 0;
|
|
109
|
-
|
|
109
|
+
for (const id of ids) {
|
|
110
110
|
if (!this.data[table][id])
|
|
111
|
-
|
|
111
|
+
continue;
|
|
112
112
|
delete this.data[table][id];
|
|
113
113
|
count++;
|
|
114
|
-
}
|
|
114
|
+
}
|
|
115
115
|
return count;
|
|
116
116
|
}
|
|
117
117
|
async patchByQuery(q, patch) {
|
|
@@ -119,7 +119,9 @@ export class InMemoryDB {
|
|
|
119
119
|
return 0;
|
|
120
120
|
const table = this.cfg.tablesPrefix + q.table;
|
|
121
121
|
const rows = queryInMemory(q, Object.values(this.data[table] || {}));
|
|
122
|
-
|
|
122
|
+
for (const row of rows) {
|
|
123
|
+
Object.assign(row, patch);
|
|
124
|
+
}
|
|
123
125
|
return rows.length;
|
|
124
126
|
}
|
|
125
127
|
async runQuery(q, _opt) {
|
|
@@ -14,7 +14,9 @@ export class InMemoryKeyValueDB {
|
|
|
14
14
|
async createTable(_table, _opt) { }
|
|
15
15
|
async deleteByIds(table, ids) {
|
|
16
16
|
this.data[table] ||= {};
|
|
17
|
-
|
|
17
|
+
for (const id of ids) {
|
|
18
|
+
delete this.data[table][id];
|
|
19
|
+
}
|
|
18
20
|
}
|
|
19
21
|
async getByIds(table, ids) {
|
|
20
22
|
this.data[table] ||= {};
|
|
@@ -22,7 +24,9 @@ export class InMemoryKeyValueDB {
|
|
|
22
24
|
}
|
|
23
25
|
async saveBatch(table, entries) {
|
|
24
26
|
this.data[table] ||= {};
|
|
25
|
-
|
|
27
|
+
for (const [id, v] of entries) {
|
|
28
|
+
this.data[table][id] = v;
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
31
|
streamIds(table, limit) {
|
|
28
32
|
return Readable.from(Object.keys(this.data[table] || {}).slice(0, limit));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _range } from '@naturalcycles/js-lib/array/range.js';
|
|
2
|
-
import {
|
|
2
|
+
import { j } from '@naturalcycles/js-lib/json-schema';
|
|
3
3
|
import { baseDBEntitySchema, binarySchema, booleanSchema, numberSchema, objectSchema, stringSchema, } from '@naturalcycles/nodejs-lib/joi';
|
|
4
4
|
const MOCK_TS_2018_06_21 = 1529539200;
|
|
5
5
|
export const TEST_TABLE = 'TEST_TABLE';
|
|
@@ -17,17 +17,17 @@ export const testItemTMSchema = objectSchema({
|
|
|
17
17
|
k1: stringSchema,
|
|
18
18
|
even: booleanSchema.optional(),
|
|
19
19
|
});
|
|
20
|
-
export const testItemBMJsonSchema =
|
|
20
|
+
export const testItemBMJsonSchema = j
|
|
21
21
|
.rootObject({
|
|
22
22
|
// todo: figure out how to not copy-paste these 3 fields
|
|
23
|
-
id:
|
|
24
|
-
created:
|
|
25
|
-
updated:
|
|
26
|
-
k1:
|
|
27
|
-
k2:
|
|
28
|
-
k3:
|
|
29
|
-
even:
|
|
30
|
-
b1:
|
|
23
|
+
id: j.string(), // todo: not strictly needed here
|
|
24
|
+
created: j.unixTimestamp(),
|
|
25
|
+
updated: j.unixTimestamp(),
|
|
26
|
+
k1: j.string(),
|
|
27
|
+
k2: j.oneOf([j.string(), j.null()]).optional(),
|
|
28
|
+
k3: j.number().optional(),
|
|
29
|
+
even: j.boolean().optional(),
|
|
30
|
+
b1: j.buffer().optional(),
|
|
31
31
|
})
|
|
32
32
|
.baseDBEntity()
|
|
33
33
|
.build();
|
package/package.json
CHANGED
|
@@ -153,7 +153,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
153
153
|
const table = this.cfg.tablesPrefix + _table
|
|
154
154
|
this.data[table] ||= {}
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
for (const r of rows) {
|
|
157
157
|
if (!r.id) {
|
|
158
158
|
this.cfg.logger!.warn({ rows })
|
|
159
159
|
throw new Error(
|
|
@@ -161,19 +161,19 @@ export class InMemoryDB implements CommonDB {
|
|
|
161
161
|
)
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
if (opt.saveMethod === 'insert' && this.data[table]
|
|
164
|
+
if (opt.saveMethod === 'insert' && this.data[table][r.id]) {
|
|
165
165
|
throw new Error(`InMemoryDB: INSERT failed, entity exists: ${table}.${r.id}`)
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
if (opt.saveMethod === 'update' && !this.data[table]
|
|
168
|
+
if (opt.saveMethod === 'update' && !this.data[table][r.id]) {
|
|
169
169
|
throw new Error(`InMemoryDB: UPDATE failed, entity doesn't exist: ${table}.${r.id}`)
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// JSON parse/stringify (deep clone) is to:
|
|
173
173
|
// 1. Not store values "by reference" (avoid mutation bugs)
|
|
174
174
|
// 2. Simulate real DB that would do something like that in a transport layer anyway
|
|
175
|
-
this.data[table]
|
|
176
|
-
}
|
|
175
|
+
this.data[table][r.id] = JSON.parse(JSON.stringify(r), bufferReviver)
|
|
176
|
+
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
async deleteByQuery<ROW extends ObjectWithId>(
|
|
@@ -191,11 +191,11 @@ export class InMemoryDB implements CommonDB {
|
|
|
191
191
|
if (!this.data[table]) return 0
|
|
192
192
|
|
|
193
193
|
let count = 0
|
|
194
|
-
|
|
195
|
-
if (!this.data[table]
|
|
196
|
-
delete this.data[table]
|
|
194
|
+
for (const id of ids) {
|
|
195
|
+
if (!this.data[table][id]) continue
|
|
196
|
+
delete this.data[table][id]
|
|
197
197
|
count++
|
|
198
|
-
}
|
|
198
|
+
}
|
|
199
199
|
|
|
200
200
|
return count
|
|
201
201
|
}
|
|
@@ -207,7 +207,9 @@ export class InMemoryDB implements CommonDB {
|
|
|
207
207
|
if (_isEmptyObject(patch)) return 0
|
|
208
208
|
const table = this.cfg.tablesPrefix + q.table
|
|
209
209
|
const rows = queryInMemory(q, Object.values(this.data[table] || {}) as ROW[])
|
|
210
|
-
|
|
210
|
+
for (const row of rows) {
|
|
211
|
+
Object.assign(row, patch)
|
|
212
|
+
}
|
|
211
213
|
return rows.length
|
|
212
214
|
}
|
|
213
215
|
|
|
@@ -23,7 +23,9 @@ export class InMemoryKeyValueDB implements CommonKeyValueDB {
|
|
|
23
23
|
|
|
24
24
|
async deleteByIds(table: string, ids: string[]): Promise<void> {
|
|
25
25
|
this.data[table] ||= {}
|
|
26
|
-
|
|
26
|
+
for (const id of ids) {
|
|
27
|
+
delete this.data[table][id]
|
|
28
|
+
}
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
async getByIds(table: string, ids: string[]): Promise<KeyValueDBTuple[]> {
|
|
@@ -33,7 +35,9 @@ export class InMemoryKeyValueDB implements CommonKeyValueDB {
|
|
|
33
35
|
|
|
34
36
|
async saveBatch(table: string, entries: KeyValueDBTuple[]): Promise<void> {
|
|
35
37
|
this.data[table] ||= {}
|
|
36
|
-
|
|
38
|
+
for (const [id, v] of entries) {
|
|
39
|
+
this.data[table][id] = v
|
|
40
|
+
}
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
streamIds(table: string, limit?: number): ReadableTyped<string> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _range } from '@naturalcycles/js-lib/array/range.js'
|
|
2
2
|
import type { JsonSchemaObject } from '@naturalcycles/js-lib/json-schema'
|
|
3
|
-
import {
|
|
3
|
+
import { j } from '@naturalcycles/js-lib/json-schema'
|
|
4
4
|
import type { BaseDBEntity, UnixTimestamp } from '@naturalcycles/js-lib/types'
|
|
5
5
|
import {
|
|
6
6
|
baseDBEntitySchema,
|
|
@@ -50,17 +50,17 @@ export const testItemTMSchema: ObjectSchema<TestItemTM> = objectSchema<TestItemT
|
|
|
50
50
|
even: booleanSchema.optional(),
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
export const testItemBMJsonSchema: JsonSchemaObject<TestItemBM> =
|
|
53
|
+
export const testItemBMJsonSchema: JsonSchemaObject<TestItemBM> = j
|
|
54
54
|
.rootObject<TestItemBM>({
|
|
55
55
|
// todo: figure out how to not copy-paste these 3 fields
|
|
56
|
-
id:
|
|
57
|
-
created:
|
|
58
|
-
updated:
|
|
59
|
-
k1:
|
|
60
|
-
k2:
|
|
61
|
-
k3:
|
|
62
|
-
even:
|
|
63
|
-
b1:
|
|
56
|
+
id: j.string(), // todo: not strictly needed here
|
|
57
|
+
created: j.unixTimestamp(),
|
|
58
|
+
updated: j.unixTimestamp(),
|
|
59
|
+
k1: j.string(),
|
|
60
|
+
k2: j.oneOf<string | null>([j.string(), j.null()]).optional(),
|
|
61
|
+
k3: j.number().optional(),
|
|
62
|
+
even: j.boolean().optional(),
|
|
63
|
+
b1: j.buffer().optional(),
|
|
64
64
|
})
|
|
65
65
|
.baseDBEntity()
|
|
66
66
|
.build()
|