summaryrefslogtreecommitdiffstats
path: root/sql
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-08 04:53:49 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-08 04:53:49 +0000
commit1bc85b268333b7c8eec62d4d5324067978fafc98 (patch)
treeeb2570af406ee60881d313f47d77360c32702faf /sql
parent1ff43c9d6c69b0b5a3acbbbb95b836be369096be (diff)
downloadchromium_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.cc16
-rw-r--r--sql/meta_table.h3
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.