检查IndexedDB数据库是否存在

时间:2013-07-04 11:19:54

标签: indexeddb

有没有办法检查IndexedDB数据库是否已经存在?当程序尝试打开不存在的数据库时,将创建数据库。 我能想到的唯一方法就是以下内容,我测试objectStore是否已经存在,如果不存在,则删除数据库:

var dbexists=false;
var request = window.indexedDB.open("TestDatabase");
request.onupgradeneeded = function(e) {
    db = e.target.result;
    if (!db.objectStoreNames.contains('todo')) {
       db.close();
       indexedDB.deleteDatabase("TestDatabase");
    } else {
       dbexists=true;
    }
}

9 个答案:

答案 0 :(得分:15)

在onupgradeneeded回调中,您可以检查版本。 (e.target.result.oldversion)。如果  它是0,db不存在。

编辑: 经过一番调查。如果创建了新的数据库,则无法100%确定。我确信的一件事是,如果indexeddb的版本为1或更高版本,则只能使用它。我相信db可以存在且版本为0(唯一的事实是你无法使用它并且将调用onupgradeneeded事件)。

我已经构建了自己的indexeddbviewer。在那里我打开没有版本的indexeddb,如果我进入onupgradeneeded事件,这意味着db不存在。在这种情况下,我调用中止,因此它不会升级到版本1.这是我检查它的方式。

var dbExists = true;
var request = window.indexeddb.open("db");
request.onupgradeneeded = function (e){
    e.target.transaction.abort();
    dbExists = false;
}

但如上所述。在这种情况下,db可能会继续存在,但是onupgradeneeded将始终被称为

答案 1 :(得分:2)

此函数检查数据库是否存在。使用onupgradeneeded事件,如果版本为1并且事件被触发,则表示数据库不存在,但是使用window.indexedDB.open(name)函数创建,这意味着您应该将其删除。

当onsuccess事件触发时,但onupgradeneeded事件(变量dbExists仍为true)表示数据库之前存在并返回true。

/**
 * Check if a database exists
 * @param {string} name Database name
 * @param {function} callback Function to return the response
 * @returns {bool} True if the database exists
 */
function databaseExists(name,callback){
    var dbExists = true;
    var request = window.indexedDB.open(name);
    request.onupgradeneeded = function (e){
        if(request.result.version===1){
            dbExists = false;
            window.indexedDB.deleteDatabase(name);
            if(callback)
                callback(dbExists);
        }

    };
    request.onsuccess = function(e) {
        if(dbExists){
            if(callback)
                callback(dbExists);
        }
    };
};

该函数的输出是通过回调函数。使用形式如下:

var name="TestDatabase";
databaseExists(name,function(exists){
    if(exists){
        console.debug("database "+name+" exists");
    }else{
        console.debug("database "+name+" does not exists");
    }
});

[对不起我的英文]

答案 2 :(得分:2)

以下代码有效。我用Chrome,IE和Opera测试了它。使用本地开放数据库进行测试并关闭,并使用不同版本的数据库进行测试,因此它应该是准确的。需要创建/删除数据库。但是,它将是一个没有竞争条件风险的原子操作,因为如果打开请求导致数据库创建,规范承诺不会启动以并行打开请求。

function databaseExists(dbname, callback) {
    var req = indexedDB.open(dbname);
    var existed = true;
    req.onsuccess = function () {
        req.result.close();
        if (!existed)
            indexedDB.deleteDatabase(dbname);
        callback(existed);
    }
    req.onupgradeneeded = function () {
        existed = false;
    }
}

要使用此功能,请执行:

databaseExists(dbName, function (yesno) {
    alert (dbName + " exists? " + yesno);
});

答案 3 :(得分:1)

我花了一个多小时玩它,基本上唯一确定性和可靠的方法是使用webkit的webkitGetDatabaseNames

确实有10种方法可以测试DB是否存在使用onupgradeneeded,但这在生产中不起作用。它被阻止了几秒钟,有时完全删除了数据库。中止交易的提示是无稽之谈,因为 window.indexeddb.open("db")请求不包含事务对象... req.transaction == null

我无法相信这是真的...

答案 4 :(得分:1)

function databaseExists(name){
    return new Promise(function(resolve, reject){
        var db = indexedDB,
            req;

        try{
            // See if it exist
            req = db.webkitGetDatabaseNames();
            req.onsuccess = function(evt){
                ~([].slice.call(evt.target.result)).indexOf(name) ? 
                    resolve(true): 
                    reject(false);
            }
        } catch (e){
            // Try if it exist
            req = db.open(name);
            req.onsuccess = function () {
                req.result.close();
                resolve(true);
            }
            req.onupgradeneeded = function (evt) {
                evt.target.transaction.abort();
                reject(false);
            }
        }

    })
}

用法:

databaseExists("foo").then(AlreadyTaken, createDatabase)

答案 5 :(得分:0)

嗨我知道这个问题已经得到回答和接受,但我认为这样做的好方法之一

var indexeddbReq = $window.indexedDB.webkitGetDatabaseNames();
                indexeddbReq.onsuccess = function(evt){
                    if(evt.target.result.contains(
                       // SUCCESS YOU FOUND THE DB
                    }
                    else{
                       // DB NOT FOUND
                    }
                }

答案 6 :(得分:0)

如果您使用的是alasql,则可以使用以下内容:

$allgroupResult= array();

$rowCount = 2; //since I have a sticky header in the excel file I start the count at 2
$boldRows = array();

foreach($prices->groups as $group){ 
    $groupItem = array(); 
    $groupItem["category_code"] = $group->category_code;
    $groupItem["category_name"] = $group->category_name; 
    $groupItem["category_description"] = $group->category_description;

    array_push($allgroupResult, $groupItem);    

    foreach($group->skus as $sku){
        $skuItem = array(); 
        $skuItem["identifier"] = $sku->info->identifier;

        array_push($allgroupResult, $skuItem);    
    }
}

这将创建数据库(如果该数据库不存在),但这是到目前为止我发现的最佳解决方案。如果数据库也存在类似的查询,也可以删除它:$boldRows

答案 7 :(得分:0)

另一种方法(在Chrome而非Firefox上)是使用异步功能,如下所示:

/**
 * Checks the IndexedDB "web-server" to see if an specific database exists.
 * Must be called with await, for example, var dbFound = await doesDbExist('mySuperDB');
 * @param {string} dbName The database name to look for.
 * @returns {boolean} Whether a database name was found.
 */
async function doesDbExist(dbName) {
    var result = await indexedDB.databases();
    var dbFound = false;
    for (var i = 0; i < result.length && !dbFound; i++) {
        dbFound = result[i].name === dbName;
    }
    return dbFound;
}

然后只需按如下所示调用函数:

var dbFound = await doesDbExist('mySuperDB');

答案 8 :(得分:0)

使用ES6,您可以使用以下代码按名称查找IndexedDB数据库:

const dbName = 'TestDatabase';
const isExiting = (await window.indexedDB.databases()).map(db => db.name).includes(dbName);