00001
00002
00003
00004
00005 #ifndef dsPGi_h
00006 #define dsPGi_h
00007
00008 #ifdef HAVE_CONFIG_H
00009 # include <config.h>
00010 #endif
00011
00012 #ifdef HAVE_UNISTD_H
00013 # include <unistd.h>
00014 #endif
00015
00016 #ifndef
00017 # include <string>
00018 #endif
00019
00020 #include <libpq-fe.h>
00021 #include <libpq-int.h>
00022
00023 #include <limits.h>
00024 #include <stdlib.h>
00025 #include <os.h>
00026
00027 #include <dsSmartException.h>
00028
00029
00030 #define LIBPQ_VERSION 64
00031
00032 DECLARE_EXCEPTION(dsPGi);
00033
00034
00035 DECLARE_EXCEPTION2(dsPGiData, dsPGi);
00036
00040 class dsPGi
00041 {
00042 public :
00043 PGconn *_conn;
00044 PGresult *_res;
00045 PGresult *_act_res;
00046 char * _cursor;
00047 char *_dbName;
00048 FILE *debf;
00049 int _has_begin;
00050 public :
00051
00052 dsPGi()
00053 { _conn = 0;
00054 _res = 0;
00055 _act_res = 0;
00056 _cursor = 0;
00057 _dbName = 0;
00058 debf = 0;
00059 _has_begin = 0;
00060 }
00061
00062 dsPGi(const char *database, const char *user = 0, const char *passwd = 0)
00063 { memset(this, 0, sizeof(*this) );
00064 connect(database,0,0,user, passwd);
00065 }
00066
00067 dsPGi(const char *database, const char *host, const char *port,
00068 const char *user, const char *passwd = 0)
00069 { memset(this, 0, sizeof(*this) );
00070 connect(database,host,port,user, passwd);
00071 }
00072
00073
00074 ~dsPGi()
00075 {
00076 destructor;
00077 if (_act_res) PQclear(_act_res);
00078 if (_conn) PQfinish(_conn);
00079 if (_dbName) delete _dbName;
00080 }
00081
00082
00083 dsPGi *get_result();
00084
00085 void connect(const char* dbName,
00086 const char *host, const char *port,
00087 const char *user, const char *passwd);
00088
00089 void close()
00090 {
00091 if (_act_res)
00092 PQclear(_act_res);
00093 if (_conn)
00094 PQfinish(_conn);
00095 _act_res = 0;
00096 _conn = 0;
00097 }
00098
00099 void openCursor(const char *query, const char *cursor = 0);
00100
00101 #ifndef
00102 void openCursor(const std::string& query, const char *cursor = 0) {
00103 openCursor((const char *) query.c_str(), cursor);
00104 }
00105 #endif
00106
00107 void closeCursor();
00108 int fetchNext();
00109 int fetchAll();
00110
00111 void runActionAsync(const char* query, int alarm_timeout = 10);
00112
00113 enum tts { no_trans = 0, do_trans = 3, begin_trans = 1, end_trans = 2 };
00114 void runAction(const char* query, tts use_tts = do_trans);
00115
00116 #ifndef
00117 void runAction(const std::string& query, tts use_tts = do_trans) {
00118 runAction((const char *) query.c_str(), use_tts);
00119 }
00120 #endif
00121
00122 void runQuery(const char *query);
00123
00124 #ifndef
00125 void runQuery(const std::string& query) { runQuery( (const char *) query.c_str()); }
00126 #endif
00127
00128
00129 int touples_changed() const
00130 {
00131 const char *res =(const char *) PQcmdTuples(_act_res);
00132 return res ? atoi(res) : 0;
00133 }
00134
00135
00136 const char *last_oid() const
00137 {
00138 const char *res = (const char *)PQoidStatus(_act_res);
00139 return res ? res : "";
00140 }
00141
00142
00143
00144 const int __tuples( PGresult *x_res){ return PQntuples(x_res); }
00145 const int __fields( PGresult *x_res){ return PQnfields(x_res); }
00146 const char * __fieldname(PGresult *x_res, int i){ return PQfname(x_res, i); }
00147 const char * __value(PGresult *x_res, int tuple, int field)
00148 { if (tuple >= __tuples(x_res))
00149 throw dsPGiException("Invalid tuple number: %d", tuple);
00150 if (field >= __fields(x_res))
00151 throw dsPGiException("Invalid field number: %d", field);
00152 return PQgetvalue(x_res, tuple, field);
00153 }
00154
00155 const char *__value(PGresult *x_res, int tuple, char *field)
00156 { for( int i = 0; i < __fields(x_res); ++i)
00157 { if (strcmp( __fieldname(x_res, i), field ) == 0 )
00158 { return __value(x_res, tuple, i);
00159 }
00160 }
00161 throw dsPGiException("No such field: '%s'", field);
00162 }
00163
00164
00165
00166
00167
00168 int qtuples() { return __tuples(_act_res); }
00169 int qtouples() { return __tuples(_act_res); }
00170 int qfields(){ return __fields(_act_res); }
00171 const char *qfieldname(int i){ return __fieldname(_act_res,i); }
00172 const char *qvalue(int field){ return __value(_act_res, 0, field); }
00173 const char *qvalue(char *field){ return __value(_act_res,0,field); }
00174 const char *qvalue(int tuple, int field){ return __value(_act_res, tuple, field); }
00175 const char *qvalue(int tuple, char *field){ return __value(_act_res,tuple,field); }
00176
00177 int tuples(){ return __tuples(_res); }
00178 int touples(){ return __tuples(_res); }
00179 int fields(){ return __fields(_res); }
00180 const char *fieldname(int i){ return __fieldname(_res,i); }
00181 const char *value(int field){ return __value(_res, 0, field); }
00182 const char *value(char *field){ return __value(_res,0,field); }
00183 const char *value(int tuple, int field){ return __value(_res, tuple, field); }
00184 const char *value(int tuple, char *field){ return __value(_res,tuple,field); }
00185
00186
00187 const char *cursor(){ return _cursor; }
00188
00189 const char *operator [](int field){ return __value(_res, 0, field); }
00190 const char *operator [](char *field){ return __value(_res, 0, field); }
00191
00192 void trace(const char *fname = 0)
00193 {
00194 char qbuf[64];
00195
00196 if (fname)
00197 { if (*fname == '-')
00198 debf = (*fname == '-') ? stderr : fopen(fname, "w");
00199 }
00200 else
00201 { sprintf(qbuf,"trace.%04d", getpid() );
00202 debf = fopen( (char *)qbuf, "w");
00203 }
00204
00205 if (!debf) debf = stderr;
00206 PQtrace(_conn, debf);
00207 }
00208 void trace(FILE *f) { PQtrace(_conn, f); }
00209
00210
00211 PGresult *getResult(){ return _res; }
00212
00213
00214 void begin();
00215 void commit();
00216 void rollback();
00217 };
00218
00219 #endif