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
3 // found in the LICENSE file.
5 #ifndef SQL_RECOVERY_H_
6 #define SQL_RECOVERY_H_
8 #include "base/basictypes.h"
10 #include "sql/connection.h"
18 // Recovery module for sql/. The basic idea is to create a fresh
19 // database and populate it with the recovered contents of the
20 // original database. If recovery is successful, the recovered
21 // database is backed up over the original database. If recovery is
22 // not successful, the original database is razed. In either case,
23 // the original handle is poisoned so that operations on the stack do
24 // not accidentally disrupt the restored data.
27 // scoped_ptr<sql::Recovery> r =
28 // sql::Recovery::Begin(orig_db, orig_db_path);
30 // if (r.db()->Execute(kCreateSchemaSql) &&
31 // r.db()->Execute(kCopyDataFromOrigSql)) {
32 // sql::Recovery::Recovered(r.Pass());
37 // If Recovered() is not called, then RazeAndClose() is called on
40 class SQL_EXPORT Recovery
{
44 // This module is intended to be used in concert with a virtual
45 // table module (see third_party/sqlite/src/src/recover.c). If the
46 // build defines USE_SYSTEM_SQLITE, this module will not be present.
47 // TODO(shess): I am still debating how to handle this - perhaps it
48 // will just imply Unrecoverable(). This is exposed to allow tests
49 // to adapt to the cases, please do not rely on it in production
51 static bool FullRecoverySupported();
53 // Begin the recovery process by opening a temporary database handle
54 // and attach the existing database to it at "corrupt". To prevent
55 // deadlock, all transactions on |connection| are rolled back.
57 // Returns NULL in case of failure, with no cleanup done on the
58 // original connection (except for breaking the transactions). The
59 // caller should Raze() or otherwise cleanup as appropriate.
61 // TODO(shess): Later versions of SQLite allow extracting the path
62 // from the connection.
63 // TODO(shess): Allow specifying the connection point?
64 static scoped_ptr
<Recovery
> Begin(
65 Connection
* connection
,
66 const base::FilePath
& db_path
) WARN_UNUSED_RESULT
;
68 // Mark recovery completed by replicating the recovery database over
69 // the original database, then closing the recovery database. The
70 // original database handle is poisoned, causing future calls
71 // against it to fail.
73 // If Recovered() is not called, the destructor will call
76 // TODO(shess): At this time, this function can fail while leaving
77 // the original database intact. Figure out which failure cases
78 // should go to RazeAndClose() instead.
79 static bool Recovered(scoped_ptr
<Recovery
> r
) WARN_UNUSED_RESULT
;
81 // Indicate that the database is unrecoverable. The original
82 // database is razed, and the handle poisoned.
83 static void Unrecoverable(scoped_ptr
<Recovery
> r
);
85 // When initially developing recovery code, sometimes the possible
86 // database states are not well-understood without further
87 // diagnostics. Abandon recovery but do not raze the original
89 // NOTE(shess): Only call this when adding recovery support. In the
90 // steady state, all databases should progress to recovered or razed.
91 static void Rollback(scoped_ptr
<Recovery
> r
);
93 // Handle to the temporary recovery database.
94 sql::Connection
* db() { return &recover_db_
; }
97 explicit Recovery(Connection
* connection
);
99 // Setup the recovery database handle for Begin(). Returns false in
100 // case anything failed.
101 bool Init(const base::FilePath
& db_path
) WARN_UNUSED_RESULT
;
103 // Copy the recovered database over the original database.
104 bool Backup() WARN_UNUSED_RESULT
;
106 // Close the recovery database, and poison the original handle.
107 // |raze| controls whether the original database is razed or just
113 void Shutdown(Disposition raze
);
115 Connection
* db_
; // Original database connection.
116 Connection recover_db_
; // Recovery connection.
118 DISALLOW_COPY_AND_ASSIGN(Recovery
);
123 #endif // SQL_RECOVERY_H_