1

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

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

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

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

正因为如此,我得到了已经存在的对象存储的数量,如果这个数量少于我添加的部分的数量。

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

这在 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);
            }
        };
    }
4

0 回答 0