2013-07-04 84 views
13

IndexedDBデータベースが既に存在するかどうかを確認する方法はありますか?プログラムが存在しないデータベースを開こうとすると、データベースが作成されます。私は考えることができる 唯一の方法は、ObjectStoreのが既に存在する場合、私がテストし、以下のようなもの、である、それは、データベースが削除されていない場合:onupgradeneededコールバックでIndexedDBデータベースが存在するかどうか確認してください

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

答えて

13

をあなたは確認することができますバージョン。 (e.target.result.oldversion)。 が0の場合、dbは存在しませんでした。

編集: 調査の後に。新しいデータベースが作成された場合、100%確実にすることはできません。私が確信していることは、バージョン1以上のバージョンであればindexeddbのみで作業できるということです。私は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; 
} 

しかし、記載されている。この場合、データベースは存在し続ける可能性がありますが、常に実行されるのは

+0

それは良いアイデアです。しかし、データベースが存在するかどうかだけを確認したい場合は、後でデータベースを削除する必要があります。データベースが存在するかどうかをテストする方法があるはずです。 –

+0

トランザクションのabortメソッドを呼び出します。 E.target.result.abort() –

+0

(e.target.result.db.version)を使用してもよろしいですか?後で(e.target.result.version)または(db.version)、(db = e.target.result;)の後にするべきではありませんか?そして、私はデータベースが作成された後、バージョンが0ではなく1であると考えます。 –

1

データベースが存在するかどうかをチェックします。 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

次のコードは動作します。 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); 
}); 
+0

Wtf?なぜデータベースが存在していればそれを削除していますか?もし存在すればテストしていますが、もしあれば削除したくありません。 if(!existed)indexedDB.deleteDatabase(dbname); '??? – lisak

+0

ありがとう!おっとっと。サンプルが更新されました。 –

+0

よくテストされ、正確です: - P – lisak

0

私はそれで遊んで時間以上を費やしており、基本的にそれを行うための唯一の決定論的で信頼性の高い方法は、WebKitのwebkitGetDatabaseNamesを使用しています。

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

私はこれが本当であると信じてすることはできません...

0

こんにちは、私はこの質問にはすでに答えて受け入れられているけど、私は良い方法の一つが、この

var indexeddbReq = $window.indexedDB.webkitGetDatabaseNames(); 
       indexeddbReq.onsuccess = function(evt){ 
        if(evt.target.result.contains(
         // SUCCESS YOU FOUND THE DB 
        } 
        else{ 
         // DB NOT FOUND 
        } 
       } 
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) 
+0

[webkitGetDatabaseNames](chrome 60でhttps://developers.google.com/web/updates/2017/06/chrome-60-deprecations#remove_indexeddbwebkitgetdatabasenames)が廃止されました –

関連する問題