-
Notifications
You must be signed in to change notification settings - Fork 74
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
Fix: nullish keys not removed/merged in IDB-Keyval (web) #333
Fix: nullish keys not removed/merged in IDB-Keyval (web) #333
Conversation
lib/storage/providers/IDBKeyVal.js
Outdated
// If the value is null, we want to delete the key from storage, | ||
// to be consistent with the native implementation with SQLite. | ||
// SQLite by default removes keys from storage that are set to nullish values | ||
if (_.isUndefined(value) || _.isNull(value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When would it be possible for value
to be undefined? Wouldn't that mean that one of the pairs
has only a key?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value
part of the pair could also be undefined
like ['something', undefined]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sort of wondering how/why that happened though. It seems inconsistent with the merge behavior. Setting something to null
has a special significance (i.e. delete me). Setting it to undefined
does not mean anything.
I would guess that we would just throw these values out vs. allow them to overwrite / delete any keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just added a [HOLD on #334]
tag to this PR. The SQLite crash PR actually fixes two things that are expected for this PR as well.
- Allow
undefined
values to be passed tofastMerge
- Remove key in
Onyx.merge
ifnull
is passed
So we'll first want to merge the other PR in order for this to continue 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way, the extra condition in IDBKeyVal.multiMerge
is not needed anymore
lib/storage/providers/IDBKeyVal.js
Outdated
// If the value is null, we want to delete the key from storage, | ||
// to be consistent with the native implementation with SQLite. | ||
// SQLite by default removes keys from storage that are set to nullish values | ||
if (_.isUndefined(value) || _.isNull(value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value
part of the pair could also be undefined
like ['something', undefined]
.
lib/storage/providers/IDBKeyVal.js
Outdated
// If the value is null, we want to delete the key from storage, | ||
// to be consistent with the native implementation with SQLite. | ||
// SQLite by default removes keys from storage that are set to nullish values | ||
if (_.isUndefined(value) || _.isNull(value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sort of wondering how/why that happened though. It seems inconsistent with the merge behavior. Setting something to null
has a special significance (i.e. delete me). Setting it to undefined
does not mean anything.
I would guess that we would just throw these values out vs. allow them to overwrite / delete any keys.
@chrispader Can we make sure the tests cover this scenario and make sure that setting key to null or undefined will remove it with either storage? I am surprised this was not caught with automated tests |
Yes, i'll update the tests accordingly 👍 Btw, over here, we decided not to remove keys when the value is set to |
@marcaaron another thought... When we merge an object with another object, where every top-level key is set to |
I see your point. If we set the value to In this case i also think it would be better to leave the Wdyt @tgolen ? |
It would be great if we could have both performance and less storage. My suggestion would be to remove it from storage, but leave something in the cache that signals "no, don't try to read this value from storage, it's been deleted, so just return nothing". That does make the caching layer a bit out-of-sync from what's in storage though. If we don't want to make a change like that, then I think sticking with |
Agree. Also in favor of leaving The current implementation achieves exactly this, so this should be ready for merging 👍🏼 |
I think it's just waiting on @marcaaron for this one. I wasn't sure that all of Marc's concerns were addressed so I didn't want to dismiss his review and merge this yet. |
Heads up, I'm probably not going to get to this today - so if you need to move forward without me, please go ahead. |
gonna have to resolve conflicts tomorrow morning anyway, so you can still chime in if you want @marcaaron |
merge conflicts resolved 👍 |
@tgolen ill leave it up to you if you want to wait for one more review by @marcaaron |
@chrispader This is not yet resolved because when solution: and |
adding ref video 85f1d156-bde3-4446-b7c7-edeaac0e67a6.mp4 |
This is actually intended as described by @marcaaron in this GH comment. @marcaaron should we maybe overthink this? Currently, we'll leave |
I agree, that this isn't optimal yet. I'm gonna change this so that |
Fixed this issue in this PR: #359 |
@tgolen @marcaaron
Details
On web in the new IDB-Keyval implementation, when merging
null
orundefined
, the keys are not removed from storage, like it's done on native with SQLite.Additionally, top-level nullish keys in an object should also be removed when merging. E.g. when merging an existing value
{a: 1, b: 2}
with{a: null}
or{a: undefined}
the resulting value should be{b: 2}
.This PR aims to fix caused problems like this one.
Related Issues
Expensify/App#26627
Automated Tests
Linked PRs