Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: sql/recovery_unittest.cc

Issue 1700483002: [sqlite] iOS running recover virtual table. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@zzsql_recover_handle_review2
Patch Set: Manually find sql/test/data for now. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sql/recovery.cc ('k') | third_party/sqlite/amalgamation/sqlite3.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 165 }
166 EXPECT_FALSE(db().is_open()); 166 EXPECT_FALSE(db().is_open());
167 ASSERT_TRUE(Reopen()); 167 ASSERT_TRUE(Reopen());
168 EXPECT_TRUE(db().is_open()); 168 EXPECT_TRUE(db().is_open());
169 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 169 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
170 170
171 ASSERT_EQ("This is a test", 171 ASSERT_EQ("This is a test",
172 ExecuteWithResults(&db(), kXSql, "|", "\n")); 172 ExecuteWithResults(&db(), kXSql, "|", "\n"));
173 } 173 }
174 174
175 // The recovery virtual table is only supported for Chromium's SQLite.
176 #if !defined(USE_SYSTEM_SQLITE)
177
178 // Test operation of the virtual table used by sql::Recovery. 175 // Test operation of the virtual table used by sql::Recovery.
179 TEST_F(SQLRecoveryTest, VirtualTable) { 176 TEST_F(SQLRecoveryTest, VirtualTable) {
180 const char kCreateSql[] = "CREATE TABLE x (t TEXT)"; 177 const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
181 ASSERT_TRUE(db().Execute(kCreateSql)); 178 ASSERT_TRUE(db().Execute(kCreateSql));
182 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')")); 179 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')"));
183 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test')")); 180 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test')"));
184 181
185 // Successfully recover the database. 182 // Successfully recover the database.
186 { 183 {
187 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 184 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path());
(...skipping 21 matching lines...) Expand all
209 // Since the database was not corrupt, the entire schema and all 206 // Since the database was not corrupt, the entire schema and all
210 // data should be recovered. 207 // data should be recovered.
211 ASSERT_TRUE(Reopen()); 208 ASSERT_TRUE(Reopen());
212 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 209 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
213 210
214 const char* kXSql = "SELECT * FROM x ORDER BY 1"; 211 const char* kXSql = "SELECT * FROM x ORDER BY 1";
215 ASSERT_EQ("That was a test\nThis is a test", 212 ASSERT_EQ("That was a test\nThis is a test",
216 ExecuteWithResults(&db(), kXSql, "|", "\n")); 213 ExecuteWithResults(&db(), kXSql, "|", "\n"));
217 } 214 }
218 215
216 // Virtual table works with page sizes other than the default, with
217 // sql::Recovery maintaining page size.
218 TEST_F(SQLRecoveryTest, VirtualTablePageSize) {
219 const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
220 ASSERT_TRUE(db().Execute(kCreateSql));
221 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')"));
222 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test')"));
223
224 // The default page size is the greater of SQLITE_DEFAULT_PAGE_SIZE and
225 // xSectorSize() returned from the vfs.
226 db().set_page_size(1024);
227 ASSERT_TRUE(Reopen());
228 ASSERT_TRUE(db().Execute("VACUUM"));
229
230 // Reset the page size.
231 ASSERT_EQ("1024", ExecuteWithResults(&db(), "PRAGMA page_size", "|", "\n"));
232 db().set_page_size(4096);
233 ASSERT_TRUE(Reopen());
234 ASSERT_TRUE(db().Execute("VACUUM"));
235 ASSERT_EQ("4096", ExecuteWithResults(&db(), "PRAGMA page_size", "|", "\n"));
236
237 // Successfully recover the database.
238 {
239 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path());
240
241 // Tables to recover original DB, now at [corrupt].
242 const char kRecoveryCreateSql[] =
243 "CREATE VIRTUAL TABLE temp.recover_x using recover("
244 " corrupt.x,"
245 " t TEXT STRICT"
246 ")";
247 ASSERT_TRUE(recovery->db()->Execute(kRecoveryCreateSql));
248
249 // Re-create the original schema.
250 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
251
252 // Copy the data from the recovery tables to the new database.
253 const char kRecoveryCopySql[] =
254 "INSERT INTO x SELECT t FROM recover_x";
255 ASSERT_TRUE(recovery->db()->Execute(kRecoveryCopySql));
256
257 // Successfully recovered.
258 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
259 }
260
261 // Since the database was not corrupt, the entire schema and all
262 // data should be recovered.
263 ASSERT_TRUE(Reopen());
264 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
265 ASSERT_EQ("4096", ExecuteWithResults(&db(), "PRAGMA page_size", "|", "\n"));
266
267 const char* kXSql = "SELECT * FROM x ORDER BY 1";
268 ASSERT_EQ("That was a test\nThis is a test",
269 ExecuteWithResults(&db(), kXSql, "|", "\n"));
270 }
271
219 void RecoveryCallback(sql::Connection* db, const base::FilePath& db_path, 272 void RecoveryCallback(sql::Connection* db, const base::FilePath& db_path,
220 const char* create_table, const char* create_index, 273 const char* create_table, const char* create_index,
221 int* record_error, int error, sql::Statement* stmt) { 274 int* record_error, int error, sql::Statement* stmt) {
222 *record_error = error; 275 *record_error = error;
223 276
224 // Clear the error callback to prevent reentrancy. 277 // Clear the error callback to prevent reentrancy.
225 db->reset_error_callback(); 278 db->reset_error_callback();
226 279
227 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path); 280 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path);
228 ASSERT_TRUE(recovery.get()); 281 ASSERT_TRUE(recovery.get());
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 ASSERT_TRUE(Reopen()); 760 ASSERT_TRUE(Reopen());
708 ASSERT_EQ(expected_schema, GetSchema(&db())); 761 ASSERT_EQ(expected_schema, GetSchema(&db()));
709 ASSERT_EQ(expected_data, ExecuteWithResults(&db(), kXSql, "|", "\n")); 762 ASSERT_EQ(expected_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
710 } 763 }
711 764
712 // Recover a golden file where an interior page has been manually modified so 765 // Recover a golden file where an interior page has been manually modified so
713 // that the number of cells is greater than will fit on a single page. This 766 // that the number of cells is greater than will fit on a single page. This
714 // case happened in <http://crbug.com/387868>. 767 // case happened in <http://crbug.com/387868>.
715 TEST_F(SQLRecoveryTest, Bug387868) { 768 TEST_F(SQLRecoveryTest, Bug387868) {
716 base::FilePath golden_path; 769 base::FilePath golden_path;
717 ASSERT_TRUE(PathService::Get(sql::test::DIR_TEST_DATA, &golden_path)); 770 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &golden_path));
771 golden_path = golden_path.AppendASCII("sql");
772 golden_path = golden_path.AppendASCII("test");
773 golden_path = golden_path.AppendASCII("data");
718 golden_path = golden_path.AppendASCII("recovery_387868"); 774 golden_path = golden_path.AppendASCII("recovery_387868");
719 db().Close(); 775 db().Close();
720 ASSERT_TRUE(base::CopyFile(golden_path, db_path())); 776 ASSERT_TRUE(base::CopyFile(golden_path, db_path()));
721 ASSERT_TRUE(Reopen()); 777 ASSERT_TRUE(Reopen());
722 778
723 { 779 {
724 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 780 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path());
725 ASSERT_TRUE(recovery.get()); 781 ASSERT_TRUE(recovery.get());
726 782
727 // Create the new version of the table. 783 // Create the new version of the table.
728 const char kCreateSql[] = 784 const char kCreateSql[] =
729 "CREATE TABLE x (id INTEGER PRIMARY KEY, t0 TEXT)"; 785 "CREATE TABLE x (id INTEGER PRIMARY KEY, t0 TEXT)";
730 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 786 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
731 787
732 size_t rows = 0; 788 size_t rows = 0;
733 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 789 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
734 EXPECT_EQ(43u, rows); 790 EXPECT_EQ(43u, rows);
735 791
736 // Successfully recovered. 792 // Successfully recovered.
737 EXPECT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 793 EXPECT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
738 } 794 }
739 } 795 }
740 #endif // !defined(USE_SYSTEM_SQLITE)
741 796
742 // Memory-mapped I/O interacts poorly with I/O errors. Make sure the recovery 797 // Memory-mapped I/O interacts poorly with I/O errors. Make sure the recovery
743 // database doesn't accidentally enable it. 798 // database doesn't accidentally enable it.
744 TEST_F(SQLRecoveryTest, NoMmap) { 799 TEST_F(SQLRecoveryTest, NoMmap) {
745 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 800 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path());
746 ASSERT_TRUE(recovery.get()); 801 ASSERT_TRUE(recovery.get());
747 802
748 // In the current implementation, the PRAGMA successfully runs with no result 803 // In the current implementation, the PRAGMA successfully runs with no result
749 // rows. Running with a single result of |0| is also acceptable. 804 // rows. Running with a single result of |0| is also acceptable.
750 sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size")); 805 sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size"));
751 EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0)); 806 EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0));
752 } 807 }
753 808
754 } // namespace 809 } // namespace
OLDNEW
« no previous file with comments | « sql/recovery.cc ('k') | third_party/sqlite/amalgamation/sqlite3.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698