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

Side by Side Diff: sql/recovery_unittest.cc

Issue 1851913002: Convert //sql to use std::unique_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: IWYU fixup in precache_url_table_unittest.cc Created 4 years, 8 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') | sql/test/sql_test_base.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
9 #include <memory>
8 #include <string> 10 #include <string>
9 #include <utility> 11 #include <utility>
10 12
11 #include "base/bind.h" 13 #include "base/bind.h"
12 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
13 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
14 #include "base/files/scoped_temp_dir.h" 16 #include "base/files/scoped_temp_dir.h"
15 #include "base/path_service.h" 17 #include "base/path_service.h"
16 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
17 #include "sql/connection.h" 19 #include "sql/connection.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 const char kCreateSql[] = "CREATE TABLE x (t TEXT)"; 75 const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
74 const char kInsertSql[] = "INSERT INTO x VALUES ('This is a test')"; 76 const char kInsertSql[] = "INSERT INTO x VALUES ('This is a test')";
75 const char kAltInsertSql[] = "INSERT INTO x VALUES ('That was a test')"; 77 const char kAltInsertSql[] = "INSERT INTO x VALUES ('That was a test')";
76 ASSERT_TRUE(db().Execute(kCreateSql)); 78 ASSERT_TRUE(db().Execute(kCreateSql));
77 ASSERT_TRUE(db().Execute(kInsertSql)); 79 ASSERT_TRUE(db().Execute(kInsertSql));
78 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 80 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
79 81
80 // If the Recovery handle goes out of scope without being 82 // If the Recovery handle goes out of scope without being
81 // Recovered(), the database is razed. 83 // Recovered(), the database is razed.
82 { 84 {
83 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 85 std::unique_ptr<sql::Recovery> recovery =
86 sql::Recovery::Begin(&db(), db_path());
84 ASSERT_TRUE(recovery.get()); 87 ASSERT_TRUE(recovery.get());
85 } 88 }
86 EXPECT_FALSE(db().is_open()); 89 EXPECT_FALSE(db().is_open());
87 ASSERT_TRUE(Reopen()); 90 ASSERT_TRUE(Reopen());
88 EXPECT_TRUE(db().is_open()); 91 EXPECT_TRUE(db().is_open());
89 ASSERT_EQ("", GetSchema(&db())); 92 ASSERT_EQ("", GetSchema(&db()));
90 93
91 // Recreate the database. 94 // Recreate the database.
92 ASSERT_TRUE(db().Execute(kCreateSql)); 95 ASSERT_TRUE(db().Execute(kCreateSql));
93 ASSERT_TRUE(db().Execute(kInsertSql)); 96 ASSERT_TRUE(db().Execute(kInsertSql));
94 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 97 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
95 98
96 // Unrecoverable() also razes. 99 // Unrecoverable() also razes.
97 { 100 {
98 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 101 std::unique_ptr<sql::Recovery> recovery =
102 sql::Recovery::Begin(&db(), db_path());
99 ASSERT_TRUE(recovery.get()); 103 ASSERT_TRUE(recovery.get());
100 sql::Recovery::Unrecoverable(std::move(recovery)); 104 sql::Recovery::Unrecoverable(std::move(recovery));
101 105
102 // TODO(shess): Test that calls to recover.db() start failing. 106 // TODO(shess): Test that calls to recover.db() start failing.
103 } 107 }
104 EXPECT_FALSE(db().is_open()); 108 EXPECT_FALSE(db().is_open());
105 ASSERT_TRUE(Reopen()); 109 ASSERT_TRUE(Reopen());
106 EXPECT_TRUE(db().is_open()); 110 EXPECT_TRUE(db().is_open());
107 ASSERT_EQ("", GetSchema(&db())); 111 ASSERT_EQ("", GetSchema(&db()));
108 112
109 // Attempting to recover a previously-recovered handle fails early. 113 // Attempting to recover a previously-recovered handle fails early.
110 { 114 {
111 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 115 std::unique_ptr<sql::Recovery> recovery =
116 sql::Recovery::Begin(&db(), db_path());
112 ASSERT_TRUE(recovery.get()); 117 ASSERT_TRUE(recovery.get());
113 recovery.reset(); 118 recovery.reset();
114 119
115 recovery = sql::Recovery::Begin(&db(), db_path()); 120 recovery = sql::Recovery::Begin(&db(), db_path());
116 ASSERT_FALSE(recovery.get()); 121 ASSERT_FALSE(recovery.get());
117 } 122 }
118 ASSERT_TRUE(Reopen()); 123 ASSERT_TRUE(Reopen());
119 124
120 // Recreate the database. 125 // Recreate the database.
121 ASSERT_TRUE(db().Execute(kCreateSql)); 126 ASSERT_TRUE(db().Execute(kCreateSql));
122 ASSERT_TRUE(db().Execute(kInsertSql)); 127 ASSERT_TRUE(db().Execute(kInsertSql));
123 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 128 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
124 129
125 // Unrecovered table to distinguish from recovered database. 130 // Unrecovered table to distinguish from recovered database.
126 ASSERT_TRUE(db().Execute("CREATE TABLE y (c INTEGER)")); 131 ASSERT_TRUE(db().Execute("CREATE TABLE y (c INTEGER)"));
127 ASSERT_NE("CREATE TABLE x (t TEXT)", GetSchema(&db())); 132 ASSERT_NE("CREATE TABLE x (t TEXT)", GetSchema(&db()));
128 133
129 // Recovered() replaces the original with the "recovered" version. 134 // Recovered() replaces the original with the "recovered" version.
130 { 135 {
131 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 136 std::unique_ptr<sql::Recovery> recovery =
137 sql::Recovery::Begin(&db(), db_path());
132 ASSERT_TRUE(recovery.get()); 138 ASSERT_TRUE(recovery.get());
133 139
134 // Create the new version of the table. 140 // Create the new version of the table.
135 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 141 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
136 142
137 // Insert different data to distinguish from original database. 143 // Insert different data to distinguish from original database.
138 ASSERT_TRUE(recovery->db()->Execute(kAltInsertSql)); 144 ASSERT_TRUE(recovery->db()->Execute(kAltInsertSql));
139 145
140 // Successfully recovered. 146 // Successfully recovered.
141 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 147 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
142 } 148 }
143 EXPECT_FALSE(db().is_open()); 149 EXPECT_FALSE(db().is_open());
144 ASSERT_TRUE(Reopen()); 150 ASSERT_TRUE(Reopen());
145 EXPECT_TRUE(db().is_open()); 151 EXPECT_TRUE(db().is_open());
146 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 152 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
147 153
148 const char* kXSql = "SELECT * FROM x ORDER BY 1"; 154 const char* kXSql = "SELECT * FROM x ORDER BY 1";
149 ASSERT_EQ("That was a test", 155 ASSERT_EQ("That was a test",
150 ExecuteWithResults(&db(), kXSql, "|", "\n")); 156 ExecuteWithResults(&db(), kXSql, "|", "\n"));
151 157
152 // Reset the database contents. 158 // Reset the database contents.
153 ASSERT_TRUE(db().Execute("DELETE FROM x")); 159 ASSERT_TRUE(db().Execute("DELETE FROM x"));
154 ASSERT_TRUE(db().Execute(kInsertSql)); 160 ASSERT_TRUE(db().Execute(kInsertSql));
155 161
156 // Rollback() discards recovery progress and leaves the database as it was. 162 // Rollback() discards recovery progress and leaves the database as it was.
157 { 163 {
158 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 164 std::unique_ptr<sql::Recovery> recovery =
165 sql::Recovery::Begin(&db(), db_path());
159 ASSERT_TRUE(recovery.get()); 166 ASSERT_TRUE(recovery.get());
160 167
161 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 168 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
162 ASSERT_TRUE(recovery->db()->Execute(kAltInsertSql)); 169 ASSERT_TRUE(recovery->db()->Execute(kAltInsertSql));
163 170
164 sql::Recovery::Rollback(std::move(recovery)); 171 sql::Recovery::Rollback(std::move(recovery));
165 } 172 }
166 EXPECT_FALSE(db().is_open()); 173 EXPECT_FALSE(db().is_open());
167 ASSERT_TRUE(Reopen()); 174 ASSERT_TRUE(Reopen());
168 EXPECT_TRUE(db().is_open()); 175 EXPECT_TRUE(db().is_open());
169 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db())); 176 ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
170 177
171 ASSERT_EQ("This is a test", 178 ASSERT_EQ("This is a test",
172 ExecuteWithResults(&db(), kXSql, "|", "\n")); 179 ExecuteWithResults(&db(), kXSql, "|", "\n"));
173 } 180 }
174 181
175 // Test operation of the virtual table used by sql::Recovery. 182 // Test operation of the virtual table used by sql::Recovery.
176 TEST_F(SQLRecoveryTest, VirtualTable) { 183 TEST_F(SQLRecoveryTest, VirtualTable) {
177 const char kCreateSql[] = "CREATE TABLE x (t TEXT)"; 184 const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
178 ASSERT_TRUE(db().Execute(kCreateSql)); 185 ASSERT_TRUE(db().Execute(kCreateSql));
179 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')")); 186 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')"));
180 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test')")); 187 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test')"));
181 188
182 // Successfully recover the database. 189 // Successfully recover the database.
183 { 190 {
184 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 191 std::unique_ptr<sql::Recovery> recovery =
192 sql::Recovery::Begin(&db(), db_path());
185 193
186 // Tables to recover original DB, now at [corrupt]. 194 // Tables to recover original DB, now at [corrupt].
187 const char kRecoveryCreateSql[] = 195 const char kRecoveryCreateSql[] =
188 "CREATE VIRTUAL TABLE temp.recover_x using recover(" 196 "CREATE VIRTUAL TABLE temp.recover_x using recover("
189 " corrupt.x," 197 " corrupt.x,"
190 " t TEXT STRICT" 198 " t TEXT STRICT"
191 ")"; 199 ")";
192 ASSERT_TRUE(recovery->db()->Execute(kRecoveryCreateSql)); 200 ASSERT_TRUE(recovery->db()->Execute(kRecoveryCreateSql));
193 201
194 // Re-create the original schema. 202 // Re-create the original schema.
(...skipping 19 matching lines...) Expand all
214 } 222 }
215 223
216 void RecoveryCallback(sql::Connection* db, const base::FilePath& db_path, 224 void RecoveryCallback(sql::Connection* db, const base::FilePath& db_path,
217 const char* create_table, const char* create_index, 225 const char* create_table, const char* create_index,
218 int* record_error, int error, sql::Statement* stmt) { 226 int* record_error, int error, sql::Statement* stmt) {
219 *record_error = error; 227 *record_error = error;
220 228
221 // Clear the error callback to prevent reentrancy. 229 // Clear the error callback to prevent reentrancy.
222 db->reset_error_callback(); 230 db->reset_error_callback();
223 231
224 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path); 232 std::unique_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path);
225 ASSERT_TRUE(recovery.get()); 233 ASSERT_TRUE(recovery.get());
226 234
227 ASSERT_TRUE(recovery->db()->Execute(create_table)); 235 ASSERT_TRUE(recovery->db()->Execute(create_table));
228 ASSERT_TRUE(recovery->db()->Execute(create_index)); 236 ASSERT_TRUE(recovery->db()->Execute(create_index));
229 237
230 size_t rows = 0; 238 size_t rows = 0;
231 ASSERT_TRUE(recovery->AutoRecoverTable("x", &rows)); 239 ASSERT_TRUE(recovery->AutoRecoverTable("x", &rows));
232 240
233 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 241 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
234 } 242 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 const int kCompatibleVersion = 2; 387 const int kCompatibleVersion = 2;
380 388
381 { 389 {
382 sql::MetaTable meta; 390 sql::MetaTable meta;
383 EXPECT_TRUE(meta.Init(&db(), kVersion, kCompatibleVersion)); 391 EXPECT_TRUE(meta.Init(&db(), kVersion, kCompatibleVersion));
384 EXPECT_EQ(kVersion, meta.GetVersionNumber()); 392 EXPECT_EQ(kVersion, meta.GetVersionNumber());
385 } 393 }
386 394
387 // Test expected case where everything works. 395 // Test expected case where everything works.
388 { 396 {
389 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 397 std::unique_ptr<sql::Recovery> recovery =
398 sql::Recovery::Begin(&db(), db_path());
390 EXPECT_TRUE(recovery->SetupMeta()); 399 EXPECT_TRUE(recovery->SetupMeta());
391 int version = 0; 400 int version = 0;
392 EXPECT_TRUE(recovery->GetMetaVersionNumber(&version)); 401 EXPECT_TRUE(recovery->GetMetaVersionNumber(&version));
393 EXPECT_EQ(kVersion, version); 402 EXPECT_EQ(kVersion, version);
394 403
395 sql::Recovery::Rollback(std::move(recovery)); 404 sql::Recovery::Rollback(std::move(recovery));
396 } 405 }
397 ASSERT_TRUE(Reopen()); // Handle was poisoned. 406 ASSERT_TRUE(Reopen()); // Handle was poisoned.
398 407
399 // Test version row missing. 408 // Test version row missing.
400 EXPECT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'version'")); 409 EXPECT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'version'"));
401 { 410 {
402 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 411 std::unique_ptr<sql::Recovery> recovery =
412 sql::Recovery::Begin(&db(), db_path());
403 EXPECT_TRUE(recovery->SetupMeta()); 413 EXPECT_TRUE(recovery->SetupMeta());
404 int version = 0; 414 int version = 0;
405 EXPECT_FALSE(recovery->GetMetaVersionNumber(&version)); 415 EXPECT_FALSE(recovery->GetMetaVersionNumber(&version));
406 EXPECT_EQ(0, version); 416 EXPECT_EQ(0, version);
407 417
408 sql::Recovery::Rollback(std::move(recovery)); 418 sql::Recovery::Rollback(std::move(recovery));
409 } 419 }
410 ASSERT_TRUE(Reopen()); // Handle was poisoned. 420 ASSERT_TRUE(Reopen()); // Handle was poisoned.
411 421
412 // Test meta table missing. 422 // Test meta table missing.
413 EXPECT_TRUE(db().Execute("DROP TABLE meta")); 423 EXPECT_TRUE(db().Execute("DROP TABLE meta"));
414 { 424 {
415 sql::ScopedErrorIgnorer ignore_errors; 425 sql::ScopedErrorIgnorer ignore_errors;
416 ignore_errors.IgnoreError(SQLITE_CORRUPT); // From virtual table. 426 ignore_errors.IgnoreError(SQLITE_CORRUPT); // From virtual table.
417 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 427 std::unique_ptr<sql::Recovery> recovery =
428 sql::Recovery::Begin(&db(), db_path());
418 EXPECT_FALSE(recovery->SetupMeta()); 429 EXPECT_FALSE(recovery->SetupMeta());
419 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); 430 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
420 } 431 }
421 } 432 }
422 433
423 // Baseline AutoRecoverTable() test. 434 // Baseline AutoRecoverTable() test.
424 TEST_F(SQLRecoveryTest, AutoRecoverTable) { 435 TEST_F(SQLRecoveryTest, AutoRecoverTable) {
425 // BIGINT and VARCHAR to test type affinity. 436 // BIGINT and VARCHAR to test type affinity.
426 const char kCreateSql[] = "CREATE TABLE x (id BIGINT, t TEXT, v VARCHAR)"; 437 const char kCreateSql[] = "CREATE TABLE x (id BIGINT, t TEXT, v VARCHAR)";
427 ASSERT_TRUE(db().Execute(kCreateSql)); 438 ASSERT_TRUE(db().Execute(kCreateSql));
428 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (11, 'This is', 'a test')")); 439 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (11, 'This is', 'a test')"));
429 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5, 'That was', 'a test')")); 440 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5, 'That was', 'a test')"));
430 441
431 // Save aside a copy of the original schema and data. 442 // Save aside a copy of the original schema and data.
432 const std::string orig_schema(GetSchema(&db())); 443 const std::string orig_schema(GetSchema(&db()));
433 const char kXSql[] = "SELECT * FROM x ORDER BY 1"; 444 const char kXSql[] = "SELECT * FROM x ORDER BY 1";
434 const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n")); 445 const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
435 446
436 // Create a lame-duck table which will not be propagated by recovery to 447 // Create a lame-duck table which will not be propagated by recovery to
437 // detect that the recovery code actually ran. 448 // detect that the recovery code actually ran.
438 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)")); 449 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
439 ASSERT_NE(orig_schema, GetSchema(&db())); 450 ASSERT_NE(orig_schema, GetSchema(&db()));
440 451
441 { 452 {
442 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 453 std::unique_ptr<sql::Recovery> recovery =
454 sql::Recovery::Begin(&db(), db_path());
443 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 455 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
444 456
445 // Save a copy of the temp db's schema before recovering the table. 457 // Save a copy of the temp db's schema before recovering the table.
446 const char kTempSchemaSql[] = "SELECT name, sql FROM sqlite_temp_master"; 458 const char kTempSchemaSql[] = "SELECT name, sql FROM sqlite_temp_master";
447 const std::string temp_schema( 459 const std::string temp_schema(
448 ExecuteWithResults(recovery->db(), kTempSchemaSql, "|", "\n")); 460 ExecuteWithResults(recovery->db(), kTempSchemaSql, "|", "\n"));
449 461
450 size_t rows = 0; 462 size_t rows = 0;
451 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 463 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
452 EXPECT_EQ(2u, rows); 464 EXPECT_EQ(2u, rows);
453 465
454 // Test that any additional temp tables were cleaned up. 466 // Test that any additional temp tables were cleaned up.
455 EXPECT_EQ(temp_schema, 467 EXPECT_EQ(temp_schema,
456 ExecuteWithResults(recovery->db(), kTempSchemaSql, "|", "\n")); 468 ExecuteWithResults(recovery->db(), kTempSchemaSql, "|", "\n"));
457 469
458 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 470 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
459 } 471 }
460 472
461 // Since the database was not corrupt, the entire schema and all 473 // Since the database was not corrupt, the entire schema and all
462 // data should be recovered. 474 // data should be recovered.
463 ASSERT_TRUE(Reopen()); 475 ASSERT_TRUE(Reopen());
464 ASSERT_EQ(orig_schema, GetSchema(&db())); 476 ASSERT_EQ(orig_schema, GetSchema(&db()));
465 ASSERT_EQ(orig_data, ExecuteWithResults(&db(), kXSql, "|", "\n")); 477 ASSERT_EQ(orig_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
466 478
467 // Recovery fails if the target table doesn't exist. 479 // Recovery fails if the target table doesn't exist.
468 { 480 {
469 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 481 std::unique_ptr<sql::Recovery> recovery =
482 sql::Recovery::Begin(&db(), db_path());
470 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 483 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
471 484
472 // TODO(shess): Should this failure implicitly lead to Raze()? 485 // TODO(shess): Should this failure implicitly lead to Raze()?
473 size_t rows = 0; 486 size_t rows = 0;
474 EXPECT_FALSE(recovery->AutoRecoverTable("y", &rows)); 487 EXPECT_FALSE(recovery->AutoRecoverTable("y", &rows));
475 488
476 sql::Recovery::Unrecoverable(std::move(recovery)); 489 sql::Recovery::Unrecoverable(std::move(recovery));
477 } 490 }
478 } 491 }
479 492
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 std::string final_data(orig_data); 529 std::string final_data(orig_data);
517 size_t pos; 530 size_t pos;
518 while ((pos = final_schema.find("'a''a'")) != std::string::npos) { 531 while ((pos = final_schema.find("'a''a'")) != std::string::npos) {
519 final_schema.replace(pos, 6, "'c''c'"); 532 final_schema.replace(pos, 6, "'c''c'");
520 } 533 }
521 while ((pos = final_data.find("5|a'a")) != std::string::npos) { 534 while ((pos = final_data.find("5|a'a")) != std::string::npos) {
522 final_data.replace(pos, 5, "5|c'c"); 535 final_data.replace(pos, 5, "5|c'c");
523 } 536 }
524 537
525 { 538 {
526 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 539 std::unique_ptr<sql::Recovery> recovery =
540 sql::Recovery::Begin(&db(), db_path());
527 // Different default to detect which table provides the default. 541 // Different default to detect which table provides the default.
528 ASSERT_TRUE(recovery->db()->Execute(final_schema.c_str())); 542 ASSERT_TRUE(recovery->db()->Execute(final_schema.c_str()));
529 543
530 size_t rows = 0; 544 size_t rows = 0;
531 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 545 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
532 EXPECT_EQ(4u, rows); 546 EXPECT_EQ(4u, rows);
533 547
534 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 548 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
535 } 549 }
536 550
(...skipping 16 matching lines...) Expand all
553 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5, null)")); 567 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5, null)"));
554 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (15, 'this is a test')")); 568 ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (15, 'this is a test')"));
555 569
556 // Create a lame-duck table which will not be propagated by recovery to 570 // Create a lame-duck table which will not be propagated by recovery to
557 // detect that the recovery code actually ran. 571 // detect that the recovery code actually ran.
558 ASSERT_EQ(kOrigSchema, GetSchema(&db())); 572 ASSERT_EQ(kOrigSchema, GetSchema(&db()));
559 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)")); 573 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
560 ASSERT_NE(kOrigSchema, GetSchema(&db())); 574 ASSERT_NE(kOrigSchema, GetSchema(&db()));
561 575
562 { 576 {
563 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 577 std::unique_ptr<sql::Recovery> recovery =
578 sql::Recovery::Begin(&db(), db_path());
564 ASSERT_TRUE(recovery->db()->Execute(kFinalSchema)); 579 ASSERT_TRUE(recovery->db()->Execute(kFinalSchema));
565 580
566 size_t rows = 0; 581 size_t rows = 0;
567 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 582 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
568 EXPECT_EQ(1u, rows); 583 EXPECT_EQ(1u, rows);
569 584
570 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 585 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
571 } 586 }
572 587
573 // The schema should be the same, but only one row of data should 588 // The schema should be the same, but only one row of data should
(...skipping 18 matching lines...) Expand all
592 const std::string orig_schema(GetSchema(&db())); 607 const std::string orig_schema(GetSchema(&db()));
593 const char kXSql[] = "SELECT * FROM x ORDER BY 1"; 608 const char kXSql[] = "SELECT * FROM x ORDER BY 1";
594 const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n")); 609 const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
595 610
596 // Create a lame-duck table which will not be propagated by recovery to 611 // Create a lame-duck table which will not be propagated by recovery to
597 // detect that the recovery code actually ran. 612 // detect that the recovery code actually ran.
598 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)")); 613 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
599 ASSERT_NE(orig_schema, GetSchema(&db())); 614 ASSERT_NE(orig_schema, GetSchema(&db()));
600 615
601 { 616 {
602 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 617 std::unique_ptr<sql::Recovery> recovery =
618 sql::Recovery::Begin(&db(), db_path());
603 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 619 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
604 620
605 size_t rows = 0; 621 size_t rows = 0;
606 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 622 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
607 EXPECT_EQ(2u, rows); 623 EXPECT_EQ(2u, rows);
608 624
609 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 625 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
610 } 626 }
611 627
612 // Since the database was not corrupt, the entire schema and all 628 // Since the database was not corrupt, the entire schema and all
(...skipping 24 matching lines...) Expand all
637 const std::string orig_schema(GetSchema(&db())); 653 const std::string orig_schema(GetSchema(&db()));
638 const char kXSql[] = "SELECT * FROM x ORDER BY 1"; 654 const char kXSql[] = "SELECT * FROM x ORDER BY 1";
639 const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n")); 655 const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
640 656
641 // Create a lame-duck table which will not be propagated by recovery to 657 // Create a lame-duck table which will not be propagated by recovery to
642 // detect that the recovery code actually ran. 658 // detect that the recovery code actually ran.
643 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)")); 659 ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
644 ASSERT_NE(orig_schema, GetSchema(&db())); 660 ASSERT_NE(orig_schema, GetSchema(&db()));
645 661
646 { 662 {
647 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 663 std::unique_ptr<sql::Recovery> recovery =
664 sql::Recovery::Begin(&db(), db_path());
648 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 665 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
649 666
650 size_t rows = 0; 667 size_t rows = 0;
651 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 668 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
652 EXPECT_EQ(3u, rows); 669 EXPECT_EQ(3u, rows);
653 670
654 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 671 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
655 } 672 }
656 673
657 // Since the database was not corrupt, the entire schema and all 674 // Since the database was not corrupt, the entire schema and all
(...skipping 25 matching lines...) Expand all
683 expected_data = ExecuteWithResults(&db(), kXSql, "|", "\n"); 700 expected_data = ExecuteWithResults(&db(), kXSql, "|", "\n");
684 701
685 db().RollbackTransaction(); 702 db().RollbackTransaction();
686 } 703 }
687 704
688 // Following tests are pointless if the rollback didn't work. 705 // Following tests are pointless if the rollback didn't work.
689 ASSERT_EQ(orig_schema, GetSchema(&db())); 706 ASSERT_EQ(orig_schema, GetSchema(&db()));
690 707
691 // Recover the previous version of the table into the altered version. 708 // Recover the previous version of the table into the altered version.
692 { 709 {
693 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 710 std::unique_ptr<sql::Recovery> recovery =
711 sql::Recovery::Begin(&db(), db_path());
694 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 712 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
695 ASSERT_TRUE(recovery->db()->Execute(kAlterSql)); 713 ASSERT_TRUE(recovery->db()->Execute(kAlterSql));
696 size_t rows = 0; 714 size_t rows = 0;
697 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 715 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
698 EXPECT_EQ(2u, rows); 716 EXPECT_EQ(2u, rows);
699 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 717 ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
700 } 718 }
701 719
702 // Since the database was not corrupt, the entire schema and all 720 // Since the database was not corrupt, the entire schema and all
703 // data should be recovered. 721 // data should be recovered.
704 ASSERT_TRUE(Reopen()); 722 ASSERT_TRUE(Reopen());
705 ASSERT_EQ(expected_schema, GetSchema(&db())); 723 ASSERT_EQ(expected_schema, GetSchema(&db()));
706 ASSERT_EQ(expected_data, ExecuteWithResults(&db(), kXSql, "|", "\n")); 724 ASSERT_EQ(expected_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
707 } 725 }
708 726
709 // Recover a golden file where an interior page has been manually modified so 727 // Recover a golden file where an interior page has been manually modified so
710 // that the number of cells is greater than will fit on a single page. This 728 // that the number of cells is greater than will fit on a single page. This
711 // case happened in <http://crbug.com/387868>. 729 // case happened in <http://crbug.com/387868>.
712 TEST_F(SQLRecoveryTest, Bug387868) { 730 TEST_F(SQLRecoveryTest, Bug387868) {
713 base::FilePath golden_path; 731 base::FilePath golden_path;
714 ASSERT_TRUE(PathService::Get(sql::test::DIR_TEST_DATA, &golden_path)); 732 ASSERT_TRUE(PathService::Get(sql::test::DIR_TEST_DATA, &golden_path));
715 golden_path = golden_path.AppendASCII("recovery_387868"); 733 golden_path = golden_path.AppendASCII("recovery_387868");
716 db().Close(); 734 db().Close();
717 ASSERT_TRUE(base::CopyFile(golden_path, db_path())); 735 ASSERT_TRUE(base::CopyFile(golden_path, db_path()));
718 ASSERT_TRUE(Reopen()); 736 ASSERT_TRUE(Reopen());
719 737
720 { 738 {
721 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 739 std::unique_ptr<sql::Recovery> recovery =
740 sql::Recovery::Begin(&db(), db_path());
722 ASSERT_TRUE(recovery.get()); 741 ASSERT_TRUE(recovery.get());
723 742
724 // Create the new version of the table. 743 // Create the new version of the table.
725 const char kCreateSql[] = 744 const char kCreateSql[] =
726 "CREATE TABLE x (id INTEGER PRIMARY KEY, t0 TEXT)"; 745 "CREATE TABLE x (id INTEGER PRIMARY KEY, t0 TEXT)";
727 ASSERT_TRUE(recovery->db()->Execute(kCreateSql)); 746 ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
728 747
729 size_t rows = 0; 748 size_t rows = 0;
730 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows)); 749 EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
731 EXPECT_EQ(43u, rows); 750 EXPECT_EQ(43u, rows);
732 751
733 // Successfully recovered. 752 // Successfully recovered.
734 EXPECT_TRUE(sql::Recovery::Recovered(std::move(recovery))); 753 EXPECT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
735 } 754 }
736 } 755 }
737 756
738 // Memory-mapped I/O interacts poorly with I/O errors. Make sure the recovery 757 // Memory-mapped I/O interacts poorly with I/O errors. Make sure the recovery
739 // database doesn't accidentally enable it. 758 // database doesn't accidentally enable it.
740 TEST_F(SQLRecoveryTest, NoMmap) { 759 TEST_F(SQLRecoveryTest, NoMmap) {
741 scoped_ptr<sql::Recovery> recovery = sql::Recovery::Begin(&db(), db_path()); 760 std::unique_ptr<sql::Recovery> recovery =
761 sql::Recovery::Begin(&db(), db_path());
742 ASSERT_TRUE(recovery.get()); 762 ASSERT_TRUE(recovery.get());
743 763
744 // In the current implementation, the PRAGMA successfully runs with no result 764 // In the current implementation, the PRAGMA successfully runs with no result
745 // rows. Running with a single result of |0| is also acceptable. 765 // rows. Running with a single result of |0| is also acceptable.
746 sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size")); 766 sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size"));
747 EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0)); 767 EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0));
748 } 768 }
749 769
750 } // namespace 770 } // namespace
OLDNEW
« no previous file with comments | « sql/recovery.cc ('k') | sql/test/sql_test_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698