Skip to content
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 detect IDB adapter for existing DB? #8510

Closed
kiyanovsky opened this issue May 22, 2022 · 5 comments
Closed

How to detect IDB adapter for existing DB? #8510

kiyanovsky opened this issue May 22, 2022 · 5 comments
Labels

Comments

@kiyanovsky
Copy link

Issue

I have an existing user base using 'idb' adapter. For new users, I want to create DB with 'indexeddb' adapter. I need to find a way to figure out what adapter is used for the existing DB, as it may be either of those two.

So, the idea is to open it via 'indexeddb' and if there is an error, then open it with 'idb'. The thing is, I can't catch the error with invalid adapter, this one:
Uncaught Error: Incorrect adapter: you should specify the "idb" adapter to open this DB at IDBOpenDBRequest.openReq.onupgradeneeded

Instead, I'm catching the error:
DOMException: Version change transaction was aborted in upgradeneeded event handler

  1. I don't know if the caught error is always an evidence of an incorrect adapter.
  2. Even though, I don't want to have uncaught errors in the program.

Question
How do I catch the "Incorrect adapter" error?
or
Is there a different way to determine the existing DB's adapter?

Info

  • Environment: (browser)
  • Platform: (Chrome)
  • Adapter: (idb/indexeddb)

Reproduce

Code is on codepen

@filionf
Copy link
Contributor

filionf commented Jun 1, 2022

Here is how I do it.

async function getCurrentAdapterForDb(dbname: string): Promise<string> {
  return new Promise<undefined | "idb" | "indexeddb">((resolve, reject) => {
    // To detect whether the database is using idb or indexeddb, we look at the version property of the indexeddb
    // If the database does not exists ==> onupgradeneeded is called with oldVersion = 0 (requesting version 1)
    // If the database exists, a version below Math.pow(10, 13) is considered idb. A version above is considered indexeddb.
    let request = window.indexedDB.open(`_pouch_${dbname}`);
    request.onupgradeneeded = function (e: IDBVersionChangeEvent): void {
      // Since no version has been requested, this mean the database do not exists.
      if (e.oldVersion === 0) {
        resolve(undefined); // Database does not exists
      }

      // We do not want the database to be created or migrated here, this is only a check. Therefore, abort the transaction.
      request.transaction.abort();
    };

    request.onerror = function (err: Event): void {
      if (request.error.code !== request.error.ABORT_ERR) {
        // Abort Error has been triggered above. Ignoring since we already resolved the promise.
        reject(request.error);
      }
    };

    request.onsuccess = function (): void {
      // When the database is successfully opened, we detect the adapter using the version
      // If we are dealing with a new database, oldVersion will be 0.
      // If we are dealing with an existing database, oldVersion will be less than maxIdbVersion.
      // maxIdbVersion is taken from pouchdb-adapter-indexeddb/index.es.js -- v7.2.2
      let maxIdbVersion = Math.pow(10, 13);

      if (request.result.version < maxIdbVersion) {
        resolve("idb");
      } else {
        resolve("indexeddb");
      }

      // Closes the database
      request.result.close();
    };
  })
}

@kiyanovsky
Copy link
Author

Thank you a lot, @filionf, I'd never get it done by myself! The example is very detailed and commented. Do you mind if I ask this question on Stackoverflow, and then you put this answer there as well, if it makes sense?

The only thing, I can't figure out how Math.pow is the maxIdbVersion? Could you please elaborate?

@filionf
Copy link
Contributor

filionf commented Jun 2, 2022

Sure, go ahead with StackOverflow and let me know.

The maxIdbVersion value is coming from this file within the indexeddb adapter: https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-indexeddb/src/setup.js

Basically, PouchDB databases that are created with the indexeddb adapter have their version higher the Math.pow(10, 13).
Perhaps I should have named that variable minIndexedDbVersion instead.

@kiyanovsky
Copy link
Author

I've posted this question on Stackoverflow. Thank you for the prompt reply, @filionf, and please feel free to close this issue.

@github-actions
Copy link

github-actions bot commented Aug 2, 2022

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the stale label Aug 2, 2022
@github-actions github-actions bot closed this as completed Aug 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants