xref: /src/contrib/kyua/utils/sqlite/statement.cpp (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
108334c51SBrooks Davis // Copyright 2011 The Kyua Authors.
208334c51SBrooks Davis // All rights reserved.
308334c51SBrooks Davis //
408334c51SBrooks Davis // Redistribution and use in source and binary forms, with or without
508334c51SBrooks Davis // modification, are permitted provided that the following conditions are
608334c51SBrooks Davis // met:
708334c51SBrooks Davis //
808334c51SBrooks Davis // * Redistributions of source code must retain the above copyright
908334c51SBrooks Davis //   notice, this list of conditions and the following disclaimer.
1008334c51SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
1108334c51SBrooks Davis //   notice, this list of conditions and the following disclaimer in the
1208334c51SBrooks Davis //   documentation and/or other materials provided with the distribution.
1308334c51SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
1408334c51SBrooks Davis //   may be used to endorse or promote products derived from this software
1508334c51SBrooks Davis //   without specific prior written permission.
1608334c51SBrooks Davis //
1708334c51SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1808334c51SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1908334c51SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2008334c51SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2108334c51SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2208334c51SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2308334c51SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2408334c51SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2508334c51SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2608334c51SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2708334c51SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2808334c51SBrooks Davis 
2908334c51SBrooks Davis #include "utils/sqlite/statement.hpp"
3008334c51SBrooks Davis 
3108334c51SBrooks Davis extern "C" {
3208334c51SBrooks Davis #include <sqlite3.h>
3308334c51SBrooks Davis }
3408334c51SBrooks Davis 
3508334c51SBrooks Davis #include <map>
3608334c51SBrooks Davis 
3708334c51SBrooks Davis #include "utils/defs.hpp"
3808334c51SBrooks Davis #include "utils/format/macros.hpp"
3908334c51SBrooks Davis #include "utils/logging/macros.hpp"
4008334c51SBrooks Davis #include "utils/noncopyable.hpp"
4108334c51SBrooks Davis #include "utils/sanity.hpp"
4208334c51SBrooks Davis #include "utils/sqlite/c_gate.hpp"
4308334c51SBrooks Davis #include "utils/sqlite/database.hpp"
4408334c51SBrooks Davis #include "utils/sqlite/exceptions.hpp"
4508334c51SBrooks Davis 
4608334c51SBrooks Davis namespace sqlite = utils::sqlite;
4708334c51SBrooks Davis 
4808334c51SBrooks Davis 
4908334c51SBrooks Davis namespace {
5008334c51SBrooks Davis 
5108334c51SBrooks Davis 
5208334c51SBrooks Davis static sqlite::type c_type_to_cxx(const int) UTILS_PURE;
5308334c51SBrooks Davis 
5408334c51SBrooks Davis 
5508334c51SBrooks Davis /// Maps a SQLite 3 data type to our own representation.
5608334c51SBrooks Davis ///
5708334c51SBrooks Davis /// \param original The native SQLite 3 data type.
5808334c51SBrooks Davis ///
5908334c51SBrooks Davis /// \return Our internal representation for the native data type.
6008334c51SBrooks Davis static sqlite::type
c_type_to_cxx(const int original)6108334c51SBrooks Davis c_type_to_cxx(const int original)
6208334c51SBrooks Davis {
6308334c51SBrooks Davis     switch (original) {
6408334c51SBrooks Davis     case SQLITE_BLOB: return sqlite::type_blob;
6508334c51SBrooks Davis     case SQLITE_FLOAT: return sqlite::type_float;
6608334c51SBrooks Davis     case SQLITE_INTEGER: return sqlite::type_integer;
6708334c51SBrooks Davis     case SQLITE_NULL: return sqlite::type_null;
6808334c51SBrooks Davis     case SQLITE_TEXT: return sqlite::type_text;
6908334c51SBrooks Davis     default: UNREACHABLE_MSG("Unknown data type returned by SQLite 3");
7008334c51SBrooks Davis     }
7108334c51SBrooks Davis     UNREACHABLE;
7208334c51SBrooks Davis }
7308334c51SBrooks Davis 
7408334c51SBrooks Davis 
7508334c51SBrooks Davis /// Handles the return value of a sqlite3_bind_* call.
7608334c51SBrooks Davis ///
7708334c51SBrooks Davis /// \param db The database the call was made on.
7808334c51SBrooks Davis /// \param api_function The name of the sqlite3_bind_* function called.
7908334c51SBrooks Davis /// \param error The error code returned by the function; can be SQLITE_OK.
8008334c51SBrooks Davis ///
8108334c51SBrooks Davis /// \throw std::bad_alloc If there was no memory for the binding.
8208334c51SBrooks Davis /// \throw api_error If the binding fails for any other reason.
8308334c51SBrooks Davis static void
handle_bind_error(sqlite::database & db,const char * api_function,const int error)8408334c51SBrooks Davis handle_bind_error(sqlite::database& db, const char* api_function,
8508334c51SBrooks Davis                   const int error)
8608334c51SBrooks Davis {
8708334c51SBrooks Davis     switch (error) {
8808334c51SBrooks Davis     case SQLITE_OK:
8908334c51SBrooks Davis         return;
9008334c51SBrooks Davis     case SQLITE_RANGE:
9108334c51SBrooks Davis         UNREACHABLE_MSG("Invalid index for bind argument");
9208334c51SBrooks Davis     case SQLITE_NOMEM:
9308334c51SBrooks Davis         throw std::bad_alloc();
9408334c51SBrooks Davis     default:
9508334c51SBrooks Davis         throw sqlite::api_error::from_database(db, api_function);
9608334c51SBrooks Davis     }
9708334c51SBrooks Davis }
9808334c51SBrooks Davis 
9908334c51SBrooks Davis 
10008334c51SBrooks Davis }  // anonymous namespace
10108334c51SBrooks Davis 
10208334c51SBrooks Davis 
10308334c51SBrooks Davis /// Internal implementation for sqlite::statement.
10408334c51SBrooks Davis struct utils::sqlite::statement::impl : utils::noncopyable {
10508334c51SBrooks Davis     /// The database this statement belongs to.
10608334c51SBrooks Davis     sqlite::database& db;
10708334c51SBrooks Davis 
10808334c51SBrooks Davis     /// The SQLite 3 internal statement.
10908334c51SBrooks Davis     ::sqlite3_stmt* stmt;
11008334c51SBrooks Davis 
11108334c51SBrooks Davis     /// Cache for the column names in a statement; lazily initialized.
11208334c51SBrooks Davis     std::map< std::string, int > column_cache;
11308334c51SBrooks Davis 
11408334c51SBrooks Davis     /// Constructor.
11508334c51SBrooks Davis     ///
11608334c51SBrooks Davis     /// \param db_ The database this statement belongs to.  Be aware that we
11708334c51SBrooks Davis     ///     keep a *reference* to the database; in other words, if the database
11808334c51SBrooks Davis     ///     vanishes, this object will become invalid.  (It'd be trivial to keep
11908334c51SBrooks Davis     ///     a shallow copy here instead, but I feel that statements that outlive
12008334c51SBrooks Davis     ///     their database represents sloppy programming.)
12108334c51SBrooks Davis     /// \param stmt_ The SQLite internal statement.
implutils::sqlite::statement::impl12208334c51SBrooks Davis     impl(database& db_, ::sqlite3_stmt* stmt_) :
12308334c51SBrooks Davis         db(db_),
12408334c51SBrooks Davis         stmt(stmt_)
12508334c51SBrooks Davis     {
12608334c51SBrooks Davis     }
12708334c51SBrooks Davis 
12808334c51SBrooks Davis     /// Destructor.
12908334c51SBrooks Davis     ///
13008334c51SBrooks Davis     /// It is important to keep this as part of the 'impl' class instead of the
13108334c51SBrooks Davis     /// container class.  The 'impl' class is destroyed exactly once (because it
13208334c51SBrooks Davis     /// is managed by a shared_ptr) and thus releasing the resources here is
13308334c51SBrooks Davis     /// OK.  However, the container class is potentially released many times,
13408334c51SBrooks Davis     /// which means that we would be double-freeing the internal object and
13508334c51SBrooks Davis     /// reusing invalid data.
~implutils::sqlite::statement::impl13608334c51SBrooks Davis     ~impl(void)
13708334c51SBrooks Davis     {
13808334c51SBrooks Davis         (void)::sqlite3_finalize(stmt);
13908334c51SBrooks Davis     }
14008334c51SBrooks Davis };
14108334c51SBrooks Davis 
14208334c51SBrooks Davis 
14308334c51SBrooks Davis /// Initializes a statement object.
14408334c51SBrooks Davis ///
14508334c51SBrooks Davis /// This is an internal function.  Use database::create_statement() to
14608334c51SBrooks Davis /// instantiate one of these objects.
14708334c51SBrooks Davis ///
14808334c51SBrooks Davis /// \param db The database this statement belongs to.
14908334c51SBrooks Davis /// \param raw_stmt A void pointer representing a SQLite native statement of
15008334c51SBrooks Davis ///     type sqlite3_stmt.
statement(database & db,void * raw_stmt)15108334c51SBrooks Davis sqlite::statement::statement(database& db, void* raw_stmt) :
15208334c51SBrooks Davis     _pimpl(new impl(db, static_cast< ::sqlite3_stmt* >(raw_stmt)))
15308334c51SBrooks Davis {
15408334c51SBrooks Davis }
15508334c51SBrooks Davis 
15608334c51SBrooks Davis 
15708334c51SBrooks Davis /// Destructor for the statement.
15808334c51SBrooks Davis ///
15908334c51SBrooks Davis /// Remember that statements are reference-counted, so the statement will only
16008334c51SBrooks Davis /// cease to be valid once its last copy is destroyed.
~statement(void)16108334c51SBrooks Davis sqlite::statement::~statement(void)
16208334c51SBrooks Davis {
16308334c51SBrooks Davis }
16408334c51SBrooks Davis 
16508334c51SBrooks Davis 
16608334c51SBrooks Davis /// Executes a statement that is not supposed to return any data.
16708334c51SBrooks Davis ///
16808334c51SBrooks Davis /// Use this function to execute DDL and INSERT statements; i.e. statements that
16908334c51SBrooks Davis /// only have one processing step and deliver no rows.  This frees the caller
17008334c51SBrooks Davis /// from having to deal with the return value of the step() function.
17108334c51SBrooks Davis ///
17208334c51SBrooks Davis /// \pre The statement to execute will not produce any rows.
17308334c51SBrooks Davis void
step_without_results(void)17408334c51SBrooks Davis sqlite::statement::step_without_results(void)
17508334c51SBrooks Davis {
17608334c51SBrooks Davis     const bool data = step();
17708334c51SBrooks Davis     INV_MSG(!data, "The statement should not have produced any rows, but it "
17808334c51SBrooks Davis             "did");
17908334c51SBrooks Davis }
18008334c51SBrooks Davis 
18108334c51SBrooks Davis 
18208334c51SBrooks Davis /// Performs a processing step on the statement.
18308334c51SBrooks Davis ///
18408334c51SBrooks Davis /// \return True if the statement returned a row; false if the processing has
18508334c51SBrooks Davis /// finished.
18608334c51SBrooks Davis ///
18708334c51SBrooks Davis /// \throw api_error If the processing of the step raises an error.
18808334c51SBrooks Davis bool
step(void)18908334c51SBrooks Davis sqlite::statement::step(void)
19008334c51SBrooks Davis {
19108334c51SBrooks Davis     const int error = ::sqlite3_step(_pimpl->stmt);
19208334c51SBrooks Davis     switch (error) {
19308334c51SBrooks Davis     case SQLITE_DONE:
19408334c51SBrooks Davis         LD("Step statement; no more rows");
19508334c51SBrooks Davis         return false;
19608334c51SBrooks Davis     case SQLITE_ROW:
19708334c51SBrooks Davis         LD("Step statement; row available for processing");
19808334c51SBrooks Davis         return true;
19908334c51SBrooks Davis     default:
20008334c51SBrooks Davis         throw api_error::from_database(_pimpl->db, "sqlite3_step");
20108334c51SBrooks Davis     }
20208334c51SBrooks Davis     UNREACHABLE;
20308334c51SBrooks Davis }
20408334c51SBrooks Davis 
20508334c51SBrooks Davis 
20608334c51SBrooks Davis /// Returns the number of columns in the step result.
20708334c51SBrooks Davis ///
20808334c51SBrooks Davis /// \return The number of columns available for data retrieval.
20908334c51SBrooks Davis int
column_count(void)21008334c51SBrooks Davis sqlite::statement::column_count(void)
21108334c51SBrooks Davis {
21208334c51SBrooks Davis     return ::sqlite3_column_count(_pimpl->stmt);
21308334c51SBrooks Davis }
21408334c51SBrooks Davis 
21508334c51SBrooks Davis 
21608334c51SBrooks Davis /// Returns the name of a particular column in the result.
21708334c51SBrooks Davis ///
21808334c51SBrooks Davis /// \param index The column to request the name of.
21908334c51SBrooks Davis ///
22008334c51SBrooks Davis /// \return The name of the requested column.
22108334c51SBrooks Davis std::string
column_name(const int index)22208334c51SBrooks Davis sqlite::statement::column_name(const int index)
22308334c51SBrooks Davis {
22408334c51SBrooks Davis     const char* name = ::sqlite3_column_name(_pimpl->stmt, index);
22508334c51SBrooks Davis     if (name == NULL)
22608334c51SBrooks Davis         throw api_error::from_database(_pimpl->db, "sqlite3_column_name");
22708334c51SBrooks Davis     return name;
22808334c51SBrooks Davis }
22908334c51SBrooks Davis 
23008334c51SBrooks Davis 
23108334c51SBrooks Davis /// Returns the type of a particular column in the result.
23208334c51SBrooks Davis ///
23308334c51SBrooks Davis /// \param index The column to request the type of.
23408334c51SBrooks Davis ///
23508334c51SBrooks Davis /// \return The type of the requested column.
23608334c51SBrooks Davis sqlite::type
column_type(const int index)23708334c51SBrooks Davis sqlite::statement::column_type(const int index)
23808334c51SBrooks Davis {
23908334c51SBrooks Davis     return c_type_to_cxx(::sqlite3_column_type(_pimpl->stmt, index));
24008334c51SBrooks Davis }
24108334c51SBrooks Davis 
24208334c51SBrooks Davis 
24308334c51SBrooks Davis /// Finds a column by name.
24408334c51SBrooks Davis ///
24508334c51SBrooks Davis /// \param name The name of the column to search for.
24608334c51SBrooks Davis ///
24708334c51SBrooks Davis /// \return The column identifier.
24808334c51SBrooks Davis ///
24908334c51SBrooks Davis /// \throw value_error If the name cannot be found.
25008334c51SBrooks Davis int
column_id(const char * name)25108334c51SBrooks Davis sqlite::statement::column_id(const char* name)
25208334c51SBrooks Davis {
25308334c51SBrooks Davis     std::map< std::string, int >& cache = _pimpl->column_cache;
25408334c51SBrooks Davis 
25508334c51SBrooks Davis     if (cache.empty()) {
25608334c51SBrooks Davis         for (int i = 0; i < column_count(); i++) {
25708334c51SBrooks Davis             const std::string aux_name = column_name(i);
25808334c51SBrooks Davis             INV(cache.find(aux_name) == cache.end());
25908334c51SBrooks Davis             cache[aux_name] = i;
26008334c51SBrooks Davis         }
26108334c51SBrooks Davis     }
26208334c51SBrooks Davis 
26308334c51SBrooks Davis     const std::map< std::string, int >::const_iterator iter = cache.find(name);
26408334c51SBrooks Davis     if (iter == cache.end())
26508334c51SBrooks Davis         throw invalid_column_error(_pimpl->db.db_filename(), name);
26608334c51SBrooks Davis     else
26708334c51SBrooks Davis         return (*iter).second;
26808334c51SBrooks Davis }
26908334c51SBrooks Davis 
27008334c51SBrooks Davis 
27108334c51SBrooks Davis /// Returns a particular column in the result as a blob.
27208334c51SBrooks Davis ///
27308334c51SBrooks Davis /// \param index The column to retrieve.
27408334c51SBrooks Davis ///
27508334c51SBrooks Davis /// \return A block of memory with the blob contents.  Note that the pointer
27608334c51SBrooks Davis /// returned by this call will be invalidated on the next call to any SQLite API
27708334c51SBrooks Davis /// function.
27808334c51SBrooks Davis sqlite::blob
column_blob(const int index)27908334c51SBrooks Davis sqlite::statement::column_blob(const int index)
28008334c51SBrooks Davis {
28108334c51SBrooks Davis     PRE(column_type(index) == type_blob);
28208334c51SBrooks Davis     return blob(::sqlite3_column_blob(_pimpl->stmt, index),
28308334c51SBrooks Davis                 ::sqlite3_column_bytes(_pimpl->stmt, index));
28408334c51SBrooks Davis }
28508334c51SBrooks Davis 
28608334c51SBrooks Davis 
28708334c51SBrooks Davis /// Returns a particular column in the result as a double.
28808334c51SBrooks Davis ///
28908334c51SBrooks Davis /// \param index The column to retrieve.
29008334c51SBrooks Davis ///
29108334c51SBrooks Davis /// \return The double value.
29208334c51SBrooks Davis double
column_double(const int index)29308334c51SBrooks Davis sqlite::statement::column_double(const int index)
29408334c51SBrooks Davis {
29508334c51SBrooks Davis     PRE(column_type(index) == type_float);
29608334c51SBrooks Davis     return ::sqlite3_column_double(_pimpl->stmt, index);
29708334c51SBrooks Davis }
29808334c51SBrooks Davis 
29908334c51SBrooks Davis 
30008334c51SBrooks Davis /// Returns a particular column in the result as an integer.
30108334c51SBrooks Davis ///
30208334c51SBrooks Davis /// \param index The column to retrieve.
30308334c51SBrooks Davis ///
30408334c51SBrooks Davis /// \return The integer value.  Note that the value may not fit in an integer
30508334c51SBrooks Davis /// depending on the platform.  Use column_int64 to retrieve the integer without
30608334c51SBrooks Davis /// truncation.
30708334c51SBrooks Davis int
column_int(const int index)30808334c51SBrooks Davis sqlite::statement::column_int(const int index)
30908334c51SBrooks Davis {
31008334c51SBrooks Davis     PRE(column_type(index) == type_integer);
31108334c51SBrooks Davis     return ::sqlite3_column_int(_pimpl->stmt, index);
31208334c51SBrooks Davis }
31308334c51SBrooks Davis 
31408334c51SBrooks Davis 
31508334c51SBrooks Davis /// Returns a particular column in the result as a 64-bit integer.
31608334c51SBrooks Davis ///
31708334c51SBrooks Davis /// \param index The column to retrieve.
31808334c51SBrooks Davis ///
31908334c51SBrooks Davis /// \return The integer value.
32008334c51SBrooks Davis int64_t
column_int64(const int index)32108334c51SBrooks Davis sqlite::statement::column_int64(const int index)
32208334c51SBrooks Davis {
32308334c51SBrooks Davis     PRE(column_type(index) == type_integer);
32408334c51SBrooks Davis     return ::sqlite3_column_int64(_pimpl->stmt, index);
32508334c51SBrooks Davis }
32608334c51SBrooks Davis 
32708334c51SBrooks Davis 
32808334c51SBrooks Davis /// Returns a particular column in the result as a double.
32908334c51SBrooks Davis ///
33008334c51SBrooks Davis /// \param index The column to retrieve.
33108334c51SBrooks Davis ///
33208334c51SBrooks Davis /// \return A C string with the contents.  Note that the pointer returned by
33308334c51SBrooks Davis /// this call will be invalidated on the next call to any SQLite API function.
33408334c51SBrooks Davis /// If you want to be extra safe, store the result in a std::string to not worry
33508334c51SBrooks Davis /// about this.
33608334c51SBrooks Davis std::string
column_text(const int index)33708334c51SBrooks Davis sqlite::statement::column_text(const int index)
33808334c51SBrooks Davis {
33908334c51SBrooks Davis     PRE(column_type(index) == type_text);
34008334c51SBrooks Davis     return reinterpret_cast< const char* >(::sqlite3_column_text(
34108334c51SBrooks Davis         _pimpl->stmt, index));
34208334c51SBrooks Davis }
34308334c51SBrooks Davis 
34408334c51SBrooks Davis 
34508334c51SBrooks Davis /// Returns the number of bytes stored in the column.
34608334c51SBrooks Davis ///
34708334c51SBrooks Davis /// \pre This is only valid for columns of type blob and text.
34808334c51SBrooks Davis ///
34908334c51SBrooks Davis /// \param index The column to retrieve the size of.
35008334c51SBrooks Davis ///
35108334c51SBrooks Davis /// \return The number of bytes in the column.  Remember that strings are stored
35208334c51SBrooks Davis /// in their UTF-8 representation; this call returns the number of *bytes*, not
35308334c51SBrooks Davis /// characters.
35408334c51SBrooks Davis int
column_bytes(const int index)35508334c51SBrooks Davis sqlite::statement::column_bytes(const int index)
35608334c51SBrooks Davis {
35708334c51SBrooks Davis     PRE(column_type(index) == type_blob || column_type(index) == type_text);
35808334c51SBrooks Davis     return ::sqlite3_column_bytes(_pimpl->stmt, index);
35908334c51SBrooks Davis }
36008334c51SBrooks Davis 
36108334c51SBrooks Davis 
36208334c51SBrooks Davis /// Type-checked version of column_blob.
36308334c51SBrooks Davis ///
36408334c51SBrooks Davis /// \param name The name of the column to retrieve.
36508334c51SBrooks Davis ///
36608334c51SBrooks Davis /// \return The same as column_blob if the value can be retrieved.
36708334c51SBrooks Davis ///
36808334c51SBrooks Davis /// \throw error If the type of the cell to retrieve is invalid.
36908334c51SBrooks Davis /// \throw invalid_column_error If name is invalid.
37008334c51SBrooks Davis sqlite::blob
safe_column_blob(const char * name)37108334c51SBrooks Davis sqlite::statement::safe_column_blob(const char* name)
37208334c51SBrooks Davis {
37308334c51SBrooks Davis     const int column = column_id(name);
37408334c51SBrooks Davis     if (column_type(column) != sqlite::type_blob)
37508334c51SBrooks Davis         throw sqlite::error(_pimpl->db.db_filename(),
37608334c51SBrooks Davis                             F("Column '%s' is not a blob") % name);
37708334c51SBrooks Davis     return column_blob(column);
37808334c51SBrooks Davis }
37908334c51SBrooks Davis 
38008334c51SBrooks Davis 
38108334c51SBrooks Davis /// Type-checked version of column_double.
38208334c51SBrooks Davis ///
38308334c51SBrooks Davis /// \param name The name of the column to retrieve.
38408334c51SBrooks Davis ///
38508334c51SBrooks Davis /// \return The same as column_double if the value can be retrieved.
38608334c51SBrooks Davis ///
38708334c51SBrooks Davis /// \throw error If the type of the cell to retrieve is invalid.
38808334c51SBrooks Davis /// \throw invalid_column_error If name is invalid.
38908334c51SBrooks Davis double
safe_column_double(const char * name)39008334c51SBrooks Davis sqlite::statement::safe_column_double(const char* name)
39108334c51SBrooks Davis {
39208334c51SBrooks Davis     const int column = column_id(name);
39308334c51SBrooks Davis     if (column_type(column) != sqlite::type_float)
39408334c51SBrooks Davis         throw sqlite::error(_pimpl->db.db_filename(),
39508334c51SBrooks Davis                             F("Column '%s' is not a float") % name);
39608334c51SBrooks Davis     return column_double(column);
39708334c51SBrooks Davis }
39808334c51SBrooks Davis 
39908334c51SBrooks Davis 
40008334c51SBrooks Davis /// Type-checked version of column_int.
40108334c51SBrooks Davis ///
40208334c51SBrooks Davis /// \param name The name of the column to retrieve.
40308334c51SBrooks Davis ///
40408334c51SBrooks Davis /// \return The same as column_int if the value can be retrieved.
40508334c51SBrooks Davis ///
40608334c51SBrooks Davis /// \throw error If the type of the cell to retrieve is invalid.
40708334c51SBrooks Davis /// \throw invalid_column_error If name is invalid.
40808334c51SBrooks Davis int
safe_column_int(const char * name)40908334c51SBrooks Davis sqlite::statement::safe_column_int(const char* name)
41008334c51SBrooks Davis {
41108334c51SBrooks Davis     const int column = column_id(name);
41208334c51SBrooks Davis     if (column_type(column) != sqlite::type_integer)
41308334c51SBrooks Davis         throw sqlite::error(_pimpl->db.db_filename(),
41408334c51SBrooks Davis                             F("Column '%s' is not an integer") % name);
41508334c51SBrooks Davis     return column_int(column);
41608334c51SBrooks Davis }
41708334c51SBrooks Davis 
41808334c51SBrooks Davis 
41908334c51SBrooks Davis /// Type-checked version of column_int64.
42008334c51SBrooks Davis ///
42108334c51SBrooks Davis /// \param name The name of the column to retrieve.
42208334c51SBrooks Davis ///
42308334c51SBrooks Davis /// \return The same as column_int64 if the value can be retrieved.
42408334c51SBrooks Davis ///
42508334c51SBrooks Davis /// \throw error If the type of the cell to retrieve is invalid.
42608334c51SBrooks Davis /// \throw invalid_column_error If name is invalid.
42708334c51SBrooks Davis int64_t
safe_column_int64(const char * name)42808334c51SBrooks Davis sqlite::statement::safe_column_int64(const char* name)
42908334c51SBrooks Davis {
43008334c51SBrooks Davis     const int column = column_id(name);
43108334c51SBrooks Davis     if (column_type(column) != sqlite::type_integer)
43208334c51SBrooks Davis         throw sqlite::error(_pimpl->db.db_filename(),
43308334c51SBrooks Davis                             F("Column '%s' is not an integer") % name);
43408334c51SBrooks Davis     return column_int64(column);
43508334c51SBrooks Davis }
43608334c51SBrooks Davis 
43708334c51SBrooks Davis 
43808334c51SBrooks Davis /// Type-checked version of column_text.
43908334c51SBrooks Davis ///
44008334c51SBrooks Davis /// \param name The name of the column to retrieve.
44108334c51SBrooks Davis ///
44208334c51SBrooks Davis /// \return The same as column_text if the value can be retrieved.
44308334c51SBrooks Davis ///
44408334c51SBrooks Davis /// \throw error If the type of the cell to retrieve is invalid.
44508334c51SBrooks Davis /// \throw invalid_column_error If name is invalid.
44608334c51SBrooks Davis std::string
safe_column_text(const char * name)44708334c51SBrooks Davis sqlite::statement::safe_column_text(const char* name)
44808334c51SBrooks Davis {
44908334c51SBrooks Davis     const int column = column_id(name);
45008334c51SBrooks Davis     if (column_type(column) != sqlite::type_text)
45108334c51SBrooks Davis         throw sqlite::error(_pimpl->db.db_filename(),
45208334c51SBrooks Davis                             F("Column '%s' is not a string") % name);
45308334c51SBrooks Davis     return column_text(column);
45408334c51SBrooks Davis }
45508334c51SBrooks Davis 
45608334c51SBrooks Davis 
45708334c51SBrooks Davis /// Type-checked version of column_bytes.
45808334c51SBrooks Davis ///
45908334c51SBrooks Davis /// \param name The name of the column to retrieve the size of.
46008334c51SBrooks Davis ///
46108334c51SBrooks Davis /// \return The same as column_bytes if the value can be retrieved.
46208334c51SBrooks Davis ///
46308334c51SBrooks Davis /// \throw error If the type of the cell to retrieve the size of is invalid.
46408334c51SBrooks Davis /// \throw invalid_column_error If name is invalid.
46508334c51SBrooks Davis int
safe_column_bytes(const char * name)46608334c51SBrooks Davis sqlite::statement::safe_column_bytes(const char* name)
46708334c51SBrooks Davis {
46808334c51SBrooks Davis     const int column = column_id(name);
46908334c51SBrooks Davis     if (column_type(column) != sqlite::type_blob &&
47008334c51SBrooks Davis         column_type(column) != sqlite::type_text)
47108334c51SBrooks Davis         throw sqlite::error(_pimpl->db.db_filename(),
47208334c51SBrooks Davis                             F("Column '%s' is not a blob or a string") % name);
47308334c51SBrooks Davis     return column_bytes(column);
47408334c51SBrooks Davis }
47508334c51SBrooks Davis 
47608334c51SBrooks Davis 
47708334c51SBrooks Davis /// Resets a statement to allow further processing.
47808334c51SBrooks Davis void
reset(void)47908334c51SBrooks Davis sqlite::statement::reset(void)
48008334c51SBrooks Davis {
48108334c51SBrooks Davis     (void)::sqlite3_reset(_pimpl->stmt);
48208334c51SBrooks Davis }
48308334c51SBrooks Davis 
48408334c51SBrooks Davis 
48508334c51SBrooks Davis /// Binds a blob to a prepared statement.
48608334c51SBrooks Davis ///
48708334c51SBrooks Davis /// \param index The index of the binding.
48808334c51SBrooks Davis /// \param b Description of the blob, which must remain valid during the
48908334c51SBrooks Davis ///     execution of the statement.
49008334c51SBrooks Davis ///
49108334c51SBrooks Davis /// \throw api_error If the binding fails.
49208334c51SBrooks Davis void
bind(const int index,const blob & b)49308334c51SBrooks Davis sqlite::statement::bind(const int index, const blob& b)
49408334c51SBrooks Davis {
49508334c51SBrooks Davis     const int error = ::sqlite3_bind_blob(_pimpl->stmt, index, b.memory, b.size,
49608334c51SBrooks Davis                                           SQLITE_STATIC);
49708334c51SBrooks Davis     handle_bind_error(_pimpl->db, "sqlite3_bind_blob", error);
49808334c51SBrooks Davis }
49908334c51SBrooks Davis 
50008334c51SBrooks Davis 
50108334c51SBrooks Davis /// Binds a double value to a prepared statement.
50208334c51SBrooks Davis ///
50308334c51SBrooks Davis /// \param index The index of the binding.
50408334c51SBrooks Davis /// \param value The double value to bind.
50508334c51SBrooks Davis ///
50608334c51SBrooks Davis /// \throw api_error If the binding fails.
50708334c51SBrooks Davis void
bind(const int index,const double value)50808334c51SBrooks Davis sqlite::statement::bind(const int index, const double value)
50908334c51SBrooks Davis {
51008334c51SBrooks Davis     const int error = ::sqlite3_bind_double(_pimpl->stmt, index, value);
51108334c51SBrooks Davis     handle_bind_error(_pimpl->db, "sqlite3_bind_double", error);
51208334c51SBrooks Davis }
51308334c51SBrooks Davis 
51408334c51SBrooks Davis 
51508334c51SBrooks Davis /// Binds an integer value to a prepared statement.
51608334c51SBrooks Davis ///
51708334c51SBrooks Davis /// \param index The index of the binding.
51808334c51SBrooks Davis /// \param value The integer value to bind.
51908334c51SBrooks Davis ///
52008334c51SBrooks Davis /// \throw api_error If the binding fails.
52108334c51SBrooks Davis void
bind(const int index,const int value)52208334c51SBrooks Davis sqlite::statement::bind(const int index, const int value)
52308334c51SBrooks Davis {
52408334c51SBrooks Davis     const int error = ::sqlite3_bind_int(_pimpl->stmt, index, value);
52508334c51SBrooks Davis     handle_bind_error(_pimpl->db, "sqlite3_bind_int", error);
52608334c51SBrooks Davis }
52708334c51SBrooks Davis 
52808334c51SBrooks Davis 
52908334c51SBrooks Davis /// Binds a 64-bit integer value to a prepared statement.
53008334c51SBrooks Davis ///
53108334c51SBrooks Davis /// \param index The index of the binding.
53208334c51SBrooks Davis /// \param value The 64-bin integer value to bind.
53308334c51SBrooks Davis ///
53408334c51SBrooks Davis /// \throw api_error If the binding fails.
53508334c51SBrooks Davis void
bind(const int index,const int64_t value)53608334c51SBrooks Davis sqlite::statement::bind(const int index, const int64_t value)
53708334c51SBrooks Davis {
53808334c51SBrooks Davis     const int error = ::sqlite3_bind_int64(_pimpl->stmt, index, value);
53908334c51SBrooks Davis     handle_bind_error(_pimpl->db, "sqlite3_bind_int64", error);
54008334c51SBrooks Davis }
54108334c51SBrooks Davis 
54208334c51SBrooks Davis 
54308334c51SBrooks Davis /// Binds a NULL value to a prepared statement.
54408334c51SBrooks Davis ///
54508334c51SBrooks Davis /// \param index The index of the binding.
54608334c51SBrooks Davis ///
54708334c51SBrooks Davis /// \throw api_error If the binding fails.
54808334c51SBrooks Davis void
bind(const int index,const null &)54908334c51SBrooks Davis sqlite::statement::bind(const int index, const null& /* null */)
55008334c51SBrooks Davis {
55108334c51SBrooks Davis     const int error = ::sqlite3_bind_null(_pimpl->stmt, index);
55208334c51SBrooks Davis     handle_bind_error(_pimpl->db, "sqlite3_bind_null", error);
55308334c51SBrooks Davis }
55408334c51SBrooks Davis 
55508334c51SBrooks Davis 
55608334c51SBrooks Davis /// Binds a text string to a prepared statement.
55708334c51SBrooks Davis ///
55808334c51SBrooks Davis /// \param index The index of the binding.
55908334c51SBrooks Davis /// \param text The string to bind.  SQLite generates an internal copy of this
56008334c51SBrooks Davis ///     string, so the original string object does not have to remain live.  We
56108334c51SBrooks Davis ///     do this because handling the lifetime of std::string objects is very
56208334c51SBrooks Davis ///     hard (think about implicit conversions), so it is very easy to shoot
56308334c51SBrooks Davis ///     ourselves in the foot if we don't do this.
56408334c51SBrooks Davis ///
56508334c51SBrooks Davis /// \throw api_error If the binding fails.
56608334c51SBrooks Davis void
bind(const int index,const std::string & text)56708334c51SBrooks Davis sqlite::statement::bind(const int index, const std::string& text)
56808334c51SBrooks Davis {
56908334c51SBrooks Davis     const int error = ::sqlite3_bind_text(_pimpl->stmt, index, text.c_str(),
57008334c51SBrooks Davis                                           text.length(), SQLITE_TRANSIENT);
57108334c51SBrooks Davis     handle_bind_error(_pimpl->db, "sqlite3_bind_text", error);
57208334c51SBrooks Davis }
57308334c51SBrooks Davis 
57408334c51SBrooks Davis 
57508334c51SBrooks Davis /// Returns the index of the highest parameter.
57608334c51SBrooks Davis ///
57708334c51SBrooks Davis /// \return A parameter index.
57808334c51SBrooks Davis int
bind_parameter_count(void)57908334c51SBrooks Davis sqlite::statement::bind_parameter_count(void)
58008334c51SBrooks Davis {
58108334c51SBrooks Davis     return ::sqlite3_bind_parameter_count(_pimpl->stmt);
58208334c51SBrooks Davis }
58308334c51SBrooks Davis 
58408334c51SBrooks Davis 
58508334c51SBrooks Davis /// Returns the index of a named parameter.
58608334c51SBrooks Davis ///
58708334c51SBrooks Davis /// \param name The name of the parameter to be queried; must exist.
58808334c51SBrooks Davis ///
58908334c51SBrooks Davis /// \return A parameter index.
59008334c51SBrooks Davis int
bind_parameter_index(const std::string & name)59108334c51SBrooks Davis sqlite::statement::bind_parameter_index(const std::string& name)
59208334c51SBrooks Davis {
59308334c51SBrooks Davis     const int index = ::sqlite3_bind_parameter_index(_pimpl->stmt,
59408334c51SBrooks Davis                                                      name.c_str());
59508334c51SBrooks Davis     PRE_MSG(index > 0, "Parameter name not in statement");
59608334c51SBrooks Davis     return index;
59708334c51SBrooks Davis }
59808334c51SBrooks Davis 
59908334c51SBrooks Davis 
60008334c51SBrooks Davis /// Returns the name of a parameter by index.
60108334c51SBrooks Davis ///
60208334c51SBrooks Davis /// \param index The index to query; must be valid.
60308334c51SBrooks Davis ///
60408334c51SBrooks Davis /// \return The name of the parameter.
60508334c51SBrooks Davis std::string
bind_parameter_name(const int index)60608334c51SBrooks Davis sqlite::statement::bind_parameter_name(const int index)
60708334c51SBrooks Davis {
60808334c51SBrooks Davis     const char* name = ::sqlite3_bind_parameter_name(_pimpl->stmt, index);
60908334c51SBrooks Davis     PRE_MSG(name != NULL, "Index value out of range or nameless parameter");
61008334c51SBrooks Davis     return std::string(name);
61108334c51SBrooks Davis }
61208334c51SBrooks Davis 
61308334c51SBrooks Davis 
61408334c51SBrooks Davis /// Clears any bindings and releases their memory.
61508334c51SBrooks Davis void
clear_bindings(void)61608334c51SBrooks Davis sqlite::statement::clear_bindings(void)
61708334c51SBrooks Davis {
61808334c51SBrooks Davis     const int error = ::sqlite3_clear_bindings(_pimpl->stmt);
61908334c51SBrooks Davis     PRE_MSG(error == SQLITE_OK, "SQLite3 contract has changed; it should "
62008334c51SBrooks Davis             "only return SQLITE_OK");
62108334c51SBrooks Davis }
622