00001 #ifndef _DBIXX_H_
00002 #define _DBIXX_H_
00003 
00004 #include <dbi/dbi.h>
00005 #include <stdexcept>
00006 #include <ctime>
00007 #include <map>
00008 #include <cstring>
00009 
00010 namespace dbixx {
00011 
00015 class dbixx_error : public std::runtime_error
00016 {
00017 public:
00021         char const *query() const { return query_.c_str(); };
00025         dbixx_error(std::string const &error,std::string const &q=std::string()) :
00026                 std::runtime_error(error),
00027                 query_()
00028         {
00029         }
00030         ~dbixx_error() throw()
00031         {
00032         }
00033 private:
00034         std::string query_;
00035 };
00036 
00040 
00041 class row 
00042 {
00043         
00044         row(row const &);
00045         row const &operator=(row const &);
00046 public:
00050         row() { current=0; owner=false; res=NULL; };
00051         ~row();
00055         dbi_result get_dbi_result() { return res; };
00059         bool isempty();
00063         bool isnull(int inx);
00067         bool isnull(std::string const &id);
00071         bool fetch(int pos,short &value);
00075         bool fetch(int pos,unsigned short &value);
00079         bool fetch(int pos,int &value);
00083         bool fetch(int pos,unsigned &value);
00087         bool fetch(int pos,long  &value);
00091         bool fetch(int pos,unsigned long &value);
00095         bool fetch(int pos,long long &value);
00099         bool fetch(int pos,unsigned long long &value);
00103         bool fetch(int pos,float &value);
00107         bool fetch(int pos,double &value);
00111         bool fetch(int pos,long double &value);
00115         bool fetch(int pos,std::string &value);
00119         bool fetch(int pos,std::tm &value);
00123         bool operator[](std::string const & id) { return isnull(id); };
00127         bool operator[](int ind) { return isnull(ind); };
00132         template<typename T>
00133         row &operator>>(T &v) { current++; fetch(current,v); return *this; };
00137         unsigned int cols();
00138 
00143         template<typename T>
00144         T get(int col)
00145         {
00146                 T v;
00147                 if(!fetch(col,v)) {
00148                         throw dbixx_error("Null value fetch");
00149                 }
00150                 return v;
00151         }
00152 private:
00153         template<typename T>
00154         bool ufetch(int post,T &v);
00155         template<typename T>
00156         bool sfetch(int post,T &v);
00157 
00158         dbi_result res;
00159         bool owner;
00160         int current;
00161         void check_set();
00162 
00163         void set(dbi_result &r);
00164         void reset();
00165         void assign(dbi_result &r);
00166         bool next();
00167 
00168         friend class session;
00169         friend class result;
00170 };
00171 
00175 class result
00176 {
00177         result(result const &);
00178         result const &operator=(result const &);
00179 public:
00183         dbi_result get_dbi_result() { return res; };
00187         result() : res(NULL) {};
00191         ~result();
00195         unsigned long long rows();
00199         unsigned int cols();
00203         bool next(row &r);
00204 private:
00205         dbi_result res;
00206         void assign(dbi_result r);
00207         friend class session;
00208 };
00209 
00210 
00214 struct null {};
00218 struct exec {};
00219 
00228 template<typename T>
00229 std::pair<T,bool> use(T ref, bool isnull=false)
00230 {
00231         return std::pair<T,bool>(ref,isnull);
00232 }
00233 
00237 class session {
00238         
00239         session(session const &);
00240         session const &operator=(session const &);
00241 public:
00245         session();
00256         session(std::string const &backend_or_connection_string);
00260         ~session();
00288         void connect(std::string const &connection_string);
00292         void driver(std::string const &backend);
00296         std::string driver();
00300         void param(std::string const &par,std::string const &val);
00304         void param(std::string const &par,int);
00308         void connect();
00312         void reconnect();
00316         void close();
00317         
00321         dbi_conn get_dbi_conn() { return conn; };
00322 
00323 
00337         void query(std::string const &query);
00342         unsigned long long rowid(char const *seq=NULL);
00343 
00347         unsigned long long affected() { return affected_rows ;};
00348 
00352         void bind(std::string const &s,bool isnull=false);
00356         void bind(int v,bool isnull=false);
00360         void bind(unsigned v,bool isnull=false);
00364         void bind(long v,bool isnull=false);
00368         void bind(unsigned long v,bool isnull=false);
00372         void bind(long long int v,bool isnull=false);
00376         void bind(unsigned long long v,bool isnull=false);
00380         void bind(double v,bool isnull=false);
00384         void bind(long double v,bool isnull=false);
00388         void bind(std::tm const &time,bool isnull=false);
00392         void bind(null const &,bool isnull=true);
00393 
00397         void exec();
00398 
00402         void fetch(result &res);
00403 
00409         bool single(row &r);
00410 
00414         session &operator<<(std::string const &q) { query(q); return *this; };
00418         session &operator,(std::string const &v) { bind(v,false); return *this; };
00422         session &operator,(std::pair<std::string,bool> p) { bind(p.first,p.second); return *this; }
00426         session &operator,(char const *v) { bind(v,false); return *this; };
00430         session &operator,(std::tm const &v) { bind(v,false); return *this; };
00431         
00435         void operator,(dbixx::exec const &e) { exec(); };
00439         void operator,(result &res) { fetch(res); };
00443         bool operator,(row &r) { return single(r); };
00444 
00448         template<typename T>
00449         session &operator,(T v) { bind(v,false); return *this; };
00450 
00454         template<typename T>
00455         session &operator,(std::pair<T,bool> p) { bind(p.first,p.second); return *this; }
00456 private:
00457         template<typename T>
00458         void do_bind(T v,bool);
00459 
00460         std::string query_in;
00461         unsigned pos_read;
00462         std::string escaped_query;
00463         unsigned pos_write;
00464         bool ready_for_input;
00465         bool complete;
00466         unsigned long long affected_rows;
00467 
00468 
00469         std::string backend;
00470         dbi_conn conn;
00471         std::map<std::string,std::string> string_params; 
00472         std::map<std::string,int> numeric_params; 
00473         void check_open();
00474         void error();
00475         void escape();
00476         void check_input();
00477 
00478 };
00479 
00486 class transaction {
00487         
00488         transaction(transaction const &);
00489         transaction const &operator=(transaction const &);
00490 public:
00494         transaction(session &s) : sql(s) { commited=false; begin(); }
00498         void commit();
00502         void rollback();
00506         ~transaction();
00507 private:
00508         session &sql;
00509         bool commited;
00510         void begin();
00511 };
00512 
00513 }
00514 
00515 #endif // _DBIXX_H_