IndexedDBにはまってます。(その23)で、インデックスキー(補キー)の場合のカーソルの移動によるレコードとキーの参照(取得)を紹介しました。
今回は(その17)と(その18)と同様に、deleteメソッドによるレコードの削除と、updateメソッドによる更新を一気に紹介します。(どちらもIDBCursorのインスタンスメソッドです。)
今回もコピペコード全てをテキストファイル「code_IndexedDB_24.txt.zip」にまとめてアップロードしました。ご利用ください。
前回同様にWebブラウザ(Google Chromeを利用)のコンソールを利用して、つぎのインデックスキー(補キー)登録用とレコード格納用配列を登録して、レコードの格納までを済ませます。
コピペコードファイルの「登録用インデックスキー(補キー)の配列」「レコードの配列」を登録して、つづけて「オブジェクトストア生成と共にインデックスキー(補キー)登録」と「レコードの格納」を実行します。
const storeIndex = [
{name:'indexEn', path:'index.en', unique:false, multi:false},
{name:'indexSn', path:'index.sn', unique:false, multi:false},
{name:'id', path:'id', unique:true, multi:false},
{name:'attributeArray', path:['attribute','note'], unique:true, multi:false},
{name:'indexArray', path:['index.en','id'], unique:false, multi:false},
{name:'tagMulti', path:'tag', unique:false, multi:true}
];
const records = [
{key:2, data:{index:{en:1, sn:'SN0003'}, date:0, title:'ZINC', attribute:'transition', tag:['plate','Zn','shingle','brass'], note:'Zn', id:2}},
{key:6, data:{index:{en:2, sn:'SN0001'}, date:0, title:'GOLD', attribute:'transition', tag:['coin','jewelry','plate','Au','finger'], note:'Au', id:6}},
{key:5, data:{index:{en:3, sn:'SN0002'}, date:0, title:'SILVER', attribute:'transition', tag:['coin','jewelry','plate','tableware'], note:'Ag', id:5}},
{key:7, data:{index:{en:4, sn:'SN0004'}, date:0, title:'PLATIUM', attribute:'transition', tag:['css','jewelry','plate','catalyst'], note:'Pt', id:7}},
{key:1, data:{index:{en:5, sn:'SN0005'}, date:0, title:'COPPER', attribute:'transition', tag:['coin','pans','plate','shingle','brass'], note:'Cu', id:1}},
{key:3, data:{index:{en:6, sn:'SN0006'}, date:0, title:'ALUMINUM', attribute:'post-transition', tag:['coin','sash','pans','Macbook'], note:'Al', id:3}},
{key:9, data:{index:{en:7, sn:'SN0009'}, date:0, title:'TIN', attribute:'post-transition', tag:['pewter','cup','plate','suzunari'], note:'Sn', id:8}},
{key:4, data:{index:{en:9, sn:'SN0011'}, date:0, title:'LEAD', attribute:'post-transition', tag:['solder','bullet','glass','battery'], note:'Pb', id:9}}
];
そしてラングオブジェクト生成メソッドも準備します。
コピペコードファイルの「ラングオブジェクトを生成するメソッド」を登録します。
(その23)とコードの構造は同様です。注意事項を確認します。
レコードの削除(更新も)ですから、トランザクションの生成は’readwrite’モードです。
const tx = db.transaction('Store_name', 'readwrite');
インデックスオブジェクトのカーソル移動は、マルチエントリーを真にしたインデックスキー(補キー)’tagMulti’を対象とします。
indexObject = objectStore.index('tagMulti');
ラングオブジェクトの生成指定は(その22)の最後尾の検証と同じく配列要素に’jewelry’があるレコードとします。
const range = newRange({start:{v:'jewelry', b:false}, end:{v:'jewelry', b:false}});
確認まで「//インデックスキー(補キー)のカーソルを生成する。」ではopenCursorメソッド(IDBIndexのインスタンスメソッドです。)を利用します。
//インデックスキー(補キー)のカーソルを生成する。
cursorRequest = indexObject.openCursor(range, direction);
あとはカーソルオブジェクトの生成すれば、やっぱり(その23)と同じく、一段階層が深くなるだけで(その17)からのコピペで済みました。つぎです。
//操作前のレコードを取得する。
r.push(JSON.parse(JSON.stringify(cursor.value)));
let req = null;
try {
req = cursor.delete();
req.addEventListener('success', (event)=>{
console.log(`レコードの削除に成功しました。`);
}, false);
req.addEventListener('error', (event)=>{
console. error(`レコードの削除に失敗しました。`);
}, false);
} catch(exception) {
console.error(`カーソルによる操作に失敗しました。`);
console.dir(exception);
}
if(req !== null) {
try {
cursor.advance(cursorStep);
} catch(exception) {
console.error(`カーソルの移動に失敗しました。`);
console.dir(exception);
}
count++;
}
留意点としては、JSONのメソッドを使って「//操作前のレコードを取得する。」(試験的バックアップです。)こと、
r.push(JSON.parse(JSON.stringify(cursor.value)));
カーソルオブジェクトのdeleteメソッドを利用することです。
req = cursor.delete();
同じ説明をすることもないので、(その17)で確認してください。
それでは、コピペコードファイルの「カーソル移動:インデックスキー(補キー)’tagMulti’によるレコードの削除」を実行します。
目的のレコードが削除されています。(ごそっと消えるのでよく確認しましょう。)
つづけてカーソル移動によるレコードの更新を紹介します。
レコードの格納状態を復旧しますので、つぎと同じ、コピペコードファイルの「レコードの配列(復旧用)」をコンソールに登録して、「レコードの格納」を実行し、最初のレコード格納状態に戻します。
const records = [
{key:6, data:{index:{en:2, sn:'SN0001'}, date:0, title:'GOLD', attribute:'transition', tag:['coin','jewelry','plate','Au','finger'], note:'Au', id:6}},
{key:5, data:{index:{en:3, sn:'SN0002'}, date:0, title:'SILVER', attribute:'transition', tag:['coin','jewelry','plate','tableware'], note:'Ag', id:5}},
{key:7, data:{index:{en:4, sn:'SN0004'}, date:0, title:'PLATIUM', attribute:'transition', tag:['css','jewelry','plate','catalyst'], note:'Pt', id:7}},
];
ここまで削除と同様の準備ですから、最初からやり直しても大丈夫です。
そしたら先に、コピペコードファイルから「レコードの配列(更新用)」を利用して、コンソールに更新用のレコード配列を登録します。
const records = [
{key:[1, 'SN0003'], data:{index:{en:1, sn:'SN0003'}, title:'亜鉛'}},
{key:[2, 'SN0001'], data:{index:{en:2, sn:'SN0001'}, title:'金'}},
{key:[3, 'SN0002'], data:{index:{en:3, sn:'SN0002'}, title:'銀'}},
{key:[4, 'SN0004'], data:{index:{en:4, sn:'SN0004'}, title:'プラチナ'}},
{key:[5, 'SN0005'], data:{index:{en:5, sn:'SN0005'}, title:'銅'}},
{key:[6, 'SN0006'], data:{index:{en:6, sn:'SN0006'}, title:'アルミニウム'}},
{key:[7, 'SN0009'], data:{index:{en:7, sn:'SN0009'}, title:'錫'}},
{key:[9, 'SN0011'], data:{index:{en:9, sn:'SN0011'}, title:'鉛'}}
];
この配列につては(その18)に説明があります。検証の手を抜くために少しややこしいことをしてますので、ご注意ください。
レコードの更新実行コードは、削除の場合と同様です。同じ位置に(その18)からコードのコピペで済みました。つぎのコードです。
//操作前のレコードを取得する。
r.push(JSON.parse(JSON.stringify(cursor.value)));
const upValue = cursor.value;
for(let i=0; i<records.length; i++) {
//更新データのkeyとプライマリキー(主キー)の値を比較する。
if(indexedDB.cmp(records[i].key, cursor.primaryKey) === 0) {
const ks = Object.keys(records[i].data);
for(let k of ks) {
upValue[k] = records[i].data[k];
}
break;
}
}
let req = null;
try {
req = cursor.update(upValue);
req.addEventListener('success', (event)=>{
console.log(`レコードの更新に成功しました。`);
}, false);
req.addEventListener('error', (event)=>{
console. error(`レコードの更新に失敗しました。`);
}, false);
} catch(exception) {
console.error(`カーソルによる操作に失敗しました。`);
console.dir(exception);
}
if(req !== null) {
try {
cursor.advance(cursorStep);
} catch(exception) {
console.error(`カーソルの移動に失敗しました。`);
console.dir(exception);
}
count++;
}
留意点は、JSONオブジェクトを使って「//操作前のレコードを取得する。」の実コードのつぎ、ここでは三行目からです。
移動中のカーソルが今現在抱えているレコードが、更新配列の中にあったらば、そのレコード内の情報を代入(変更)して、更新準備をするというものです。
更新配列の中に対象がなければ、レコードは現状のまま素通りします。
const upValue = cursor.value;
for(let i=0; i<records.length; i++) {
//更新データのkeyとプライマリキー(主キー)の値を比較する。
if(indexedDB.cmp(records[i].key, cursor.primaryKey) === 0) {
const ks = Object.keys(records[i].data);
for(let k of ks) {
upValue[k] = records[i].data[k];
}
break;
}
}
そして、削除のdeleteメソッド行をupdateメソッドに差し替えて、変更もしくは現状のレコードをパラメータにして、ともかく更新を実行してしまいます。
req = cursor.update(upValue);
詳しく同じ説明をすることもないので、(その18)でご確認ください。
それでは、コピペコードファイルの「カーソル移動:インデックスキー(補キー)’tagMulti’によるレコードの更新」を実行します。
目的のレコードのタイトルが日本語に代わりました。
よっしゃー。比較的短い文章で済みました。プライマリキー(主キー)の時の苦労が報われました。
これで、はまったシリーズはその紹介が一通り済みました。(とりま、自分を褒めたい。)
「しかしま、こんなに大掛かりなものをどうやって取り扱うの?」と、感想を持たれるやもしれません。
いやいや、私の駄文を根気よく読んでここまで到達したような強者(感謝。)であれば、そんな心配は不要なのかもしれません。
しかしながら、ばらばらの紹介をしたままでは少々気が引けます。
はまったシリーズ(まとめ)として、投稿しながら開発した独自手法の概略を紹介いたします。
参考になるのか甚だ不安ですが、まあ、今更ってところですか。そかさ。