sql: Restrict recovery-only API in Connection with passkeys.

This CL uses the passkey idiom recommended in https://abseil.io/tips/134
to restrict APIs in sql::Connection to sql::Recovery. Test APIs are
exposed via a peer class, following recommendations in the same tip.

This CL also exposes sql::Connection::page_size(). Asides from being
used in sql::Recovery, this can be useful in unit tests. It is worth
noting that set_page_size() is a widely-used part of the sql::Connection
API, so page_size() does not introduce a new concept.

Last, in order to make page_size() intuitive, this CL removes the
possibility of having sql::Connection::page_size_ be zero. Instead,
SQLite is configured with an explicit SQLITE_DEFAULT_PAGE_SIZE (matching
the current default), and page_size_ is initialized with
sql::Connection::kDefaultPageSize, which is guaranteed to match the
SQLite configuration.

Bug: none
Change-Id: I555a0bcf02f12ee006bbfc1a91080d7c0b8845d4
Reviewed-on: https://chromium-review.googlesource.com/1146768
Commit-Queue: Victor Costan <[email protected]>
Reviewed-by: Chris Mumford <[email protected]>
Cr-Commit-Position: refs/heads/master@{#578945}
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc
index a09fe824..22c57c1 100644
--- a/sql/connection_unittest.cc
+++ b/sql/connection_unittest.cc
@@ -28,6 +28,20 @@
 #include "third_party/sqlite/sqlite3.h"
 
 namespace sql {
+
+class ConnectionTestPeer {
+ public:
+  static bool AttachDatabase(Connection* db,
+                             const base::FilePath& other_db_path,
+                             const char* attachment_point) {
+    return db->AttachDatabase(other_db_path, attachment_point,
+                              InternalApiToken());
+  }
+  static bool DetachDatabase(Connection* db, const char* attachment_point) {
+    return db->DetachDatabase(attachment_point, InternalApiToken());
+  }
+};
+
 namespace test {
 
 // Allow a test to add a SQLite function in a scoped context.
@@ -541,11 +555,7 @@
   const std::string default_page_size =
       ExecuteWithResult(&db(), "PRAGMA page_size");
 
-  // The database should have the default page size after raze.
-  EXPECT_NO_FATAL_FAILURE(
-      TestPageSize(db_path(), 0, default_page_size, 0, default_page_size));
-
-  // Sync user 32k pages.
+  // Sync uses 32k pages.
   EXPECT_NO_FATAL_FAILURE(
       TestPageSize(db_path(), 32768, "32768", 32768, "32768"));
 
@@ -558,11 +568,12 @@
   EXPECT_NO_FATAL_FAILURE(
       TestPageSize(db_path(), 2048, "2048", 4096, "4096"));
 
-  // Databases with no page size specified should result in the new default
+  // Databases with no page size specified should result in the default
   // page size.  2k has never been the default page size.
   ASSERT_NE("2048", default_page_size);
-  EXPECT_NO_FATAL_FAILURE(
-      TestPageSize(db_path(), 2048, "2048", 0, default_page_size));
+  EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 2048, "2048",
+                                       Connection::kDefaultPageSize,
+                                       default_page_size));
 }
 
 // Test that Raze() results are seen in other connections.
@@ -1003,7 +1014,8 @@
   // Cannot see the attached database, yet.
   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
 
-  EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint));
+  EXPECT_TRUE(
+      ConnectionTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
   EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
 
   // Queries can touch both databases after the ATTACH.
@@ -1014,7 +1026,7 @@
     EXPECT_EQ(1, s.ColumnInt(0));
   }
 
-  EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint));
+  EXPECT_TRUE(ConnectionTestPeer::DetachDatabase(&db(), kAttachmentPoint));
   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
 }
 
@@ -1037,7 +1049,8 @@
 
   // Attach succeeds in a transaction.
   EXPECT_TRUE(db().BeginTransaction());
-  EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint));
+  EXPECT_TRUE(
+      ConnectionTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
   EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
 
   // Queries can touch both databases after the ATTACH.
@@ -1052,14 +1065,14 @@
   {
     sql::test::ScopedErrorExpecter expecter;
     expecter.ExpectError(SQLITE_ERROR);
-    EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint));
+    EXPECT_FALSE(ConnectionTestPeer::DetachDatabase(&db(), kAttachmentPoint));
     EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
     ASSERT_TRUE(expecter.SawExpectedErrors());
   }
 
   // Detach succeeds when the transaction is closed.
   db().RollbackTransaction();
-  EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint));
+  EXPECT_TRUE(ConnectionTestPeer::DetachDatabase(&db(), kAttachmentPoint));
   EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
 }