// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "sql/meta_table.h" #include #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "sql/connection.h" #include "sql/statement.h" #include "sql/test/sql_test_base.h" #include "testing/gtest/include/gtest/gtest.h" namespace { using SQLMetaTableTest = sql::SQLTestBase; TEST_F(SQLMetaTableTest, DoesTableExist) { EXPECT_FALSE(sql::MetaTable::DoesTableExist(&db())); { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); } EXPECT_TRUE(sql::MetaTable::DoesTableExist(&db())); } TEST_F(SQLMetaTableTest, RazeIfDeprecated) { const int kDeprecatedVersion = 1; const int kVersion = 2; // Setup a current database. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), kVersion, kVersion)); EXPECT_TRUE(db().Execute("CREATE TABLE t(c)")); EXPECT_TRUE(db().DoesTableExist("t")); } // Table should should still exist if the database version is new enough. sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion); EXPECT_TRUE(db().DoesTableExist("t")); // TODO(shess): It may make sense to Raze() if meta isn't present or // version isn't present. See meta_table.h TODO on RazeIfDeprecated(). // Table should still exist if the version is not available. EXPECT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'version'")); { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), kVersion, kVersion)); EXPECT_EQ(0, meta_table.GetVersionNumber()); } sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion); EXPECT_TRUE(db().DoesTableExist("t")); // Table should still exist if meta table is missing. EXPECT_TRUE(db().Execute("DROP TABLE meta")); sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion); EXPECT_TRUE(db().DoesTableExist("t")); // Setup meta with deprecated version. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), kDeprecatedVersion, kDeprecatedVersion)); } // Deprecation check should remove the table. EXPECT_TRUE(db().DoesTableExist("t")); sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion); EXPECT_FALSE(sql::MetaTable::DoesTableExist(&db())); EXPECT_FALSE(db().DoesTableExist("t")); } TEST_F(SQLMetaTableTest, VersionNumber) { // Compatibility versions one less than the main versions to make // sure the values aren't being crossed with each other. const int kVersionFirst = 2; const int kCompatVersionFirst = kVersionFirst - 1; const int kVersionSecond = 4; const int kCompatVersionSecond = kVersionSecond - 1; const int kVersionThird = 6; const int kCompatVersionThird = kVersionThird - 1; // First Init() sets the version info as expected. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), kVersionFirst, kCompatVersionFirst)); EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber()); EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber()); } // Second Init() does not change the version info. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), kVersionSecond, kCompatVersionSecond)); EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber()); EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber()); meta_table.SetVersionNumber(kVersionSecond); meta_table.SetCompatibleVersionNumber(kCompatVersionSecond); } // Version info from Set*() calls is seen. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), kVersionThird, kCompatVersionThird)); EXPECT_EQ(kVersionSecond, meta_table.GetVersionNumber()); EXPECT_EQ(kCompatVersionSecond, meta_table.GetCompatibleVersionNumber()); } } TEST_F(SQLMetaTableTest, StringValue) { const char kKey[] = "String Key"; const std::string kFirstValue("First Value"); const std::string kSecondValue("Second Value"); // Initially, the value isn't there until set. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); std::string value; EXPECT_FALSE(meta_table.GetValue(kKey, &value)); EXPECT_TRUE(meta_table.SetValue(kKey, kFirstValue)); EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kFirstValue, value); } // Value is persistent across different instances. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); std::string value; EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kFirstValue, value); EXPECT_TRUE(meta_table.SetValue(kKey, kSecondValue)); } // Existing value was successfully changed. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); std::string value; EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kSecondValue, value); } } TEST_F(SQLMetaTableTest, IntValue) { const char kKey[] = "Int Key"; const int kFirstValue = 17; const int kSecondValue = 23; // Initially, the value isn't there until set. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); int value; EXPECT_FALSE(meta_table.GetValue(kKey, &value)); EXPECT_TRUE(meta_table.SetValue(kKey, kFirstValue)); EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kFirstValue, value); } // Value is persistent across different instances. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); int value; EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kFirstValue, value); EXPECT_TRUE(meta_table.SetValue(kKey, kSecondValue)); } // Existing value was successfully changed. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); int value; EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kSecondValue, value); } } TEST_F(SQLMetaTableTest, Int64Value) { const char kKey[] = "Int Key"; const int64_t kFirstValue = 5000000017LL; const int64_t kSecondValue = 5000000023LL; // Initially, the value isn't there until set. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); int64_t value; EXPECT_FALSE(meta_table.GetValue(kKey, &value)); EXPECT_TRUE(meta_table.SetValue(kKey, kFirstValue)); EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kFirstValue, value); } // Value is persistent across different instances. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); int64_t value; EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kFirstValue, value); EXPECT_TRUE(meta_table.SetValue(kKey, kSecondValue)); } // Existing value was successfully changed. { sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); int64_t value; EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kSecondValue, value); } } TEST_F(SQLMetaTableTest, DeleteKey) { const char kKey[] = "String Key"; const std::string kValue("String Value"); sql::MetaTable meta_table; EXPECT_TRUE(meta_table.Init(&db(), 1, 1)); // Value isn't present. std::string value; EXPECT_FALSE(meta_table.GetValue(kKey, &value)); // Now value is present. EXPECT_TRUE(meta_table.SetValue(kKey, kValue)); EXPECT_TRUE(meta_table.GetValue(kKey, &value)); EXPECT_EQ(kValue, value); // After delete value isn't present. EXPECT_TRUE(meta_table.DeleteKey(kKey)); EXPECT_FALSE(meta_table.GetValue(kKey, &value)); } } // namespace