--- 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; } -
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 @@
This section is non-normative.
...
All diagrams, examples, and notes in this specification are + -->
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); + }); + }); +}
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]The IDL blocks in this specification use the semantics of the - WebIDL specification. [WebIDL]
+ WebIDL specification. [WEBIDL]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]
Each origin has an associated set of databases. Each + widely known. [ECMA262]
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 - theWindow
andWorkerUtils
interfaces must - return a newly constructedDatabase
object that - represents the database requested.The
openDatabaseSync()
- method on theWorkerUtils
interfaces must return a - newly constructedDatabaseSync
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 theWindow
object must use and create databases from - the origin of the active document of the - browsing context of theWindow
object on - which the method was invoked.The
openDatabase()
and -openDatabaseSync()
- methods on theWorkerUtils
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
andWorkerUtils
interfaces and + theopenDatabaseSync()
+ method on theWorkerUtils
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 callchangeVersion()
; 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:
- + +
+ +The user agent may raise a
+ +SECURITY_ERR
exception + instead of returning aDatabase
object if the request + violates a policy decision (e.g. if the user agent is configured + to not allow the page to open databases).- + +
+ +For the method on the
+ +Window
object: let origin be the origin of the + active document of the browsing context + of theWindow
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.- + +
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.- + +
+ +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.
+ +- + +
+ +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.- + +
+ +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.- + +
+ +Return result.
+ +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
orDatabaseSync
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 aDatabase
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:
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.
-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.
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.
...and the mode being read/write.
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.
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]@@ -638,11 +734,11 @@ interface SQLResultSet object that represents the result of the statement. - If the statement failed, jump to the "in case of error" steps below.
+ 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 + newSQLResultSet
object as its second argument, and + wait for that task to be run.@@ -654,11 +750,11 @@ interface - If the callback was invoked and raised an exception, jump to the last step in the overall steps.
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, +
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 + constructedSQLError
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.- +
If the error callback returns false, then move on to the @@ -671,44 +767,77 @@ interface changeVersion() - method.)
- -
- +
Commit the transaction.
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.
-- +
If an error occurred in the committing of the transaction, - jump to the last step.
- + callback, if it is not null.
Queue a task to invoke the success - callback.
End these steps. The next step is only used when something goes wrong.
- - -
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.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. + +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 aSQLTransactionSync
- object for a read/write transaction, and return that - object.The
readTransaction()
- method must create aSQLTransactionSync
- object for a read/only transaction, and return that - object.On getting, the
version
+ andreadTransaction()
+ methods must run the following steps:
- + +
If the method was the
transaction()
method, + create aSQLTransactionSync
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.- + +
If the first argument is null, rollback the transaction, + throw a
SQLException
exception, and abort these + steps. (Error code + 0.)- + +
Invoke the callback given by the first argument, passing it + the transaction object as its only + argument.
Mark the
+ +SQLTransactionSync
object as stale.- + +
If the callback was terminated by an exception, then + rollback the transaction, rethrow that exception, and abort these + steps.
- + +
Commit the transaction.
- + +
If an error occurred in the committing of the transaction, + rollback the transaction, throw a
SQLException
+ exception, and abort these steps.On getting, the
version
attribute must return the current version of the database (as opposed to the expected version of theDatabaseSync
object).The
changeVersion()
@@ -716,19 +845,31 @@ interface Create aSQLTransactionSync
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 aSQLTransactionSync
object and abort + not, then throw aSQLException
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'scommit()
method is - invoked, when the steps for that method invoke the postcommit - operation, the user agent must run the following steps:
- Change the database's actual version to the value of the second +
Mark the
+ +SQLTransactionSync
object as stale.- + +
If the callback was terminated by an exception, then + rollback the transaction, rethrow the exception, and abort these + steps.
- + +
Commit the transaction.
- + +
If an error occurred in the committing of the transaction, + rollback the transaction, throw a
SQLException
+ exception, and abort these steps.- Change the database's actual version to the value of the second argument to the
@@ -757,12 +898,11 @@ interface 4.4.1 Executing SQL statementschangeVersion()
method.The
transaction()
,readTransaction()
, andchangeVersion()
- methods returnSQLTransactionSync
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:
If the
SQLTransactionSync
object is stale, then throw anINVALID_STATE_ERR
@@ -783,7 +923,7 @@ interface SSQLException
exception.Execute the statement in the context of the transaction. - [SQL]
+ [SQL]@@ -794,28 +934,7 @@ interface S If the statement failed, throw a
SQLException
exception.- Return the newly created
SQLResultSet
object.When the
commit()
- method is invoked, the user agent must run the following - algorithm:
- - -
Commit the transaction.
Mark the
- -SQLTransactionSync
object as stale.If appropriate (i.e. if the
- -changeVersion()
- method created theSQLTransactionSync
object), invoke - the postcommit operation.- - -
If an error occurred in the committing of the transaction, - throw a
SQLException
exception.When the
rollback()
- method is invoked, the user agent must run the following - algorithm:
- - -
Rollback the transaction.
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 aSQLResultSet
object as an argument.interface SQLResultSet { readonly attribute long insertId; @@ -838,7 +957,7 @@ interface S (itslength
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 alength
@@ -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 asBEGIN
,COMMIT
, orROLLBACK
, 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
, orREPLACE
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
@@ -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.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]6.2 Cookie resurrection
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 theexecuteSql()
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 theexecuteSql()
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.
+ +