3

当我尝试使用比浏览器当前具有的更高版本升级我的 indexedDB 数据库时出现异常,但有趣的部分中止是,它被升级了。这是设计使然还是我做错了什么。

我从 dart 示例 Todo 中得到了很大的启发,所以我的代码最终看起来像这样。

void open_db(String DB_name, int Version, String Store_Name){
  var request = window.indexedDB.open(DB_name, Version);
  request.on.success.add((e) => _onDbOpened(request.result));
  request.on.error.add((e) => print("Error opening db"));
  request.on.upgradeNeeded.add((e) => _onUpgradeNeeded(request.transaction, Store_Name));
}

void _onDbOpened(IDBDatabase db){
  _db = db;
  print("DB opened");
}

void _onUpgradeNeeded(IDBTransaction changeVersionTransaction, String Store_Name){
  changeVersionTransaction.on.error.add((e) => print("Error upgrading db"));
  changeVersionTransaction.on.complete.add((e) => print("Success upgrading db"));
  changeVersionTransaction.db.createObjectStore(Store_Name);
}

当我使用 version=4 运行它并且浏览器只有 version=3 时,它会按预期跳转到 _onUpgradeNeeded,但我收到 IDBDatabaseException 消息:“ConstraintError: DOM IDBDatabase Exception 4”。

那么我哪里错了?

4

1 回答 1

0

谢谢你的提问!

您可能需要先检查商店是否存在。

  if (db.objectStoreNames.indexOf(storeName) == -1) {  
    db.createObjectStore(storeName);
  } 

这是一些使用 Dart 更新 IndexedDB 数据库的代码。请注意,这补偿了两种升级方式(Chrome 使用的旧方式,以及 Firefox 和较新版本 Chrome 使用的新方式)

_openDb(afterOpen()) {
    var request = window.indexedDB.open(DB_NAME, VERSION);
    if (request is IDBOpenDBRequest) {
      // New upgrade protocol. FireFox 15, Chrome 24, hopefully IE10.
      request.on.success.add(expectAsync1((e) {
            db = e.target.result;
            afterOpen();
          }));
      request.on.upgradeNeeded.add((e) {
          guardAsync(() {
              _createObjectStore(e.target.result);
            });
        });
      request.on.error.add(fail('open'));
    } else {
      // Legacy setVersion upgrade protocol. Chrome < 23.
      request.on.success.add(expectAsync1((e) {
            db = e.target.result;
            if (db.version != '$VERSION') {
              var setRequest = db.setVersion('$VERSION');
              setRequest.on.success.add(
                  expectAsync1((e) {
                      _createObjectStore(db);
                      var transaction = e.target.result;
                      transaction.on.complete.add(
                          expectAsync1((e) => afterOpen()));
                      transaction.on.error.add(fail('Upgrade'));
                    }));
              setRequest.on.error.add(fail('setVersion error'));
            } else {
              afterOpen();
            }
          }));
      request.on.error.add(fail('open'));
    }
  }

_createObjectStore(db) {
    try {
      // Nuke object store if it already exists.
      db.deleteObjectStore(STORE_NAME);
    }
    on IDBDatabaseException catch(e) { }  // Chrome
    on DOMException catch(e) { }          // Firefox
    db.createObjectStore(STORE_NAME);
  }

请注意,此代码来自此测试:http ://code.google.com/p/dart/source/browse/trunk/dart/tests/html/indexeddb_3_test.dart

于 2012-11-29T21:48:43.657 回答