- add sources.
[platform/framework/web/crosswalk.git] / src / sql / recovery.h
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.
4
5 #ifndef SQL_RECOVERY_H_
6 #define SQL_RECOVERY_H_
7
8 #include "base/basictypes.h"
9
10 #include "sql/connection.h"
11
12 namespace base {
13 class FilePath;
14 }
15
16 namespace sql {
17
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.
25 //
26 // {
27 //   scoped_ptr<sql::Recovery> r =
28 //       sql::Recovery::Begin(orig_db, orig_db_path);
29 //   if (r) {
30 //     if (r.db()->Execute(kCreateSchemaSql) &&
31 //         r.db()->Execute(kCopyDataFromOrigSql)) {
32 //       sql::Recovery::Recovered(r.Pass());
33 //     }
34 //   }
35 // }
36 //
37 // If Recovered() is not called, then RazeAndClose() is called on
38 // orig_db.
39
40 class SQL_EXPORT Recovery {
41  public:
42   ~Recovery();
43
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
50   // code.
51   static bool FullRecoverySupported();
52
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.
56   //
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.
60   //
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;
67
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.
72   //
73   // If Recovered() is not called, the destructor will call
74   // Unrecoverable().
75   //
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;
80
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);
84
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
88   // database.
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);
92
93   // Handle to the temporary recovery database.
94   sql::Connection* db() { return &recover_db_; }
95
96  private:
97   explicit Recovery(Connection* connection);
98
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;
102
103   // Copy the recovered database over the original database.
104   bool Backup() WARN_UNUSED_RESULT;
105
106   // Close the recovery database, and poison the original handle.
107   // |raze| controls whether the original database is razed or just
108   // poisoned.
109   enum Disposition {
110     RAZE_AND_POISON,
111     POISON,
112   };
113   void Shutdown(Disposition raze);
114
115   Connection* db_;         // Original database connection.
116   Connection recover_db_;  // Recovery connection.
117
118   DISALLOW_COPY_AND_ASSIGN(Recovery);
119 };
120
121 }  // namespace sql
122
123 #endif  // SQL_RECOVERY_H_