IndexedDBにはまってます。(その15)に続いてカーソル運用の紹介をします。
移動用メソッド以外に、updateメソッドとdeleteメソッドによるレコードの更新と削除の機能があります。まずは後者で比較的簡単なdeleteメソッドから紹介します。
(その15)の作業を「オブジェクトストアStore_name生成」→レコードの「配列オブジェクトを準備」→「レコード格納」と、「というわけで、レコード格納までは(その14)と同じでした。」まで済ませます。
はい、投稿を前後するのはとっても面倒ですね。
今回のコピペコード全てをテキストファイル「code_IndexedDB_17.txt.zip」にまとめてアップロードしましたので、ダウンロードしてご利用ください。
アプリケーション画面でレコードも確認します。
そして「ラングオブジェクトを生成するメソッド」は、IndexedDBにはまってます。(その16)からコピー&ペーストしてコンソールに登録してください。
今回(と次回)は、レコードの削除(と更新)による改変処理ですから、トランザクションの生成は’readwrite’モードです。
const tx = db.transaction('Store_name', 'readwrite');
また、レコードの改変処理を行うメソッドはカーソルに入ってきたレコードの処理を行いますが、カーソルの移動はできません。よって前回(その15)のadvanceメソッドと同居になります。
さらに、今回のdeleteメソッドとadvanceメソッドは各々に例外が発生しますので、try文も別々に用意します。
例によって、(個人的に)入れ子にしたくないので、つぎのように前後に並べます。
前回(その15)の「カウント出力」行から「カウントインクリメント」までのカーソル処理ブロックはつぎのように変更します。
console.log(`カーソルの移動は_>${count}回めです。`);
console.log(`カーソルリクエストを参照_>${cursor.request}`);
//操作前のレコードを取得する。
r.push(JSON.parse(JSON.stringify(cursor.value)));
let req = null;
try {
req = cursor.delete();
req.addEventListener('success', (e)=>{
console.log(`レコードの削除に成功しました。`);
}, false);
req.addEventListener('error', (e)=>{
console. error(`レコードの削除に失敗しました。`);
}, false);
} catch(e) {
console.error(`カーソルによる操作に失敗しました。`);
console.dir(e);
}
if(req!==null) {
try {
cursor.advance(cursorStep);
} catch(e) {
console.error(`カーソルの移動に失敗しました。`);
console.dir(e);
}
}
count++;
コードの説明をします。
まず「操作前のレコードを取得する。」です。
(その15)では「cursor.value」だけを取得してましたが、それは削除してしまうのでモニター(観察)するのではなくて取得します。
となると、データベースからの参照を断ち切るため、一度JSON文字列に変換してからJavascriptのオブジェクトにパースします。
将来、バックアップが必要な場合に使える手法になると期待できます。(まだ、そこまで開発はしてませんので予測の範疇です。)
最初のtry文では、deleteメソッドでカーソルの対象レコードを削除します。さらに、成功と失敗イベントが発火しますので受け取り枠を準備します。
そしてdeleteメソッドのリクエストが代入される変数reqがnullでなければ、advanceメソッドによるカーソル移動が行われます。こちらも(その15)と同じっくtry文で包みます。
それでは、つぎのコードをWebブラウザ(Google Chromeを利用)のコンソールにコピー&ペーストし、エンターキーで実行します。
const openRequest = indexedDB.open('DB_name');
openRequest.addEventListener('success', (event)=>{
const db = event.target.result;
console.log(`データベースを開始しました。`);
if(db.objectStoreNames.contains('Store_name')) {
const tx = db.transaction('Store_name', 'readwrite');
tx.addEventListener('complete', (event)=>{console.log(`トランザクションが完遂しました。`);}, false);
tx.addEventListener('error', (event)=>{console.error(`トランザクションでエラーが発生しました。`);}, false);
tx.addEventListener('abort', (event)=>{console.error(`トランザクションが中断しました。`);}, false);
const objectStore = tx.objectStore('Store_name');
//ラングオブジェクト生成
const range = newRange({start:{v:[2, 'SN0001'], b:false}, end:{v:[5, 'SN0005'], b:false}});
//カーソル移動方向キーワード
const direction = 'next';
//カーソル移動ステップ(整数)
const cursorStep = 1;
let cursorRequest;
try {
//オブジェクトストアのカーソルを生成する。
cursorRequest = objectStore.openCursor(range, direction);
} catch(e) {
console.error(`カーソルの生成に失敗しました。`);
}
if(cursorRequest!==null) {
//カーソルによるオブジェクトストア操作箇所の始まり
let r = new Array();
let count = 0;
cursorRequest.addEventListener('success', (e)=>{
const cursor = e.target.result;
if(cursor===null){
console.log(`カーソルの移動が終了しました。`);
if(count===0) console.error(`対象となるレコードがありませんでした。`);
else {
console.log(`カーソルの移動が終了しました。_全移動回数_>${count}`);
console.dir(e.target.source);
console.dir(r);
}
} else {
console.log(`カーソルの移動は_>${count}回めです。`);
console.log(`カーソルリクエストを参照_>${cursor.request}`);
//操作前のレコードを取得する。
r.push(JSON.parse(JSON.stringify(cursor.value)));
let req = null;
try {
req = cursor.delete();
req.addEventListener('success', (e)=>{
console.log(`レコードの削除に成功しました。`);
}, false);
req.addEventListener('error', (e)=>{
console. error(`レコードの削除に失敗しました。`);
}, false);
} catch(e) {
console.error(`カーソルによる操作に失敗しました。`);
console.dir(e);
}
if(req!==null) {
try {
cursor.advance(cursorStep);
} catch(e) {
console.error(`カーソルの移動に失敗しました。`);
console.dir(e);
}
}
count++;
}
}, false);
cursorRequest.addEventListener('error', (e)=>{
console.error(`カーソルの移動の_>${count}回めを失敗しました。`);
}, false);
//カーソルによるオブジェクトストア操作箇所の終わり
}
} else console.error(`目的のオブジェクトストアはありませんでした。`);
db.close();
db.addEventListener('close', ()=>{console.log(`データベースが閉鎖されました。`);}, false);
}, false);
openRequest.addEventListener('error', (event)=>{console.error(`データベースの開始に失敗しました。`);}, false);
ちゃんとバックアップ(ぽい)が取れた上で、削除がされている(レコードが消えている。)のを確認できます。
カーソルは付け足しの重なりで処理が進む印象です。つぎのupdateメソッドは、今回の構造の上にさらにてんこ盛りになります。
本当にてんこ盛りにすると、訳わからなくなりますので、なんとか端折れるように工夫します。そかさ。