Index: sql/recovery.h |
diff --git a/sql/recovery.h b/sql/recovery.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..72f83e9b8fc696c00e483528f91fcc0354b43a54 |
--- /dev/null |
+++ b/sql/recovery.h |
@@ -0,0 +1,80 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef SQL_RECOVERY_H_ |
+#define SQL_RECOVERY_H_ |
+ |
+#include "base/basictypes.h" |
+ |
+#include "sql/connection.h" |
+#include "sql/scoped_attach.h" |
+ |
+namespace base { |
+class FilePath; |
+} |
+ |
+namespace sql { |
+ |
+// Recovery module for sql/. The basic idea is that a fresh database |
+// is created, which is populated with the recovered contents of the |
+// original database, and if recovery is successful the recovered |
+// database is backed up over the original database. If recovery is |
+// not successful, the original database is razed. |
+// |
+// Usage is something like: |
+// { |
+// sql::Recovery recover(orig_db); |
+// if (recover.Open(orig_db_path)) { |
+// if (recover.db()->Execute(kCreateSchemaSql) && |
+// recover.db()->Execute(kCopyDataFromOrigSql)) { |
+// recover.Recovered(); |
+// } |
+// } |
+// } |
+// |
+// If Recovered() does not return successfully, then RazeAndClose() is |
+// called on orig_db. |
+ |
+ |
+// TODO(shess): Move the scoper to a separate file. |
+class SQL_EXPORT Recovery { |
erikwright (departed)
2013/07/05 19:02:30
An idiom I've been using from time to time is like
Scott Hess - ex-Googler
2013/07/08 21:41:51
I'll prototype that and see how it looks. My main
|
+ public: |
+ // TODO(shess): Allow specifying the attachment point? |
+ explicit Recovery(Connection* connection); |
+ ~Recovery(); |
+ |
+ // TODO(shess): Later versions of SQLite allow querying for the |
+ // existing db's path. |
+ bool Open(const base::FilePath& db_path) WARN_UNUSED_RESULT; |
+ |
+ // Mark recovery completed by replicating the recovery database over |
+ // the original database, then closing the recovery database. The |
+ // original database is closed and the handle poisoned, causing |
+ // future calls against it to fail. |
+ // |
+ // If this is not called before the object goes out of scope, the |
+ // destructor will call Unrecoverable(). |
+ // TODO(shess): What does it mean for this to fail? Should there be |
+ // an option for "Bail out without razing the original database"? |
+ bool Recovered() WARN_UNUSED_RESULT; |
+ |
+ // Indicate that the database is unrecoverable. The original |
+ // database is razed, and the handle is closed and poisoned. The |
+ // recovery database is also closed. |
+ void Unrecoverable(); |
+ |
+ // Handle to the temporary recovery database. |
+ sql::Connection* db() { return &recover_db_; } |
+ |
+ private: |
+ Connection* db_; |
+ Connection recover_db_; |
+ ScopedAttach attach_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Recovery); |
+}; |
+ |
+} // namespace sql |
+ |
+#endif // SQL_RECOVERY_H_ |