|
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
- //
- // 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 <cppdb/frontend.h>
- #include <cppdb/backend.h>
- #include <cppdb/conn_manager.h>
- #include <cppdb/pool.h>
-
- namespace cppdb {
- struct result::data {};
-
- class throw_guard {
- public:
- throw_guard(ref_ptr<backend::connection> 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<backend::result> res,
- ref_ptr<backend::statement> stat,
- ref_ptr<backend::connection> 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<backend::statement> stat,ref_ptr<backend::connection> 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::result> 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<backend::result> 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<backend::connection> conn) : conn_(conn)
- {
- }
- session::session(ref_ptr<backend::connection> 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<backend::statement> 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<backend::statement> 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<backend::statement> 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<backend::statement> 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
|