| // Copyright 2013 The Chromium Authors |
| // 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<stdint.h> |
| |
| #include<string> |
| |
| #include"base/files/file_path.h" |
| #include"base/files/scoped_temp_dir.h" |
| #include"sql/database.h" |
| #include"sql/test/test_helpers.h" |
| #include"testing/gtest/include/gtest/gtest.h" |
| |
| namespace sql{ |
| |
| namespace{ |
| |
| classSQLMetaTableTest:public testing::Test{ |
| public: |
| voidSetUp() override{ |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| ASSERT_TRUE( |
| db_.Open(temp_dir_.GetPath().AppendASCII("meta_table_test.sqlite"))); |
| } |
| |
| protected: |
| base::ScopedTempDir temp_dir_; |
| Database db_{test::kTestTag}; |
| }; |
| |
| TEST_F(SQLMetaTableTest,DoesTableExist){ |
| EXPECT_FALSE(MetaTable::DoesTableExist(&db_)); |
| |
| { |
| MetaTable meta_table; |
| EXPECT_TRUE(meta_table.Init(&db_,1,1)); |
| } |
| |
| EXPECT_TRUE(MetaTable::DoesTableExist(&db_)); |
| } |
| |
| TEST_F(SQLMetaTableTest,DeleteTableForTesting){ |
| MetaTable meta_table; |
| EXPECT_TRUE(meta_table.Init(&db_,1,1)); |
| |
| EXPECT_TRUE(MetaTable::DeleteTableForTesting(&db_)); |
| EXPECT_FALSE(MetaTable::DoesTableExist(&db_)); |
| } |
| |
| TEST_F(SQLMetaTableTest,RazeIfIncompatiblePreservesDatabasesWithoutMetadata){ |
| EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); |
| ASSERT_TRUE(db_.DoesTableExist("data")); |
| |
| // The table should not have been cleared, since the database does not have a |
| // metadata table. |
| EXPECT_EQ(RazeIfIncompatibleResult::kCompatible, |
| MetaTable::RazeIfIncompatible(&db_,1, |
| /*current_version=*/1)); |
| EXPECT_TRUE(db_.DoesTableExist("data")); |
| } |
| |
| TEST_F(SQLMetaTableTest,RazeIfIncompatibleRazesIncompatiblyOldTables){ |
| constexprint kWrittenVersion=1; |
| constexprint kCompatibleVersion=1; |
| |
| // Setup a current database. |
| { |
| MetaTable meta_table; |
| EXPECT_TRUE(meta_table.Init(&db_, kWrittenVersion, kCompatibleVersion)); |
| EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); |
| ASSERT_TRUE(db_.DoesTableExist("data")); |
| } |
| |
| // The table should have been cleared, since the least version compatible with |
| // the written database is greater than the current version. |
| EXPECT_EQ( |
| RazeIfIncompatibleResult::kRazedSuccessfully, |
| MetaTable::RazeIfIncompatible(&db_, kWrittenVersion+1, |
| /*current_version=*/kWrittenVersion+1)); |
| EXPECT_FALSE(db_.DoesTableExist("data")); |
| } |
| |
| TEST_F(SQLMetaTableTest,RazeIfIncompatibleRazesIncompatiblyNewTables){ |
| constexprint kCompatibleVersion=2; |
| constexprint kWrittenVersion=3; |
| |
| // Setup a current database. |
| { |
| MetaTable meta_table; |
| EXPECT_TRUE(meta_table.Init(&db_, kWrittenVersion, kCompatibleVersion)); |
| EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); |
| ASSERT_TRUE(db_.DoesTableExist("data")); |
| } |
| |
| // The table should have been cleared, since the least version compatible with |
| // the written database is greater than the current version. |
| EXPECT_EQ(RazeIfIncompatibleResult::kRazedSuccessfully, |
| MetaTable::RazeIfIncompatible( |
| &db_,MetaTable::kNoLowestSupportedVersion, |
| /*current_version=*/kCompatibleVersion-1)); |
| EXPECT_FALSE(db_.DoesTableExist("data")); |
| } |
| |
| TEST_F(SQLMetaTableTest,RazeIfIncompatibleDoesntRazeWhenItShouldnt){ |
| constexprint kVersion=2; |
| |
| { |
| MetaTable meta_table; |
| EXPECT_TRUE( |
| meta_table.Init(&db_, kVersion,/*compatible_version=*/kVersion-1)); |
| EXPECT_TRUE(db_.Execute("CREATE TABLE data(id INTEGER PRIMARY KEY)")); |
| EXPECT_TRUE(db_.DoesTableExist("data")); |
| } |
| |
| EXPECT_EQ(RazeIfIncompatibleResult::kCompatible, |
| MetaTable::RazeIfIncompatible(&db_, kVersion, |
| /*current_version=*/kVersion)); |
| EXPECT_TRUE(db_.DoesTableExist("data")) |
| <<"Table should still exist if the database version is exactly right."; |
| |
| EXPECT_EQ(RazeIfIncompatibleResult::kCompatible, |
| MetaTable::RazeIfIncompatible(&db_, kVersion-1, |
| /*current_version=*/kVersion)); |
| EXPECT_TRUE(db_.DoesTableExist("data")) |
| <<"... or if the lower bound is less than the actual version"; |
| |
| EXPECT_EQ( |
| RazeIfIncompatibleResult::kCompatible, |
| MetaTable::RazeIfIncompatible(&db_,MetaTable::kNoLowestSupportedVersion, |
| /*current_version=*/kVersion)); |
| EXPECT_TRUE(db_.DoesTableExist("data")) |
| <<"... or if the lower bound is not set"; |
| |
| EXPECT_EQ( |
| RazeIfIncompatibleResult::kCompatible, |
| MetaTable::RazeIfIncompatible(&db_,MetaTable::kNoLowestSupportedVersion, |
| /*current_version=*/kVersion-1)); |
| EXPECT_TRUE(db_.DoesTableExist("data")) |
| <<"... even if the current version exactly matches the written " |
| "database's least compatible version."; |
| } |
| |
| TEST_F(SQLMetaTableTest,VersionNumber){ |
| // Compatibility versions one less than the main versions to make |
| // sure the values aren't being crossed with each other. |
| constexprint kVersionFirst=2; |
| constexprint kCompatVersionFirst= kVersionFirst-1; |
| constexprint kVersionSecond=4; |
| constexprint kCompatVersionSecond= kVersionSecond-1; |
| constexprint kVersionThird=6; |
| constexprint kCompatVersionThird= kVersionThird-1; |
| |
| // First Init() sets the version info as expected. |
| { |
| 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. |
| { |
| MetaTable meta_table; |
| EXPECT_TRUE(meta_table.Init(&db_, kVersionSecond, kCompatVersionSecond)); |
| EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber()); |
| EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber()); |
| |
| EXPECT_TRUE(meta_table.SetVersionNumber(kVersionSecond)); |
| EXPECT_TRUE(meta_table.SetCompatibleVersionNumber(kCompatVersionSecond)); |
| } |
| |
| // Version info from Set*() calls is seen. |
| { |
| 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){ |
| staticconstchar kKey[]="String Key"; |
| const std::string kFirstValue("First Value"); |
| const std::string kSecondValue("Second Value"); |
| |
| // Initially, the value isn't there until set. |
| { |
| 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. |
| { |
| 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. |
| { |
| 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){ |
| staticconstchar kKey[]="Int Key"; |
| constexprint kFirstValue=17; |
| constexprint kSecondValue=23; |
| |
| // Initially, the value isn't there until set. |
| { |
| 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. |
| { |
| 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. |
| { |
| 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){ |
| staticconstchar kKey[]="Int Key"; |
| constint64_t kFirstValue=5000000017LL; |
| constint64_t kSecondValue=5000000023LL; |
| |
| // Initially, the value isn't there until set. |
| { |
| 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. |
| { |
| 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. |
| { |
| 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){ |
| staticconstchar kKey[]="String Key"; |
| const std::string kValue("String Value"); |
| |
| 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 |
| |
| }// namespace sql |