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
00058 struct Notification {
00059 std::string channel;
00060 int sending_pid;
00061 std::string payload;
00062 };
00063
00064 class PostgresqlDatabaseConfig
00065 {
00066 private:
00067 std::string password_;
00068 std::string user_;
00069 std::string host_;
00070 std::string port_;
00071 std::string dbname_;
00072
00073 public:
00074 PostgresqlDatabaseConfig() { }
00075
00076 std::string getPassword() const { return password_; }
00077 std::string getUser() const { return user_; }
00078 std::string getHost() const { return host_; }
00079 std::string getPort() const { return port_; }
00080 std::string getDBname() const { return dbname_; }
00081
00082 friend void operator>>(const YAML::Node &node, PostgresqlDatabaseConfig &options);
00083 };
00084
00088 void operator>>(const YAML::Node& node, PostgresqlDatabaseConfig &options);
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
00213 bool listenToChannel(std::string channel);
00214
00216 bool unlistenToChannel(std::string channel);
00217
00219 bool checkNotify(Notification &no);
00220
00222 bool waitForNotify(Notification &no);
00223
00224 };
00225
00246 template <class T>
00247 bool PostgresqlDatabase::getList(std::vector< boost::shared_ptr<T> > &vec,
00248 const T &example, std::string where_clause) const
00249 {
00250
00251 std::vector<const DBFieldBase*> fields;
00252
00253 std::vector<int> column_ids;
00254 boost::shared_ptr<PGresultAutoPtr> result;
00255
00256 int num_tuples;
00257
00258 if (!getListRawResult(&example, fields, column_ids, where_clause, result, num_tuples))
00259 {
00260 return false;
00261 }
00262
00263 vec.clear();
00264 if (!num_tuples)
00265 {
00266 return true;
00267 }
00268
00269
00270 for (int i=0; i<num_tuples; i++)
00271 {
00272 boost::shared_ptr<T> entry(new T);
00273 if (populateListEntry(entry.get(), result, i, fields, column_ids))
00274 {
00275 vec.push_back(entry);
00276 }
00277 }
00278 return true;
00279 }
00280
00281
00282 }
00283
00284 #endif