SQLite: Add support for WAL mode

As per issue 78507, we are looking to add support for SQLite databases
to use Write-ahead logging (https://www.sqlite.org/wal.html) mode in
Chromium. WAL mode should give us significant performance gains across
almost all use-cases.

This change is a first step towards achieving this. It adds opt-in
support to enable WAL mode for a database connection and perform a
checkpoint. It also adds a feature flag to enable WAL mode for all
databases by default to investigate its feasibility and impact on
performance.

Bug: 78507
Change-Id: I7fc5edcc39b50d2a13755d587cf342bded1af60a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095927
Commit-Queue: Shubham Aggarwal <[email protected]>
Reviewed-by: Brandon Maslen <[email protected]>
Reviewed-by: Victor Costan <[email protected]>
Reviewed-by: Chris Mumford <[email protected]>
Cr-Commit-Position: refs/heads/master@{#780318}
diff --git a/sql/database.h b/sql/database.h
index 18ccdcd..2bf8652f 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -88,6 +88,23 @@
     cache_size_ = cache_size;
   }
 
+  // Returns whether a database will be opened in WAL mode.
+  bool UseWALMode() const;
+
+  // Enables/disables WAL mode (https://www.sqlite.org/wal.html) when
+  // opening a new database.
+  //
+  // WAL mode is currently not fully supported on FuchsiaOS. It will only be
+  // turned on if the database is also using exclusive locking mode.
+  // (https://crbug.com/1082059)
+  //
+  // Note: Changing page size is not supported when in WAL mode. So running
+  // 'PRAGMA page_size = <new-size>' or using set_page_size will result in
+  // no-ops.
+  //
+  // This must be called before Open() to have an effect.
+  void want_wal_mode(bool enabled) { want_wal_mode_ = enabled; }
+
   // Call to put the database in exclusive locking mode. There is no "back to
   // normal" flag because of some additional requirements sqlite puts on this
   // transaction (requires another access to the DB) and because we don't
@@ -396,6 +413,14 @@
   // See GetCachedStatement above for examples and error information.
   scoped_refptr<StatementRef> GetUniqueStatement(const char* sql);
 
+  // Performs a passive checkpoint on the main attached database if it is in
+  // WAL mode. Returns true if the checkpoint was successful and false in case
+  // of an error. It is a no-op if the database is not in WAL mode.
+  //
+  // Note: Checkpointing is a very slow operation and will block any writes
+  // until it is finished. Please use with care.
+  bool CheckpointDatabase();
+
   // Info querying -------------------------------------------------------------
 
   // Returns true if the given structure exists.  Instead of test-then-create,
@@ -693,7 +718,9 @@
   // use the default value.
   int page_size_;
   int cache_size_;
+
   bool exclusive_locking_;
+  bool want_wal_mode_;
 
   // Holds references to all cached statements so they remain active.
   //