1// Copyright 2013 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/files/file_path.h"
8#include "base/files/scoped_temp_dir.h"
9#include "sql/connection.h"
10#include "sql/statement.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace {
14
15class SQLMetaTableTest : public testing::Test {
16 public:
17  virtual void SetUp() {
18    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
19    ASSERT_TRUE(db_.Open(temp_dir_.path().AppendASCII("SQLMetaTableTest.db")));
20  }
21
22  virtual void TearDown() {
23    db_.Close();
24  }
25
26  sql::Connection& db() { return db_; }
27
28 private:
29  base::ScopedTempDir temp_dir_;
30  sql::Connection db_;
31};
32
33TEST_F(SQLMetaTableTest, DoesTableExist) {
34  EXPECT_FALSE(sql::MetaTable::DoesTableExist(&db()));
35
36  {
37    sql::MetaTable meta_table;
38    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
39  }
40
41  EXPECT_TRUE(sql::MetaTable::DoesTableExist(&db()));
42}
43
44TEST_F(SQLMetaTableTest, RazeIfDeprecated) {
45  const int kDeprecatedVersion = 1;
46  const int kVersion = 2;
47
48  // Setup a current database.
49  {
50    sql::MetaTable meta_table;
51    EXPECT_TRUE(meta_table.Init(&db(), kVersion, kVersion));
52    EXPECT_TRUE(db().Execute("CREATE TABLE t(c)"));
53    EXPECT_TRUE(db().DoesTableExist("t"));
54  }
55
56  // Table should should still exist if the database version is new enough.
57  sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
58  EXPECT_TRUE(db().DoesTableExist("t"));
59
60  // TODO(shess): It may make sense to Raze() if meta isn't present or
61  // version isn't present.  See meta_table.h TODO on RazeIfDeprecated().
62
63  // Table should still exist if the version is not available.
64  EXPECT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'version'"));
65  {
66    sql::MetaTable meta_table;
67    EXPECT_TRUE(meta_table.Init(&db(), kVersion, kVersion));
68    EXPECT_EQ(0, meta_table.GetVersionNumber());
69  }
70  sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
71  EXPECT_TRUE(db().DoesTableExist("t"));
72
73  // Table should still exist if meta table is missing.
74  EXPECT_TRUE(db().Execute("DROP TABLE meta"));
75  sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
76  EXPECT_TRUE(db().DoesTableExist("t"));
77
78  // Setup meta with deprecated version.
79  {
80    sql::MetaTable meta_table;
81    EXPECT_TRUE(meta_table.Init(&db(), kDeprecatedVersion, kDeprecatedVersion));
82  }
83
84  // Deprecation check should remove the table.
85  EXPECT_TRUE(db().DoesTableExist("t"));
86  sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
87  EXPECT_FALSE(sql::MetaTable::DoesTableExist(&db()));
88  EXPECT_FALSE(db().DoesTableExist("t"));
89}
90
91TEST_F(SQLMetaTableTest, VersionNumber) {
92  // Compatibility versions one less than the main versions to make
93  // sure the values aren't being crossed with each other.
94  const int kVersionFirst = 2;
95  const int kCompatVersionFirst = kVersionFirst - 1;
96  const int kVersionSecond = 4;
97  const int kCompatVersionSecond = kVersionSecond - 1;
98  const int kVersionThird = 6;
99  const int kCompatVersionThird = kVersionThird - 1;
100
101  // First Init() sets the version info as expected.
102  {
103    sql::MetaTable meta_table;
104    EXPECT_TRUE(meta_table.Init(&db(), kVersionFirst, kCompatVersionFirst));
105    EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber());
106    EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber());
107  }
108
109  // Second Init() does not change the version info.
110  {
111    sql::MetaTable meta_table;
112    EXPECT_TRUE(meta_table.Init(&db(), kVersionSecond, kCompatVersionSecond));
113    EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber());
114    EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber());
115
116    meta_table.SetVersionNumber(kVersionSecond);
117    meta_table.SetCompatibleVersionNumber(kCompatVersionSecond);
118  }
119
120  // Version info from Set*() calls is seen.
121  {
122    sql::MetaTable meta_table;
123    EXPECT_TRUE(meta_table.Init(&db(), kVersionThird, kCompatVersionThird));
124    EXPECT_EQ(kVersionSecond, meta_table.GetVersionNumber());
125    EXPECT_EQ(kCompatVersionSecond, meta_table.GetCompatibleVersionNumber());
126  }
127}
128
129TEST_F(SQLMetaTableTest, StringValue) {
130  const char kKey[] = "String Key";
131  const std::string kFirstValue("First Value");
132  const std::string kSecondValue("Second Value");
133
134  // Initially, the value isn't there until set.
135  {
136    sql::MetaTable meta_table;
137    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
138
139    std::string value;
140    EXPECT_FALSE(meta_table.GetValue(kKey, &value));
141
142    EXPECT_TRUE(meta_table.SetValue(kKey, kFirstValue));
143    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
144    EXPECT_EQ(kFirstValue, value);
145  }
146
147  // Value is persistent across different instances.
148  {
149    sql::MetaTable meta_table;
150    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
151
152    std::string value;
153    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
154    EXPECT_EQ(kFirstValue, value);
155
156    EXPECT_TRUE(meta_table.SetValue(kKey, kSecondValue));
157  }
158
159  // Existing value was successfully changed.
160  {
161    sql::MetaTable meta_table;
162    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
163
164    std::string value;
165    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
166    EXPECT_EQ(kSecondValue, value);
167  }
168}
169
170TEST_F(SQLMetaTableTest, IntValue) {
171  const char kKey[] = "Int Key";
172  const int kFirstValue = 17;
173  const int kSecondValue = 23;
174
175  // Initially, the value isn't there until set.
176  {
177    sql::MetaTable meta_table;
178    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
179
180    int value;
181    EXPECT_FALSE(meta_table.GetValue(kKey, &value));
182
183    EXPECT_TRUE(meta_table.SetValue(kKey, kFirstValue));
184    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
185    EXPECT_EQ(kFirstValue, value);
186  }
187
188  // Value is persistent across different instances.
189  {
190    sql::MetaTable meta_table;
191    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
192
193    int value;
194    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
195    EXPECT_EQ(kFirstValue, value);
196
197    EXPECT_TRUE(meta_table.SetValue(kKey, kSecondValue));
198  }
199
200  // Existing value was successfully changed.
201  {
202    sql::MetaTable meta_table;
203    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
204
205    int value;
206    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
207    EXPECT_EQ(kSecondValue, value);
208  }
209}
210
211TEST_F(SQLMetaTableTest, Int64Value) {
212  const char kKey[] = "Int Key";
213  const int64 kFirstValue = 5000000017LL;
214  const int64 kSecondValue = 5000000023LL;
215
216  // Initially, the value isn't there until set.
217  {
218    sql::MetaTable meta_table;
219    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
220
221    int64 value;
222    EXPECT_FALSE(meta_table.GetValue(kKey, &value));
223
224    EXPECT_TRUE(meta_table.SetValue(kKey, kFirstValue));
225    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
226    EXPECT_EQ(kFirstValue, value);
227  }
228
229  // Value is persistent across different instances.
230  {
231    sql::MetaTable meta_table;
232    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
233
234    int64 value;
235    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
236    EXPECT_EQ(kFirstValue, value);
237
238    EXPECT_TRUE(meta_table.SetValue(kKey, kSecondValue));
239  }
240
241  // Existing value was successfully changed.
242  {
243    sql::MetaTable meta_table;
244    EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
245
246    int64 value;
247    EXPECT_TRUE(meta_table.GetValue(kKey, &value));
248    EXPECT_EQ(kSecondValue, value);
249  }
250}
251
252TEST_F(SQLMetaTableTest, DeleteKey) {
253  const char kKey[] = "String Key";
254  const std::string kValue("String Value");
255
256  sql::MetaTable meta_table;
257  EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
258
259  // Value isn't present.
260  std::string value;
261  EXPECT_FALSE(meta_table.GetValue(kKey, &value));
262
263  // Now value is present.
264  EXPECT_TRUE(meta_table.SetValue(kKey, kValue));
265  EXPECT_TRUE(meta_table.GetValue(kKey, &value));
266  EXPECT_EQ(kValue, value);
267
268  // After delete value isn't present.
269  EXPECT_TRUE(meta_table.DeleteKey(kKey));
270  EXPECT_FALSE(meta_table.GetValue(kKey, &value));
271}
272
273}  // namespace
274