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
00038 #include "pgdb_property.hh"
00039 #include <vos/corelibs/vos/vos.hh>
00040
00041 #ifdef HAVE_POSTGRESQL_LIBPQ_FE_H
00042 #include <postgresql/libpq-fe.h>
00043 #else
00044 #ifdef HAVE_PGSQL_LIBPQ_FE_H
00045 #include <pgsql/libpq-fe.h>
00046 #else
00047 #error "Neither HAVE_POSTGRESQL_LIBPQ_FE_H nor HAVE_PGSQL_LIBPQ_FE_H are define, so I don't know where libpq-fe.h is!"
00048 #endif
00049 #endif
00050
00051
00052
00053 PGDBProperty::PGDBProperty(MetaObject* superobject) :
00054 DBProperty(superobject), LocalProperty(superobject), Property(superobject), MetaObject(superobject), dbcon(NULL) {
00055
00056 }
00057
00058
00059
00060 void PGDBProperty::open(const string& dbinfo = "")
00061 {
00062 dbcon = PQconnectdb(dbinfo.c_str());
00063
00064 LOG("postgres property", 4, "opening connection to database ("<<dbinfo<<")");
00065
00066 switch(PQstatus(dbcon)) {
00067 case CONNECTION_OK: break;
00068 case CONNECTION_BAD: throw DBAccessError("Failed to make database connection."); break;
00069 #ifndef HAVE_PGSQL_LIBPQ_FE_H
00070
00071 case CONNECTION_STARTED: throw DBAccessError("Database connection incomplete. (waiting for connection to be made)"); break;
00072 case CONNECTION_AWAITING_RESPONSE: throw DBAccessError("Database connection incomplete. (still waiting for response from PG postmaster)"); break;
00073 case CONNECTION_AUTH_OK: throw DBAccessError("Database connection incomplete. (authorization was okay, backend did not start)"); break;
00074 case CONNECTION_SETENV: throw DBAccessError("Database connection incomplete. (getting environment variables)"); break;
00075 #endif
00076 default: throw DBAccessError(string("Failed to make database connection (unkown error at ") + string(__FILE__) + string(" (PGDBProperty::PGDBProperty())."));
00077 }
00078
00079
00080
00081 }
00082
00083
00084
00085 PGDBProperty::~PGDBProperty() {
00086 PQfinish(dbcon);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 string PGDBProperty::queryDB(const string& query) throw(DBAccessError) {
00097
00098 PGresult *result;
00099 int ntuples, nfields, t, f;
00100 string s = "";
00101
00102
00103 LOG("postgres", 7, "querying db: " << query);
00104
00105 result = PQexec(dbcon, query.c_str());
00106
00107
00108
00109
00110
00111
00112 switch(PQresultStatus(result)) {
00113
00114 case PGRES_COMMAND_OK:
00115 case PGRES_COPY_OUT:
00116 case PGRES_COPY_IN:
00117
00118 PQclear(result);
00119 return "";
00120
00121 case PGRES_TUPLES_OK:
00122 ntuples = PQntuples(result);
00123 nfields = PQnfields(result);
00124 LOG("postgres", 9, "queryDB: there are "<<ntuples<<" tuples and "<<nfields<<" fields."<< (( (ntuples > 1) || (nfields > 1))?"Warning: only the first field will be returned.":""));
00125 s = string(PQgetvalue(result, 0, 0));
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 PQclear(result);
00138 return s;
00139
00140
00141 case PGRES_BAD_RESPONSE:
00142 throw DBAccessError(string("Error, Postgres server is talking jibba-jabba. ")+PQresultErrorMessage(result));
00143
00144 case PGRES_NONFATAL_ERROR:
00145 throw DBAccessError(string("Postgres reports a nonfatal error. But I don't know what to do with it, you try something: ")+PQresultErrorMessage(result));
00146
00147 case PGRES_EMPTY_QUERY:
00148 case PGRES_FATAL_ERROR:
00149 throw DBAccessError(string("Fatal error querying Postgres database! ")+PQresultErrorMessage(result));
00150 }
00151
00152 PQclear(result);
00153 return "";
00154
00155 }