web-dev-qa-db-ja.com

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;
    }
}
17
Pedro Almeida

Onupgradeneededコールバックで、バージョンを確認できます。 (e.target.result.oldversion)。 0の場合、データベースは存在しませんでした。

編集:いくつかの調査の後。新しいデータベースが作成されたかどうかを100%確信することはできません。私が確信していることの1つは、indexeddbがバージョン1以降である場合にのみ作業できるという事実です。 dbが存在し、バージョン0を持つことができると思います(唯一の事実は、dbを操作できず、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は常に呼び出されます。

16
Kristof Degrave

次のコードは機能します。 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);
});
6
David Fahlander

私はそれで1時間以上遊んでいましたが、基本的にそれを行うための唯一の決定論的で信頼できる方法は、webkitのwebkitGetDatabaseNamesを使用することです。

Onupgradeneededを使用してDBが存在するかどうかをテストする方法は文字通り10通りありますが、それは本番環境では機能しません。データベースを削除すると、数秒間ブロックされることもありました。 window.indexeddb.open("db")リクエストにはトランザクションオブジェクトが含まれていないため、トランザクションを中止するためのヒントは意味がありません... req.transaction == null

これが本物だなんて信じられない...

5
lisak

この関数は、データベースが存在するかどうかをチェックします。 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
maparrar
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)
1
Endless

ES6では、次のコードを使用して、名前でIndexedDBデータベースを見つけることができます。

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

1

これを行う別の方法(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');

alasql を使用している場合は、次のようなものを使用できます。

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

これにより、データベースが存在しない場合でもデータベースが作成されますが、これまでに見つけた最善のソリューションでした。同様のクエリでデータベースが存在する場合は、データベースを削除できます。drop indexeddb database if exists ${myDatabase};

0
GarouDan

こんにちは私はこの質問がすでに答えられて受け入れられていることを知っています、しかし私はこのようにそれをする良い方法の1つだと思います

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