--- html5/webdatabase/Overview.html 2009/07/15 10:54:00 1.1 +++ html5/webdatabase/Overview.html 2009/10/04 10:14:19 1.36 @@ -35,10 +35,6 @@ .dice-example { border-collapse: collapse; border-style: hidden solid solid hidden; border-width: thin; margin-left: 3em; } .dice-example caption { width: 30em; font-size: smaller; font-style: italic; padding: 0.75em 0; text-align: left; } .dice-example td, .dice-example th { border: solid thin; width: 1.35em; height: 1.05em; text-align: center; padding: 0; } - .applies th > * { display: block; white-space: nowrap; } - .applies thead code { display: block; } - .applies td { text-align: center; } - .applies .yes { background: yellow; } .toc dfn, h1 dfn, h2 dfn, h3 dfn, h4 dfn, h5 dfn, h6 dfn { font: inherit; } img.extra { float: right; } @@ -96,6 +92,11 @@ .XXX { color: #E50000; background: white; border: solid red; padding: 0.5em; margin: 1em 0; } .XXX > :first-child { margin-top: 0; } p .XXX { line-height: 3em; } + .annotation { border: solid thin black; background: #0C479D; color: white; position: relative; margin: 8px 0 20px 0; } + .annotation:before { position: absolute; left: 0; top: 0; width: 100%; height: 100%; margin: 6px -6px -6px 6px; background: #333333; z-index: -1; content: ''; } + .annotation :link, .annotation :visited { color: inherit; } + .annotation :link:hover, .annotation :visited:hover { background: transparent; } + .annotation span { border: none ! important; } .note { color: green; background: transparent; font-family: sans-serif; } .warning { color: red; background: transparent; } .note, .warning { font-weight: bolder; font-style: italic; } @@ -136,14 +137,8 @@ border-width: 0.25em; } - .example { - display: block; - color: #222222; - background: #FCFCFC; - border-left: double; - margin-left: 2em; - padding-left: 1em; - } + .example { display: block; color: #222222; background: #FCFCFC; border-left: double; margin-left: 2em; padding-left: 1em; } + td > .example:only-child { margin: 0 0 0 0.1em; } .tall-and-narrow { font-size: 0.6em; @@ -169,19 +164,16 @@ ul.domTree .t7 code, .domTree .t8 code { color: green; } ul.domTree .t10 code { color: teal; } -
+

W3C

Web Database

- - -

Editor's Draft 15 July 2009

- -
+ +
This Version:
+
http://www.w3.org/TR/2009/WD-webdatabase-20090910/
Latest Published Version:
http://www.w3.org/TR/webdatabase/
- :ZZZ -->
Latest Editor's Draft:
+
Latest Editor's Draft:
http://dev.w3.org/html5/webdatabase/

The W3C Web Apps Working Group is the W3C working group responsible for this specification's progress along the W3C Recommendation track. - - - This specification is the 15 July 2009 Editor's Draft. - + This specification is the 10 September 2009 First Public Working Draft. +

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables @@ -271,40 +261,84 @@

  • 4.4.1 Executing SQL statements
  • 4.5 Database query results
  • 4.6 Errors and exceptions
  • -
  • 5 Disk space
  • -
  • 6 Privacy +
  • 5 Web SQL
  • +
  • 6 Disk space
  • +
  • 7 Privacy
      -
    1. 6.1 User tracking
    2. -
    3. 6.2 Cookie resurrection
  • -
  • 7 Security +
  • 7.1 User tracking
  • +
  • 7.2 Sensitivity of data
  • +
  • 8 Security
      -
    1. 7.1 DNS spoofing attacks
    2. -
    3. 7.2 Cross-directory attacks
    4. -
    5. 7.3 Implementation risks
    6. -
    7. 7.4 SQL and user agents
    8. -
    9. 7.5 SQL injection
  • +
  • 8.1 DNS spoofing attacks
  • +
  • 8.2 Cross-directory attacks
  • +
  • 8.3 Implementation risks
  • +
  • 8.4 SQL and user agents
  • +
  • 8.5 SQL injection
  • References

    1 Introduction

    This section is non-normative.

    ...

    2 Conformance requirements

    All diagrams, examples, and notes in this specification are + -->

    1 Introduction

    This section is non-normative.

    This specification introduces a set of APIs to manipulate + client-side databases using SQL.

    The API is asynchronous, so authors are likely to find anonymous + functions (lambdas) very useful in using this API.

    Here is an example of a script using this API. First, a function + prepareDatabase() is defined. This function + tries to create the database if necessary, giving it one table + called "docids" with two columns ("id" and "name"). If it is + successful, or if the table doesn't need creating, it calls a + section function, getDatabase(), which obtains + a handle to the database, and then calls the function to do the + actual work, in this case showDocCount().

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

    The executeSql() method has + an argument intended to allow variables to be substituted into + statements without risking SQL injection vulnerabilities:

    db.readTransaction(function (t) {
    +  t.executeSql('SELECT title, author FROM docs WHERE id=?', [id], function (t, data) {
    +    report(data.rows[0].title, data.rows[0].author);
    +  });
    +});

    Sometimes, there might be an arbitrary number of variables to + substitute in. Even in these case, the right solution is to + construct the query using only "?" characters, and then to pass the + variables in as the second argument:

    function findDocs(db, resultCallback) {
    +  var q = "";
    +  for each (var i in labels)
    +    q += (q == "" ? "" : ", ") + "?";
    +  db.readTransaction(function (t) {
    +    t.executeSql('SELECT id FROM docs WHERE label IN (' + q + ')', labels, function (t, data) {
    +      resultCallback(data);
    +    });
    +  });
    +}

    2 Conformance requirements

    All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

    The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do - not appear in all uppercase letters in this specification. [RFC2119]

    Requirements phrased in the imperative as part of algorithms + not appear in all uppercase letters in this specification. [RFC2119]

    Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the @@ -324,7 +358,7 @@ have a variable and unknowable number of

    Many fundamental concepts from HTML5 are used by this - specification. [HTML5]

    + specification. [HTML5]

    @@ -333,7 +367,7 @@ have a variable and unknowable number of

    The IDL blocks in this specification use the semantics of the - WebIDL specification. [WebIDL]

    + WebIDL specification. [WEBIDL]

    @@ -344,11 +378,11 @@ have a variable and unknowable number of scripts in Web applications, and does not necessarily imply the existence of an actual Document object or of any other Node objects as defined in the DOM Core - specifications. [DOM3CORE]

    A DOM attribute is said to be getting when its value is + specifications. [DOMCORE]

    An IDL attribute is said to be getting when its value is being retrieved (e.g. by author script), and is said to be setting when a new value is assigned to it.

    The term "JavaScript" is used to refer to ECMA262, rather than the official term ECMAScript, since the term JavaScript is more - widely known. [ECMA262]

    4 The API

    4.1 Databases

    Each origin has an associated set of databases. Each + widely known. [ECMA262]

    4 The API

    4.1 Databases

    Each origin has an associated set of databases. Each database has a name and a current version. There is no way to enumerate or delete the databases available for an origin from this API.

    Each database has one version at a time; a database @@ -356,50 +390,122 @@ have a variable and unknowable number of allow authors to manage schema changes incrementally and non-destructively, and without running the risk of old code (e.g. in another browser window) trying to write to a database with incorrect - assumptions.

    [Supplemental] interface Window {
    -  Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
    +  assumptions.
    [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;
     
    -[Supplemental] interface WorkerUtils {
    -  Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
    -  DatabaseSync openDatabaseSync(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
    +[Callback=FunctionOnly, NoInterfaceObject]
    +interface DatabaseCallback {
    +  void handleEvent(in Database database);
     };

    The openDatabase() method on - the Window and WorkerUtils interfaces must - return a newly constructed Database object that - represents the database requested.

    The openDatabaseSync() - method on the WorkerUtils interfaces must return a - newly constructed DatabaseSync object that represents - the database requested.

    These methods take four arguments: a database name, a database - version, a display name, and an estimated size, in bytes, of the - data that will be stored in the database.

    The database requested is the one with the given database - name from the appropriate origin.

    The openDatabase() method - on the Window object must use and create databases from - the origin of the active document of the - browsing context of the Window object on - which the method was invoked.

    The openDatabase() and - openDatabaseSync() - methods on the WorkerUtils object must use and create - databases from the origin of the scripts in the - worker.

    All strings including the empty string are valid database + the Window and WorkerUtils interfaces and + the openDatabaseSync() + method on the WorkerUtils interface take the following + arguments: a database name, a database version, a display name, an + estimated size — in bytes — of the data that will be + stored in the database, and optionally a callback to be invoked if + the database has not yet been created. The callback, if provided, is + intended to be used to call changeVersion(); the + callback is invoked with the database having the empty string as its + version regardless of the given database version. If the callback is + not provided, the database is created with the given database + version as its version.

    When invoked, these methods must run the following steps, with all + but the last two steps being run atomically:

    1. + +

      The user agent may raise a SECURITY_ERR exception + instead of returning a Database object if the request + violates a policy decision (e.g. if the user agent is configured + to not allow the page to open databases).

      + +
    2. + +
    3. + +

      For the method on the Window object: let origin be the origin of the + active document of the browsing context + of the Window object on which the method was + invoked.

      + +

      For the methods on the WorkerUtils object: let + origin be the origin of the + scripts in the worker.

      + +
    4. + +
    5. If the database version provided is not the empty string, + and there is already a database with the given name from the origin + origin, but the database has a different + version than the version provided, then throw an + INVALID_STATE_ERR exception and abort these + steps.

    6. + +
    7. + +

      If no database with the given name from the origin origin exists, then create the database and let + created be true. If a callback was passed to + the method, then set the new database's version to the empty + string. Otherwise, set the new database's version to the given + database version.

      + +

      Otherwise, if a database with the given name already exists, + let created be false.

      + +
    8. + +
    9. + +

      For the openDatabase() + methods: let result be a newly constructed + Database object representing the database with the + given database name from the origin origin.

      + +

      For the openDatabaseSync() method: + let result be a newly constructed + DatabaseSync object representing the database with + the given database name from the origin origin.

      + +
    10. + +
    11. + +

      If created is false or if no callback was + passed to the method, skip this step. Otherwise:

      + +

      For the openDatabase() + methods: queue a task to to invoke the callback with + result as its only argument.

      + +

      For the openDatabaseSync() method: + invoke the callback with result as its only + argument. If the callback throws an exception, rethrow that + exception and abort these steps.

      + +
    12. + +
    13. + +

      Return result.

      + +
    14. + +

    All strings including the empty string are valid database names. Database names must be compared in a case-sensitive manner.

    Implementations can support this even in environments that only support a subset of all strings as database names by mapping database names (e.g. using a hashing algorithm) to - the supported set of names.

    If the database version provided is not the empty string, and the - database already exists but has a different version, or no version, - then the method must raise an INVALID_STATE_ERR - exception.

    The version that the database was opened with is the expected version of + the supported set of names.

    The version that the database was opened with is the expected version of this Database or DatabaseSync object. It can be the empty string, in which case there is no expected version - — any version is fine.

    Otherwise, if the database version provided is the empty string, - or if the database doesn't yet exist, or if the database exists and - the version requested is the same as the current version associated - with the database, then the method must return an object - representing the database that has the name that was given. If no - such database exists, it must be created first.

    The user agent may raise a SECURITY_ERR exception - instead of returning a Database object if the request - violates a policy decision (e.g. if the user agent is configured to - not allow the page to open databases).

    User agents are expected to use the display name and the + — any version is fine.

    User agents are expected to use the display name and the estimated database size to optimize the user experience. For example, a user agent could use the estimated size to suggest an initial quota to the user. This allows a site that is aware that it @@ -408,7 +514,7 @@ have a variable and unknowable number of increase the quota every five megabytes.

    4.2 Parsing and processing SQL statements

    When the user agent is to preprocess a SQL statement sqlStatement with an array of arguments arguments, it must run the following steps:

    1. Parse sqlStatement as a SQL statement, with the exception that U+003F QUESTION MARK (?) characters can be - used in place of SQL literals in the statement. [SQL]

    2. + used in place of SQL literals in the statement. [SQL]
    3. @@ -426,12 +532,6 @@ have a variable and unknowable number of

      The result is the statement.

      -

      Implementation feedback is requested on what - to do with arguments that are of types that are not supported by - the underlying SQL backend. For example, SQLite doesn't support - booleans, so what should the UA do if passed a boolean? The Gears - team suggests failing, not silently converting types.

      -
    4. If the Database object that the @@ -484,11 +584,11 @@ have a variable and unknowable number of example, attempts to read from or write to the file system will fail.

      A future version of this specification will probably define the exact SQL subset required in more detail.

      4.3 Asynchronous database API

      interface Database {
      -  void transaction(in SQLTransactionCallback callback, [Optional] in SQLTransactionErrorCallback errorCallback, [Optional] in SQLVoidCallback successCallback);
      -  void readTransaction(in SQLTransactionCallback callback, [Optional] in SQLTransactionErrorCallback errorCallback, [Optional] in SQLVoidCallback successCallback);
      +  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 SQLTransactionCallback callback, in SQLTransactionErrorCallback errorCallback, in SQLVoidCallback successCallback);
      +  void changeVersion(in DOMString oldVersion, in DOMString newVersion, in optional SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback);
       };
       
       [Callback=FunctionOnly, NoInterfaceObject]
      @@ -537,14 +637,15 @@ interface changeVersion()
          method.
    5. -

    ...and the mode being read/write.

    4.3.1 Executing SQL statements

    The transaction(), +

    ...and the mode being read/write.

    If any of the optional arguments are omitted, then they must be + treated as if they were null.

    4.3.1 Executing SQL statements

    The transaction(), readTransaction(), and changeVersion() methods invoke callbacks with SQLTransaction objects.

    typedef sequence<any> ObjectArray;
     
     interface SQLTransaction {
    -  void executeSql(in DOMString sqlStatement, [Optional] in ObjectArray arguments, [Optional] in SQLStatementCallback callback, [Optional] in SQLStatementErrorCallback errorCallback);
    +  void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);
     };
     
     [Callback=FunctionOnly, NoInterfaceObject]
    @@ -607,19 +708,14 @@ interface changeVersion()
        method.)
  • -
  • Queue a task to invoke the transaction - callback with the aforementioned SQLTransaction - object as its only argument, and wait for that task to be - run.

  • +
  • If the transaction callback is not null, queue + a task to invoke the transaction callback with the + aforementioned SQLTransaction object as its only + argument, and wait for that task to be run.

  • -
  • If the callback couldn't be called (e.g. it was null), or if - the callback was invoked and raised an exception, jump to the last +

  • If the callback raised an exception, jump to the last step.

  • - +
  • While there are any statements queued up in the transaction, perform the following steps for each queued up statement in the transaction, oldest first. Each statement has a statement, @@ -630,7 +726,7 @@ interface

  • Execute the statement in the context of the transaction. - [SQL]

    + [SQL]

  • If the statement failed, jump to the "in case of error" steps below.

  • @@ -638,11 +734,11 @@ interface SQLResultSet object that represents the result of the statement. -
  • If the statement has a result set callback, queue a - task to invoke it with the SQLTransaction - object as its first argument and the new - SQLResultSet object as its second argument, and wait - for that task to be run.

  • +
  • If the statement has a result set callback that is not + null, queue a task to invoke it with the + SQLTransaction object as its first argument and the + new SQLResultSet object as its second argument, and + wait for that task to be run.

  • If the callback was invoked and raised an exception, jump to the last step in the overall steps.

  • @@ -654,11 +750,11 @@ interface -
    1. If the statement had an associated error callback, then - queue a task to invoke that error callback with the - SQLTransaction object and a newly constructed - SQLError object that represents the error that - caused these substeps to be run as the two arguments, +

      1. If the statement had an associated error callback that is + not null, then queue a task to invoke that error + callback with the SQLTransaction object and a newly + constructed SQLError object that represents the + error that caused these substeps to be run as the two arguments, respectively, and wait for the task to be run.

      2. If the error callback returns false, then move on to the @@ -671,44 +767,77 @@ interface changeVersion() - method.)

      3. +
      4. -
      5. Commit the transaction.

      6. +

        If a postflight operation was defined for this instance + of the transaction steps, then: as one atomic operation, commit + the transaction and run the postflight operation. If either + fails, then do neither, and instead jump to the last step. (This + is basically a hook for the changeVersion() + method.)

        + +

        Otherwise: commit the transaction and run the postflight + operation. If an error occurred in the committing of the + transaction, jump to the last step.

        -
      7. If an error occurred in the committing of the transaction, - jump to the last step.

      8. +
      9. Queue a task to invoke the success - callback.

      10. + callback, if it is not null.
      11. End these steps. The next step is only used when something goes wrong.

      12. Queue a task to invoke the error - callback with a newly constructed SQLError object - that represents the last error to have occurred in this - transaction. Rollback the transaction. Any still-pending statements - in the transaction are discarded.

      13. - -

      The task source for these tasks is the database - access task source.

      4.4 Synchronous database API

      interface DatabaseSync {
      -  SQLTransactionSync transaction();
      -  SQLTransactionSync readTransaction();
      +   callback, if it is not null, with a newly constructed
      +   SQLError object that represents the last error to have
      +   occurred in this transaction. Rollback the transaction. Any
      +   still-pending statements in the transaction are discarded.
    2. + +

    The task source for these tasks is the database access task + source.

    4.4 Synchronous database API

    interface DatabaseSync {
    +  void transaction(in SQLTransactionSyncCallback callback);
    +  void readTransaction(in SQLTransactionSyncCallback callback);
     
       readonly attribute DOMString version;
    -  SQLTransactionSync changeVersion(in DOMString oldVersion, in DOMString newVersion);
    +  void changeVersion(in DOMString oldVersion, in DOMString newVersion, in optional SQLTransactionSyncCallback callback);
    +};
    +
    +[Callback=FunctionOnly, NoInterfaceObject]
    +interface SQLTransactionSyncCallback {
    +  void handleEvent(in SQLTransactionSync transaction);
     };

    The transaction() - method must create a SQLTransactionSync - object for a read/write transaction, and return that - object.

    The readTransaction() - method must create a SQLTransactionSync - object for a read/only transaction, and return that - object.

    On getting, the version + and readTransaction() + methods must run the following steps:

    1. If the method was the transaction() method, + create a SQLTransactionSync object for a + read/write transaction. Otherwise, create a + SQLTransactionSync object for a read-only + transaction. In either case, if this throws an exception, then + rethrow it and abort these steps. Otherwise, let transaction be the newly created + SQLTransactionSync object.

    2. + +
    3. If the first argument is null, rollback the transaction, + throw a SQLException exception, and abort these + steps. (Error code + 0.)

    4. + +
    5. Invoke the callback given by the first argument, passing it + the transaction object as its only + argument.

    6. + +
    7. Mark the SQLTransactionSync object as stale.

      + +
    8. If the callback was terminated by an exception, then + rollback the transaction, rethrow that exception, and abort these + steps.

    9. + +
    10. Commit the transaction.

    11. + +
    12. If an error occurred in the committing of the transaction, + rollback the transaction, throw a SQLException + exception, and abort these steps.

    13. + +

    On getting, the version attribute must return the current version of the database (as opposed to the expected version of the DatabaseSync object).

    The changeVersion() @@ -716,19 +845,31 @@ interface Create a SQLTransactionSync object for a read/write transaction. If this throws an exception, then - rethrow it and abort these steps. + rethrow it and abort these steps. Otherwise, let transaction be the newly created + SQLTransactionSync object.

  • Check that the value of the first argument to the changeVersion() method exactly matches the database's actual version. If it does - not, then throw a SQLTransactionSync object and abort + not, then throw a SQLException exception and abort these steps. (Error code 2.)

  • -
  • Return the SQLTransactionSync object.

  • +
  • If the third argument is not null, invoke the callback given + by the third argument, passing it the transaction object as its only argument.

  • -

    When the SQLTransactionSync object's commit() method is - invoked, when the steps for that method invoke the postcommit - operation, the user agent must run the following steps:

    1. Change the database's actual version to the value of the second +
    2. Mark the SQLTransactionSync object as stale.

      + +
    3. If the callback was terminated by an exception, then + rollback the transaction, rethrow the exception, and abort these + steps.

    4. + +
    5. Commit the transaction.

    6. + +
    7. If an error occurred in the committing of the transaction, + rollback the transaction, throw a SQLException + exception, and abort these steps.

    8. + +
    9. Change the database's actual version to the value of the second argument to the changeVersion() method.
    10. @@ -757,12 +898,11 @@ interface 4.4.1 Executing SQL statements

      The transaction(), readTransaction(), and changeVersion() - methods return SQLTransactionSync objects.

      // typedef sequence<any> ObjectArray;
      +  methods invoke callbacks that are passed
      +  SQLTransactionSync objects.
      // typedef sequence<any> ObjectArray;
       
       interface SQLTransactionSync {
      -  SQLResultSet executeSql(in DOMString sqlStatement, [Optional] in ObjectArray arguments);
      -  void commit();
      -  void rollback();
      +  SQLResultSet executeSql(in DOMString sqlStatement, in optional ObjectArray arguments);
       };

      A SQLTransactionSync object is initially fresh, but it will be marked as stale once it has been committed or rolled back.

      When the executeSql(sqlStatement, arguments) method is invoked, the user agent must run the following algorithm:

      1. If the SQLTransactionSync object is stale, then throw an INVALID_STATE_ERR @@ -783,7 +923,7 @@ interface S SQLException exception.

      2. Execute the statement in the context of the transaction. - [SQL]

        + [SQL]

      3. If the statement failed, throw a SQLException exception.

      4. @@ -794,28 +934,7 @@ interface S
      5. Return the newly created SQLResultSet object.

      6. -

      When the commit() - method is invoked, the user agent must run the following - algorithm:

      1. Commit the transaction.

      2. - -
      3. Mark the SQLTransactionSync object as stale.

        - -
      4. If appropriate (i.e. if the changeVersion() - method created the SQLTransactionSync object), invoke - the postcommit operation.

        - -
      5. If an error occurred in the committing of the transaction, - throw a SQLException exception.

      6. - -

      When the rollback() - method is invoked, the user agent must run the following - algorithm:

      1. Rollback the transaction.

      2. - -
      3. Mark the SQLTransactionSync object as stale.

        - -

      If a SQLTransactionSync object is garbage collected - while still fresh, the user agent must rollback the - transaction.

      4.5 Database query results

      The executeSql() +

    4.5 Database query results

    The executeSql() method invokes its callback with a SQLResultSet object as an argument.

    interface SQLResultSet {
       readonly attribute long insertId;
    @@ -838,7 +957,7 @@ interface S
       (its length will
       be zero).
    interface SQLResultSetRowList {
       readonly attribute unsigned long length;
    -  [IndexGetter] any item(in unsigned long index);
    +  getter any item(in unsigned long index);
     };

    Implementors are encouraged to implement SQLResultSetRowList objects lazily, or at least asynchronously, for better performance.

    SQLResultSetRowList objects have a length @@ -861,33 +980,53 @@ interface S by the database.

    4.6 Errors and exceptions

    Errors in the asynchronous database API are reported using callbacks that have a SQLError object as one of their arguments.

    interface SQLError {
    -  readonly attribute unsigned long code;
    +  const unsigned short UNKNOWN_ERR = 0;
    +  const unsigned short DATABASE_ERR = 1;
    +  const unsigned short VERSION_ERR = 2;
    +  const unsigned short TOO_LARGE_ERR = 3;
    +  const unsigned short QUOTA_ERR = 4;
    +  const unsigned short SYNTAX_ERR = 5;
    +  const unsigned short CONSTRAINT_ERR = 6;
    +  const unsigned short TIMEOUT_ERR = 7;
    +  readonly attribute unsigned short code;
       readonly attribute DOMString message;
    -};

    The code DOM +};

    The code IDL attribute must return the most appropriate code from the table below.

    The message - DOM attribute must return an error message describing the error + IDL attribute must return an error message describing the error encountered. The message should be localized to the user's language.


    Errors in the synchronous database API are reported using SQLException exceptions:

    exception SQLException {
    -  unsigned long code;
    +  const unsigned short UNKNOWN_ERR = 0;
    +  const unsigned short DATABASE_ERR = 1;
    +  const unsigned short VERSION_ERR = 2;
    +  const unsigned short TOO_LARGE_ERR = 3;
    +  const unsigned short QUOTA_ERR = 4;
    +  const unsigned short SYNTAX_ERR = 5;
    +  const unsigned short CONSTRAINT_ERR = 6;
    +  const unsigned short TIMEOUT_ERR = 7;
    +  unsigned short code;
       DOMString message;
     };

    The code - DOM attribute must return the most appropriate code from the table - below.

    The message DOM + IDL attribute must return the most appropriate code from the table + below.

    The message IDL attribute must return an error message describing the error encountered. The message should be localized to the user's - language.


    The error codes are as follows:
    Code + language.

    The error codes are as follows:
    Constant + Code Situation -
    0 +
    UNKNOWN_ERR + 0 The transaction failed for reasons unrelated to the database itself and not covered by any other error code. -
    1 +
    DATABASE_ERR + 1 The statement failed for database reasons not covered by any other error code. -
    2 +
    VERSION_ERR + 2 The operation failed because the actual database version was not what it should be. For example, a statement found that the actual database version no longer matched the expected version @@ -897,34 +1036,39 @@ interface S methods were passed a version that doesn't match the actual database version. -
    3 +
    TOO_LARGE_ERR + 3 The statement failed because the data returned from the database was too large. The SQL "LIMIT" modifier might be useful to reduce the size of the result set. -
    4 +
    QUOTA_ERR + 4 The statement failed because there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database. -
    5 +
    SYNTAX_ERR + 5 The statement failed because of a syntax error, or the number of arguments did not match the number of ? placeholders in the statement, or the statement tried to use a statement that is not allowed, such as BEGIN, COMMIT, or ROLLBACK, or the statement tried to use a verb that could modify the database but the transaction was read-only. -
    6 +
    CONSTRAINT_ERR + 6 An INSERT, UPDATE, or REPLACE statement failed due to a constraint failure. For example, because a row was being inserted and the value given for the primary key column duplicated the value of an existing row. -
    7 +
    TIMEOUT_ERR + 7 A lock for the transaction could not be obtained in a reasonable time. -

    5 Disk space

    User agents should limit the total amount of space allowed for +

    5 Web SQL

    Need to define the SQL dialect.

    6 Disk space

    User agents should limit the total amount of space allowed for databases.

    User agents should guard against sites storing data under the @@ -937,7 +1081,7 @@ interface S is using.

    A mostly arbitrary limit of five megabytes per origin is recommended. Implementation feedback is welcome and will be used to update this suggestion in the - future.

    6 Privacy

    6.1 User tracking

    A third-party advertiser (or any entity capable of getting + future.

    7 Privacy

    7.1 User tracking

    A third-party advertiser (or any entity capable of getting content distributed to multiple sites) could use a unique identifier stored in its client-side database @@ -976,23 +1120,25 @@ interface S

    However, this also puts the user's data at risk.

    - +
    Treating persistent storage as cookies
    -

    User agents should present the - database feature +

    If users attempt to protect their privacy by clearing cookies + without also clearing data stored in the + + database - to the user in a way that does not distinguish them from HTTP - session cookies. [RFC2109] [RFC2965]

    -

    This might encourage users to view such storage with healthy - suspicion.

    + feature, sites can defeat those attempts by using the two features + as redundant backup for each other. User agents should present the + interfaces for clearing these in a way that helps users to + understand this possibility and enables them to delete data in all + persistent storage features simultaneously. [COOKIES]

    @@ -1049,19 +1195,18 @@ interface S retroactively). This information can then be shared with other sites, using using visitors' IP addresses and other user-specific data (e.g. user-agent headers and configuration settings) to combine - separate sessions into coherent user profiles.

    If the user interface for persistent storage presents data in the - persistent storage features described in this specification - separately from data in HTTP session cookies, then users are likely - to delete data in one and not the other. This would allow sites to - use the two features as redundant backup for each other, defeating a - user's attempts to protect his privacy.

    7 Security

    7.1 DNS spoofing attacks

    Because of the potential for DNS spoofing attacks, one cannot + separate sessions into coherent user profiles.

    7.2 Sensitivity of data

    User agents should treat persistently stored data as potentially + sensitive; it's quite possible for e-mails, calendar appointments, + health records, or other confidential documents to be stored in this + mechanism.

    To this end, user agents should ensure that when deleting data, + it is promptly deleted from the underlying storage.

    8 Security

    8.1 DNS spoofing attacks

    Because of the potential for DNS spoofing attacks, one cannot guarantee that a host claiming to be in a certain domain really is from that domain. To mitigate this, pages can use SSL. Pages using SSL can be sure that only pages using SSL that have certificates identifying them as being from the same domain can access their databases. -

    7.2 Cross-directory attacks

    Different authors sharing one host name, for example users +

    8.2 Cross-directory attacks

    Different authors sharing one host name, for example users hosting content on geocities.com, all share one set of databases. @@ -1071,7 +1216,7 @@ interface S and overwrite it.

    Even if a path-restriction feature was made available, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any - path.

    7.3 Implementation risks

    The two primary risks when implementing these persistent storage + path.

    8.3 Implementation risks

    The two primary risks when implementing these persistent storage features are letting hostile sites read information from other domains, and letting hostile sites write information that is then read from other domains.

    Letting third-party sites read data that is not supposed to be @@ -1085,13 +1230,61 @@ interface S user's wishlist; or a hostile site could set a user's session identifier to a known ID that the hostile site can then use to track the user's actions on the victim site.

    Thus, strictly following the origin model described - in this specification is important for user security.

    7.4 SQL and user agents

    User agent implementors are strongly encouraged to audit all + in this specification is important for user security.

    8.4 SQL and user agents

    User agent implementors are strongly encouraged to audit all their supported SQL statements for security implications. For example, LOAD DATA INFILE is likely to pose security risks and there is little reason to support it.

    In general, it is recommended that user agents not support features that control how databases are stored on disk. For example, there is little reason to allow Web authors to control the character encoding used in the disk representation of the data, as all data in - JavaScript is implicitly UTF-16.

    7.5 SQL injection

    Authors are strongly recommended to make use of the ? placeholder feature of the executeSql() method, - and to never construct SQL statements on the fly.

    References

    This section will be written in a future - draft. + JavaScript is implicitly UTF-16.

    8.5 SQL injection

    Authors are strongly recommended to make use of the ? placeholder feature of the executeSql() method, + and to never construct SQL statements on the fly.

    References

    All references are normative unless marked "Non-normative".

    [COOKIES]
    + +
    HTTP State + Management Mechanism, A. Barth. IETF, August 2009.
    + +
    [DOMCORE]
    +
    Document + Object Model (DOM) Level 3 Core Specification, A. Le + Hors, P. Le Hegaret, L. Wood, G. Nicol, J. Robie, M. Champion, + S. Byrnes. W3C, April 2004.
    + + +
    [ECMA262]
    +
    ECMAScript + Language Specification. ECMA, December 1999.
    + +
    [HTML5]
    + +
    HTML5, + I. Hickson. WHATWG, August 2009.
    + +
    [RFC2119]
    +
    Key words for use in + RFCs to Indicate Requirement Levels, S. Bradner. IETF, March + 1997.
    + +
    [SQL]
    +
    The precise dialect has not yet been specified.
    + +
    [WEBIDL]
    + +
    Web + IDL, C. McCormack. W3C, July 2009.
    + +