1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "sql/meta_table.h" 6 7 #include "base/logging.h" 8 #include "base/strings/string_util.h" 9 #include "sql/connection.h" 10 #include "sql/statement.h" 11 #include "sql/transaction.h" 12 13 namespace sql { 14 15 // Key used in our meta table for version numbers. 16 static const char kVersionKey[] = "version"; 17 static const char kCompatibleVersionKey[] = "last_compatible_version"; 18 19 MetaTable::MetaTable() : db_(NULL) { 20 } 21 22 MetaTable::~MetaTable() { 23 } 24 25 // static 26 bool MetaTable::DoesTableExist(sql::Connection* db) { 27 DCHECK(db); 28 return db->DoesTableExist("meta"); 29 } 30 31 bool MetaTable::Init(Connection* db, int version, int compatible_version) { 32 DCHECK(!db_ && db); 33 db_ = db; 34 35 // If values stored are null or missing entirely, 0 will be reported. 36 // Require new clients to start with a greater initial version. 37 DCHECK_GT(version, 0); 38 DCHECK_GT(compatible_version, 0); 39 40 // Make sure the table is created an populated atomically. 41 sql::Transaction transaction(db_); 42 if (!transaction.Begin()) 43 return false; 44 45 if (!DoesTableExist(db)) { 46 if (!db_->Execute("CREATE TABLE meta" 47 "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR)")) 48 return false; 49 50 // Note: there is no index over the meta table. We currently only have a 51 // couple of keys, so it doesn't matter. If we start storing more stuff in 52 // there, we should create an index. 53 SetVersionNumber(version); 54 SetCompatibleVersionNumber(compatible_version); 55 } else { 56 db_->AddTaggedHistogram("Sqlite.Version", GetVersionNumber()); 57 } 58 return transaction.Commit(); 59 } 60 61 void MetaTable::Reset() { 62 db_ = NULL; 63 } 64 65 void MetaTable::SetVersionNumber(int version) { 66 DCHECK_GT(version, 0); 67 SetValue(kVersionKey, version); 68 } 69 70 int MetaTable::GetVersionNumber() { 71 int version = 0; 72 return GetValue(kVersionKey, &version) ? version : 0; 73 } 74 75 void MetaTable::SetCompatibleVersionNumber(int version) { 76 DCHECK_GT(version, 0); 77 SetValue(kCompatibleVersionKey, version); 78 } 79 80 int MetaTable::GetCompatibleVersionNumber() { 81 int version = 0; 82 return GetValue(kCompatibleVersionKey, &version) ? version : 0; 83 } 84 85 bool MetaTable::SetValue(const char* key, const std::string& value) { 86 Statement s; 87 PrepareSetStatement(&s, key); 88 s.BindString(1, value); 89 return s.Run(); 90 } 91 92 bool MetaTable::SetValue(const char* key, int value) { 93 Statement s; 94 PrepareSetStatement(&s, key); 95 s.BindInt(1, value); 96 return s.Run(); 97 } 98 99 bool MetaTable::SetValue(const char* key, int64 value) { 100 Statement s; 101 PrepareSetStatement(&s, key); 102 s.BindInt64(1, value); 103 return s.Run(); 104 } 105 106 bool MetaTable::GetValue(const char* key, std::string* value) { 107 Statement s; 108 if (!PrepareGetStatement(&s, key)) 109 return false; 110 111 *value = s.ColumnString(0); 112 return true; 113 } 114 115 bool MetaTable::GetValue(const char* key, int* value) { 116 Statement s; 117 if (!PrepareGetStatement(&s, key)) 118 return false; 119 120 *value = s.ColumnInt(0); 121 return true; 122 } 123 124 bool MetaTable::GetValue(const char* key, int64* value) { 125 Statement s; 126 if (!PrepareGetStatement(&s, key)) 127 return false; 128 129 *value = s.ColumnInt64(0); 130 return true; 131 } 132 133 bool MetaTable::DeleteKey(const char* key) { 134 DCHECK(db_); 135 Statement s(db_->GetUniqueStatement("DELETE FROM meta WHERE key=?")); 136 s.BindCString(0, key); 137 return s.Run(); 138 } 139 140 void MetaTable::PrepareSetStatement(Statement* statement, const char* key) { 141 DCHECK(db_ && statement); 142 statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE, 143 "INSERT OR REPLACE INTO meta (key,value) VALUES (?,?)")); 144 statement->BindCString(0, key); 145 } 146 147 bool MetaTable::PrepareGetStatement(Statement* statement, const char* key) { 148 DCHECK(db_ && statement); 149 statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE, 150 "SELECT value FROM meta WHERE key=?")); 151 statement->BindCString(0, key); 152 return statement->Step(); 153 } 154 155 } // namespace sql 156