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

Unified Diff: sql/recovery.h

Issue 19281002: [sql] Scoped recovery framework. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to match Open() retry logic. Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sql/connection_unittest.cc ('k') | sql/recovery.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sql/recovery.h
diff --git a/sql/recovery.h b/sql/recovery.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f33719c16a68b86ddd65cac64870f1ec63bc3e9
--- /dev/null
+++ b/sql/recovery.h
@@ -0,0 +1,106 @@
+// 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"
+
+namespace base {
+class FilePath;
+}
+
+namespace sql {
+
+// Recovery module for sql/. The basic idea is to create a fresh
+// database and populate it with the recovered contents of the
+// original database. If recovery is successful, the recovered
+// database is backed up over the original database. If recovery is
+// not successful, the original database is razed. In either case,
+// the original handle is poisoned so that operations on the stack do
+// not accidentally disrupt the restored data.
+//
+// {
+// scoped_ptr<sql::Recovery> r =
+// sql::Recovery::Begin(orig_db, orig_db_path);
+// if (r) {
+// if (r.db()->Execute(kCreateSchemaSql) &&
+// r.db()->Execute(kCopyDataFromOrigSql)) {
+// sql::Recovery::Recovered(r.Pass());
+// }
+// }
+// }
+//
+// If Recovered() is not called, then RazeAndClose() is called on
+// orig_db.
+
+class SQL_EXPORT Recovery {
+ public:
+ ~Recovery();
+
+ // Begin the recovery process by opening a temporary database handle
+ // and attach the existing database to it at "corrupt". To prevent
+ // deadlock, all transactions on |connection| are rolled back.
+ //
+ // Returns NULL in case of failure, with no cleanup done on the
+ // original connection (except for breaking the transactions). The
+ // caller should Raze() or otherwise cleanup as appropriate.
+ //
+ // TODO(shess): Later versions of SQLite allow extracting the path
+ // from the connection.
+ // TODO(shess): Allow specifying the connection point?
+ static scoped_ptr<Recovery> Begin(
+ Connection* connection,
+ 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 handle is poisoned, causing future calls
+ // against it to fail.
+ //
+ // If Recovered() is not called, the destructor will call
+ // Unrecoverable().
+ //
+ // TODO(shess): At this time, this function an fail while leaving
+ // the original database intact. Figure out which failure cases
+ // should go to RazeAndClose() instead.
+ static bool Recovered(scoped_ptr<Recovery> r) WARN_UNUSED_RESULT;
+
+ // Indicate that the database is unrecoverable. The original
+ // database is razed, and the handle poisoned.
+ static void Unrecoverable(scoped_ptr<Recovery> r);
+
+ // Handle to the temporary recovery database.
+ sql::Connection* db() { return &recover_db_; }
+
+ private:
+ explicit Recovery(Connection* connection);
+
+ // Setup the recovery database handle for Begin(). Returns false in
+ // case anything failed.
+ bool Init(const base::FilePath& db_path) WARN_UNUSED_RESULT;
+
+ // Copy the recovered database over the original database.
+ bool Backup() WARN_UNUSED_RESULT;
+
+ // Close the recovery database, and poison the original handle.
+ // |raze| controls whether the original database is razed or just
+ // poisoned.
+ enum Disposition {
+ RAZE_AND_POISON,
+ POISON,
+ };
+ void Shutdown(Disposition raze);
+
+ Connection* db_; // Original database connection.
+ Connection recover_db_; // Recovery connection.
+
+ DISALLOW_COPY_AND_ASSIGN(Recovery);
+};
+
+} // namespace sql
+
+#endif // SQL_RECOVERY_H_
« no previous file with comments | « sql/connection_unittest.cc ('k') | sql/recovery.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698