15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQL_STATEMENT_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SQL_STATEMENT_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/connection.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/sql_export.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sql { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Possible return values from ColumnType in a statement. These should match 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the values in sqlite3.h. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ColType { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COLUMN_TYPE_INTEGER = 1, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COLUMN_TYPE_FLOAT = 2, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COLUMN_TYPE_TEXT = 3, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COLUMN_TYPE_BLOB = 4, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COLUMN_TYPE_NULL = 5, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Normal usage: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sql::Statement s(connection_.GetUniqueStatement(...)); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// s.BindInt(0, a); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (s.Step()) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return s.ColumnString(0); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there are errors getting the statement, the statement will be inert; no 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mutating or database-access methods will work. If you need to check for 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// validity, use: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (!s.is_valid()) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return false; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Step() and Run() just return true to signal success. If you want to handle 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specific errors such as database corruption, install an error handler in 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the connection object using set_error_delegate(). 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SQL_EXPORT Statement { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an uninitialized statement. The statement will be invalid until 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // you initialize it via Assign. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statement(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Statement(scoped_refptr<Connection::StatementRef> ref); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Statement(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes this object with the given statement, which may or may not 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be valid. Use is_valid() to check if it's OK. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Assign(scoped_refptr<Connection::StatementRef> ref); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resets the statement to an uninitialized state corrosponding to 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the default constructor, releasing the StatementRef. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Clear(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the statement can be executed. All functions can still 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be used if the statement is invalid, but they will return failure or some 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default value. This is because the statement can become invalid in the 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // middle of executing a command if there is a serious error and the database 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has to be reset. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_valid() const { return ref_->is_valid(); } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Running ------------------------------------------------------------------- 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Executes the statement, returning true on success. This is like Step but 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for when there is no output, like an INSERT statement. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Run(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Executes the statement, returning true if there is a row of data returned. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // You can keep calling Step() until it returns false to iterate through all 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the rows in your result set. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When Step returns false, the result is either that there is no more data 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or there is an error. This makes it most convenient for loop usage. If you 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to disambiguate these cases, use Succeeded(). 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Typical example: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // while (s.Step()) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return s.Succeeded(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Step(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resets the statement to its initial condition. This includes any current 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result row, and also the bound variables if the |clear_bound_vars| is true. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset(bool clear_bound_vars); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the last executed thing in this statement succeeded. If 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there was no last executed thing or the statement is invalid, this will 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return false. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Succeeded() const; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Binding ------------------------------------------------------------------- 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These all take a 0-based argument index and return true on success. You 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may not always care about the return value (they'll DCHECK if they fail). 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The main thing you may want to check is when binding large blobs or 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // strings there may be out of memory. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindNull(int col); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindBool(int col, bool val); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindInt(int col, int val); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindInt64(int col, int64 val); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindDouble(int col, double val); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindCString(int col, const char* val); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindString(int col, const std::string& val); 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool BindString16(int col, const base::string16& value); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BindBlob(int col, const void* value, int value_len); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieving ---------------------------------------------------------------- 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of output columns in the result. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ColumnCount() const; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the type associated with the given column. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Watch out: the type may be undefined if you've done something to cause a 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "type conversion." This means requesting the value of a column of a type 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // where that type is not the native type. For safety, call ColumnType only 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on a column before getting the value out in any way. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ColType ColumnType(int col) const; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ColType DeclaredColumnType(int col) const; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These all take a 0-based argument index. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ColumnBool(int col) const; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ColumnInt(int col) const; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 ColumnInt64(int col) const; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double ColumnDouble(int col) const; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ColumnString(int col) const; 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 ColumnString16(int col) const; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When reading a blob, you can get a raw pointer to the underlying data, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // along with the length, or you can just ask us to copy the blob into a 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // vector. Danger! ColumnBlob may return NULL if there is no data! 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ColumnByteLength(int col) const; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* ColumnBlob(int col) const; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ColumnBlobAsString(int col, std::string* blob); 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool ColumnBlobAsString16(int col, base::string16* val) const; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ColumnBlobAsVector(int col, std::vector<char>* val) const; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ColumnBlobAsVector(int col, std::vector<unsigned char>* val) const; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Diagnostics -------------------------------------------------------------- 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the original text of sql statement. Do not keep a pointer to it. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* GetSQLStatement(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is intended to check for serious errors and report them to the 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // connection object. It takes a sqlite error code, and returns the same 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code. Currently this function just updates the succeeded flag, but will be 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enhanced in the future to do the notification. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int CheckError(int err); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Contraction for checking an error code against SQLITE_OK. Does not set the 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succeeded flag. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CheckOk(int err) const; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should be called by all mutating methods to check that the statement is 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // valid. Returns true if the statement is valid. DCHECKS and returns false 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if it is not. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The reason for this is to handle two specific cases in which a Statement 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may be invalid. The first case is that the programmer made an SQL error. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Those cases need to be DCHECKed so that we are guaranteed to find them 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before release. The second case is that the computer has an error (probably 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // out of disk space) which is prohibiting the correct operation of the 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // database. Our testing apparatus should not exhibit this defect, but release 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // situations may. Therefore, the code is handling disjoint situations in 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release and test. In test, we're ensuring correct SQL. In release, we're 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ensuring that contracts are honored in error edge cases. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CheckValid() const; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual sqlite statement. This may be unique to us, or it may be cached 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the connection, which is why it's refcounted. This pointer is 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // guaranteed non-NULL. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Connection::StatementRef> ref_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Set after Step() or Run() are called, reset by Reset(). Used to 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // prevent accidental calls to API functions which would not work 1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // correctly after stepping has started. 1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool stepped_; 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See Succeeded() for what this holds. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool succeeded_; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Statement); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sql 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SQL_STATEMENT_H_ 195