oliver-oloughlin / kvdex

A high-level abstraction layer for Deno KV with zero third-party dependencies by default 🦕🗝️

Home Page:https://jsr.io/@olli/kvdex

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot use a primary index identical to the key

juliendorra opened this issue · comments

If I set my collection like this:

    apps: collection(
        AppsModel,
        {
            indices: {
                appid: "primary",
                timestamp: "secondary",
                username: "secondary",
            },
            history: true,
            serialized: {
                serialize: (obj) => new TextEncoder().encode(JSON.stringify(obj)),
                deserialize: (data) => JSON.parse(new TextDecoder().decode(data)),
            }
        }),

and use the same id for both the key and the appid value, the first write works, but subsequent write or update fails.

I understand that it might be by design, or a limitation, and that it's indeed redundant to use the appid as both the unique key and a unique index.

But it surprised me nonetheless.

The issue probably isn't the fact that you are using the same value as id and primary index (although I would advise against this), but that writing or updating with the same value as an existing primary index causes an index collision. Is there a reason you are trying to override the appid value on write/update with the same value?

I'm just overwriting the same document without trying to be subtle when writing the new version. (Partial updates being always a bit more delicate)
My (implicit, I guess) expectation was that overwriting a primary key with the same unique value wouldn't be an issue, but I understand now that it might be complicated /overkillfor kvdex to check that kind of case.

(In any case, I set this value as secondary index, as in my case it shouldn't be an issue.)

I'm just overwriting the same document without trying to be subtle when writing the new version. (Partial updates being always a bit more delicate) My (implicit, I guess) expectation was that overwriting a primary key with the same unique value wouldn't be an issue, but I understand now that it might be complicated /overkillfor kvdex to check that kind of case.

Yeah, it would require an extra check for each primary index after the initial index collision check to assert that the value is colliding with the same document and not some other entry. Possible to implement, but quite unnecessary imo.

I'm just overwriting the same document without trying to be subtle when writing the new version. (Partial updates being always a bit more delicate) My (implicit, I guess) expectation was that overwriting a primary key with the same unique value wouldn't be an issue, but I understand now that it might be complicated /overkillfor kvdex to check that kind of case.

Yeah, it would require an extra check for each primary index after the initial index collision check to assert that the value is colliding with the same document and not some other entry. Possible to implement, but quite unnecessary imo.

This answer saved me after spending hours figuring why updating records failed because by default that primary key is null. I just added an extra check to only update the value of the PK if the existing one is null and it worked, eg.

await db.table.update(id, {
  ... (existingRecord.somePk? {somePk: newValue})
// rest of the values to update
})