Javascript IndexedDb的iOS8实现的主要关键问题

Javascript IndexedDb的iOS8实现的主要关键问题,javascript,mobile-safari,ios8,indexeddb,Javascript,Mobile Safari,Ios8,Indexeddb,问题是,当在同一indexeddb中有两个不同的对象存储时,主键值似乎在所有存储中“共享” <body> <script type="text/javascript"> //prefixes of implementation that we want to test window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || win

问题是,当在同一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>

//我们要测试的实现的前缀
window.indexedDB=window.indexedDB | | window.mozIndexedDB | | window.webkitIndexedDB | | window.msIndexedDB;
//window.IDB对象的前缀
window.IDBTransaction=window.IDBTransaction | | window.webkitibdransaction | | window.msIDBTransaction;
window.IDBKeyRange=window.IDBKeyRange | | window.webkitIDBKeyRange | | window.msIDBKeyRange
如果(!window.indexedDB){
警告(“您的浏览器不支持IndexedDB的稳定版本。”)
}
var-db;
var request=window.indexedDB.open(“newDatabase”,4);
request.onerror=函数(事件){
日志(“错误:”);
};
request.onsuccess=函数(事件){
db=请求。结果;
console.log(“成功:+db”);
};
request.onupgradeneeded=函数(事件){
var db=event.target.result;
var objectStore=db.createObjectStore(“客户”{keyPath:“arseid”});
var objectStore=db.createObjectStore(“test”{keyPath:“id”});
}
函数add1(){
var x=新日期();
var h1=x.getHours();
var m1=x.getMinutes();
var s1=x.getSeconds();
log('在'+h1+'上开始插入:'+m1+':'+s1);
var tx=db.transaction([“客户”],“读写”);
对于(变量i=0;i<1000;i++){
var请求=tx.objectStore(“客户”)
.put({arseid:i,姓名:“乔纳森·史密斯”,电子邮件:“乔纳森。smith@anemailaddress.com,宠儿:“巧克力蛋糕”,宠物:“红鼻子驯鹿鲁道夫”,地址:“countyshire汤顿莱茨比大道999号”});
}
tx.oncomplete=函数(e){
//重新渲染所有待办事项
var x2=新日期();
var h2=x2.getHours();
var m2=x2.getMinutes();
var s2=x2.getSeconds();
log('transaction complete'+h2+':'+m2+':'+s2);
}
}
函数add2(){
//tx 2
var tx2=db.transaction([“test”],“readwrite”);
对于(变量i=0;i<1000;i++){
var request2=tx2.objectStore(“测试”)
.put({id:i,姓名:“Robwin Mwengway”),电子邮件:“jonathan。smith@anemailaddress.com,宠儿:“巧克力蛋糕”,宠物:“红鼻子驯鹿鲁道夫”,地址:“countyshire汤顿莱茨比大道999号”});
}
tx2.oncomplete=功能(e){
var x3=新日期();
var h3=x3.getHours();
var m3=x3.getMinutes();
var s3=x3.getSeconds();
log('事务完成'+h3+':'+m3+':'+s3);
}
}
将1个数据添加到indexedDb
将2个数据添加到indexedDb
(小提琴:)

在iOS8中,如果运行fiddle并单击“Add1 data to IndexedDb”,那么1000个条目将添加到“customers”表中。如果然后单击“Add2 data to IndexedDb”,则会将1000个条目添加到“suppliers”表中,但会删除“customers”表中的1000个条目

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


编辑:发现:“在一个给定的对象存储中,不可能有多个记录使用同一个键。”苹果似乎已经在数据库级别应用了这一点。

我可以确认,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");
    }

}

注意,我为这个操作系统指定了“id”的keyPath

我遇到了类似的问题,但是我第一次插入objectstore是一个只有用户名和电子邮件的小数组,第二个objectstore非常大,有几个嵌套的数据数组

我下面的insert方法将调用所有项的success,但是只有第二个对象存储将正确写入数据库

当我尝试反转写入数据库的顺序时(首先写入大型objectstore项,然后写入用户名/电子邮件),两个objectstore都被正确写入,但是主键在两个objectstore之间共享。 飞行员主键:1,2,3,4,5 AC主键:6,7,8

function insert_GroupRecord(Record, Store){
    //update individual sync record
    var trans = dbGroup.transaction([Store],"readwrite");
    var store = trans.objectStore(Store);
    var request = store.put(Record);
    request.onsuccess = function(e){
        IOS_postMessage({Message:"SyncStatus", status:"Group_Insert "+Store});
    };
    request.onerror = function(e){
        GroupSyncERROR = true;
        //IOS_postMessage({Message:"SyncStatus", status:"GroupSyncFail "+Store});
    };

    request.onupgradeneeded = function(evt){
        var objectStore = evt.currentTarget.result.createObjectStore("AC",{ keyPath: "id", autoIncrement: true });
        objectStore.createIndex("ident", "ident", { unique: true });
        var objectStore2 = evt.currentTarget.result.createObjectStore("Pilots",{ keyPath: "id", autoIncrement: true });
        objectStore2.createIndex("chatname", "chatname", { unique: true });
        console.log("KFM_Group Upgrade Completed");

    };
}

哇,真糟糕。我还没有尝试过iOS 8,但从用户那里得到一些报告,我的基于iDB的应用程序根本没有在iOS 8中运行,这就是原因。我不能说我感到惊讶,这符合我的阴谋论:)天哪。即使您让它指定自动递增,它似乎也被破坏了。我试图通过使用一个事务来修复它-您可以在一个事务中指定N个objectstores。不,抛出一个错误。据我所知,您必须指定键,并且必须使它们在每个db中唯一。今天我要在博客上写这篇文章。哦,天哪,是的。以多种方式。我有一个解决办法,我要写博客。我在raymondcamden.com。它将在30分钟内启动。假设iOS使用基于SQLite的IndexedDB实现,代码为,对象数据存储在SQLite DB中带有“key”字段的“Records”表中。密钥字段具有唯一约束,并且存储ID不是密钥的一部分。哎呀。我猜这也会影响到OSX10.10中的Safari。看起来苹果几天前签下了一个修复程序:看起来它在iOS9中得到了修复。见: