CppDB
cppdb/frontend.h
00001 
00002 //                                                                             
00003 //  Copyright (C) 2010-2011  Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>     
00004 //                                                                             
00005 //  Distributed under:
00006 //
00007 //                   the Boost Software License, Version 1.0.
00008 //              (See accompanying file LICENSE_1_0.txt or copy at 
00009 //                     http://www.boost.org/LICENSE_1_0.txt)
00010 //
00011 //  or (at your opinion) under:
00012 //
00013 //                               The MIT License
00014 //                 (See accompanying file MIT.txt or a copy at
00015 //              http://www.opensource.org/licenses/mit-license.php)
00016 //
00018 #ifndef CPPDB_FRONTEND_H
00019 #define CPPDB_FRONTEND_H
00020 #include <cppdb/defs.h>
00021 #include <cppdb/errors.h>
00022 #include <cppdb/ref_ptr.h>
00023 
00024 // Borland errors about unknown pool-type without this include.
00025 #ifdef __BORLANDC__
00026 #include <cppdb/backend.h>
00027 #endif
00028 
00029 #include <iosfwd>
00030 #include <ctime>
00031 #include <string>
00032 #include <memory>
00033 #include <typeinfo>
00034 
00038 
00039 namespace cppdb {
00040 
00041         class result;
00042         class statement;
00043         class session;
00044         class connection_info;
00045         class connection_specific_data;
00046 
00052         CPPDB_API char const *version_string();
00058         CPPDB_API int version_number();
00059         
00060         // Borland needs pool.h, but not this forward declaration.
00061         #ifndef __BORLANDC__
00062         namespace backend {
00063                 class result;
00064                 class statement;
00065                 class connection;
00066         }
00067         #endif
00068         
00072         typedef enum {
00073                 null_value,     
00074                 not_null_value  
00075         } null_tag_type;
00076 
00078         namespace tags {
00079                 template<typename T>
00080                 struct into_tag {
00081                         T &value;
00082                         null_tag_type &tag;
00083                         into_tag(T &v, null_tag_type &t) : value(v),tag(t) {}
00084                 };
00085 
00086                 template<typename T>
00087                 struct use_tag {
00088                         T value;
00089                         null_tag_type tag;
00090                         use_tag(T v,null_tag_type t) : value(v),tag(t) {}
00091                 };
00092 
00093         } // tags
00095 
00103         template<typename T>
00104         tags::into_tag<T> into(T &value,null_tag_type &tag)
00105         {
00106                 return tags::into_tag<T>(value,tag);
00107         }
00108 
00112 
00113         inline tags::use_tag<std::string const &> use(std::string const &v,null_tag_type tag)
00114         {
00115                 return tags::use_tag<std::string const &>(v,tag);
00116         }
00117 
00121 
00122         inline tags::use_tag<char const *> use(char const *v,null_tag_type tag)
00123         {
00124                 return tags::use_tag<char const *>(v,tag);
00125         }
00126         
00130         template<typename T>
00131         tags::use_tag<T> use(T value,null_tag_type tag)
00132         {
00133                 return tags::use_tag<T>(value,tag);
00134         }
00135 
00137         namespace details {
00138                 template<typename Object>
00139                 class functor {
00140                 public:
00141                         functor(functor const &other)  : 
00142                                 functor_(other.functor_),
00143                                 wrapper_(other.wrapper_)
00144                         {
00145                         }
00146                         functor const &operator=(functor const &other) 
00147                         {
00148                                 functor_ = other.functor_;
00149                                 wrapper_ = other.wrapper_;
00150                                 return *this;
00151                         }
00152                         functor(void (*func)(Object &))
00153                         {
00154                                 functor_ = reinterpret_cast<void *>(reinterpret_cast<size_t>(func));
00155                                 wrapper_ = &functor::call_func;
00156                                 
00157                         }
00158                         template<typename RealFunctor>
00159                         functor(RealFunctor const &f)
00160                         {
00161                                 // The usual casts are not enough for all compilers
00162                                 functor_ = reinterpret_cast<void const *>(&f);
00163                                 wrapper_ = &functor<Object>::template call_it<RealFunctor>;
00164                         }
00165                         void operator()(Object &p) const
00166                         {
00167                                 wrapper_(functor_,p);
00168                         }
00169                 private:
00170                         static void call_func(void const *pointer,Object &parameter)
00171                         {
00172                                 typedef void function_type(Object &);
00173                                 function_type *f = reinterpret_cast<function_type *>(reinterpret_cast<size_t>((pointer)));
00174                                 f(parameter);
00175                         }
00176                         template<typename Functor>
00177                         static void call_it(void const *pointer,Object &parameter)
00178                         {
00179                                 Functor const *f_ptr = reinterpret_cast<Functor const *>(pointer);
00180                                 Functor const &f=*f_ptr;
00181                                 f(parameter);
00182                         }
00183                         void const *functor_;
00184                         void (*wrapper_)(void const *,Object &);
00185                 };
00186         } // details
00188 
00189         #ifdef CPPDB_DOXYGEN
00190 
00191 
00192 
00193 
00194 
00195         typedef unspecified_class_type once_functor;
00196         #else
00197         typedef details::functor<session> once_functor;
00198         #endif
00199 
00207         class CPPDB_API result {
00208         public:
00212                 result();
00217                 ~result();
00222                 result(result const &);
00227                 result const &operator=(result const &);
00228 
00232                 int cols();
00241                 bool next();
00242                 
00246                 int index(std::string const &n);
00250                 int find_column(std::string const &name);
00251 
00255                 std::string name(int col);
00256 
00260                 bool is_null(int col);
00264                 bool is_null(std::string const &n);
00265 
00271                 void clear();
00275                 void rewind_column();
00283                 bool empty();
00284 
00285                 
00293                 bool fetch(int col,short &v);
00297                 bool fetch(int col,unsigned short &v);
00301                 bool fetch(int col,int &v);
00305                 bool fetch(int col,unsigned &v);
00309                 bool fetch(int col,long &v);
00313                 bool fetch(int col,unsigned long &v);
00317                 bool fetch(int col,long long &v);
00321                 bool fetch(int col,unsigned long long &v);
00325                 bool fetch(int col,float &v);
00329                 bool fetch(int col,double &v);
00333                 bool fetch(int col,long double &v);
00340                 bool fetch(int col,std::string &v);
00344                 bool fetch(int col,std::tm &v);
00351                 bool fetch(int col,std::ostream &v);
00352 
00362                 bool fetch(std::string const &n,short &v);
00366                 bool fetch(std::string const &n,unsigned short &v);
00370                 bool fetch(std::string const &n,int &v);
00374                 bool fetch(std::string const &n,unsigned &v);
00378                 bool fetch(std::string const &n,long &v);
00382                 bool fetch(std::string const &n,unsigned long &v);
00386                 bool fetch(std::string const &n,long long &v);
00390                 bool fetch(std::string const &n,unsigned long long &v);
00394                 bool fetch(std::string const &n,float &v);
00398                 bool fetch(std::string const &n,double &v);
00402                 bool fetch(std::string const &n,long double &v);
00410                 bool fetch(std::string const &n,std::string &v);
00414                 bool fetch(std::string const &n,std::tm &v);
00422                 bool fetch(std::string const &n,std::ostream &v);
00423 
00424 
00437                 bool fetch(short &v);
00439                 bool fetch(unsigned short &v);
00441                 bool fetch(int &v);
00443                 bool fetch(unsigned &v);
00445                 bool fetch(long &v);
00447                 bool fetch(unsigned long &v);
00449                 bool fetch(long long &v);
00451                 bool fetch(unsigned long long &v);
00453                 bool fetch(float &v);
00455                 bool fetch(double &v);
00457                 bool fetch(long double &v);
00469                 bool fetch(std::string &v);
00471                 bool fetch(std::tm &v);
00483                 bool fetch(std::ostream &v);
00484 
00490                 
00491                 template<typename T>
00492                 T get(std::string const &name)
00493                 {
00494                         T v=T();
00495                         if(!fetch(name,v))
00496                                 throw null_value_fetch();
00497                         return v;
00498                 }
00499 
00505                 template<typename T>
00506                 T get(std::string const &name, T const &def)
00507                 {
00508                         T v=T();
00509                         if(!fetch(name,v))
00510                                 return def;
00511                         return v;
00512                 }
00513 
00519                 template<typename T>
00520                 T get(int col)
00521                 {
00522                         T v=T();
00523                         if(!fetch(col,v))
00524                                 throw null_value_fetch();
00525                         return v;
00526                 }
00527 
00533                 template<typename T>
00534                 T get(int col, T const &def)
00535                 {
00536                         T v=T();
00537                         if(!fetch(col,v))
00538                                 return def;
00539                         return v;
00540                 }
00541 
00551                 template<typename T>
00552                 result &operator>>(tags::into_tag<T> ref)
00553                 {
00554                         if(fetch(ref.value))
00555                                 ref.tag = not_null_value;
00556                         else
00557                                 ref.tag = null_value;
00558                         return *this;
00559                 }
00560 
00564                 template<typename T>
00565                 result &operator>>(T &value)
00566                 {
00567                         fetch(value);
00568                         return *this;
00569                 }
00570 
00571                 
00572         private:
00573                 result( ref_ptr<backend::result> res,
00574                         ref_ptr<backend::statement> stat,
00575                         ref_ptr<backend::connection> conn);
00576 
00577                 void check();
00578                 
00579                 friend class statement;
00580 
00581                 struct data;
00582 
00583                 std::auto_ptr<data> d;
00584 
00585                 bool eof_;
00586                 bool fetched_;
00587                 int current_col_;
00588                 ref_ptr<backend::result> res_;
00589                 ref_ptr<backend::statement> stat_;
00590                 ref_ptr<backend::connection> conn_;
00591         };
00592 
00598         class CPPDB_API statement {
00599         public:
00604                 statement();
00613                 ~statement();
00621                 statement(statement const &);
00629                 statement const &operator=(statement const &);
00630 
00640                 void reset();
00641 
00646                 
00647                 void clear();
00648 
00653                 bool empty() const;
00654                 
00663                 statement &bind(int v);
00665                 statement &bind(unsigned v);
00667                 statement &bind(long v);
00669                 statement &bind(unsigned long v);
00671                 statement &bind(long long v);
00673                 statement &bind(unsigned long long v);
00675                 statement &bind(double v);
00677                 statement &bind(long double v);
00688                 statement &bind(std::string const &v);
00699                 statement &bind(char const *s);
00710                 statement &bind(char const *b,char const *e);
00712                 statement &bind(std::tm const &v);
00724                 statement &bind(std::istream &v);
00733                 statement &bind_null();
00734 
00735 // Without the following statement &operator<<(T v) errors for tags::use_tag<T> as T.
00736 #ifdef __BORLANDC__
00737                 template<typename T>
00738                 statement &bind(tags::use_tag<T> const &val)
00739                 {
00740                         if(val.tag == null_value)
00741                                 return bind_null();
00742                         else
00743                                 return bind(val.value);
00744                 }
00745 #endif
00746 
00755                 void bind(int col,int v);
00757                 void bind(int col,unsigned v);
00759                 void bind(int col,long v);
00761                 void bind(int col,unsigned long v);
00763                 void bind(int col,long long v);
00765                 void bind(int col,unsigned long long v);
00767                 void bind(int col,double v);
00769                 void bind(int col,long double v);
00780                 void bind(int col,std::string const &v);
00791                 void bind(int col,char const *s);
00802                 void bind(int col,char const *b,char const *e);
00804                 void bind(int col,std::tm const &v);
00815                 void bind(int col,std::istream &v);
00824                 void bind_null(int col);
00825 
00834                 long long last_insert_id();
00844                 long long sequence_last(std::string const &seq);
00851                 unsigned long long affected();
00852 
00864                 result row();
00869                 result query();
00873                 operator result();
00874 
00879                 void exec();
00880 
00884                 statement &operator<<(std::string const &v);
00888                 statement &operator<<(char const *s);
00892                 statement &operator<<(std::tm const &v);
00896                 statement &operator<<(std::istream &v);
00900                 statement &operator<<(void (*manipulator)(statement &st));
00904                 result operator<<(result (*manipulator)(statement &st));
00905 
00915                 template<typename T>
00916                 statement &operator<<(tags::use_tag<T> const &val)
00917                 {
00918                         if(val.tag == null_value)
00919                                 return bind_null();
00920                         else 
00921                                 return bind(val.value);
00922                 }
00923         
00927                 template<typename T>
00928                 statement &operator<<(T v)
00929                 {
00930                         return bind(v);
00931                 }
00932                 
00933         private:
00934                 statement(ref_ptr<backend::statement> stat,ref_ptr<backend::connection> conn);
00935 
00936                 friend class session;
00937 
00938                 int placeholder_;
00939                 ref_ptr<backend::statement> stat_;
00940                 ref_ptr<backend::connection> conn_;
00941                 struct data;
00942                 std::auto_ptr<data> d;
00943         };
00944 
00952         inline void exec(statement &st)
00953         {
00954                 st.exec();
00955         }
00956         
00964         inline void null(statement &st)
00965         {
00966                 st.bind_null();
00967         }
00968 
00987         inline result row(statement &st)
00988         {
00989                 return st.row();
00990         }
00991 
00998         class CPPDB_API session {
00999         public:
01000 
01004                 session();
01009                 session(session const &);
01014                 session const &operator=(session const &);
01021                 ~session();
01022 
01028                 session(connection_info const &ci);
01034                 session(std::string const &cs);
01047                 session(connection_info const &ci,once_functor const &f);
01060                 session(std::string const &cs,once_functor const &f);
01072                 session(ref_ptr<backend::connection> conn,once_functor const &f);
01076                 session(ref_ptr<backend::connection> conn);
01077                 
01081                 void open(connection_info const &ci);
01087                 void open(std::string const &cs);
01092                 void close();
01096                 bool is_open();
01097 
01104                 statement prepare(std::string const &query);
01108                 statement operator<<(std::string const &q);
01112                 statement operator<<(char const *s);
01113 
01114 
01119                 statement create_statement(std::string const &q);
01123                 statement create_prepared_statement(std::string const &q);
01128                 statement create_prepared_uncached_statement(std::string const &q);
01129 
01133                 void clear_cache();
01134 
01140                 void clear_pool();
01141 
01145                 void begin();
01149                 void commit();
01153                 void rollback();
01154 
01161                 std::string escape(char const *b,char const *e);
01168                 std::string escape(char const *s);
01175                 std::string escape(std::string const &s);
01179                 std::string driver();
01183                 std::string engine();
01192                 bool recyclable();
01193                 
01198                 void recyclable(bool value);
01199 
01203                 bool once_called();
01207                 void once_called(bool state);
01216                 void once(once_functor const &f);
01217                 
01218                 
01222                 connection_specific_data *get_specific(std::type_info const &t);
01226                 connection_specific_data *release_specific(std::type_info const &t);
01230                 void reset_specific(std::type_info const &t,connection_specific_data *p=0);
01231                 
01235                 template<typename T>
01236                 T *get_specific()
01237                 {
01238                         return static_cast<T*>(get_specific(typeid(T)));
01239                 }
01243                 template<typename T>
01244                 T *release_specific()
01245                 {
01246                         return static_cast<T*>(release_specific(typeid(T)));
01247                 }
01251                 template<typename T>
01252                 void reset_specific(T *p=0)
01253                 {
01254                         reset_specific(typeid(T),p);
01255                 }
01256 
01257         private:
01258                 struct data;
01259                 std::auto_ptr<data> d;
01260                 ref_ptr<backend::connection> conn_;
01261         };
01262 
01269         class CPPDB_API transaction {
01270                 transaction(transaction const &);
01271                 void operator=(transaction const &);
01272         public:
01276                 transaction(session &s);
01280                 ~transaction();
01284                 void commit();
01288                 void rollback();
01289         private:
01290                 
01291                 struct data;
01292                 session *s_;
01293                 bool commited_;
01294                 std::auto_ptr<data> d;
01295         };
01296 
01297 
01298 } // cppdb
01299 
01300 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator