/home/martin/workspace/OpenStreetNav/src/sqlite/Statement.h
Go to the documentation of this file.
00001 /*
00002  * Statement.h
00003  *
00004  *  Created on: Nov 2, 2011
00005  *      Author: martin
00006  */
00007 
00008 #ifndef STATEMENT_H_
00009 #define STATEMENT_H_
00010 
00011 #include <sqlite3.h>
00012 #include "Database.h"
00013 #include <vector>
00014 #include <cstdint>
00015 #include <tuple>
00016 #include <cassert>
00017 
00018 namespace sqlite
00019 {
00020 
00026 class Statement
00027 {
00028 private:
00029     template <class T>
00030     class ColType
00031     {
00032     public:
00033         T get_data(Statement& st, int col_index)
00034         {
00035             return T();
00036         }
00037     };
00038     friend Statement::ColType<double> coldouble();
00039     friend Statement::ColType<int> colint();
00040     friend Statement::ColType<int64_t> colint64();
00041     friend Statement::ColType<std::string> colstr();
00042 
00043     template <class T>
00044     class BindWrap
00045     {
00046     };
00047 
00048 public:
00052     Statement();
00058     Statement(std::string const& sql, Database& db);
00059     virtual ~Statement();
00060     Statement(Statement const&) = delete;
00061     Statement& operator=(Statement const&) = delete;
00062     Statement(Statement && other);
00063     Statement& operator=(Statement && other);
00064 
00068     bool done();
00073     bool has_row();
00077     void step();
00078 
00079 
00085     void reset();
00090     void finalize();
00091 
00097     double val_double(int col_index);
00103     int val_int(int col_index);
00109     int64_t val_int64(int col_index);
00115     std::string val_string(int col_index);
00116 
00122     void bind_double(int param_index, double value);
00128     void bind_int(int param_index, int value);
00134     void bind_int64(int param_index, int64_t value);
00140     void bind_string(int param_index, std::string const& value);
00141 
00147     template<typename... Args> std::tuple<Args...> get_row(ColType<Args>... types)
00148     {
00149         return get_row_internal(0, types...);
00150     }
00151 
00157     template<typename... Args> std::vector<std::tuple<Args...> > get_remaining_rows(ColType<Args>... types)
00158     {
00159         std::vector<std::tuple<Args...> > ret;
00160         while (!done())
00161         {
00162             if (has_row())
00163                 ret.push_back(get_row(types...));
00164             step();
00165         }
00166         return ret;
00167     }
00168 
00174     template<typename... Args> void bind(Args... values)
00175     {
00176         bind_internal(1, values...);
00177     }
00178 
00182     static ColType<int> colint;
00186     static ColType<double> coldouble;
00190     static ColType<int64_t> colint64;
00194     static ColType<std::string> colstring;
00195 
00196 private:
00197     void reset_internal();
00198     void reset_nothrow();
00199     sqlite3_stmt* stmt;
00200     Database* db;
00201     void check_value_conditions(int col);
00202     int cols;
00203     bool hrow;
00204     bool dn;
00205 
00206     std::tuple<> get_row_internal(int)
00207     {
00208         return std::tuple<>();
00209     }
00210     template<typename Head, typename... Tail> std::tuple<Head, Tail...> get_row_internal(int i, ColType<Head> h, ColType<Tail>... t)
00211     {
00212         std::tuple<Tail...> tail = get_row_internal(i + 1, t...);
00213         Head head = h.get_data(*this, i);
00214         return std::tuple_cat(std::make_tuple(head), tail);
00215     }
00216 
00217     void bind_internal(int)
00218     {
00219     }
00220 
00221     template<typename Head, typename... Tail> void bind_internal(int i, Head h, Tail... t)
00222     {
00223         BindWrap<Head> bw;
00224         bw.bind(i, h, *this);
00225         bind_internal(i + 1, t...);
00226     }
00227 
00228 };
00229 
00235 void execute_sql(std::string sql, Database& db);
00236 
00244 template<typename... Args> std::vector<std::tuple<Args...> > query_sql(std::string sql, Database& db, Statement::ColType<Args>... types)
00245 {
00246     Statement st(sql, db);
00247     return st.get_remaining_rows(types...);
00248 }
00249 
00250 template<>
00251 class Statement::ColType<int>
00252 {
00253 public:
00254     int get_data(Statement& st, int col_index)
00255     {
00256         return st.val_int(col_index);
00257     }
00258 };
00259 
00260 template<>
00261 class Statement::ColType<double>
00262 {
00263 public:
00264     double get_data(Statement& st, int col_index)
00265     {
00266         return st.val_double(col_index);
00267     }
00268 };
00269 
00270 template<>
00271 class Statement::ColType<int64_t>
00272 {
00273 public:
00274     int64_t get_data(Statement& st, int col_index)
00275     {
00276         return st.val_int64(col_index);
00277     }
00278 };
00279 
00280 template<>
00281 class Statement::ColType<std::string>
00282 {
00283 public:
00284     std::string get_data(Statement& st, int col_index)
00285     {
00286         return st.val_string(col_index);
00287     }
00288 };
00289 
00290 Statement::ColType<double> coldouble();
00291 
00292 Statement::ColType<int> colint();
00293 
00294 Statement::ColType<int64_t> colint64();
00295 
00296 Statement::ColType<std::string> colstr();
00297 
00298 template<>
00299 class Statement::BindWrap<int>
00300 {
00301 public:
00302     void bind(int index, int val, Statement& st)
00303     {
00304         st.bind_int(index, val);
00305     }
00306 };
00307 
00308 template<>
00309 class Statement::BindWrap<int64_t>
00310 {
00311 public:
00312     void bind(int index, int64_t val, Statement& st)
00313     {
00314         st.bind_int64(index, val);
00315     }
00316 };
00317 
00318 template<>
00319 class Statement::BindWrap<std::string>
00320 {
00321 public:
00322     void bind(int index, std::string const& val, Statement& st)
00323     {
00324         st.bind_string(index, val);
00325     }
00326 };
00327 
00328 template<>
00329 class Statement::BindWrap<double>
00330 {
00331 public:
00332     void bind(int index, double val, Statement& st)
00333     {
00334         st.bind_double(index, val);
00335     }
00336 };
00337 
00338 }
00339 
00340 #endif /* STATEMENT_H_ */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines