Проверьте, существует ли база данных 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;
    }
}

Ответы

Ответ 1

В обратном вызове onupgradeded вы можете проверить версию. (E.target.result.oldversion). Если  это 0, db не существует.

Изменить: После некоторого расследования. Вы не можете быть на 100% уверены, что новый db будет создан. 1 вещь, я уверен, в том, что вы можете работать только с indexeddb, если у него есть версия 1 или выше. Я считаю, что db может существовать и иметь версию 0 (единственный факт заключается в том, что вы не можете работать с ним, и будет вызвано событие onupgradededed).

У меня есть собственный indexeddbviewer. В этом я открываю indexeddb без версии и, если я вхожу в событие onupgradedededed, это означает, что db не существует. В этом случае я вызываю прерывание, поэтому он не обновляется до версии 1. Так я его проверяю.

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

но, как уже упоминалось. Возможно, что db будет продолжать существовать в этом случае, но onupgradededed всегда будет называться

Ответ 2

Эта функция проверяет, существует ли база данных. Используйте событие onupgradedededed, если версия равна 1 и событие инициировано, это означает, что база данных не существует, но создается с помощью функции window.indexedDB.open(name), что означает, что вы должны ее удалить.

Когда событие onsuccess запускается, но не событие onupgradededed (Variable 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");
    }
});

[извините за мой английский]

Ответ 3

Работает следующий код. Я тестировал его с помощью Chrome, IE и Opera. Протестировано как локально открытыми базами данных, так и закрытыми и с базами данных разных версий, поэтому оно должно быть точным. Требуется создание/удаление базы данных. Тем не менее, это будет атомная операция без риска для условий гонки, потому что спецификация promises не запускается для открытия запросов в параллельном режиме, если открытый запрос приводит к созданию базы данных.

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);
});

Ответ 4

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

Я провел больше часа, играя с ним, и в основном единственный детерминированный и надежный способ сделать это с помощью webkit webkitGetDatabaseNames.

Существует буквально 10 способов проверить, существует ли СУБ с использованием onupgradededed, но это просто не работает в производстве. Он был заблокирован на несколько секунд, иногда полностью удалив базу данных. Эти советы по прекращению транзакции нонсенс, потому что window.indexeddb.open("db") запрос не содержит объекта транзакции... req.transaction == null

Я не могу поверить, что это реально...

Ответ 6

Привет, я знаю, что этот вопрос уже ответил и принят, но я думаю, что один из хороших способов сделать это, как это

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

Ответ 7

Если вы используете alasql, вы можете использовать что-то вроде:

async existsDatabase(myDatabase) {
    return !(await alasql.promise('
        create indexeddb database if not exists ${myDatabase};
    '));
}

Это создаст базу данных, если она не существует, но это было лучшее решение, которое я нашел до сих пор. Вы можете удалить базу данных, если она существует с аналогичным запросом: drop indexeddb database if exists ${myDatabase};