CppDB
|
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 ¶meter) 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 ¶meter) 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