diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-08 04:53:49 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-08 04:53:49 +0000 |
commit | 1bc85b268333b7c8eec62d4d5324067978fafc98 (patch) | |
tree | eb2570af406ee60881d313f47d77360c32702faf /sql | |
parent | 1ff43c9d6c69b0b5a3acbbbb95b836be369096be (diff) | |
download | chromium_src-1bc85b268333b7c8eec62d4d5324067978fafc98.zip chromium_src-1bc85b268333b7c8eec62d4d5324067978fafc98.tar.gz chromium_src-1bc85b268333b7c8eec62d4d5324067978fafc98.tar.bz2 |
Create meta table atomically.
http://crbug.com/111376 happened because a crash between creation and
population of the meta table could leave a meta table returning 0 for
the version numbers, even though no client ever stored 0 for the
versions. This makes creation and population atomic.
Additionally, version numbers are restricted to positive values, to
prevent this case from being masked in the future.
BUG=116306
TEST=none
Review URL: http://codereview.chromium.org/9592026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125557 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sql')
-rw-r--r-- | sql/meta_table.cc | 16 | ||||
-rw-r--r-- | sql/meta_table.h | 3 |
2 files changed, 17 insertions, 2 deletions
diff --git a/sql/meta_table.cc b/sql/meta_table.cc index cbda772..45f4ee0 100644 --- a/sql/meta_table.cc +++ b/sql/meta_table.cc @@ -8,6 +8,7 @@ #include "base/string_util.h" #include "sql/connection.h" #include "sql/statement.h" +#include "sql/transaction.h" namespace sql { @@ -30,6 +31,17 @@ bool MetaTable::DoesTableExist(sql::Connection* db) { bool MetaTable::Init(Connection* db, int version, int compatible_version) { DCHECK(!db_ && db); db_ = db; + + // If values stored are null or missing entirely, 0 will be reported. + // Require new clients to start with a greater initial version. + DCHECK_GT(version, 0); + DCHECK_GT(compatible_version, 0); + + // Make sure the table is created an populated atomically. + sql::Transaction transaction(db_); + if (!transaction.Begin()) + return false; + if (!DoesTableExist(db)) { if (!db_->Execute("CREATE TABLE meta" "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR)")) @@ -41,7 +53,7 @@ bool MetaTable::Init(Connection* db, int version, int compatible_version) { SetVersionNumber(version); SetCompatibleVersionNumber(compatible_version); } - return true; + return transaction.Commit(); } void MetaTable::Reset() { @@ -49,6 +61,7 @@ void MetaTable::Reset() { } void MetaTable::SetVersionNumber(int version) { + DCHECK_GT(version, 0); SetValue(kVersionKey, version); } @@ -58,6 +71,7 @@ int MetaTable::GetVersionNumber() { } void MetaTable::SetCompatibleVersionNumber(int version) { + DCHECK_GT(version, 0); SetValue(kCompatibleVersionKey, version); } diff --git a/sql/meta_table.h b/sql/meta_table.h index 497d918..03ec705 100644 --- a/sql/meta_table.h +++ b/sql/meta_table.h @@ -26,7 +26,8 @@ class SQL_EXPORT MetaTable { // Initializes the MetaTableHelper, creating the meta table if necessary. For // new tables, it will initialize the version number to |version| and the - // compatible version number to |compatible_version|. + // compatible version number to |compatible_version|. Versions must be + // greater than 0 to distinguish missing versions (see GetVersionNumber()). bool Init(Connection* db, int version, int compatible_version); // Resets this MetaTable object, making another call to Init() possible. |