00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 #ifndef _POSTGRESQL_DATABASE_H_
00038 #define _POSTGRESQL_DATABASE_H_
00039 
00040 #include <vector>
00041 #include <string>
00042 #include <boost/shared_ptr.hpp>
00043 
00044 
00045 #include <ros/ros.h>
00046 #include <yaml-cpp/yaml.h>
00047 
00048 #include "database_interface/db_class.h"
00049 #include "database_interface/db_filters.h"
00050 
00051 
00052 struct pg_conn;
00053 typedef struct pg_conn PGconn;
00054 
00055 namespace database_interface {
00056 
00057 class PostgresqlDatabaseConfig
00058 {
00059 private:
00060   std::string password_;
00061   std::string user_;
00062   std::string host_;
00063   std::string port_;
00064   std::string dbname_;
00065 
00066 public:
00067   PostgresqlDatabaseConfig() {  }
00068 
00069   std::string getPassword() const { return password_; }
00070   std::string getUser() const { return user_; }
00071   std::string getHost() const { return host_; }
00072   std::string getPort() const { return port_; }
00073   std::string getDBname() const { return dbname_; }
00074 
00075   friend void operator>>(const YAML::Node &node, PostgresqlDatabaseConfig &options);
00076 };
00077 
00081 inline void operator>>(const YAML::Node& node, PostgresqlDatabaseConfig &options)
00082 {
00083   node["password"] >> options.password_;
00084   node["user"] >> options.user_;
00085   node["host"] >> options.host_;
00086   node["port"] >> options.port_;
00087   node["dbname"] >> options.dbname_;
00088 }
00089 
00090 class PostgresqlDatabase
00091 {
00092  protected:
00093   void pgMDBconstruct(std::string host, std::string port, std::string user,
00094                       std::string password, std::string dbname );
00095 
00097   PGconn* connection_;
00098 
00100   class PGresultAutoPtr;
00101 
00102   
00103   bool in_transaction_;
00104 
00106   bool getVariable(std::string name, std::string &value) const;
00107   
00109   bool rollback();
00110 
00112   bool begin();
00113 
00115   bool commit();
00116 
00118   template <class T>
00119     bool getList(std::vector< boost::shared_ptr<T> > &vec, const T& example, std::string where_clause) const;
00120 
00122   bool getListRawResult(const DBClass *example, std::vector<const DBFieldBase*> &fields, 
00123                         std::vector<int> &column_ids, std::string where_clause,
00124                         boost::shared_ptr<PGresultAutoPtr> &result, int &num_tuples) const;
00125 
00127   bool populateListEntry(DBClass *entry, boost::shared_ptr<PGresultAutoPtr> result, int row_num,
00128                          const std::vector<const DBFieldBase*> &fields,
00129                          const std::vector<int> &column_ids) const;
00130 
00132   bool getSequence(std::string name, std::string &value);
00133 
00135   bool insertIntoTable(std::string table_name, const std::vector<const DBFieldBase*> &fields);
00136 
00138   bool deleteFromTable(std::string table_name, const DBFieldBase *key_field);
00139 
00140  public:
00142   PostgresqlDatabase(std::string host, std::string port, std::string user,
00143                      std::string password, std::string dbname);
00144 
00146   PostgresqlDatabase(const PostgresqlDatabaseConfig &config);
00147 
00148 
00150   ~PostgresqlDatabase();
00151 
00153   bool isConnected() const;
00154 
00155   
00156 
00157   
00158   template <class T>
00159   bool getList(std::vector< boost::shared_ptr<T> > &vec) const
00160   {
00161     T example;
00162     return getList<T>(vec, example, "");
00163   }
00164   template <class T>
00165   bool getList(std::vector< boost::shared_ptr<T> > &vec, const FilterClause clause) const
00166   {
00167     T example;
00168     return getList<T>(vec, example, clause.clause_);
00169   }
00170   template <class T>
00171   bool getList(std::vector< boost::shared_ptr<T> > &vec, std::string where_clause) const
00172   {
00173     T example;
00174     return getList<T>(vec, example, where_clause);
00175   }
00176 
00177   
00178   template <class T>
00179   bool getList(std::vector< boost::shared_ptr<T> > &vec, const T &example) const
00180   {
00181     return getList<T>(vec, example, "");
00182   }
00183   template <class T>
00184   bool getList(std::vector< boost::shared_ptr<T> > &vec, const T &example, const FilterClause clause) const
00185   {
00186     return getList<T>(vec, example, clause.clause_);
00187   }
00188 
00190   bool countList(const DBClass *example, int &count, std::string where_clause) const;
00191 
00193   template <typename T>
00194   bool countList(int &count, const FilterClause clause=FilterClause()) const
00195   {
00196     T example;
00197     return countList(&example, count, clause.clause_);
00198   }
00199 
00201   bool saveToDatabase(const DBFieldBase* field);
00202 
00204   bool loadFromDatabase(DBFieldBase* field) const;
00205 
00207   bool insertIntoDatabase(DBClass* instance);
00208 
00210   bool deleteFromDatabase(DBClass* instance);
00211 
00212 };
00213 
00234 template <class T>
00235 bool PostgresqlDatabase::getList(std::vector< boost::shared_ptr<T> > &vec, 
00236                                  const T &example, std::string where_clause) const
00237 {
00238   
00239   std::vector<const DBFieldBase*> fields;
00240   
00241   std::vector<int> column_ids;
00242   boost::shared_ptr<PGresultAutoPtr> result;
00243 
00244   int num_tuples;
00245   
00246   if (!getListRawResult(&example, fields, column_ids, where_clause, result, num_tuples))
00247   {
00248     return false;
00249   }
00250 
00251   vec.clear();
00252   if (!num_tuples)
00253   {
00254     return true;
00255   }
00256 
00257   
00258   for (int i=0; i<num_tuples; i++)
00259   {
00260     boost::shared_ptr<T> entry(new T);
00261     if (populateListEntry(entry.get(), result, i, fields, column_ids))
00262     {
00263       vec.push_back(entry);
00264     }
00265   }
00266   return true;
00267 }
00268 
00269 
00270 }
00271 
00272 #endif