postgresql_database.h
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 // Author(s): Matei Ciocarlie
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 //for ROS error messages
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 //A bit of an involved way to forward declare PGconn, which is a typedef
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   // beginTransaction sets this flag. endTransaction clears it.
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   //------- general queries that should work regardless of the datatypes actually being used ------
00156 
00157   //------- retrieval without examples ------- 
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   //------- retrieval with examples ------- 
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   //we will store here the fields to be retrieved retrieve from the database
00239   std::vector<const DBFieldBase*> fields;
00240   //we will store here their index in the result returned from the database
00241   std::vector<int> column_ids;
00242   boost::shared_ptr<PGresultAutoPtr> result;
00243 
00244   int num_tuples;
00245   //do all the heavy lifting of querying the database and getting the raw result
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   //parse the raw result and populate the list 
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 }//namespace
00271 
00272 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends


database_interface
Author(s): Matei Ciocarlie and Lorenz Mosenlechner
autogenerated on Wed Jan 16 2013 13:32:14