在Safari Mobile(iOS8.1)/ Safari Desktop上重新打开具有版本更改的对象库

时间:2014-11-10 18:29:51

标签: javascript safari indexeddb ios8.1

TL; DR 我想打开一个数据库,从中获取一些信息,关闭它,然后根据我从中获取的信息使用升级参数重新打开它(版本,对象的数量等。)

我的indexeddb插件遇到了一些麻烦,我写了关闭一个对象存储,然后通过版本更改重新打开它。

但首先要了解一下我究竟在做什么。由于this issue,我被迫为我的数据库做了一个非常难看的结构。基本上,我发现当您插入更多记录时,插入速度会变慢。由于我需要保存一组非常大的数据,因此将每个数据块保存到单独的Objectstore中要快得多。起初我正在为每个对象库创建一个新数据库。这很好,但随着我越来越了解indexedDB,我意识到这不是最好的方法。我将我的插件从使用多个数据库切换到具有多个对象库的一个数据库。但是,这是我的问题开始的地方。

由于我无法知道我需要多少块数据,以及每个数据块一个对象库,我首先从服务器获取将要插入的记录总数,然后将其除以大小每个块。这样我就知道我需要多少个对象店。但是,由于我将需要同步这些数据,因此这些对象库可能已经存在,或者它们可能不存在。

因此,我获得了已经存在的对象库的数量,如果该数量少于我添加的部件数量。

为了获得那么多的对象存储,我需要先打开数据库,然后再使用更新的模式信息再次打开它。但是,当我尝试这样做时,它总是在我的onupgradeneeded中击中我的中止功能。但是,如果我只是从页面加载运行创建函数而不是首先打开数据库,它似乎很好地更新数据库模式(但这并不能帮助我,因为我需要知道我有多少个表在我可以更新任何内容之前的当前db版本。

这在Android上的chrome,firefox和chrome上工作得很好,但在iOS或Safari上却没有。看起来像某种WebKit问题,但我一直在挖掘他们的bugtracker并且找不到任何看起来很像这样的东西。

我认为它没有正确关闭以前的数据库连接,所以它无法打开一个新的,但我可能在这里错了。有没有人遇到过这个问题,或者对我如何解决它有任何想法?

如果有帮助,这是我的一些代码:

$.ajax({
        type: 'POST',
        url: "website/myURL.json",
        success: function(data){
            partCount = data;
            console.log("Got " + partCount + " parts.");

            $().database.get(timeTable,{"success":function(obj){
                tables = obj;
                if(tables.length < partCount){//Build new tables
                    var newTables = [];
                    var version = ($().database.version() + 1);

                    for(var i=tables.length; i<partCount; i++){
                        newTables.push({name:"table_"+i});
                    }
                    $().database.close();
                    $().database.open("database", 
                        {   version: version,
                            tables: newTables,
                            success: function(){
                                callbackFunction();
                            }
                        }
                    );
                }
                else{
                    callbackFunction();
                }
            }});

从插件中打开函数:

    function open(options){
        var opts = $.extend({
            version: settings.version,
            name: settings.name,
            keyPath: settings.keyPath
        },options);

        _dbExists = true;
        _logging = opts.logging;

        database.indexedDB = {};
        database.indexedDB.db = null;

        var request;
        if(opts.version === null || opts.version === ""){
            request = indexedDB.open(opts.name);
        }
        else{
            request = indexedDB.open(opts.name, opts.version);
        }

        request.onupgradeneeded = function(e) {
            var db = request.result;
            db.onabort = function (es) {
                console.log("DB action aborted.");
                opts.abort(es);
            };

            if(opts.tables){
                for(var j=0; j<opts.tables.length; j++){
                    table = opts.tables[j];

                    if(db.objectStoreNames.contains(table.name)){
                        db.deleteObjectStore(table.name);
                    }
                    //Create object store for each table.
                    var key = (table.hasOwnProperty("keyPath") && table.keyPath != null) ? table.keyPath : opts.keyPath; 
                    var objectStore = db.createObjectStore(table.name, {keyPath: key});
                    if(table.indices){
                        for(var i=0; i<table.indices.length; i++){
                            //Add indecies to table.
                            objectStore.createIndex(table.indices[i].name, table.indices[i].keyPath, table.indices[i].param);
                        }
                    }
                }
            }
            if(_logging) console.log("Upgrading database.");
        };

        request.onsuccess = function(e){
            database.indexedDB.db = request.result;
            _version = parseInt(request.result.version);
            console.log("DB opened");
            if(opts.success != null){
                opts.success(e);
            }
        };

        request.onerror = function(e) {
            console.log(e);
            if(opts.error != null){
                opts.error(e);
            }
        };
    }

0 个答案:

没有答案