Path: blob/main/contrib/kyua/utils/sqlite/statement.cpp
48178 views
// Copyright 2011 The Kyua Authors.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are5// met:6//7// * Redistributions of source code must retain the above copyright8// notice, this list of conditions and the following disclaimer.9// * Redistributions in binary form must reproduce the above copyright10// notice, this list of conditions and the following disclaimer in the11// documentation and/or other materials provided with the distribution.12// * Neither the name of Google Inc. nor the names of its contributors13// may be used to endorse or promote products derived from this software14// without specific prior written permission.15//16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2728#include "utils/sqlite/statement.hpp"2930extern "C" {31#include <sqlite3.h>32}3334#include <map>3536#include "utils/defs.hpp"37#include "utils/format/macros.hpp"38#include "utils/logging/macros.hpp"39#include "utils/noncopyable.hpp"40#include "utils/sanity.hpp"41#include "utils/sqlite/c_gate.hpp"42#include "utils/sqlite/database.hpp"43#include "utils/sqlite/exceptions.hpp"4445namespace sqlite = utils::sqlite;464748namespace {495051static sqlite::type c_type_to_cxx(const int) UTILS_PURE;525354/// Maps a SQLite 3 data type to our own representation.55///56/// \param original The native SQLite 3 data type.57///58/// \return Our internal representation for the native data type.59static sqlite::type60c_type_to_cxx(const int original)61{62switch (original) {63case SQLITE_BLOB: return sqlite::type_blob;64case SQLITE_FLOAT: return sqlite::type_float;65case SQLITE_INTEGER: return sqlite::type_integer;66case SQLITE_NULL: return sqlite::type_null;67case SQLITE_TEXT: return sqlite::type_text;68default: UNREACHABLE_MSG("Unknown data type returned by SQLite 3");69}70UNREACHABLE;71}727374/// Handles the return value of a sqlite3_bind_* call.75///76/// \param db The database the call was made on.77/// \param api_function The name of the sqlite3_bind_* function called.78/// \param error The error code returned by the function; can be SQLITE_OK.79///80/// \throw std::bad_alloc If there was no memory for the binding.81/// \throw api_error If the binding fails for any other reason.82static void83handle_bind_error(sqlite::database& db, const char* api_function,84const int error)85{86switch (error) {87case SQLITE_OK:88return;89case SQLITE_RANGE:90UNREACHABLE_MSG("Invalid index for bind argument");91case SQLITE_NOMEM:92throw std::bad_alloc();93default:94throw sqlite::api_error::from_database(db, api_function);95}96}979899} // anonymous namespace100101102/// Internal implementation for sqlite::statement.103struct utils::sqlite::statement::impl : utils::noncopyable {104/// The database this statement belongs to.105sqlite::database& db;106107/// The SQLite 3 internal statement.108::sqlite3_stmt* stmt;109110/// Cache for the column names in a statement; lazily initialized.111std::map< std::string, int > column_cache;112113/// Constructor.114///115/// \param db_ The database this statement belongs to. Be aware that we116/// keep a *reference* to the database; in other words, if the database117/// vanishes, this object will become invalid. (It'd be trivial to keep118/// a shallow copy here instead, but I feel that statements that outlive119/// their database represents sloppy programming.)120/// \param stmt_ The SQLite internal statement.121impl(database& db_, ::sqlite3_stmt* stmt_) :122db(db_),123stmt(stmt_)124{125}126127/// Destructor.128///129/// It is important to keep this as part of the 'impl' class instead of the130/// container class. The 'impl' class is destroyed exactly once (because it131/// is managed by a shared_ptr) and thus releasing the resources here is132/// OK. However, the container class is potentially released many times,133/// which means that we would be double-freeing the internal object and134/// reusing invalid data.135~impl(void)136{137(void)::sqlite3_finalize(stmt);138}139};140141142/// Initializes a statement object.143///144/// This is an internal function. Use database::create_statement() to145/// instantiate one of these objects.146///147/// \param db The database this statement belongs to.148/// \param raw_stmt A void pointer representing a SQLite native statement of149/// type sqlite3_stmt.150sqlite::statement::statement(database& db, void* raw_stmt) :151_pimpl(new impl(db, static_cast< ::sqlite3_stmt* >(raw_stmt)))152{153}154155156/// Destructor for the statement.157///158/// Remember that statements are reference-counted, so the statement will only159/// cease to be valid once its last copy is destroyed.160sqlite::statement::~statement(void)161{162}163164165/// Executes a statement that is not supposed to return any data.166///167/// Use this function to execute DDL and INSERT statements; i.e. statements that168/// only have one processing step and deliver no rows. This frees the caller169/// from having to deal with the return value of the step() function.170///171/// \pre The statement to execute will not produce any rows.172void173sqlite::statement::step_without_results(void)174{175const bool data = step();176INV_MSG(!data, "The statement should not have produced any rows, but it "177"did");178}179180181/// Performs a processing step on the statement.182///183/// \return True if the statement returned a row; false if the processing has184/// finished.185///186/// \throw api_error If the processing of the step raises an error.187bool188sqlite::statement::step(void)189{190const int error = ::sqlite3_step(_pimpl->stmt);191switch (error) {192case SQLITE_DONE:193LD("Step statement; no more rows");194return false;195case SQLITE_ROW:196LD("Step statement; row available for processing");197return true;198default:199throw api_error::from_database(_pimpl->db, "sqlite3_step");200}201UNREACHABLE;202}203204205/// Returns the number of columns in the step result.206///207/// \return The number of columns available for data retrieval.208int209sqlite::statement::column_count(void)210{211return ::sqlite3_column_count(_pimpl->stmt);212}213214215/// Returns the name of a particular column in the result.216///217/// \param index The column to request the name of.218///219/// \return The name of the requested column.220std::string221sqlite::statement::column_name(const int index)222{223const char* name = ::sqlite3_column_name(_pimpl->stmt, index);224if (name == NULL)225throw api_error::from_database(_pimpl->db, "sqlite3_column_name");226return name;227}228229230/// Returns the type of a particular column in the result.231///232/// \param index The column to request the type of.233///234/// \return The type of the requested column.235sqlite::type236sqlite::statement::column_type(const int index)237{238return c_type_to_cxx(::sqlite3_column_type(_pimpl->stmt, index));239}240241242/// Finds a column by name.243///244/// \param name The name of the column to search for.245///246/// \return The column identifier.247///248/// \throw value_error If the name cannot be found.249int250sqlite::statement::column_id(const char* name)251{252std::map< std::string, int >& cache = _pimpl->column_cache;253254if (cache.empty()) {255for (int i = 0; i < column_count(); i++) {256const std::string aux_name = column_name(i);257INV(cache.find(aux_name) == cache.end());258cache[aux_name] = i;259}260}261262const std::map< std::string, int >::const_iterator iter = cache.find(name);263if (iter == cache.end())264throw invalid_column_error(_pimpl->db.db_filename(), name);265else266return (*iter).second;267}268269270/// Returns a particular column in the result as a blob.271///272/// \param index The column to retrieve.273///274/// \return A block of memory with the blob contents. Note that the pointer275/// returned by this call will be invalidated on the next call to any SQLite API276/// function.277sqlite::blob278sqlite::statement::column_blob(const int index)279{280PRE(column_type(index) == type_blob);281return blob(::sqlite3_column_blob(_pimpl->stmt, index),282::sqlite3_column_bytes(_pimpl->stmt, index));283}284285286/// Returns a particular column in the result as a double.287///288/// \param index The column to retrieve.289///290/// \return The double value.291double292sqlite::statement::column_double(const int index)293{294PRE(column_type(index) == type_float);295return ::sqlite3_column_double(_pimpl->stmt, index);296}297298299/// Returns a particular column in the result as an integer.300///301/// \param index The column to retrieve.302///303/// \return The integer value. Note that the value may not fit in an integer304/// depending on the platform. Use column_int64 to retrieve the integer without305/// truncation.306int307sqlite::statement::column_int(const int index)308{309PRE(column_type(index) == type_integer);310return ::sqlite3_column_int(_pimpl->stmt, index);311}312313314/// Returns a particular column in the result as a 64-bit integer.315///316/// \param index The column to retrieve.317///318/// \return The integer value.319int64_t320sqlite::statement::column_int64(const int index)321{322PRE(column_type(index) == type_integer);323return ::sqlite3_column_int64(_pimpl->stmt, index);324}325326327/// Returns a particular column in the result as a double.328///329/// \param index The column to retrieve.330///331/// \return A C string with the contents. Note that the pointer returned by332/// this call will be invalidated on the next call to any SQLite API function.333/// If you want to be extra safe, store the result in a std::string to not worry334/// about this.335std::string336sqlite::statement::column_text(const int index)337{338PRE(column_type(index) == type_text);339return reinterpret_cast< const char* >(::sqlite3_column_text(340_pimpl->stmt, index));341}342343344/// Returns the number of bytes stored in the column.345///346/// \pre This is only valid for columns of type blob and text.347///348/// \param index The column to retrieve the size of.349///350/// \return The number of bytes in the column. Remember that strings are stored351/// in their UTF-8 representation; this call returns the number of *bytes*, not352/// characters.353int354sqlite::statement::column_bytes(const int index)355{356PRE(column_type(index) == type_blob || column_type(index) == type_text);357return ::sqlite3_column_bytes(_pimpl->stmt, index);358}359360361/// Type-checked version of column_blob.362///363/// \param name The name of the column to retrieve.364///365/// \return The same as column_blob if the value can be retrieved.366///367/// \throw error If the type of the cell to retrieve is invalid.368/// \throw invalid_column_error If name is invalid.369sqlite::blob370sqlite::statement::safe_column_blob(const char* name)371{372const int column = column_id(name);373if (column_type(column) != sqlite::type_blob)374throw sqlite::error(_pimpl->db.db_filename(),375F("Column '%s' is not a blob") % name);376return column_blob(column);377}378379380/// Type-checked version of column_double.381///382/// \param name The name of the column to retrieve.383///384/// \return The same as column_double if the value can be retrieved.385///386/// \throw error If the type of the cell to retrieve is invalid.387/// \throw invalid_column_error If name is invalid.388double389sqlite::statement::safe_column_double(const char* name)390{391const int column = column_id(name);392if (column_type(column) != sqlite::type_float)393throw sqlite::error(_pimpl->db.db_filename(),394F("Column '%s' is not a float") % name);395return column_double(column);396}397398399/// Type-checked version of column_int.400///401/// \param name The name of the column to retrieve.402///403/// \return The same as column_int if the value can be retrieved.404///405/// \throw error If the type of the cell to retrieve is invalid.406/// \throw invalid_column_error If name is invalid.407int408sqlite::statement::safe_column_int(const char* name)409{410const int column = column_id(name);411if (column_type(column) != sqlite::type_integer)412throw sqlite::error(_pimpl->db.db_filename(),413F("Column '%s' is not an integer") % name);414return column_int(column);415}416417418/// Type-checked version of column_int64.419///420/// \param name The name of the column to retrieve.421///422/// \return The same as column_int64 if the value can be retrieved.423///424/// \throw error If the type of the cell to retrieve is invalid.425/// \throw invalid_column_error If name is invalid.426int64_t427sqlite::statement::safe_column_int64(const char* name)428{429const int column = column_id(name);430if (column_type(column) != sqlite::type_integer)431throw sqlite::error(_pimpl->db.db_filename(),432F("Column '%s' is not an integer") % name);433return column_int64(column);434}435436437/// Type-checked version of column_text.438///439/// \param name The name of the column to retrieve.440///441/// \return The same as column_text if the value can be retrieved.442///443/// \throw error If the type of the cell to retrieve is invalid.444/// \throw invalid_column_error If name is invalid.445std::string446sqlite::statement::safe_column_text(const char* name)447{448const int column = column_id(name);449if (column_type(column) != sqlite::type_text)450throw sqlite::error(_pimpl->db.db_filename(),451F("Column '%s' is not a string") % name);452return column_text(column);453}454455456/// Type-checked version of column_bytes.457///458/// \param name The name of the column to retrieve the size of.459///460/// \return The same as column_bytes if the value can be retrieved.461///462/// \throw error If the type of the cell to retrieve the size of is invalid.463/// \throw invalid_column_error If name is invalid.464int465sqlite::statement::safe_column_bytes(const char* name)466{467const int column = column_id(name);468if (column_type(column) != sqlite::type_blob &&469column_type(column) != sqlite::type_text)470throw sqlite::error(_pimpl->db.db_filename(),471F("Column '%s' is not a blob or a string") % name);472return column_bytes(column);473}474475476/// Resets a statement to allow further processing.477void478sqlite::statement::reset(void)479{480(void)::sqlite3_reset(_pimpl->stmt);481}482483484/// Binds a blob to a prepared statement.485///486/// \param index The index of the binding.487/// \param b Description of the blob, which must remain valid during the488/// execution of the statement.489///490/// \throw api_error If the binding fails.491void492sqlite::statement::bind(const int index, const blob& b)493{494const int error = ::sqlite3_bind_blob(_pimpl->stmt, index, b.memory, b.size,495SQLITE_STATIC);496handle_bind_error(_pimpl->db, "sqlite3_bind_blob", error);497}498499500/// Binds a double value to a prepared statement.501///502/// \param index The index of the binding.503/// \param value The double value to bind.504///505/// \throw api_error If the binding fails.506void507sqlite::statement::bind(const int index, const double value)508{509const int error = ::sqlite3_bind_double(_pimpl->stmt, index, value);510handle_bind_error(_pimpl->db, "sqlite3_bind_double", error);511}512513514/// Binds an integer value to a prepared statement.515///516/// \param index The index of the binding.517/// \param value The integer value to bind.518///519/// \throw api_error If the binding fails.520void521sqlite::statement::bind(const int index, const int value)522{523const int error = ::sqlite3_bind_int(_pimpl->stmt, index, value);524handle_bind_error(_pimpl->db, "sqlite3_bind_int", error);525}526527528/// Binds a 64-bit integer value to a prepared statement.529///530/// \param index The index of the binding.531/// \param value The 64-bin integer value to bind.532///533/// \throw api_error If the binding fails.534void535sqlite::statement::bind(const int index, const int64_t value)536{537const int error = ::sqlite3_bind_int64(_pimpl->stmt, index, value);538handle_bind_error(_pimpl->db, "sqlite3_bind_int64", error);539}540541542/// Binds a NULL value to a prepared statement.543///544/// \param index The index of the binding.545///546/// \throw api_error If the binding fails.547void548sqlite::statement::bind(const int index, const null& /* null */)549{550const int error = ::sqlite3_bind_null(_pimpl->stmt, index);551handle_bind_error(_pimpl->db, "sqlite3_bind_null", error);552}553554555/// Binds a text string to a prepared statement.556///557/// \param index The index of the binding.558/// \param text The string to bind. SQLite generates an internal copy of this559/// string, so the original string object does not have to remain live. We560/// do this because handling the lifetime of std::string objects is very561/// hard (think about implicit conversions), so it is very easy to shoot562/// ourselves in the foot if we don't do this.563///564/// \throw api_error If the binding fails.565void566sqlite::statement::bind(const int index, const std::string& text)567{568const int error = ::sqlite3_bind_text(_pimpl->stmt, index, text.c_str(),569text.length(), SQLITE_TRANSIENT);570handle_bind_error(_pimpl->db, "sqlite3_bind_text", error);571}572573574/// Returns the index of the highest parameter.575///576/// \return A parameter index.577int578sqlite::statement::bind_parameter_count(void)579{580return ::sqlite3_bind_parameter_count(_pimpl->stmt);581}582583584/// Returns the index of a named parameter.585///586/// \param name The name of the parameter to be queried; must exist.587///588/// \return A parameter index.589int590sqlite::statement::bind_parameter_index(const std::string& name)591{592const int index = ::sqlite3_bind_parameter_index(_pimpl->stmt,593name.c_str());594PRE_MSG(index > 0, "Parameter name not in statement");595return index;596}597598599/// Returns the name of a parameter by index.600///601/// \param index The index to query; must be valid.602///603/// \return The name of the parameter.604std::string605sqlite::statement::bind_parameter_name(const int index)606{607const char* name = ::sqlite3_bind_parameter_name(_pimpl->stmt, index);608PRE_MSG(name != NULL, "Index value out of range or nameless parameter");609return std::string(name);610}611612613/// Clears any bindings and releases their memory.614void615sqlite::statement::clear_bindings(void)616{617const int error = ::sqlite3_clear_bindings(_pimpl->stmt);618PRE_MSG(error == SQLITE_OK, "SQLite3 contract has changed; it should "619"only return SQLITE_OK");620}621622623