ueberdb2 2.1.0 → 2.2.2

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/test/test.js CHANGED
@@ -7,8 +7,8 @@ const Randexp = require('randexp');
7
7
  const assert = require('assert').strict;
8
8
  const databases = require('./lib/databases').databases;
9
9
  const fs = require('fs').promises;
10
+ const logging = require('../lib/logging');
10
11
  const ueberdb = require('../index');
11
- const util = require('util');
12
12
 
13
13
  const maxKeyLength = 100;
14
14
  const randomString = (length = maxKeyLength) => new Randexp(new RegExp(`.{${length}}`)).gen();
@@ -25,18 +25,9 @@ after(async function () {
25
25
  }, 5000).unref();
26
26
  });
27
27
 
28
- // Returns an object with promisified equivalents of ueberdb.Database methods.
29
- const promisifyDb = (db) => {
30
- const ret = {};
31
- const fns = ['init', 'close', 'get', 'getSub', 'findKeys', 'set', 'setSub', 'remove', 'flush'];
32
- for (const fn of fns) ret[fn] = util.promisify(db[fn].bind(db));
33
- return ret;
34
- };
35
-
36
28
  describe(__filename, function () {
37
29
  let speedTable;
38
30
  let db;
39
- let pdb;
40
31
 
41
32
  before(async function () {
42
33
  speedTable = new Clitable({
@@ -74,13 +65,12 @@ describe(__filename, function () {
74
65
  db = new ueberdb.Database(database, dbSettings, {
75
66
  ...(readCache ? {} : {cache: 0}),
76
67
  ...(writeBuffer ? {} : {writeInterval: 0}),
77
- });
78
- pdb = promisifyDb(db);
79
- await pdb.init();
68
+ }, new logging.ConsoleLogger());
69
+ await db.init();
80
70
  });
81
71
 
82
72
  after(async function () {
83
- await pdb.close();
73
+ await db.close();
84
74
  if (dbSettings.filename) await fs.unlink(dbSettings.filename).catch(() => {});
85
75
  });
86
76
 
@@ -93,22 +83,22 @@ describe(__filename, function () {
93
83
  before(async function () {
94
84
  input = {a: 1, b: new Randexp(/.+/).gen()};
95
85
  key = randomString(maxKeyLength - 1) + (space ? ' ' : '');
96
- await pdb.set(key, input);
86
+ await db.set(key, input);
97
87
  });
98
88
 
99
89
  it('get(key) -> record', async function () {
100
- const output = await pdb.get(key);
90
+ const output = await db.get(key);
101
91
  assert.equal(JSON.stringify(output), JSON.stringify(input));
102
92
  });
103
93
 
104
94
  it('get(`${key} `) -> nullish', async function () {
105
- const output = await pdb.get(`${key} `);
95
+ const output = await db.get(`${key} `);
106
96
  assert(output == null);
107
97
  });
108
98
 
109
99
  if (space) {
110
100
  it('get(key.slice(0, -1)) -> nullish', async function () {
111
- const output = await pdb.get(key.slice(0, -1));
101
+ const output = await db.get(key.slice(0, -1));
112
102
  assert(output == null);
113
103
  });
114
104
  }
@@ -118,104 +108,131 @@ describe(__filename, function () {
118
108
 
119
109
  it('get of unknown key -> nullish', async function () {
120
110
  const key = randomString();
121
- assert(await pdb.get(key) == null);
111
+ assert(await db.get(key) == null);
122
112
  });
123
113
 
124
114
  it('set+get works', async function () {
125
115
  const input = {a: 1, b: new Randexp(/.+/).gen()};
126
116
  const key = randomString();
127
- await pdb.set(key, input);
128
- const output = await pdb.get(key);
117
+ await db.set(key, input);
118
+ const output = await db.get(key);
129
119
  assert.equal(JSON.stringify(output), JSON.stringify(input));
130
120
  });
131
121
 
132
122
  it('set+get with random key/value works', async function () {
133
123
  const input = {testLongString: new Randexp(/[a-f0-9]{50000}/).gen()};
134
124
  const key = randomString();
135
- await pdb.set(key, input);
136
- const output = await pdb.get(key);
125
+ await db.set(key, input);
126
+ const output = await db.get(key);
137
127
  assert.equal(JSON.stringify(output), JSON.stringify(input));
138
128
  });
139
129
 
140
130
  it('findKeys works', async function () {
141
- const input = {a: 1, b: new Randexp(/.+/).gen()};
131
+ if (database === 'mongodb') this.skip(); // TODO: Fix mongodb.
142
132
  // TODO setting a key with non ascii chars
143
133
  const key = new Randexp(/([a-z]\w{0,20})foo\1/).gen();
144
134
  await Promise.all([
145
- pdb.set(`${key}:test2`, input),
146
- pdb.set(`${key}:test`, input),
135
+ db.set(key, true),
136
+ db.set(`${key}a`, true),
137
+ db.set(`nonmatching_${key}`, false),
147
138
  ]);
148
- const output = await pdb.findKeys(`${key}:*`, null);
149
- for (const keyVal of output) {
150
- const output = await pdb.get(keyVal);
151
- assert.equal(JSON.stringify(output), JSON.stringify(input));
152
- }
139
+ const keys = await db.findKeys(`${key}*`, null);
140
+ assert.deepEqual(keys.sort(), [key, `${key}a`]);
141
+ });
142
+
143
+ it('findKeys with exclusion works', async function () {
144
+ if (database === 'mongodb') this.skip(); // TODO: Fix mongodb.
145
+ if (database === 'redis') this.skip(); // TODO: Fix redis.
146
+ const key = new Randexp(/([a-z]\w{0,20})foo\1/).gen();
147
+ await Promise.all([
148
+ db.set(key, true),
149
+ db.set(`${key}a`, true),
150
+ db.set(`${key}b`, false),
151
+ db.set(`${key}b2`, false),
152
+ db.set(`nonmatching_${key}`, false),
153
+ ]);
154
+ const keys = await db.findKeys(`${key}*`, `${key}b*`);
155
+ assert.deepEqual(keys.sort(), [key, `${key}a`].sort());
156
+ });
157
+
158
+ it('findKeys with no matches works', async function () {
159
+ const key = new Randexp(/([a-z]\w{0,20})foo\1/).gen();
160
+ await db.set(key, true);
161
+ const keys = await db.findKeys(`${key}_nomatch_*`, null);
162
+ assert.deepEqual(keys, []);
163
+ });
164
+
165
+ it('findKeys with no wildcard works', async function () {
166
+ const key = new Randexp(/([a-z]\w{0,20})foo\1/).gen();
167
+ await db.set(key, true);
168
+ const keys = await db.findKeys(key, null);
169
+ assert.deepEqual(keys, [key]);
153
170
  });
154
171
 
155
172
  it('remove works', async function () {
156
173
  const input = {a: 1, b: new Randexp(/.+/).gen()};
157
174
  const key = randomString();
158
- await pdb.set(key, input);
159
- assert.equal(JSON.stringify(await pdb.get(key)), JSON.stringify(input));
160
- await pdb.remove(key);
161
- assert(await pdb.get(key) == null);
175
+ await db.set(key, input);
176
+ assert.equal(JSON.stringify(await db.get(key)), JSON.stringify(input));
177
+ await db.remove(key);
178
+ assert(await db.get(key) == null);
162
179
  });
163
180
 
164
181
  it('getSub of existing property works', async function () {
165
- await pdb.set('k', {sub1: {sub2: 'v'}});
166
- assert.equal(await pdb.getSub('k', ['sub1', 'sub2']), 'v');
167
- assert.deepEqual(await pdb.getSub('k', ['sub1']), {sub2: 'v'});
168
- assert.deepEqual(await pdb.getSub('k', []), {sub1: {sub2: 'v'}});
182
+ await db.set('k', {sub1: {sub2: 'v'}});
183
+ assert.equal(await db.getSub('k', ['sub1', 'sub2']), 'v');
184
+ assert.deepEqual(await db.getSub('k', ['sub1']), {sub2: 'v'});
185
+ assert.deepEqual(await db.getSub('k', []), {sub1: {sub2: 'v'}});
169
186
  });
170
187
 
171
188
  it('getSub of missing property returns nullish', async function () {
172
- await pdb.set('k', {sub1: {}});
173
- assert(await pdb.getSub('k', ['sub1', 'sub2']) == null);
189
+ await db.set('k', {sub1: {}});
190
+ assert(await db.getSub('k', ['sub1', 'sub2']) == null);
174
191
 
175
- await pdb.set('k', {});
176
- assert(await pdb.getSub('k', ['sub1', 'sub2']) == null);
177
- assert(await pdb.getSub('k', ['sub1']) == null);
192
+ await db.set('k', {});
193
+ assert(await db.getSub('k', ['sub1', 'sub2']) == null);
194
+ assert(await db.getSub('k', ['sub1']) == null);
178
195
 
179
- await pdb.remove('k');
180
- assert(await pdb.getSub('k', ['sub1', 'sub2']) == null);
181
- assert(await pdb.getSub('k', ['sub1']) == null);
182
- assert(await pdb.getSub('k', []) == null);
196
+ await db.remove('k');
197
+ assert(await db.getSub('k', ['sub1', 'sub2']) == null);
198
+ assert(await db.getSub('k', ['sub1']) == null);
199
+ assert(await db.getSub('k', []) == null);
183
200
  });
184
201
 
185
202
  it('setSub can modify an existing property', async function () {
186
- await pdb.set('k', {sub1: {sub2: 'v'}});
187
- await pdb.setSub('k', ['sub1', 'sub2'], 'v2');
188
- assert.deepEqual(await pdb.get('k'), {sub1: {sub2: 'v2'}});
203
+ await db.set('k', {sub1: {sub2: 'v'}});
204
+ await db.setSub('k', ['sub1', 'sub2'], 'v2');
205
+ assert.deepEqual(await db.get('k'), {sub1: {sub2: 'v2'}});
189
206
 
190
- await pdb.setSub('k', ['sub1'], 'v2');
191
- assert.deepEqual(await pdb.get('k'), {sub1: 'v2'});
207
+ await db.setSub('k', ['sub1'], 'v2');
208
+ assert.deepEqual(await db.get('k'), {sub1: 'v2'});
192
209
 
193
- await pdb.setSub('k', [], 'v3');
194
- assert.equal(await pdb.get('k'), 'v3');
210
+ await db.setSub('k', [], 'v3');
211
+ assert.equal(await db.get('k'), 'v3');
195
212
  });
196
213
 
197
214
  it('setSub can add a new property', async function () {
198
- await pdb.remove('k');
199
- await pdb.setSub('k', [], {});
200
- assert.deepEqual(await pdb.get('k'), {});
201
- await pdb.setSub('k', ['sub1'], {});
202
- assert.deepEqual(await pdb.get('k'), {sub1: {}});
203
- await pdb.setSub('k', ['sub1', 'sub2'], 'v');
204
- assert.deepEqual(await pdb.get('k'), {sub1: {sub2: 'v'}});
205
-
206
- await pdb.remove('k');
207
- await pdb.setSub('k', ['sub1', 'sub2'], 'v');
208
- assert.deepEqual(await pdb.get('k'), {sub1: {sub2: 'v'}});
215
+ await db.remove('k');
216
+ await db.setSub('k', [], {});
217
+ assert.deepEqual(await db.get('k'), {});
218
+ await db.setSub('k', ['sub1'], {});
219
+ assert.deepEqual(await db.get('k'), {sub1: {}});
220
+ await db.setSub('k', ['sub1', 'sub2'], 'v');
221
+ assert.deepEqual(await db.get('k'), {sub1: {sub2: 'v'}});
222
+
223
+ await db.remove('k');
224
+ await db.setSub('k', ['sub1', 'sub2'], 'v');
225
+ assert.deepEqual(await db.get('k'), {sub1: {sub2: 'v'}});
209
226
  });
210
227
 
211
228
  it('setSub rejects attempts to set properties on primitives', async function () {
212
229
  for (const v of ['hello world', 42, true]) {
213
- await pdb.set('k', v);
214
- assert.rejects(pdb.setSub('k', ['sub'], 'x'), {
230
+ await db.set('k', v);
231
+ assert.rejects(db.setSub('k', ['sub'], 'x'), {
215
232
  name: 'TypeError',
216
233
  message: /property "sub" on non-object/,
217
234
  });
218
- assert.deepEqual(await pdb.get('k'), v);
235
+ assert.deepEqual(await db.get('k'), v);
219
236
  }
220
237
  });
221
238
 
@@ -239,21 +256,21 @@ describe(__filename, function () {
239
256
 
240
257
  const timers = {start: Date.now()};
241
258
 
242
- for (let i = 0; i < count; ++i) promises[i] = pdb.set(key + i, input);
243
- promises[count] = pdb.flush();
259
+ for (let i = 0; i < count; ++i) promises[i] = db.set(key + i, input);
260
+ promises[count] = db.flush();
244
261
  await Promise.all(promises);
245
262
  timers.set = Date.now();
246
263
 
247
- for (let i = 0; i < count; ++i) promises[i] = pdb.get(key + i);
264
+ for (let i = 0; i < count; ++i) promises[i] = db.get(key + i);
248
265
  await Promise.all(promises);
249
266
  timers.get = Date.now();
250
267
 
251
- for (let i = 0; i < count; ++i) promises[i] = pdb.findKeys(key + i, null);
268
+ for (let i = 0; i < count; ++i) promises[i] = db.findKeys(key + i, null);
252
269
  await Promise.all(promises);
253
270
  timers.findKeys = Date.now();
254
271
 
255
- for (let i = 0; i < count; ++i) promises[i] = pdb.remove(key + i);
256
- promises[count] = pdb.flush();
272
+ for (let i = 0; i < count; ++i) promises[i] = db.remove(key + i);
273
+ promises[count] = db.flush();
257
274
  await Promise.all(promises);
258
275
  timers.remove = Date.now();
259
276
 
package/test/test_bulk.js CHANGED
@@ -11,10 +11,8 @@ describe(__filename, function () {
11
11
  let mock = null;
12
12
  const createDb = async (wrapperSettings) => {
13
13
  const settings = {};
14
- const udb = new ueberdb.Database('mock', settings, wrapperSettings);
14
+ db = new ueberdb.Database('mock', settings, wrapperSettings);
15
15
  mock = settings.mock;
16
- db = {};
17
- for (const fn of ['init', 'close', 'set']) db[fn] = util.promisify(udb[fn].bind(udb));
18
16
  mock.once('init', (cb) => cb());
19
17
  await db.init();
20
18
  };
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert').strict;
4
+ const logging = require('../lib/logging');
5
+ const ueberdb = require('../index');
6
+
7
+ const logger = new logging.ConsoleLogger();
8
+
9
+ describe(__filename, function () {
10
+ let db = null;
11
+ let mock = null;
12
+ const createDb = async (wrapperSettings = {}) => {
13
+ const settings = {};
14
+ db = new ueberdb.Database('mock', settings, {json: false, ...wrapperSettings}, logger);
15
+ mock = settings.mock;
16
+ mock.once('init', (cb) => cb());
17
+ await db.init();
18
+ };
19
+
20
+ afterEach(async function () {
21
+ if (mock != null) {
22
+ mock.removeAllListeners();
23
+ mock.once('close', (cb) => cb());
24
+ mock = null;
25
+ }
26
+ if (db != null) {
27
+ await db.close();
28
+ db = null;
29
+ }
30
+ });
31
+
32
+ it('cached entries are flushed before calling findKeys', async function () {
33
+ // Trigger a test timeout if flush() completes before the write operation is buffered.
34
+ await createDb({writeInterval: 1e9});
35
+ let called = false;
36
+ mock.on('set', (k, v, cb) => { called = true; cb(null); });
37
+ mock.on('findKeys', (k, nk, cb) => { assert(called); cb(null, []); });
38
+ await Promise.all([
39
+ db.set('key', 'value'),
40
+ db.findKeys('key', null),
41
+ ]);
42
+ });
43
+ });
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const logging = require('../lib/logging');
4
+ const ueberdb = require('../index');
5
+
6
+ const logger = new logging.ConsoleLogger();
7
+
8
+ describe(__filename, function () {
9
+ let db = null;
10
+ let mock = null;
11
+ const createDb = async (wrapperSettings = {}) => {
12
+ const settings = {};
13
+ db = new ueberdb.Database('mock', settings, {json: false, ...wrapperSettings}, logger);
14
+ mock = settings.mock;
15
+ mock.once('init', (cb) => cb());
16
+ await db.init();
17
+ };
18
+
19
+ afterEach(async function () {
20
+ if (mock != null) {
21
+ mock.removeAllListeners();
22
+ mock.once('close', (cb) => cb());
23
+ mock = null;
24
+ }
25
+ if (db != null) {
26
+ await db.close();
27
+ db = null;
28
+ }
29
+ });
30
+
31
+ it('flush() immediately after set() sees the write operation', async function () {
32
+ // Trigger a test timeout if flush() completes before the write operation is buffered.
33
+ await createDb({writeInterval: 1e9});
34
+ mock.on('set', (k, v, cb) => cb());
35
+ await Promise.all([
36
+ db.set('key', 'value'),
37
+ db.flush(),
38
+ ]);
39
+ });
40
+
41
+ it('flush() immediately after setSub() sees the write operation', async function () {
42
+ // Trigger a test timeout if flush() completes before the write operation is buffered.
43
+ await createDb({writeInterval: 1e9});
44
+ mock.on('get', (k, cb) => cb(null, {sub: 'oldvalue'}));
45
+ mock.on('set', (k, v, cb) => cb(null));
46
+ await Promise.all([
47
+ db.setSub('key', ['sub'], 'newvalue'),
48
+ db.flush(),
49
+ ]);
50
+ });
51
+
52
+ it('flush() immediately after remove() sees the write operation', async function () {
53
+ // Trigger a test timeout if flush() completes before the write operation is buffered.
54
+ await createDb({writeInterval: 1e9});
55
+ mock.on('remove', (k, cb) => cb(null));
56
+ await Promise.all([
57
+ db.remove('key'),
58
+ db.flush(),
59
+ ]);
60
+ });
61
+ });
@@ -2,7 +2,6 @@
2
2
 
3
3
  const assert = require('assert').strict;
4
4
  const ueberdb = require('../index');
5
- const util = require('util');
6
5
 
7
6
  // Gate is a normal Promise that resolves when its open() method is called.
8
7
  class Gate extends Promise {
@@ -43,11 +42,8 @@ describe(__filename, function () {
43
42
 
44
43
  before(async function () {
45
44
  const settings = {};
46
- const udb = new ueberdb.Database('mock', settings);
45
+ db = new ueberdb.Database('mock', settings);
47
46
  mock = settings.mock;
48
- db = {metrics: udb.metrics};
49
- const fns = ['init', 'close', 'get', 'getSub', 'findKeys', 'flush', 'remove', 'set', 'setSub'];
50
- for (const fn of fns) db[fn] = util.promisify(udb[fn].bind(udb));
51
47
  mock.once('init', (cb) => cb());
52
48
  await db.init();
53
49
  });
@@ -3,15 +3,14 @@
3
3
  const assert = require('assert').strict;
4
4
  const {databases} = require('./lib/databases');
5
5
  const ueberdb = require('../index');
6
- const util = require('util');
7
6
 
8
7
  describe(__filename, function () {
9
8
  it('connection string instead of settings object', async function () {
10
9
  const {user, password, host, database} = databases.postgres;
11
10
  const db =
12
11
  new ueberdb.Database('postgres', `postgres://${user}:${password}@${host}/${database}`);
13
- await util.promisify(db.init.bind(db))();
14
- await util.promisify(db.set.bind(db))('key', 'val');
15
- assert.equal(await util.promisify(db.get.bind(db))('key'), 'val');
12
+ await db.init();
13
+ await db.set('key', 'val');
14
+ assert.equal(await db.get('key'), 'val');
16
15
  });
17
16
  });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert').strict;
4
+ const ueberdb = require('../index');
5
+
6
+ describe(__filename, function () {
7
+ it('setSub rejects __proto__', async function () {
8
+ const db = new ueberdb.Database('memory', {}, {});
9
+ await db.init();
10
+ await db.set('k', {});
11
+ await assert.rejects(db.setSub('k', ['__proto__'], 'v'));
12
+ });
13
+ });
@@ -2,15 +2,12 @@
2
2
 
3
3
  const assert = require('assert').strict;
4
4
  const ueberdb = require('../index');
5
- const util = require('util');
6
5
 
7
6
  describe(__filename, function () {
8
7
  let db = null;
9
8
 
10
9
  before(async function () {
11
- const udb = new ueberdb.Database('memory', {}, {});
12
- db = {};
13
- for (const fn of ['init', 'close', 'set', 'get']) db[fn] = util.promisify(udb[fn].bind(udb));
10
+ db = new ueberdb.Database('memory', {}, {});
14
11
  await db.init();
15
12
  });
16
13