`

w3c-html-javascript: webdatabase

阅读更多
首先看一下例子源码:

function prepareDatabase(ready, error) {
  return openDatabase('documents', '1.0', 'Offline document storage', 5*1024*1024, function (db) {
    db.changeVersion('', '1.0', function (t) {
      t.executeSql('CREATE TABLE docids (id, name)');
    }, error);
  });
}

function showDocCount(db, span) {
  db.readTransaction(function (t) {
    t.executeSql('SELECT COUNT(*) AS c FROM docids', [], function (t, r) {
      span.textContent = r.rows[0].c;
    }, function (t, e) {
      // couldn't read database
      span.textContent = '(unknown: ' + e.message + ')';
    });
  });
}

prepareDatabase(function(db) {
  // got database
  var span = document.getElementById('doc-count');
  showDocCount(db, span);
}, function (e) {
  // error getting database
  alert(e.message);
});


阅读记录

1、 对于openDatabase的一切API 都是一部的,如果想用同步的API,可以考虑使用openDatabaseSync
2、 当我们调用openDatabase方法的时候,会发生了什么,
            [Supplemental, NoInterfaceObject]
interface WindowDatabase {
  Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);
};
Window implements WindowDatabase;

[Supplemental, NoInterfaceObject]
interface WorkerUtilsDatabase {
  Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);
  DatabaseSync openDatabaseSync(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);
};
WorkerUtils implements WorkerUtilsDatabase;

[Callback=FunctionOnly, NoInterfaceObject]
interface DatabaseCallback {
  void handleEvent(in Database database);
};

      参数解释: DOMString name数据库名称、DOMString version数据库版本 、DOMString displayName显示名称(这个参数的意思,举个例子,如果我通过浏览器参看webdatabase的状态,该参数将会提供更友好的文字描述),estimatedSize 容量大小(单位bytes)、creationCallback回调函数
      1)、如果浏览器禁用了webdatabase,此时会抛出异常
      2)、openDatabase属于window对象
      3)、如果提供了数据库版本,并且提供的数据库名称已经存在,但是数据库的版本与方法参数的版本信息不一致,则会抛出异常,此时会中断后续步骤的处理
      4)、如果提供的数据库名称没有被创建,怎么新创建一个数据库,成功之后会调用callback回调函数,此时我们可以设置数据的版本为空,否者次数的数据库版本号,与方法参数提供的一致,同理,如果数据库存在,则会创建失败
     5)、对于openDatabase()方法返回的数据库对象是最新构建的对象,并且数据库名称为参数名称。(openDatabaseSync同理)
     6)、如果openDatabse或openDatabseSync创建失败,即使提供了callback,那么callback 也是不会被执行的
            对于openDatabse方式,会将datbase结果传递个callback函数,并调用它
            对于openDatabseSync方式,如果callback方法抛出异常 则也会中断
      7)、返回database结果

  3、从opendatabase方法中可以看出,我们可以指定版本号,从而创建我们期望版本的数据库对象,如果版本号参数为空(即空字符串),则任意版本都可以
 
  4、有关sql方面
      1)、sql参数也支持?作为参数占位符
      2)、如果我们创建的database对象版本不存在,则所有的SQL操作都将是无效的,并且会抛出异常,举个例子,此版本号如果callback
      3)、sql语法不对、sql中存在不支持的特性函数、sql参数与?占位符不一致,则sql statement无效
      4)、如果sqltrasaction事务mode是read-only,如果执行修改操作,则sql statement无效


异步database API

interface Database {
  void transaction(in SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback);
  void readTransaction(in SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback);

  readonly attribute DOMString version;
  void changeVersion(in DOMString oldVersion, in DOMString newVersion, in optional SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback);
};

[Callback=FunctionOnly, NoInterfaceObject]
interface SQLVoidCallback {
  void handleEvent();
};

[Callback=FunctionOnly, NoInterfaceObject]
interface SQLTransactionCallback {
  void handleEvent(in SQLTransaction transaction);
};

[Callback=FunctionOnly, NoInterfaceObject]
interface SQLTransactionErrorCallback {
  void handleEvent(in SQLError error);
};


  1、从上面的方法可以看出transaction() and readTransaction()都有三个参数,这三个参数都是Funtion, 第一个参数Fun是处理业务的,如果该方法报错,会执行第二个errorCallback,如果成功怎么执行第三个successCallback。

  2、从名字中可以看出readTransaction是只读的, transaction可以是read or write

  3、如果你蛋疼的话,你可以切换当前的数据库版本为参数指定的版本,切换过程是原子性的,ok,之后的处理就可以transaction()或readTransaction()一致了(如果你指定的版本不存在,会切换失败的,估计还是会当前的版本去异步执行后续的处理)
           切换过程主要干了两件事情:
         1、Change the database's actual version to the value of the second argument to the changeVersion() method.
         2、Change the Database object's expected version to the value of the second argument to the changeVersion() method.

执行SQL语句
typedef sequence<any> ObjectArray;

interface SQLTransaction {
  void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);
};

[Callback=FunctionOnly, NoInterfaceObject]
interface SQLStatementCallback {
  void handleEvent(in SQLTransaction transaction, in SQLResultSet resultSet);
};

[Callback=FunctionOnly, NoInterfaceObject]
interface SQLStatementErrorCallback {
  boolean handleEvent(in SQLTransaction transaction, in SQLError error);
}
  


   对于executeSql方法的流程如下
   1)、打开一个新的sql transaction ,如果事务是read/write 则当前事务必须获取一个整个数据库的独占写锁,如果是只读的,则获取一个整个数据库范围的共享读锁,所以每一个请求都必须等待一个适当的锁,直至可用
   2)、如果在开始事务过程当中,发生错误,则会执行errorCallback,并且rollback事务,销毁事务对象
   3)、对于通过changeVersion()方式,如果切换目标版本发生错误时,则结局和(2)
   4)、如果callback发生异常,同(2)
   5)、每一个sql语句排入事务当中,都会发生以下事情,首先是检测sql语句是否正确(有可能失败),如果正确则会在事务的上下文中执行该语句(有可能失败),如果执行成功则会创建一个SqlResultSet对象去包装sql的返回结果,接下来会执行callback回调函数(有可能失败),并且将SqlResultSet对象传递给callback函数,接下来将重新执行下一条Sql语句,如果以上步骤发生错误的话((有可能失败)标记) 则会发生以下情况,执行errorCallback,如果errorCallback return false, 则会继续正常执行下一条sql语句,否则会终止所有业务执行

interface SQLResultSet {
  readonly attribute long insertId;
  readonly attribute long rowsAffected;
  readonly attribute SQLResultSetRowList rows;
};


interface SQLResultSetRowList {
  readonly attribute unsigned long length;
  getter any item(in unsigned long index);
};


记录:
   1、insertId 当执行sql 插入时insertId记录的是当前插入记录的ID, 如果插入多条的话,则是最后一条的ID
   2、rowsAffected, 对于更新操作是,此属性记录受影响的行数
   3、rows 对于select操作时,该记录是保存响应结果
   4、length代表记录的个数
   5、 item代表响应数据

   W3c中描述
   Note:  For the asynchronous API, implementors are encouraged to prefetch all the data for SQLResultSetRowList objects when the object is constructed (before the result set callback is invoked), rather than on-demand, for better responsiveness. For the synchronous API, an on-demand lazy evaluation implementation strategy is encouraged instead, for better performance.Fetching the length might be expensive, and authors are thus encouraged to avoid using it (or enumerating over the object, which implicitly uses it) where possible

 
  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics