April 21, 2020 [ Web ]
Indexeddbを使うならラッパーが要るやろ、とオモて、溺死やったらコレ便利やんってちゃうか、とオモて、知らんけど
■構造 DB > Table > kvs > record
(db=)schedule_db > schedule(=table) > kvs(Key=自動採番:Value=json=record)
kvsはid++が先頭に来ずでこう→ 1:"{"name":"aaa",reg_date":"20201027_11:57:24","id":1}"
var db = new Dexie("schedule_db");
db.version(1).stores({
schedule: '++id,name,reg_date'
});
■操作
var db = new Dexie("schedule_db"); schedule_dbというDBがセットされ
schedule: '++id,name,key,reg_date' テーブルscheduleにカウントアップKey:JSON{id,name,key,reg_date}が入る
もしschedule: 'name,key,reg_date'ならnameが自動で一番最初のカラムだからキーになる
キーの値が同じだとAddができない
stores()で一番最初に来るのが「主キー」
put()は追加しあれば更新、add()は追加のみで同キーがあればエラー
put()はupdateとしてDB上上書きされるように見えるがループすると全データが出てくる、謎
first()やlimit()やlast()で欲しいレコードを取得
toArray()ではobjが返るがobjは配列で引数0をつけてアクセス obj[0]
get('aaa')はkey=aaaの値を持つ最初の行、get({key: "sss", value: "ccc"})で条件付可
delete()の返り値Promiseに削除件数が入っている
■削除のレベルは行、表、DB
行削除 db.schedule.where({id: id}).delete().then (function(records){
表削除 trancateで db.schedule.clear(); コンソールには反映されていないがレコード削除済
db.table(storeName) で操作あるいはtables ->だめだった
表を複数持てる
db.version(1).stores({
genres: '++id,name',
albums: '++id,name,year,*tracks',
bands: '++id,name,*albumIds,genreId'
});
db.delete() DBを消せる(その後新たに再作成できる)
■insert
db.schedule.add({name: "aaa", key: "bbb", reg_date: getCurrentTime()}).then (function(id){
return db.schedule.get(id);
}).then(function (schedule) {
alert ("Date was set at " + schedule.reg_date);
■select
db.reserve.each(function(records){
if(records == null || records == ''){
alert ("No data found");
}else{
records.json;
toArrayは複雑になる、eachの方がよいかも、toArrayとeachの入れ替えてのselect発行が基本できるみたい
db.reserve.where({flg_del: 2}).toArray(function(records){
records.forEach(function(record){//obj.forEach直で行ける
Object.keys(record).forEach(function(key) {//直で行けずObject.keys().forEach()で
let val = this[key];
if(key == 'json'){
let v = JSON.parse(val);//直で行けずパースが必要
Object.keys(v).forEach(function(k) {
let v = this[k];
console.log(k, v);
}, v);
}
}, record);
});
複雑なものはOr句で出せる
db.reserve.where('reg_date').below(getCurrentTime()).or('flg_del').equals(2).limit(3).each(function(records){
console.log('List: ' + JSON.stringify(records));
And句はfunctionを取るが簡単な感じがする
db.reserve.where('datetime').below(display_expire_date).and(item => item.flg_del == 2).desc('datetime').limit(display_ex).each(function(records){
複数条件はwhereにオブジェクトとして記載するがbelow等のフィルターにつながらずエラー、シンプルならokだが
db.reserve.where({datetime, flg_del: 2}).below(display_expire_date).limit(display_ex).each(function(records){
複数条件にフィルターをつけるにはwhereに配列で記載するが一つはbelow、一つはequalsでフィルタが複数でうまくいかない、シンプルならokだが
db.reserve.where(["datetime", "flg_del"]).below([display_expire_date, 2]).limit(display_ex).each(function(records){
先頭行
db.schedule.where('name').equals('aaa').first().then (function(records){
x↓ダメ??
db.schedule.where('name').equals('aaa').toArray(function(records){
alert(records.reg_date);
x↓ダメ??
db.schedule.get({name: "aaa", key: "bbb"}).then (function(records){
alert (JSON.stringify(records));
for (let i in records) {
alert(i + ' item has ' + records[i].reg_date);
}
■Insert and select(キーのidを使う)
db.schedule.add({name: "ver1.0", key: document.getElementById("inputKey").value, value: document.getElementById("inputValue").value, reg_date: getCurrentTime()}).then(function(){
db.schedule.get('2').then(function(records){
alert(JSON.stringify(records));
}).catch(function(error) {
alert ("Ooops: " + error);
});
}).catch(function(error) {
alert ("Ooops2: " + error);
■Update
putは存在があれば更新、なければ挿入
db.schedule.put({key: "bbb", reg_date: set_date}).then (function(){
return db.schedule.get('bbb');
}).then(function (schedule) {
alert ("Date was set at " + schedule.reg_date);
keyが出せる場合はupdate()
db.friends.update(2, {name: "Number 2"}).then(function (updated) {
トランザクションや細かな変更はmodify()
db.friends.where("shoeSize").aboveOrEqual(47).modify({isBigfoot: 1});
modify推奨?→ https://dexie.org/docs/Collection/Collection.modify()
■Delete
db.schedule.where({name: "aaa"}).delete().then (function(){
return db.schedule.toArray();
}).then(function (records) {
if(records == null || records == ''){
alert ("No data found");
}else{
alert (JSON.stringify(records));
}
■アクセス
indexeddbは該当DBにどこからアクセスできるか>同一ドメイン、ディレクトリでじゃない
保存場所
C:\Users\<ユーザ>\AppData\Local\Google\Chrome\User Data\Default\IndexedDB
C:\Users\<ユーザ>\AppData\Roaming\Mozilla\Firefox\Profiles\XXXXX.default\storage\default
■課題
SWで外部JSを扱うにはSW内に importScripts('dexie.js'); で埋め込む
SyntaxError: Unexpected token o in JSON at position 1 はオブジェクトが返っている
JSONはオブジェクトで扱うのが楽 JSON.stringify(records)とJSON.parse(records)で変換
console.log('json: ' + JSON.stringify(json));
for(i = 0; i < json.length; i++){
if(json[i] != null) {
console.log('id: ' + json[i].id);
下のようなロジックはあるテーブルのSELECTループ中に他のテーブルにアクセスする入れ子なのでエラー「NotFoundError: Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.」→配列に入れてIndeDBの問い合わせを一旦完了し、配列のループでIndedbを操作
self.addEventListener('sync', function(event){
db.que.each(function(records){
if(event.tag.startsWith('post-data:' + records.tag)){
event.waitUntil(postDataSW(db));
}
});
function postDataSW(){
db.reserve.where({flg_server: 2}).toArray(function(records){
DevTools failed to load SourceMap: Could not load content~のエラーが出た
効果あるか不明だがdexieの最終行のコレを削除した、文字コードがUTF8に変えたりも //# sourceMappingURL=include.prepload.js.map
■関連JS、Javascript
JSでAタグリンクを挿入するにはinsertAdjacentHTMLがよい
生成したタグを追加する前に掃除するにはdocument.getElementById('xx').textContent = null;
■テスト
https://www.bangboo.com/indexeddb/indexeddb_dexie_form.html
https://www.bangboo.com/indexeddb/test/indexeddb_dexie_form.html (ディレクトリ違い)
Posted by funa : 12:00 AM