最近、ブラウザに内蔵されているローカル用のDBのIndexedDBを使ってみました。
DBのスキーマを変更したいようなときに、onupgradeneeded を使いますが、ちょっとした説明と実装例を示します。
なお、動作確認したブラウザは、Chrome 102 です。
IndexedDBでは、DBを開くときにバージョンを渡す
下記の、1
というのがバージョンです。
DBOpenRequest = window.indexedDB.open("Sample", 1);
DBがないか、バージョンが変わった場合に呼ばれる upgradeneeded
もともと、バージョンを持っていない場合、もしくは、ブラウザが保持しているバージョンがopen
で指定されているものより低い場合に、
upgradeneeded
というイベントが呼ばれます。addEventListener
で定義するか、onupgradeneeded
に代入するかで実装できます。
下記のように、定義します。
DBOpenRequest.addEventListener("onversionchanged", event => {}); DBOpenRequest.onupgradeneeded = event => {};
event の中身
下記くらい知っていれば良いのではないでしょうか。
key | value |
---|---|
event.oldversion | ブラウザが保持しているバージョン(なければ 0) |
event.newVersion | open に書かれているバージョン |
event.target.result | IDBDatabaseオブジェクト |
event.target.transaction | onupgrade 中のトランザクション |
のようなものがあります。
event.oldversion
と event.newversion
の差分を確認して、必要な変更を当てる必要があります。
実装例
下記のように各バージョンごとに関数定義すると良いのではないかなと思います。
DBOpenRequest.onupgradeneeded = event => { const oldVersion = event.oldVersion; const newVersion = event.newVersion;; const db = event.target.result; const migration = { "1": () => { { // User master const s = db.createObjectStore('user', {keyPath: "nickname"}); s.createIndex("nickname", "nickname", {unique: true}); } { // logs const s = db.createObjectStore("logs", {keyPath: "date"}); s.createIndex("date", "date", {unique: false}); s.createIndex("content", "content", {unique: false}); } }, "2": () => { { // logs (date => loggedDate に変えたくなった) db.deleteObjectStore("logs"); // 消して作り直してます。中身とって、入れ直しとかしたら良いですね。 const s = db.createObjectStore("logs", {keyPath: "date"}); s.createIndex("loggedDate", "date", {unique: false}); s.createIndex("content", "content", {unique: false}); } }, "3": () => { { // logs (titleいるよね) const s = event.target.transaction.objectStore("logs"); // transaction からとってこないとエラーになります s.createIndex("title", "title", {unique: false}); } } } // 最新バージョンになるまで差分を適用 for (let v = oldVersion + 1; v <= newVersion; v++) { if (migration[v]) { migration[v](); } } };
versionchange イベント
これは、試せてないのですが、別のタブとかで開いているときに、片方でDBのバージョンアップが走った場合に、起きるイベントのようです。 勝手にアップデートされる前に、DBに保存すると行った処理を実装するために使うようです。
例として、A, B のタブでSampleというDBを使っている。
そのときに、A で、upgradeが走るときに、B にversionchange イベントが発生するようです。
下記に詳しく載っています。