From c7137838c03b6b0529278315ef53abecf8aa3e04 Mon Sep 17 00:00:00 2001 From: Andrew Osheroff Date: Fri, 18 Oct 2024 09:46:05 +0200 Subject: [PATCH 1/2] Add nonetype collection test --- builder/codegen.js | 2 +- test/basic.js | 14 ++ test/fixtures/builders/3.js | 6 + test/fixtures/generated/1/hyperdb/index.js | 2 +- test/fixtures/generated/2/hyperdb/index.js | 4 +- test/fixtures/generated/3/hyperdb/db.json | 20 ++- test/fixtures/generated/3/hyperdb/index.js | 152 ++++++++++++------ test/fixtures/generated/3/hyperdb/messages.js | 35 +++- 8 files changed, 171 insertions(+), 64 deletions(-) diff --git a/builder/codegen.js b/builder/codegen.js index a1c2aad..bea476d 100644 --- a/builder/codegen.js +++ b/builder/codegen.js @@ -282,7 +282,7 @@ function generateEncodeCollectionKey (collection, sep) { const accessors = toProps('record', collection.fullKey) let str = '' - str += ' encodeKey (record) {\n' + str += ' encodeKey (record = {}) {\n' str += ` const key = [${accessors.join(', ')}]\n` str += ` return ${id + '_key'}.encode(key)\n` str += ` }${sep}\n` diff --git a/test/basic.js b/test/basic.js index 5baa915..4e2b4d8 100644 --- a/test/basic.js +++ b/test/basic.js @@ -285,6 +285,7 @@ test('none-type indexes', async function ({ create }, t) { await db.insert('@db/members', { id: 'maf', age: 37 }) await db.insert('@db/members', { id: 'andrew', age: 34 }) await db.insert('@db/members', { id: 'anna', age: 32 }) + await db.flush() { const result = await db.find('@db/members-by-age', { gte: { key: null, age: 33 }, lt: { key: null, age: 99 } }).toArray() @@ -304,3 +305,16 @@ test('none-type indexes', async function ({ create }, t) { await db.close() }) + +test.solo('can do a get on a collection with a none-type key', async function ({ create }, t) { + const db = await create({ fixture: 3 }) + + await db.insert('@db/digest', { id: 'maf', age: 37 }) + await db.flush() + + const record = await db.get('@db/digest') + t.ok(record) + t.is(record.name, 'maf') + + await db.close() +}) diff --git a/test/fixtures/builders/3.js b/test/fixtures/builders/3.js index 3d71414..3d51037 100644 --- a/test/fixtures/builders/3.js +++ b/test/fixtures/builders/3.js @@ -35,6 +35,12 @@ Hyperschema.toDisk(schema) const db = HyperDB.from(SCHEMA_DIR, DB_DIR) const testDb = db.namespace('db') +testDb.collections.register({ + name: 'digest', + schema: '@db/member', + key: ['key'] +}) + testDb.collections.register({ name: 'members', stats: true, diff --git a/test/fixtures/generated/1/hyperdb/index.js b/test/fixtures/generated/1/hyperdb/index.js index db109cf..8651861 100644 --- a/test/fixtures/generated/1/hyperdb/index.js +++ b/test/fixtures/generated/1/hyperdb/index.js @@ -31,7 +31,7 @@ const collection0 = { name: '@db/members', id: 0, stats: false, - encodeKey (record) { + encodeKey (record = {}) { const key = [record.id] return collection0_key.encode(key) }, diff --git a/test/fixtures/generated/2/hyperdb/index.js b/test/fixtures/generated/2/hyperdb/index.js index 96897b2..b0d85e5 100644 --- a/test/fixtures/generated/2/hyperdb/index.js +++ b/test/fixtures/generated/2/hyperdb/index.js @@ -31,7 +31,7 @@ const collection0 = { name: '@db/members', id: 0, stats: true, - encodeKey (record) { + encodeKey (record = {}) { const key = [record.id] return collection0_key.encode(key) }, @@ -77,7 +77,7 @@ const collection1 = { name: 'stats', id: 1, stats: false, - encodeKey (record) { + encodeKey (record = {}) { const key = [record.id] return collection1_key.encode(key) }, diff --git a/test/fixtures/generated/3/hyperdb/db.json b/test/fixtures/generated/3/hyperdb/db.json index e24195e..8aab944 100644 --- a/test/fixtures/generated/3/hyperdb/db.json +++ b/test/fixtures/generated/3/hyperdb/db.json @@ -3,9 +3,23 @@ "offset": 0, "schema": [ { - "name": "members", + "name": "digest", "namespace": "db", "id": 0, + "stats": false, + "type": 1, + "indexes": [], + "schema": "@db/member", + "derived": false, + "key": [ + "key" + ], + "trigger": null + }, + { + "name": "members", + "namespace": "db", + "id": 1, "stats": true, "type": 1, "indexes": [ @@ -22,7 +36,7 @@ { "name": "stats", "namespace": null, - "id": 1, + "id": 2, "stats": false, "type": 1, "indexes": [], @@ -36,7 +50,7 @@ { "name": "members-by-age", "namespace": "db", - "id": 2, + "id": 3, "stats": false, "type": 2, "collection": "@db/members", diff --git a/test/fixtures/generated/3/hyperdb/index.js b/test/fixtures/generated/3/hyperdb/index.js index 2e6662a..55cab44 100644 --- a/test/fixtures/generated/3/hyperdb/index.js +++ b/test/fixtures/generated/3/hyperdb/index.js @@ -5,13 +5,61 @@ const { IndexEncoder, c } = require('@holepunchto/hyperdb/runtime') const { version, resolveStruct } = require('./messages.js') -// '@db/members' collection key +// '@db/digest' collection key const collection0_key = new IndexEncoder([ - IndexEncoder.NONE, - IndexEncoder.STRING + IndexEncoder.NONE ], { prefix: 0 }) function collection0_indexify (record) { + const a = record.key + return a === undefined ? [] : [a] +} + +// '@db/digest' reconstruction function +function collection0_reconstruct (version, keyBuf, valueBuf) { + const key = collection0_key.decode(keyBuf) + const value = c.decode(resolveStruct('@db/digest/value', version), valueBuf) + // TODO: This should be fully code generated + return { + key: key[0], + ...value + } +} + +// '@db/digest' +const collection0 = { + name: '@db/digest', + id: 0, + stats: false, + encodeKey (record = {}) { + const key = [record.key] + const encoded = collection0_key.encode(key) + console.log('ENCODED HERE IS:', encoded) + return encoded + }, + encodeKeyRange ({ gt, lt, gte, lte } = {}) { + return collection0_key.encodeRange({ + gt: gt ? collection0_indexify(gt) : null, + lt: lt ? collection0_indexify(lt) : null, + gte: gte ? collection0_indexify(gte) : null, + lte: lte ? collection0_indexify(lte) : null + }) + }, + encodeValue (version, record) { + return c.encode(resolveStruct('@db/digest/value', version), record) + }, + trigger: null, + reconstruct: collection0_reconstruct, + indexes: [] +} + +// '@db/members' collection key +const collection1_key = new IndexEncoder([ + IndexEncoder.NONE, + IndexEncoder.STRING +], { prefix: 1 }) + +function collection1_indexify (record) { const arr = [] arr.push(null) @@ -24,8 +72,8 @@ function collection0_indexify (record) { } // '@db/members' reconstruction function -function collection0_reconstruct (version, keyBuf, valueBuf) { - const key = collection0_key.decode(keyBuf) +function collection1_reconstruct (version, keyBuf, valueBuf) { + const key = collection1_key.decode(keyBuf) const value = c.decode(resolveStruct('@db/members/value', version), valueBuf) // TODO: This should be fully code generated return { @@ -36,43 +84,43 @@ function collection0_reconstruct (version, keyBuf, valueBuf) { } // '@db/members' -const collection0 = { +const collection1 = { name: '@db/members', - id: 0, + id: 1, stats: true, - encodeKey (record) { + encodeKey (record = {}) { const key = [record.key, record.id] - return collection0_key.encode(key) + return collection1_key.encode(key) }, encodeKeyRange ({ gt, lt, gte, lte } = {}) { - return collection0_key.encodeRange({ - gt: gt ? collection0_indexify(gt) : null, - lt: lt ? collection0_indexify(lt) : null, - gte: gte ? collection0_indexify(gte) : null, - lte: lte ? collection0_indexify(lte) : null + return collection1_key.encodeRange({ + gt: gt ? collection1_indexify(gt) : null, + lt: lt ? collection1_indexify(lt) : null, + gte: gte ? collection1_indexify(gte) : null, + lte: lte ? collection1_indexify(lte) : null }) }, encodeValue (version, record) { return c.encode(resolveStruct('@db/members/value', version), record) }, trigger: null, - reconstruct: collection0_reconstruct, + reconstruct: collection1_reconstruct, indexes: [] } // 'stats' collection key -const collection1_key = new IndexEncoder([ +const collection2_key = new IndexEncoder([ IndexEncoder.UINT -], { prefix: 1 }) +], { prefix: 2 }) -function collection1_indexify (record) { +function collection2_indexify (record) { const a = record.id return a === undefined ? [] : [a] } // 'stats' reconstruction function -function collection1_reconstruct (version, keyBuf, valueBuf) { - const key = collection1_key.decode(keyBuf) +function collection2_reconstruct (version, keyBuf, valueBuf) { + const key = collection2_key.decode(keyBuf) const value = c.decode(resolveStruct('stats/value', version), valueBuf) // TODO: This should be fully code generated return { @@ -82,39 +130,39 @@ function collection1_reconstruct (version, keyBuf, valueBuf) { } // 'stats' -const collection1 = { +const collection2 = { name: 'stats', - id: 1, + id: 2, stats: false, - encodeKey (record) { + encodeKey (record = {}) { const key = [record.id] - return collection1_key.encode(key) + return collection2_key.encode(key) }, encodeKeyRange ({ gt, lt, gte, lte } = {}) { - return collection1_key.encodeRange({ - gt: gt ? collection1_indexify(gt) : null, - lt: lt ? collection1_indexify(lt) : null, - gte: gte ? collection1_indexify(gte) : null, - lte: lte ? collection1_indexify(lte) : null + return collection2_key.encodeRange({ + gt: gt ? collection2_indexify(gt) : null, + lt: lt ? collection2_indexify(lt) : null, + gte: gte ? collection2_indexify(gte) : null, + lte: lte ? collection2_indexify(lte) : null }) }, encodeValue (version, record) { return c.encode(resolveStruct('stats/value', version), record) }, trigger: null, - reconstruct: collection1_reconstruct, + reconstruct: collection2_reconstruct, indexes: [] } // '@db/members-by-age' collection key -const index2_key = new IndexEncoder([ +const index3_key = new IndexEncoder([ IndexEncoder.NONE, IndexEncoder.UINT, IndexEncoder.NONE, IndexEncoder.STRING -], { prefix: 2 }) +], { prefix: 3 }) -function index2_indexify (record) { +function index3_indexify (record) { const arr = [] arr.push(null) @@ -133,39 +181,40 @@ function index2_indexify (record) { } // '@db/members-by-age' -const index2 = { +const index3 = { name: '@db/members-by-age', - id: 2, + id: 3, stats: false, encodeKey (record) { - return index2_key.encode(index2_indexify(record)) + return index3_key.encode(index3_indexify(record)) }, encodeKeyRange ({ gt, lt, gte, lte } = {}) { - return index2_key.encodeRange({ - gt: gt ? index2_indexify(gt) : null, - lt: lt ? index2_indexify(lt) : null, - gte: gte ? index2_indexify(gte) : null, - lte: lte ? index2_indexify(lte) : null + return index3_key.encodeRange({ + gt: gt ? index3_indexify(gt) : null, + lt: lt ? index3_indexify(lt) : null, + gte: gte ? index3_indexify(gte) : null, + lte: lte ? index3_indexify(lte) : null }) }, - encodeValue: (doc) => index2.collection.encodeKey(doc), + encodeValue: (doc) => index3.collection.encodeKey(doc), encodeIndexKeys (record, context) { - return [index2_key.encode([record.key, record.age, record.key, record.id])] + return [index3_key.encode([record.key, record.age, record.key, record.id])] }, reconstruct: (keyBuf, valueBuf) => valueBuf, - offset: collection0.indexes.length, - collection: collection0 + offset: collection1.indexes.length, + collection: collection1 } -collection0.indexes.push(index2) +collection1.indexes.push(index3) module.exports = { version, collections: [ collection0, - collection1 + collection1, + collection2 ], indexes: [ - index2 + index3 ], resolveCollection, resolveIndex @@ -173,15 +222,16 @@ module.exports = { function resolveCollection (name) { switch (name) { - case '@db/members': return collection0 - case 'stats': return collection1 + case '@db/digest': return collection0 + case '@db/members': return collection1 + case 'stats': return collection2 default: return null } } function resolveIndex (name) { switch (name) { - case '@db/members-by-age': return index2 + case '@db/members-by-age': return index3 default: return null } } diff --git a/test/fixtures/generated/3/hyperdb/messages.js b/test/fixtures/generated/3/hyperdb/messages.js index 01aedf5..1f219de 100644 --- a/test/fixtures/generated/3/hyperdb/messages.js +++ b/test/fixtures/generated/3/hyperdb/messages.js @@ -35,26 +35,48 @@ const encoding0 = { } } -// @db/members/value +// @db/digest/value const encoding1 = { preencode (state, m) { + c.string.preencode(state, m.id) c.uint.preencode(state, m.age) }, encode (state, m) { + c.string.encode(state, m.id) c.uint.encode(state, m.age) }, decode (state) { const res = {} + res.id = null res.age = 0 + res.id = c.string.decode(state) res.age = c.uint.decode(state) return res } } -// stats +// @db/members/value const encoding2 = { + preencode (state, m) { + c.uint.preencode(state, m.age) + }, + encode (state, m) { + c.uint.encode(state, m.age) + }, + decode (state) { + const res = {} + res.age = 0 + + res.age = c.uint.decode(state) + + return res + } +} + +// stats +const encoding3 = { preencode (state, m) { c.uint.preencode(state, m.id) c.uint.preencode(state, m.count) @@ -76,7 +98,7 @@ const encoding2 = { } // stats/value -const encoding3 = { +const encoding4 = { preencode (state, m) { c.uint.preencode(state, m.count) }, @@ -96,9 +118,10 @@ const encoding3 = { function getStructByName (name) { switch (name) { case '@db/member': return encoding0 - case '@db/members/value': return encoding1 - case 'stats': return encoding2 - case 'stats/value': return encoding3 + case '@db/digest/value': return encoding1 + case '@db/members/value': return encoding2 + case 'stats': return encoding3 + case 'stats/value': return encoding4 default: throw new Error('Encoder not found ' + name) } } From 747ee6e4ff7f112ddbbeeab4d00896c149a62672 Mon Sep 17 00:00:00 2001 From: Andrew Osheroff Date: Fri, 18 Oct 2024 09:46:24 +0200 Subject: [PATCH 2/2] Regenerate fixtures --- test/fixtures/generated/3/hyperdb/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/fixtures/generated/3/hyperdb/index.js b/test/fixtures/generated/3/hyperdb/index.js index 55cab44..de20074 100644 --- a/test/fixtures/generated/3/hyperdb/index.js +++ b/test/fixtures/generated/3/hyperdb/index.js @@ -33,9 +33,7 @@ const collection0 = { stats: false, encodeKey (record = {}) { const key = [record.key] - const encoded = collection0_key.encode(key) - console.log('ENCODED HERE IS:', encoded) - return encoded + return collection0_key.encode(key) }, encodeKeyRange ({ gt, lt, gte, lte } = {}) { return collection0_key.encodeRange({