15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/meta_table.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/metrics/histogram.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/connection.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/transaction.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Key used in our meta table for version numbers. 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kVersionKey[] = "version"; 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kCompatibleVersionKey[] = "last_compatible_version"; 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Used to track success/failure of deprecation checks. 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)enum DeprecationEventType { 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Database has info, but no meta table. This is probably bad. 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_DATABASE_NOT_EMPTY = 0, 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // No meta, unable to query sqlite_master. This is probably bad. 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_DATABASE_UNKNOWN, 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Failure querying meta table, corruption or similar problem likely. 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_FAILED_VERSION, 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Version key not found in meta table. Some sort of update error likely. 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_NO_VERSION, 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Version was out-dated, database successfully razed. Should only 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // happen once per long-idle user, low volume expected. 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_RAZED, 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Version was out-dated, database raze failed. This user's 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // database will be stuck. 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_RAZE_FAILED, 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Always keep this at the end. 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DEPRECATION_EVENT_MAX, 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void RecordDeprecationEvent(DeprecationEventType deprecation_event) { 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sqlite.DeprecationVersionResult", 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) deprecation_event, DEPRECATION_EVENT_MAX); 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace sql { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MetaTable::MetaTable() : db_(NULL) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MetaTable::~MetaTable() { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::DoesTableExist(sql::Connection* db) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(db); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db->DoesTableExist("meta"); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MetaTable::RazeIfDeprecated(Connection* db, int deprecated_version) { 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_GT(deprecated_version, 0); 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(0, db->transaction_nesting()); 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!DoesTableExist(db)) { 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sql::Statement s(db->GetUniqueStatement( 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "SELECT COUNT(*) FROM sqlite_master")); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (s.Step()) { 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (s.ColumnInt(0) != 0) { 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordDeprecationEvent(DEPRECATION_DATABASE_NOT_EMPTY); 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // NOTE(shess): Empty database at first run is expected, so 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // don't histogram that case. 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordDeprecationEvent(DEPRECATION_DATABASE_UNKNOWN); 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(shess): Share sql with PrepareGetStatement(). 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sql::Statement s(db->GetUniqueStatement( 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "SELECT value FROM meta WHERE key=?")); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) s.BindCString(0, kVersionKey); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!s.Step()) { 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!s.Succeeded()) { 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordDeprecationEvent(DEPRECATION_FAILED_VERSION); 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordDeprecationEvent(DEPRECATION_NO_VERSION); 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int version = s.ColumnInt(0); 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) s.Clear(); // Clear potential automatic transaction for Raze(). 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (version <= deprecated_version) { 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (db->Raze()) { 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordDeprecationEvent(DEPRECATION_RAZED); 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordDeprecationEvent(DEPRECATION_RAZE_FAILED); 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // NOTE(shess): Successfully getting a version which is not 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // deprecated is expected, so don't histogram that case. 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::Init(Connection* db, int version, int compatible_version) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!db_ && db); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_ = db; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If values stored are null or missing entirely, 0 will be reported. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Require new clients to start with a greater initial version. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(version, 0); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(compatible_version, 0); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the table is created an populated atomically. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Transaction transaction(db_); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction.Begin()) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!DoesTableExist(db)) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("CREATE TABLE meta" 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR)")) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: there is no index over the meta table. We currently only have a 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // couple of keys, so it doesn't matter. If we start storing more stuff in 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there, we should create an index. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetVersionNumber(version); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetCompatibleVersionNumber(compatible_version); 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) db_->AddTaggedHistogram("Sqlite.Version", GetVersionNumber()); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transaction.Commit(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetaTable::Reset() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_ = NULL; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetaTable::SetVersionNumber(int version) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(version, 0); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetValue(kVersionKey, version); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MetaTable::GetVersionNumber() { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int version = 0; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetValue(kVersionKey, &version) ? version : 0; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetaTable::SetCompatibleVersionNumber(int version) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(version, 0); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetValue(kCompatibleVersionKey, version); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MetaTable::GetCompatibleVersionNumber() { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int version = 0; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetValue(kCompatibleVersionKey, &version) ? version : 0; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::SetValue(const char* key, const std::string& value) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareSetStatement(&s, key); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindString(1, value); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Run(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::SetValue(const char* key, int value) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareSetStatement(&s, key); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt(1, value); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Run(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::SetValue(const char* key, int64 value) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareSetStatement(&s, key); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt64(1, value); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Run(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::GetValue(const char* key, std::string* value) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PrepareGetStatement(&s, key)) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = s.ColumnString(0); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::GetValue(const char* key, int* value) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PrepareGetStatement(&s, key)) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = s.ColumnInt(0); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::GetValue(const char* key, int64* value) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PrepareGetStatement(&s, key)) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = s.ColumnInt64(0); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::DeleteKey(const char* key) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(db_); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement s(db_->GetUniqueStatement("DELETE FROM meta WHERE key=?")); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindCString(0, key); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s.Run(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MetaTable::PrepareSetStatement(Statement* statement, const char* key) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(db_ && statement); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INSERT OR REPLACE INTO meta (key,value) VALUES (?,?)")); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement->BindCString(0, key); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MetaTable::PrepareGetStatement(Statement* statement, const char* key) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(db_ && statement); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT value FROM meta WHERE key=?")); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) statement->BindCString(0, key); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return statement->Step(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sql 240