检查IndexedDB数据库是否存在

问题描述 投票:0回答:11

有没有办法检查 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;
    }
}
javascript indexeddb
11个回答
25
投票

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

编辑: 经过一番调查。您无法 100% 确定是否创建了新数据库。我确信的一件事是,您只能使用具有

1
或更高版本的 indexeddb。我相信数据库可以存在并且有一个版本
0
(唯一的事实是你无法使用它并且将调用
onupgradeneeded
事件)。

我已经构建了自己的indexeddbviewer。因为我打开没有版本的indexeddb,如果我进入

onupgradeneeded
事件,则意味着该数据库不存在。在这种情况下,我调用中止,这样它就不会升级到版本
1
。我就是这样检查的。

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

但是正如前面提到的。在这种情况下,数据库可能会继续存在,但 onupgradeneeded 将始终被调用


21
投票

使用 ES6,您可以使用以下代码通过名称找到 IndexedDB 数据库:

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


8
投票

以下代码有效。我已经用 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);
});

5
投票

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

webkitGetDatabaseNames

实际上有 10 种方法可以使用 onupgradeneeded 来测试数据库是否存在,但这在生产中不起作用。它要么被阻止几秒钟,有时在删除数据库时完全被阻止。那些中止交易的提示是无稽之谈,因为

window.indexeddb.open("db")
请求不包含交易对象...
req.transaction == null

我不敢相信这是真的......


2
投票
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)

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
投票

这是一个异步 util 函数返回 true false 以检查是否存在具有给定名称和版本的数据库。

const indexedDBUtil = {
    dbExist: async(dbName: string, version = 1)=> {
        let newDb = false;
        await ((): Promise<void>=>{
            return new Promise((resolve, reject)=>{
                const req = indexedDB.open(dbName, version );
                req.onupgradeneeded = ()=>{
                    req.transaction.abort();
                    newDb = true;
                    resolve();
                }
                req.onsuccess = () => {
                    resolve();
                }
            });
        })();
        
        return newDb;
    }
}


1
投票

如果您使用alasql,您可以使用类似以下内容:

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

如果数据库不存在,这将创建数据库,但这是迄今为止我找到的最佳解决方案。您也可以使用类似的查询删除数据库(如果存在):

drop indexeddb database if exists ${myDatabase};


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

0
投票

对于那些在 >= 2024 年登陆这里的人。

浏览器现在很好地支持

event.oldVersion
event.newVersion

var dbexists=false;
var request = window.indexedDB.open("TestDatabase");
request.onupgradeneeded = function(e) {
    db = e.target.result;
    enter code here
    if (e.oldVersion == 0) {
       db.close();
       indexedDB.deleteDatabase("TestDatabase");
    } else {
       dbexists=true;
    }
}

-1
投票

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

var indexeddbReq = $window.indexedDB.webkitGetDatabaseNames();
                indexeddbReq.onsuccess = function(evt){
                    if(evt.target.result.contains(
                       // SUCCESS YOU FOUND THE DB
                    }
                    else{
                       // DB NOT FOUND
                    }
                }
© www.soinside.com 2019 - 2024. All rights reserved.