-
Notifications
You must be signed in to change notification settings - Fork 146
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
how to have multiple stores under the same db ? #31
Comments
Ah yes. I messed this up. Will come up with a way to fix this. |
Right now, yes, you need to create a db for each store. That wasn't my intention. |
yeah its okay i understand, i found that the api is kinda a mess as u need to use an upgrade something function to add new object stores under the same db 😞 |
@jakearchibald I used your other module, |
@rodgobbi please do! I had a stab at this in https://github.com/jakearchibald/idb-keyval/compare/issue-31, but Edge is either violating the event loop, or there's something I'm not understanding. |
@jakearchibald nice, I'll gladly move forward this lib. I'll spend time on it asap. |
@rodgobbi I'm not sure I understand the proposal. Could you sketch out the usage of the API? |
That would be const [store1, store2] = idbFactory('db1', ['store1', 'store2' ], 1);
store1.set(...); // and so on |
Hmm, why not just: const store1 = new Store('db1', 'store1');
const store2 = new Store('db1', 'store2'); |
Already tried that, the main problem that I found was that you need to use a greater version of the previous existing db to upgrade that way. So it needs to be like: const store1 = new Store('db1', 'store1', 1);
const store2 = new Store('db1', 'store2', 2); At a first glance it's ok, but keeping track of this version across a project can be dangerous, for example: someone may increment the first version number to 2 and forget about the second one, which will lead to the |
I think your proposal has the same problem: const [store1, store2] = idbFactory('db1', ['store1', 'store2' ], 1);
// Then somewhere in unrelated code:
const [books, albums] = idbFactory('db1', ['books', 'albums' ], 1); I don't think this project can assume that a single db is defined in a single place. The fix I wrote in https://github.com/jakearchibald/idb-keyval/compare/issue-31 should work according to the spec (but doesn't in Edge), but it is hacky. It could be that IDB isn't suited to what I'm trying to do here. |
You are right about the same problem. |
isnt it possible to check if a previous store were found under the same name, and if yes then get the version and increment it ? const cacheStore = new Store(
'Media_Manager', // db
'cacheStore' // store
)
// b4 creating the new store, get the db name
// check if we already have something with that name
// if yes get its number and ++ for the new store
const infoStore = new Store(
'Media_Manager', // db
'infoStore' // store
) |
@ctf0 seems like you're talking about https://github.com/jakearchibald/idb-keyval/compare/issue-31. |
@jakearchibald any updates ? |
I haven't had time to dig into this further. Any ideas? |
@jakearchibald sorry, this is kinda over my head :( |
damn. just ran into this. wish I'd realised sooner. |
If I understand correctly, a possible algorithm for this might be:
I'll put together a PR as an example |
Hey, there is a PR doing this already, still posting this here if it can be of any help. We have a custom implem to solve this problem which reads like:
|
fwiw, I'm thinking about removing the custom store stuff and getting folks to use https://github.com/jakearchibald/idb if they want a custom store. Implementation is here: https://github.com/jakearchibald/idb#keyval-store |
I have no problem with a separate idb per custom store, except it would be nice to have an interface for deleting the custom store. I looked at this and could understand it, I looked at idb, and I'd have to learn a lot more about IndexedDB (or something) to understand that. Definitely a bigger learning curve. |
Don't know if anyone is still dealing with this issue, but I have a small workaround for this issue in my app. I just ensure that the stores are created with the native syntax prior to creating the // Manually create stores if they don't exist
const request = indexedDB.open('myDatabase')
request.onupgradeneeded = function(event) {
const db = event.target.result
db.createObjectStore('myStore1')
db.createObjectStore('myStore2')
// etc. for any additional stores
}
// Now the lib stores will work as expected
const store1 = new Store('myDatabase', 'myStore1')
const store2 = new Store('myDatabase', 'myStore2') |
#80 is my current plan for the next major version. |
@jakearchibald does import { set, createStore } from 'idb-keyval';
const store = createStore('custom-keyval-db', 'custom-keyval-store');
set('hello', 'world', store); solve it or do we still need this ticket ? |
I tried this fix and it did not resolve the issue. I was still unable to access 'myStore2', even when this code block immediately precedes calls to idb-keyval. (using |
The new version reworks custom stores a little, so it's easier to add your own implementation. Although if you need to do that, you may find https://github.com/jakearchibald/idb/ easier. |
I had a need for really simple key-value store, but I also need some basic partitioning for the data. I did not care what the indexed-db database name would be, but I wanted the stores to be different. Say for example: different keyval store per type of entity I wanted to store, where I can do basic read/write via the entity's id Obviously, the problem with this was that of the indexed db version during upgrades. The solution I came up was this very inelegant solution to add an object store to an indexed db database
Following is my implementation for the same. (This implementation can be generalised further, allowing for different db names as well) import { promisifyRequest } from 'idb-keyval';
export const IDB_KEYVAL = 'DB_NAME';
let keyValDB$ = promisifyRequest(indexedDB.open(IDB_KEYVAL));
export function createKeyvalStore(storeName: string) {
const probe$ = keyValDB$
.then(db => {
db.addEventListener('versionchange', () => {
db.close();
});
return db;
});
const version$ = probe$
.then(db => {
const stores = db.objectStoreNames;
if (!stores.contains(storeName)) {
return db.version + 1;
}
else {
return db.version;
}
});
const upgrade$ = (async () => {
const version = await version$;
const probe = await probe$;
if (version !== probe.version) {
const upgrade = indexedDB.open(IDB_KEYVAL, version);
upgrade.addEventListener('upgradeneeded', () => {
upgrade.result.createObjectStore(storeName);
});
return new Promise<void>((resolve) => {
upgrade.addEventListener('success', () => {
upgrade.result.close();
resolve();
});
});
}
})();
keyValDB$ = upgrade$.then(() => changeDb());
return async <T>(txMode: IDBTransactionMode, callback: (store: IDBObjectStore) => T | PromiseLike<T>) => {
const db = await keyValDB$;
return callback(db.transaction(storeName, txMode).objectStore(storeName));
};
}
function changeDb() {
return promisifyRequest(indexedDB.open(IDB_KEYVAL));
}
@jakearchibald I would really like your comments/inputs on this |
You probably want https://www.npmjs.com/package/idb rather than this package, as what you're doing is more complex than what idb-keyval was designed for. |
But I wanted to avoid the full idb package. The helper above basically helps me create a custom store that I can later pass to 'get' and 'set' functions in idb-keyval, without needing the full idb package, because my use cause does not require the complex querying and indexing. Previously, the rule for idb-keyval was: Only 1 object store, and database name and object store must be the same. With this helper function. that rule becomes: many object stores in a database, with any name you like, but all object stores in that database should be controlled/created by idb-keyval. The reason that all object stores in the given database should be controlled by idb-keyval is that the helper function updates the version of the database in a non-deterministic way. This is a problem for the normal 'upgradeneeded' flow of changing object store schemas. |
atm i have something like
but i keep getting the error
and it points to
so it that possible or do i've to create new db for each store ?
The text was updated successfully, but these errors were encountered: