iOS8实现IndexedDb的主要关键问题

Jon*_*ith 29 javascript mobile-safari indexeddb ios8

问题是当您在同一个indexeddb中有两个不同的对象库时,主键值似乎在所有商店中"共享".

<body>
    <script type="text/javascript">
        //prefixes of implementation that we want to test
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

//prefixes of window.IDB objects
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange

if (!window.indexedDB) {
    window.alert("Your browser doesn't support a stable version of IndexedDB.")
}


var db;
var request = window.indexedDB.open("newDatabase", 4);

request.onerror = function(event) {
  console.log("error: ");
};

request.onsuccess = function(event) {
  db = request.result;
  console.log("success: "+ db);
};

request.onupgradeneeded = function(event) {
        var db = event.target.result;
        var objectStore = db.createObjectStore("customers", {keyPath: "arseid"});
    var objectStore = db.createObjectStore("test", {keyPath: "id"});
}



function add1() {
        var x = new Date();
    var h1 = x.getHours();
    var m1 = x.getMinutes();
    var s1 = x.getSeconds();
    console.log('starting insert on ' +  h1 + ':' + m1 + ':' + s1);

    var tx = db.transaction(["customers"], "readwrite");
    for (var i = 0; i < 1000; i++) {
        var request = tx.objectStore("customers")
                .put({ arseid: i, name: "Jonathan Smith", email: "jonathan.smith@anemailaddress.com", favourite: "chocolate cake", pet: "rudolph the red nose reindeer", address: "999 letsbe avenue, townton, countyshire" });
    }


    tx.oncomplete = function (e) {
            // Re-render all the todo's
            var x2 = new Date(); 
            var h2 = x2.getHours(); 
            var m2 = x2.getMinutes(); 
            var s2 = x2.getSeconds(); 
               console.log('transaction complete ' + h2 + ':' + m2 + ':' + s2);
        }
}


function add2() {
    //tx 2
    var tx2 = db.transaction(["test"], "readwrite");
    for (var i = 0; i < 1000; i++) {
        var request2 = tx2.objectStore("test")
                .put({ id: i, name: "Robwin Mwengway", email: "jonathan.smith@anemailaddress.com", favourite: "chocolate cake", pet: "rudolph the red nose reindeer", address: "999 letsbe avenue, townton, countyshire" });
    }

    tx2.oncomplete = function (e) {
            var x3 = new Date(); 
            var h3 = x3.getHours(); 
            var m3 = x3.getMinutes(); 
            var s3 = x3.getSeconds(); 
               console.log('transaction complete ' + h3 + ':' + m3 + ':' + s3);
        }
}


    </script>
<button onclick="add1()">Add1 data to indexedDb</button>
<button onclick="add2()">Add2 data to indexedDb</button>
</body>
Run Code Online (Sandbox Code Playgroud)

(小提琴:http: //jsfiddle.net/jonnyknowsbest/4pdp8vxe/)

在iOS8中,如果您运行小提琴并单击"将1个数据添加到IndexedDb",则会将1000个条目添加到"customers"表中.如果然后单击"将2个数据添加到IndexedDb",则会将1000个条目添加到"供应商"表中,但会删除"客户"中的1000个条目.

还有其他人遇到过这个吗?这是IndexedDb规范的一部分吗?Chrome似乎没有这个问题.

编辑:发现这个W3 Org IndexedDB建议:"在给定的对象存储中,永远不会有多个具有相同密钥的记录." Apple似乎已在数据库级别应用此功能.

Ray*_*den 20

我可以确认iOS8肯定是错误的.我尝试了一些解决方法,但我能建议的最好的是一个主键,它将一些唯一的字符串(如objectStore的名称)与一个数字组合在一起.因此,例如,给定两个名为people和notes的objectStore,我将使用如下的键存储数据:

人/ X笔记/ X.

您可以手动设置X,或者使用objectStore上的.count()方法查找计数并添加一个.这是一个例子:

//Define a person
var person = {
    name:"Ray",
    created:new Date().toString(),
}

//Perform the add
db.transaction(["people"],"readwrite").objectStore("people").count().onsuccess = function(event) {
    var total = event.target.result;
    console.log(total);
    person.id = "person/" + (total+1);

    var request = db.transaction(["people"],"readwrite").objectStore("people").add(person);

    request.onerror = function(e) {
        console.log("Error",e.target.error.name);
        //some type of error handler
    }

    request.onsuccess = function(e) {
        console.log("Woot! Did it");
    }

}
Run Code Online (Sandbox Code Playgroud)

请注意,我为此操作系统指定了"id"的keyPath.

  • 假设的iOS使用具有在https://github.com/WebKit/webkit/blob/master/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp代码基于SQLite的的实现索引资料的,对象数据被存储在一个'Records'表,在SQLite DB中有一个'key'字段.键字段具有UNIQUE约束,并且商店ID不是键的一部分.哎呀(!).我猜这也会影响OS X 10.10中的Safari. (6认同)
  • 看起来Apple几天前检查过修复程序:https://github.com/WebKit/webkit/commit/daadc48666e5015e3b7f1ccba22588e6711a0706 (2认同)