-
Notifications
You must be signed in to change notification settings - Fork 10
Make typed random-access structures opt-in (default off) in 5.1 #1152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
65fad22
feat: make typed random-access structures configurable (config + @tab…
kriszyp e9786f6
fix: copy-on-mutate frozen records in the save and source-resolve wri…
kriszyp 36b2f28
fix: skip timestamp-prefix heuristic for audit values (classic-record…
kriszyp 41cc8df
test: cover the global storage.randomAccessFields path in OpenDBIObject
kriszyp a41b47e
test: stub envMngr.get instead of mutating config (suite-stable)
kriszyp 23a0c83
test: make OpenDBIObject config test immune to a leaked envMngr.get stub
kriszyp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
unitTests/resources/models/randomAccessFieldsDirective.test.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| 'use strict'; | ||
|
|
||
| const assert = require('node:assert/strict'); | ||
| const { setupTestDBPath } = require('../../testUtils'); | ||
| const { loadGQLSchema } = require('#src/resources/graphql'); | ||
| const { tables } = require('#src/resources/databases'); | ||
|
|
||
| // Parse-level behavior of the @table(randomAccessFields:) directive: the boolean is coerced from the | ||
| // GraphQL string value and flows through to the primary store's encoder, which keeps or stubs its | ||
| // struct-write hook. storage.randomAccessFields defaults off, so an absent directive leaves writes off. | ||
| describe('@table(randomAccessFields:) directive parsing', () => { | ||
| before(() => setupTestDBPath()); | ||
|
|
||
| it('enables typed random-access structures when randomAccessFields: true', async () => { | ||
| await loadGQLSchema(`type RafOn @table(randomAccessFields: true) { | ||
| id: ID @primaryKey | ||
| name: String | ||
| }`); | ||
| const encoder = tables.RafOn.primaryStore.encoder; | ||
| assert.equal(encoder.randomAccessStructure, true); | ||
| assert.ok(encoder._writeStruct.length > 0, 'expected the real struct-write hook'); | ||
| }); | ||
|
|
||
| it('keeps writes disabled when randomAccessFields: false', async () => { | ||
| await loadGQLSchema(`type RafOff @table(randomAccessFields: false) { | ||
| id: ID @primaryKey | ||
| name: String | ||
| }`); | ||
| const encoder = tables.RafOff.primaryStore.encoder; | ||
| assert.ok(!encoder.randomAccessStructure); | ||
| assert.equal(encoder._writeStruct.length, 0, 'expected the no-op write stub'); | ||
| }); | ||
|
|
||
| it('defaults to disabled when the directive is absent', async () => { | ||
| await loadGQLSchema(`type RafAbsent @table { | ||
| id: ID @primaryKey | ||
| name: String | ||
| }`); | ||
| const encoder = tables.RafAbsent.primaryStore.encoder; | ||
| assert.ok(!encoder.randomAccessStructure); | ||
| assert.equal(encoder._writeStruct.length, 0, 'expected the no-op write stub'); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| require('../../testUtils'); | ||
| const assert = require('assert'); | ||
| const { OpenDBIObject } = require('#src/utility/lmdb/OpenDBIObject'); | ||
| const envMngr = require('#src/utility/environment/environmentManager'); | ||
| const { CONFIG_PARAMS } = require('#src/utility/hdbTerms'); | ||
|
|
||
| // Covers the global storage.randomAccessFields path in the OpenDBIObject constructor. The directive | ||
| // tests (databases.test.js / randomAccessFieldsDirective.test.js) stamp dbiInit.randomAccessStructure | ||
| // in databases.ts before the store opens, bypassing this constructor branch — so a wrong config key, | ||
| // a non-boolean value, or a hdbTerms/YAML name mismatch would go uncaught. | ||
| // | ||
| // The constructor reads the value via envMngr.get(CONFIG_PARAMS.STORAGE_RANDOMACCESSFIELDS). We | ||
| // temporarily override that single getter via defineProperty (restored in a finally) rather than | ||
| // using sinon or envMngr.setProperty: another test in the full unit suite leaves envMngr.get wrapped | ||
| // by sinon, which (a) makes setProperty's value invisible behind that stub and (b) makes a second | ||
| // sinon.stub throw "already wrapped". Saving/replacing/restoring the property descriptor is immune to | ||
| // that — the replacement delegates to whatever get currently is (real or another test's stub) for | ||
| // every other key, and restores the exact prior descriptor afterward. | ||
| function withRandomAccessFields(value, fn) { | ||
| const previousDescriptor = Object.getOwnPropertyDescriptor(envMngr, 'get'); | ||
| const currentGet = envMngr.get; | ||
| Object.defineProperty(envMngr, 'get', { | ||
| configurable: true, | ||
| writable: true, | ||
| value: (key) => (key === CONFIG_PARAMS.STORAGE_RANDOMACCESSFIELDS ? value : currentGet(key)), | ||
| }); | ||
| try { | ||
| fn(); | ||
| } finally { | ||
| Object.defineProperty(envMngr, 'get', previousDescriptor); | ||
| } | ||
| } | ||
|
|
||
| describe('OpenDBIObject storage.randomAccessFields global config', () => { | ||
| it('enables randomAccessStructure on a primary DBI when the global config is true', () => { | ||
| withRandomAccessFields(true, () => { | ||
| assert.strictEqual(new OpenDBIObject(false, true).randomAccessStructure, true); | ||
| }); | ||
| }); | ||
|
|
||
| it('leaves randomAccessStructure off on a primary DBI when the global config is false (default)', () => { | ||
| withRandomAccessFields(false, () => { | ||
| assert.strictEqual(new OpenDBIObject(false, true).randomAccessStructure, false); | ||
| }); | ||
| }); | ||
|
|
||
| it('treats a non-boolean truthy config value as off (strict === true)', () => { | ||
| // envMngr should hand back a real boolean; the strict === true guards against a stray truthy | ||
| // (e.g. the string "true") silently flipping encoding on. | ||
| withRandomAccessFields('true', () => { | ||
| assert.strictEqual(new OpenDBIObject(false, true).randomAccessStructure, false); | ||
| }); | ||
| }); | ||
|
|
||
| it('keeps randomAccessStructure off on non-primary DBIs even when the global config is true', () => { | ||
| // Non-primary stores (e.g. the __dbis__ metadata DBI) must stay in records mode for | ||
| // v4-downgrade decodability, regardless of the global setting. | ||
| withRandomAccessFields(true, () => { | ||
| assert.strictEqual(new OpenDBIObject(false, false).randomAccessStructure, false); | ||
| }); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.