Fix: (Nested) null values will never be applied to SQLite when batched in Onyx#526
Conversation
|
Interesting issue! I'm not sure I fully understand it, even after reading it a couple of times, but as long as you have some tests that prove the bug and the fix, then I'm good with it. As for the SQLite mock, I think it would be ideal to be able to spin up an actual SQLite database and run tests directly against it. That would give us extremely accurate and reliable tests. What would need to happen to have that? |
I'm gonna further enhance the description. The thing is, that we're batching the changes from the
The idea about an in-memory SQLite database is as in https://www.sqlite.org/inmemorydb.html. It's possible to temporarily store the database only in-memory and this seems more than sufficient for testing/mocking purposes. If this is possible, i think we should prefer this, instead of relying on a local SQLite database and installation. I'm gonna fix this actual issue before i potentially start work on a mock, as the mock isn't really high-priority right now. Basically we would just ship the mock in |
null values will never be applied to SQLite when batched in Onyx
null values will never be applied to SQLite when batched in Onyx|
Ah, I see. So the in memory database would still use the exact same SQLite
interface? If so, then I agree that would be fine.
…On Fri, Mar 29, 2024 at 4:35 AM Christoph Pader ***@***.***> wrote:
Interesting issue! I'm not sure I fully understand it, even after reading
it a couple of times, but as long as you have some tests that prove the bug
and the fix, then I'm good with it.
As for the SQLite mock, I think it would be ideal to be able to spin up an
actual SQLite database and run tests directly against it. That would give
us extremely accurate and reliable tests. What would need to happen to have
that?
The idea about an in-memory SQLite database is as in
https://www.sqlite.org/inmemorydb.html. It's possible to temporarily
store the database only in-memory and this seems more than sufficient for
testing/mocking purposes. If this is possible, i think we should prefer
this, instead of relying on a local SQLite database and installation.
I'm gonna fix this actual issue before i potentially start work on a mock,
as the mock isn't really high-priority right now. Basically we would just
ship the mock in react-native-quick-sqlite and then we would need to
setup the mock in jestSetup.js, same as the other mocks.
—
Reply to this email directly, view it on GitHub
<#526 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJMABZUKY5RY73R63C6NKTY2UYXVAVCNFSM6AAAAABFNHI4VGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRXGA2DONRZHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
yes 👍 |
…plied-in-batched-changes-in-sqlite
|
@chrispader Lint is failing |
|
@mountiny @tgolen i'm gonna finish up the PR Author checklist by the end of the day, but this is already working. I've tested this thoroughly and it's working fine. Basically how you can test this is either through this test branch that i created or in some other way. This branch basically just applies some delta changes to a key with |
mountiny
left a comment
There was a problem hiding this comment.
@chrispader Changes look good to me, one comment, is there a way to test these in App now?
|
@mountiny addressed your comments.
There isn't really a use-case in which you can test exactly this fixed behavior in E/App, since at the time this only occurs in Therefore, in this test PR i do some Onyx operations and then fetch the value from storage directly instead of using something like |
mountiny
left a comment
There was a problem hiding this comment.
@chrispader thanks! I have spotted one little typo before merging then
Co-authored-by: Vit Horacek <36083550+mountiny@users.noreply.github.com>
|
🚀Published to npm in v2.0.27 |
@tgolen
Details
When we batch queued changes in
Onyx.mergeand they contain (nested) null values, SQLite will never be able to apply the individual deltas. Therefore, when we passnullor a nestednullin an object, SQLite will not delete the (nested) keys from storage.Imagine having something like this:
This will result in the following
batchedChanges:When we then apply these batched changes in the native storage layer (SQLite) with
JSON_PATCH, the initial data will not be erased and keys "a", "b", "d" and "e" will not be removed either, because SQLite never applied the top-level and nestednull's.The expected value in storage after applying the batched changes should be:
Whereas the actual value will be:
Generally, when SQLite sees a top-level or nested null value, it will remove this (nested) key from the database. But since we already batched the changes beforehand and don't pass every delta from the queue individually.
Cases that will prevent SQLite from removing the key from storage:
nullwill not affect SQLite, if there's a change after, because thebatchedChangeswill get merged with the last valuesnullbefore atop-levelnull will be cancelled out, since the top-levelnulljust clears the batched changesNotes multiple follow-up PRs
Creating a SQLite mock in
react-native-quick-sqliteI'm going to fix this issue in this PR. Additionally, i'm thinking about creating a in-memory or local SQLite mock and ship it with https://github.com/margelo/react-native-quick-sqlite. The mock could then either run in-memory directly - if possible - or we would need to spin up a local SQLite database.
Creating storage provider specific tests (with actual mocks)
With this mock we could add more native-specific tests in
react-native-onyxand potentially improve other tests so that we test for all platforms.Related Issues
GH_LINK
Automated Tests
Manual Tests
Author Checklist
### Related Issuessection aboveTestssectiontoggleReportand notonIconClick)myBool && <MyComponent />.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)Avataris modified, I verified thatAvataris working as expected in all cases)mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop