solarpowerlog trunk
/home/tobi/workspace/solarpowerlog/src/interfaces/PersistanceStorage/QueryHelper.cpp
Go to the documentation of this file.
00001 /*
00002  * _QueryHelper.cpp
00003  *
00004  *  Created on: Feb 7, 2010
00005  *      Author: tobi
00006  */
00007 
00008 #include "QueryHelper.h"
00009 
00010 #include <assert.h>
00011 
00012 QueryHelper::QueryHelper(dbixx::session *session,
00013           std::map<std::string, dbtypes> *table_spec)
00014 {
00015      this->table_spec = table_spec;
00016      this->session = session;
00017      this->r = NULL;
00018 }
00019 
00020 QueryHelper::~QueryHelper()
00021 {
00022      if (r)
00023           delete r;
00024 }
00025 
00026 int QueryHelper::DoQuery(std::vector<std::string> &what, std::string &where)
00027 {
00028      assert(session);
00029      if (!r) {
00030           r = new dbixx::result;
00031      }
00032 
00033      try {
00034           // store infos for later retrival
00035           this->what = what;
00036 
00037           // build query
00038           *session << "SELECT ";
00039 
00040           if (what.size() == 1) {
00041                *session << what[0];
00042           } else {
00043                bool first = true;
00044                std::vector<std::string>::iterator it;
00045                while (it != what.end()) {
00046                     if (first) {
00047                          *session << (*it);
00048                          first = false;
00049                     } else {
00050                          *session << "," << (*it);
00051                     }
00052                }
00053           }
00054 
00055           *session << " " << where;
00056 
00057           // now run query, assign result and return the number of rows.
00058           session->fetch(*r);
00059           return r->rows();
00060      } catch (dbixx::dbixx_error const &e) {
00061           // fixme: we need to have access of the logger here....
00062           this->what.clear();
00063           std::runtime_error ex(std::string("query ") + e.query()
00064                     + " failed with " + e.what());
00065           delete r;
00066           r = 0;
00067           throw ex;
00068      }
00069 }
00070 
00071 std::map<std::string, boost::any> QueryHelper::GetNextResult(void)
00072 {
00073      // no results without searches.
00074      assert(r);
00075 
00076      dbixx::row row;
00077      if (!r->next(row)) {
00078           std::runtime_error ex(std::string("unexpected getnextresult"));
00079           throw ex;
00080      }
00081 
00082      std::vector<std::string>::iterator columns_it;
00083      std::map<std::string, boost::any> result_map;
00084      std::pair<std::string, boost::any> p;
00085      int i = 0;
00086 
00087      dbtypes type_wanted;
00088      for (i = 0, columns_it = what.begin(); columns_it != what.end(); i++, columns_it++) {
00089           p.first = *columns_it;
00090 
00091           std::map<std::string, dbtypes>::iterator ts_it = table_spec->find(
00092                     *columns_it);
00093           if (ts_it == table_spec->end() || ts_it->second == db_string) {
00094                type_wanted = db_string;
00095           } else {
00096                type_wanted = ts_it->second;
00097           }
00098 
00099           switch (type_wanted)
00100           {
00101 
00102           case db_string:
00103           {
00104                std::string t;
00105                if (!row.fetch(i, t))
00106                     break;
00107                p.second = boost::any(t);
00108                result_map.insert(p);
00109                break;
00110           }
00111 
00112           case db_integer:
00113           case db_unsignedinteger:
00114           {
00115                long long intermediate;
00116                long t;
00117                if (!row.fetch(i, intermediate))
00118                     break;
00119                t = intermediate;
00120                p.second = boost::any(t);
00121                result_map.insert(p);
00122                break;
00123           }
00124 
00125           case db_longlong:
00126           {
00127                long long t;
00128                if (!row.fetch(i, t))
00129                     break;
00130                p.second = boost::any(t);
00131                result_map.insert(p);
00132                break;
00133           }
00134 
00135           case db_unsignedlonglong:
00136           {
00137                unsigned long long t;
00138                if (!row.fetch(i, t))
00139                     break;
00140                p.second = boost::any(t);
00141                result_map.insert(p);
00142                break;
00143           }
00144 
00145           case db_decimal:
00146           {
00147                double t;
00148                if (!row.fetch(i, t))
00149                     break;
00150                p.second = boost::any(t);
00151                result_map.insert(p);
00152                break;
00153           }
00154 
00155           case db_tm:
00156           {
00157                std::tm tm;
00158                if (!row.fetch(i, tm))
00159                     break;
00160                p.second = boost::any(tm);
00161                result_map.insert(p);
00162                break;
00163           }
00164 
00165           }
00166      }
00167 
00168      return result_map;
00169 
00170 }
00171