1// Copyright (c) 2009 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 "app/sql/meta_table.h"
6
7#include "app/sql/connection.h"
8#include "app/sql/statement.h"
9#include "base/logging.h"
10#include "base/string_util.h"
11
12namespace sql {
13
14// Key used in our meta table for version numbers.
15static const char kVersionKey[] = "version";
16static const char kCompatibleVersionKey[] = "last_compatible_version";
17
18MetaTable::MetaTable() : db_(NULL) {
19}
20
21MetaTable::~MetaTable() {
22}
23
24// static
25bool MetaTable::DoesTableExist(sql::Connection* db) {
26  DCHECK(db);
27  return db->DoesTableExist("meta");
28}
29
30bool MetaTable::Init(Connection* db, int version, int compatible_version) {
31  DCHECK(!db_ && db);
32  db_ = db;
33  if (!DoesTableExist(db)) {
34    if (!db_->Execute("CREATE TABLE meta"
35        "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY,"
36         "value LONGVARCHAR)"))
37      return false;
38
39    // Note: there is no index over the meta table. We currently only have a
40    // couple of keys, so it doesn't matter. If we start storing more stuff in
41    // there, we should create an index.
42    SetVersionNumber(version);
43    SetCompatibleVersionNumber(compatible_version);
44  }
45  return true;
46}
47
48void MetaTable::Reset() {
49  db_ = NULL;
50}
51
52bool MetaTable::SetValue(const char* key, const std::string& value) {
53  Statement s;
54  if (!PrepareSetStatement(&s, key))
55    return false;
56  s.BindString(1, value);
57  return s.Run();
58}
59
60bool MetaTable::GetValue(const char* key, std::string* value) {
61  Statement s;
62  if (!PrepareGetStatement(&s, key))
63    return false;
64
65  *value = s.ColumnString(0);
66  return true;
67}
68
69bool MetaTable::SetValue(const char* key, int value) {
70  Statement s;
71  if (!PrepareSetStatement(&s, key))
72    return false;
73
74  s.BindInt(1, value);
75  return s.Run();
76}
77
78bool MetaTable::GetValue(const char* key, int* value) {
79  Statement s;
80  if (!PrepareGetStatement(&s, key))
81    return false;
82
83  *value = s.ColumnInt(0);
84  return true;
85}
86
87bool MetaTable::SetValue(const char* key, int64 value) {
88  Statement s;
89  if (!PrepareSetStatement(&s, key))
90    return false;
91  s.BindInt64(1, value);
92  return s.Run();
93}
94
95bool MetaTable::GetValue(const char* key, int64* value) {
96  Statement s;
97  if (!PrepareGetStatement(&s, key))
98    return false;
99
100  *value = s.ColumnInt64(0);
101  return true;
102}
103
104void MetaTable::SetVersionNumber(int version) {
105  SetValue(kVersionKey, version);
106}
107
108int MetaTable::GetVersionNumber() {
109  int version = 0;
110  if (!GetValue(kVersionKey, &version))
111    return 0;
112  return version;
113}
114
115void MetaTable::SetCompatibleVersionNumber(int version) {
116  SetValue(kCompatibleVersionKey, version);
117}
118
119int MetaTable::GetCompatibleVersionNumber() {
120  int version = 0;
121  if (!GetValue(kCompatibleVersionKey, &version))
122    return 0;
123  return version;
124}
125
126bool MetaTable::PrepareSetStatement(Statement* statement, const char* key) {
127  DCHECK(db_ && statement);
128  statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE,
129      "INSERT OR REPLACE INTO meta (key,value) VALUES (?,?)"));
130  if (!statement->is_valid()) {
131    NOTREACHED() << db_->GetErrorMessage();
132    return false;
133  }
134  statement->BindCString(0, key);
135  return true;
136}
137
138bool MetaTable::PrepareGetStatement(Statement* statement, const char* key) {
139  DCHECK(db_ && statement);
140  statement->Assign(db_->GetCachedStatement(SQL_FROM_HERE,
141      "SELECT value FROM meta WHERE key=?"));
142  if (!statement->is_valid()) {
143    NOTREACHED() << db_->GetErrorMessage();
144    return false;
145  }
146  statement->BindCString(0, key);
147  if (!statement->Step())
148    return false;
149  return true;
150}
151
152}  // namespace sql
153