Put debugging assertions into sql::Statement.

Pulls out the core of gbillock's http://codereview.chromium.org/8283002/
- Move NOTREACHED and similar checks into the sql:: implementation code.
- Add malformed SQL checks to Connection::Execute.
- Add SQL-checking convenience methods to Connection.

The general idea is that the sql:: framework assumes valid statements,
rather than having client code contain scattered ad-hoc (and thus
inconsistent) checks.

This version puts back Statement operator overloading and loosy-goosy
Execute() calls to allow other code to be updated in small batches.

R=gbillock@chromium.org,jhawkins@chromium.org,dhollowa@chromium.org 
BUG=none
TEST=sql_unittests,unit_tests:*Table*.*


Review URL: http://codereview.chromium.org/8899012

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114118 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/sql/statement.h b/sql/statement.h
index 4a73578..97fdb5e 100644
--- a/sql/statement.h
+++ b/sql/statement.h
@@ -29,13 +29,16 @@
 
 // Normal usage:
 //   sql::Statement s(connection_.GetUniqueStatement(...));
-//   if (!s)  // You should check for errors before using the statement.
-//     return false;
-//
 //   s.BindInt(0, a);
 //   if (s.Step())
 //     return s.ColumnString(0);
 //
+//   If there are errors getting the statement, the statement will be inert; no
+//   mutating or database-access methods will work. If you need to check for
+//   validity, use:
+//   if (!s.is_valid())
+//     return false;
+//
 // Step() and Run() just return true to signal success. If you want to handle
 // specific errors such as database corruption, install an error handler in
 // in the connection object using set_error_delegate().
@@ -61,6 +64,7 @@
 
   // These operators allow conveniently checking if the statement is valid
   // or not. See the pattern above for an example.
+  // TODO(shess,gbillock): Remove these once clients are converted.
   operator bool() const { return is_valid(); }
   bool operator!() const { return !is_valid(); }
 
@@ -96,7 +100,7 @@
 
   // Binding -------------------------------------------------------------------
 
-  // These all take a 0-based argument index and return true on failure. You
+  // These all take a 0-based argument index and return true on success. You
   // may not always care about the return value (they'll DCHECK if they fail).
   // The main thing you may want to check is when binding large blobs or
   // strings there may be out of memory.
@@ -137,8 +141,8 @@
   int ColumnByteLength(int col) const;
   const void* ColumnBlob(int col) const;
   bool ColumnBlobAsString(int col, std::string* blob);
-  void ColumnBlobAsVector(int col, std::vector<char>* val) const;
-  void ColumnBlobAsVector(int col, std::vector<unsigned char>* val) const;
+  bool ColumnBlobAsVector(int col, std::vector<char>* val) const;
+  bool ColumnBlobAsVector(int col, std::vector<unsigned char>* val) const;
 
   // Diagnostics --------------------------------------------------------------
 
@@ -152,6 +156,24 @@
   // enhanced in the future to do the notification.
   int CheckError(int err);
 
+  // Contraction for checking an error code against SQLITE_OK. Does not set the
+  // succeeded flag.
+  bool CheckOk(int err) const;
+
+  // Should be called by all mutating methods to check that the statement is
+  // valid. Returns true if the statement is valid. DCHECKS and returns false
+  // if it is not.
+  // The reason for this is to handle two specific cases in which a Statement
+  // may be invalid. The first case is that the programmer made an SQL error.
+  // Those cases need to be DCHECKed so that we are guaranteed to find them
+  // before release. The second case is that the computer has an error (probably
+  // out of disk space) which is prohibiting the correct operation of the
+  // database. Our testing apparatus should not exhibit this defect, but release
+  // situations may. Therefore, the code is handling disjoint situations in
+  // release and test. In test, we're ensuring correct SQL. In release, we're
+  // ensuring that contracts are honored in error edge cases.
+  bool CheckValid() const;
+
   // The actual sqlite statement. This may be unique to us, or it may be cached
   // by the connection, which is why it's refcounted. This pointer is
   // guaranteed non-NULL.