/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) // // Distributed under: // // the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // or (at your opinion) under: // // The MIT License // (See accompanying file MIT.txt or a copy at // http://www.opensource.org/licenses/mit-license.php) // /////////////////////////////////////////////////////////////////////////////// #define CPPDB_SOURCE #include #include #include #include namespace cppdb { struct result::data {}; class throw_guard { public: throw_guard(ref_ptr const &conn) : conn_(conn.get()) { } void done() { conn_ = 0; } ~throw_guard() { if(conn_ && std::uncaught_exception()) { conn_->recyclable(false); } } private: backend::connection *conn_; }; result::result() : eof_(false), fetched_(false), current_col_(0) { } result::result( ref_ptr res, ref_ptr stat, ref_ptr conn) : eof_(false), fetched_(false), current_col_(0), res_(res), stat_(stat), conn_(conn) { } result::result(result const &other) : eof_(other.eof_), fetched_(other.fetched_), current_col_(other.current_col_), res_(other.res_), stat_(other.stat_), conn_(other.conn_) { } result const &result::operator=(result const &other) { eof_ = other.eof_; fetched_ = other.fetched_; current_col_ = other.current_col_; res_ = other.res_; stat_ = other.stat_; conn_ = other.conn_; return *this; } result::~result() { clear(); } int result::cols() { return res_->cols(); } bool result::next() { throw_guard g(conn_); if(eof_) return false; fetched_=true; eof_ = res_->next()==false; current_col_ = 0; return !eof_; } int result::index(std::string const &n) { int c = res_->name_to_column(n); if(c<0) throw invalid_column(); return c; } std::string result::name(int col) { if(col < 0 || col>= cols()) throw invalid_column(); return res_->column_to_name(col); } int result::find_column(std::string const &name) { int c = res_->name_to_column(name); if(c < 0) return -1; return c; } void result::rewind_column() { current_col_ = 0; } bool result::empty() { if(!res_) return true; return eof_ || !fetched_; } void result::clear() { eof_ = true; fetched_ = true; res_.reset(); stat_.reset(); conn_.reset(); } void result::check() { if(empty()) throw empty_row_access(); } bool result::is_null(int col) { return res_->is_null(col); } bool result::is_null(std::string const &n) { return is_null(index(n)); } bool result::fetch(int col,short &v) { return res_->fetch(col,v); } bool result::fetch(int col,unsigned short &v) { return res_->fetch(col,v); } bool result::fetch(int col,int &v) { return res_->fetch(col,v); } bool result::fetch(int col,unsigned &v) { return res_->fetch(col,v); } bool result::fetch(int col,long &v) { return res_->fetch(col,v); } bool result::fetch(int col,unsigned long &v) { return res_->fetch(col,v); } bool result::fetch(int col,long long &v) { return res_->fetch(col,v); } bool result::fetch(int col,unsigned long long &v) { return res_->fetch(col,v); } bool result::fetch(int col,float &v) { return res_->fetch(col,v); } bool result::fetch(int col,double &v) { return res_->fetch(col,v); } bool result::fetch(int col,long double &v) { return res_->fetch(col,v); } bool result::fetch(int col,std::string &v) { return res_->fetch(col,v); } bool result::fetch(int col,std::tm &v) { return res_->fetch(col,v); } bool result::fetch(int col,std::ostream &v) { return res_->fetch(col,v); } bool result::fetch(std::string const &n,short &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,unsigned short &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,int &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,unsigned &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,long &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,unsigned long &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,long long &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,unsigned long long &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,float &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,double &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,long double &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,std::string &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,std::tm &v) { return res_->fetch(index(n),v); } bool result::fetch(std::string const &n,std::ostream &v) { return res_->fetch(index(n),v); } bool result::fetch(short &v) { return res_->fetch(current_col_++,v); } bool result::fetch(unsigned short &v) { return res_->fetch(current_col_++,v); } bool result::fetch(int &v) { return res_->fetch(current_col_++,v); } bool result::fetch(unsigned &v) { return res_->fetch(current_col_++,v); } bool result::fetch(long &v) { return res_->fetch(current_col_++,v); } bool result::fetch(unsigned long &v) { return res_->fetch(current_col_++,v); } bool result::fetch(long long &v) { return res_->fetch(current_col_++,v); } bool result::fetch(unsigned long long &v) { return res_->fetch(current_col_++,v); } bool result::fetch(float &v) { return res_->fetch(current_col_++,v); } bool result::fetch(double &v) { return res_->fetch(current_col_++,v); } bool result::fetch(long double &v) { return res_->fetch(current_col_++,v); } bool result::fetch(std::string &v) { return res_->fetch(current_col_++,v); } bool result::fetch(std::tm &v) { return res_->fetch(current_col_++,v); } bool result::fetch(std::ostream &v) { return res_->fetch(current_col_++,v); } struct statement::data {}; statement::statement() : placeholder_(1) {} statement::~statement() { stat_.reset(); conn_.reset(); } statement::statement(statement const &other) : placeholder_(other.placeholder_), stat_(other.stat_), conn_(other.conn_) { } statement const &statement::operator=(statement const &other) { placeholder_ = other.placeholder_; stat_=other.stat_; conn_=other.conn_; return *this; } statement::statement(ref_ptr stat,ref_ptr conn) : placeholder_(1), stat_(stat), conn_(conn) { } bool statement::empty() const { return !stat_; } void statement::clear() { stat_.reset(); conn_.reset(); } void statement::reset() { throw_guard g(conn_); placeholder_ = 1; stat_->reset(); } statement &statement::operator<<(std::string const &v) { return bind(v); } statement &statement::operator<<(char const *s) { return bind(s); } statement &statement::operator<<(std::tm const &v) { return bind(v); } statement &statement::operator<<(std::istream &v) { return bind(v); } statement &statement::operator<<(void (*manipulator)(statement &st)) { manipulator(*this); return *this; } result statement::operator<<(result (*manipulator)(statement &st)) { return manipulator(*this); } statement &statement::bind(int v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(unsigned v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(long v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(unsigned long v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(long long v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(unsigned long long v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(double v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(long double v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(std::string const &v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(char const *s) { stat_->bind(placeholder_++,s); return *this; } statement &statement::bind(char const *b,char const *e) { stat_->bind(placeholder_++,b,e); return *this; } statement &statement::bind(std::tm const &v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind(std::istream &v) { stat_->bind(placeholder_++,v); return *this; } statement &statement::bind_null() { stat_->bind_null(placeholder_++); return *this; } void statement::bind(int col,std::string const &v) { stat_->bind(col,v); } void statement::bind(int col,char const *s) { stat_->bind(col,s); } void statement::bind(int col,char const *b,char const *e) { stat_->bind(col,b,e); } void statement::bind(int col,std::tm const &v) { stat_->bind(col,v); } void statement::bind(int col,std::istream &v) { stat_->bind(col,v); } void statement::bind(int col,int v) { stat_->bind(col,v); } void statement::bind(int col,unsigned v) { stat_->bind(col,v); } void statement::bind(int col,long v) { stat_->bind(col,v); } void statement::bind(int col,unsigned long v) { stat_->bind(col,v); } void statement::bind(int col,long long v) { stat_->bind(col,v); } void statement::bind(int col,unsigned long long v) { stat_->bind(col,v); } void statement::bind(int col,double v) { stat_->bind(col,v); } void statement::bind(int col,long double v) { stat_->bind(col,v); } void statement::bind_null(int col) { stat_->bind_null(col); } long long statement::last_insert_id() { throw_guard g(conn_); return stat_->sequence_last(std::string()); } long long statement::sequence_last(std::string const &seq) { throw_guard g(conn_); return stat_->sequence_last(seq); } unsigned long long statement::affected() { throw_guard g(conn_); return stat_->affected(); } result statement::row() { throw_guard g(conn_); ref_ptr backend_res = stat_->query(); result res(backend_res,stat_,conn_); if(res.next()) { if(res.res_->has_next() == backend::result::next_row_exists) { g.done(); throw multiple_rows_query(); } } return res; } result statement::query() { throw_guard g(conn_); ref_ptr res(stat_->query()); return result(res,stat_,conn_); } statement::operator result() { return query(); } void statement::exec() { throw_guard g(conn_); stat_->exec(); } struct session::data {}; session::session() { } session::session(session const &other) : conn_(other.conn_) { } session const &session::operator=(session const &other) { conn_ = other.conn_; return *this; } session::session(ref_ptr conn) : conn_(conn) { } session::session(ref_ptr conn,once_functor const &f) : conn_(conn) { once(f); } session::~session() { } session::session(connection_info const &ci) { open(ci); } session::session(std::string const &cs) { open(cs); } session::session(connection_info const &ci,once_functor const &f) { open(ci); once(f); } session::session(std::string const &cs,once_functor const &f) { open(cs); once(f); } void session::open(connection_info const &ci) { conn_ = connections_manager::instance().open(ci); } void session::open(std::string const &cs) { conn_ = connections_manager::instance().open(cs); } void session::close() { conn_.reset(); } bool session::is_open() { return conn_; } statement session::prepare(std::string const &query) { throw_guard g(conn_); ref_ptr stat_ptr(conn_->prepare(query)); statement stat(stat_ptr,conn_); return stat; } statement session::create_statement(std::string const &query) { throw_guard g(conn_); ref_ptr stat_ptr(conn_->get_statement(query)); statement stat(stat_ptr,conn_); return stat; } statement session::create_prepared_statement(std::string const &query) { throw_guard g(conn_); ref_ptr stat_ptr(conn_->get_prepared_statement(query)); statement stat(stat_ptr,conn_); return stat; } statement session::create_prepared_uncached_statement(std::string const &query) { throw_guard g(conn_); ref_ptr stat_ptr(conn_->get_prepared_uncached_statement(query)); statement stat(stat_ptr,conn_); return stat; } statement session::operator<<(std::string const &q) { return prepare(q); } statement session::operator<<(char const *s) { return prepare(s); } void session::begin() { throw_guard g(conn_); conn_->begin(); } void session::commit() { throw_guard g(conn_); conn_->commit(); } void session::rollback() { throw_guard g(conn_); conn_->rollback(); } std::string session::escape(char const *b,char const *e) { return conn_->escape(b,e); } std::string session::escape(char const *s) { return conn_->escape(s); } std::string session::escape(std::string const &s) { return conn_->escape(s); } std::string session::driver() { return conn_->driver(); } std::string session::engine() { return conn_->engine(); } void session::once_called(bool v) { conn_->once_called(v); } bool session::once_called() { return conn_->once_called(); } void session::once(once_functor const &f) { if(!once_called()) { f(*this); once_called(true); } } struct transaction::data {}; transaction::transaction(session &s) : s_(&s), commited_(false) { s_->begin(); } void transaction::commit() { s_->commit(); commited_ =true; } void transaction::rollback() { if(!commited_) s_->rollback(); commited_=true; } transaction::~transaction() { try { rollback(); } catch(...) { } } void session::clear_cache() { conn_->clear_cache(); } void session::clear_pool() { conn_->clear_cache(); conn_->recyclable(false); conn_->get_pool()->clear(); } bool session::recyclable() { return conn_->recyclable(); } void session::recyclable(bool v) { conn_->recyclable(v); } connection_specific_data *session::get_specific(std::type_info const &t) { return conn_->connection_specific_get(t); } connection_specific_data *session::release_specific(std::type_info const &t) { return conn_->connection_specific_release(t); } void session::reset_specific(std::type_info const &t,connection_specific_data *p) { conn_->connection_specific_reset(t,p); } char const *version_string() { return CPPDB_VERSION; } int version_number() { return CPPDB_MAJOR * 10000 + CPPDB_MINOR * 100 + CPPDB_PATCH; } } // cppdb