OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sql/recovery.h" | 5 #include "sql/recovery.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 std::unique_ptr<sql::Recovery> recovery = | 760 std::unique_ptr<sql::Recovery> recovery = |
761 sql::Recovery::Begin(&db(), db_path()); | 761 sql::Recovery::Begin(&db(), db_path()); |
762 ASSERT_TRUE(recovery.get()); | 762 ASSERT_TRUE(recovery.get()); |
763 | 763 |
764 // In the current implementation, the PRAGMA successfully runs with no result | 764 // In the current implementation, the PRAGMA successfully runs with no result |
765 // rows. Running with a single result of |0| is also acceptable. | 765 // rows. Running with a single result of |0| is also acceptable. |
766 sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size")); | 766 sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size")); |
767 EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0)); | 767 EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0)); |
768 } | 768 } |
769 | 769 |
770 TEST_F(SQLRecoveryTest, RecoverDatabaseOrRaze) { | |
771 // As a side effect AUTOINCREMENT creates the sqlite_sequence table for | |
Mark P
2016/04/19 23:34:28
optional nit: comma after effect
Scott Hess - ex-Googler
2016/05/13 21:24:36
Done.
| |
772 // RecoverDatabaseOrRaze() to handle. | |
773 ASSERT_TRUE(db().Execute( | |
774 "CREATE TABLE x (id INTEGER PRIMARY KEY AUTOINCREMENT, v TEXT)")); | |
775 EXPECT_TRUE(db().Execute("INSERT INTO x (v) VALUES ('turtle')")); | |
776 EXPECT_TRUE(db().Execute("INSERT INTO x (v) VALUES ('truck')")); | |
777 EXPECT_TRUE(db().Execute("INSERT INTO x (v) VALUES ('trailer')")); | |
778 | |
779 // This table needs index and a unique index to work. | |
780 ASSERT_TRUE(db().Execute("CREATE TABLE y (name TEXT, v TEXT)")); | |
781 ASSERT_TRUE(db().Execute("CREATE UNIQUE INDEX y_name ON y(name)")); | |
782 ASSERT_TRUE(db().Execute("CREATE INDEX y_v ON y(v)")); | |
783 EXPECT_TRUE(db().Execute("INSERT INTO y VALUES ('jim', 'telephone')")); | |
784 EXPECT_TRUE(db().Execute("INSERT INTO y VALUES ('bob', 'truck')")); | |
785 EXPECT_TRUE(db().Execute("INSERT INTO y VALUES ('dean', 'trailer')")); | |
786 | |
787 // View which is the intersection of [x.v] and [y.v]. | |
788 ASSERT_TRUE(db().Execute( | |
789 "CREATE VIEW v AS SELECT x.v FROM x, y WHERE x.v = y.v")); | |
790 | |
791 // When an element is deleted from [x], trigger a delete on [y]. Between the | |
792 // BEGIN and END, [old] stands for the deleted rows from [x]. | |
793 ASSERT_TRUE(db().Execute("CREATE TRIGGER t AFTER DELETE ON x " | |
794 "BEGIN DELETE FROM y WHERE y.v = old.v; END")); | |
795 | |
796 // Save aside a copy of the original schema, verifying that it has the created | |
797 // items plus the sqlite_sequence table. | |
798 const std::string orig_schema(GetSchema(&db())); | |
799 ASSERT_EQ(6U, std::count(orig_schema.begin(), orig_schema.end(), '\n')); | |
800 | |
801 const char kXSql[] = "SELECT * FROM x ORDER BY 1"; | |
802 const char kYSql[] = "SELECT * FROM y ORDER BY 1"; | |
803 const char kVSql[] = "SELECT * FROM v ORDER BY 1"; | |
804 EXPECT_EQ("1|turtle\n2|truck\n3|trailer", | |
805 ExecuteWithResults(&db(), kXSql, "|", "\n")); | |
806 EXPECT_EQ("bob|truck\ndean|trailer\njim|telephone", | |
807 ExecuteWithResults(&db(), kYSql, "|", "\n")); | |
808 EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db(), kVSql, "|", "\n")); | |
809 | |
810 // Database handle is valid before recovery, poisoned after. | |
811 const char kTrivialSql[] = "SELECT COUNT(*) FROM sqlite_master"; | |
812 EXPECT_TRUE(db().IsSQLValid(kTrivialSql)); | |
813 sql::Recovery::RecoverDatabaseOrRaze(&db(), db_path()); | |
814 EXPECT_FALSE(db().IsSQLValid(kTrivialSql)); | |
815 | |
816 // Since the database was not corrupt, the entire schema and all | |
817 // data should be recovered. | |
818 ASSERT_TRUE(Reopen()); | |
819 ASSERT_EQ(orig_schema, GetSchema(&db())); | |
820 EXPECT_EQ("1|turtle\n2|truck\n3|trailer", | |
821 ExecuteWithResults(&db(), kXSql, "|", "\n")); | |
822 EXPECT_EQ("bob|truck\ndean|trailer\njim|telephone", | |
823 ExecuteWithResults(&db(), kYSql, "|", "\n")); | |
824 EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db(), kVSql, "|", "\n")); | |
825 | |
826 // Test that the trigger works. | |
827 ASSERT_TRUE(db().Execute("DELETE FROM x WHERE v = 'truck'")); | |
828 EXPECT_EQ("1|turtle\n3|trailer", | |
829 ExecuteWithResults(&db(), kXSql, "|", "\n")); | |
830 EXPECT_EQ("dean|trailer\njim|telephone", | |
831 ExecuteWithResults(&db(), kYSql, "|", "\n")); | |
832 EXPECT_EQ("trailer", ExecuteWithResults(&db(), kVSql, "|", "\n")); | |
833 } | |
834 | |
770 } // namespace | 835 } // namespace |
OLD | NEW |