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 #include "postgresxx.hpp"
00030
00031
00032
00033 PostgresContext::PostgresContext( const string &dbName,
00034 const string &user,
00035 const string &passwd,
00036 const string &host,
00037 const int port,
00038 const string &unixSocket,
00039 const unsigned long clientFlags )
00040 : handle( 0 ),
00041 _dbName( dbName ),
00042 _user( user ),
00043 _passwd( passwd ),
00044 _host( host ),
00045 _port( port )
00046 {
00047 if( !_dbName.empty() )
00048 {
00049 try
00050 {
00051 open();
00052 }
00053 catch( SqlDatabaseOpenException &e )
00054 {
00055 throw e;
00056 }
00057 }
00058 }
00059
00060 PostgresContext::~PostgresContext()
00061 {
00062 close();
00063 }
00064
00065 void PostgresContext::close()
00066 {
00067 if( handle )
00068 {
00069 PQfinish( handle );
00070 }
00071 }
00072
00073 string PostgresContext::escapeString( const string ¶m ) const
00074 {
00075 char escapedSql[ param.length() * 2 + 1 ];
00076 PQescapeStringConn( handle, escapedSql, param.c_str(), param.length(), 0 );
00077 return escapedSql;
00078 }
00079
00080 string PostgresContext::version() const
00081 {
00082 ostringstream buf;
00083 buf << "PostgreSQL " << PQserverVersion( handle );
00084 return buf.str();
00085 }
00086
00087
00088
00089 void PostgresContext::open()
00090 {
00091 if( handle == 0 )
00092 {
00093 ostringstream buf;
00094
00095 buf << "host=" << _host << " dbname=" << _dbName
00096 << " user=" << _user << " password=" << _passwd
00097 << " connect_timeout=5" << " options=" << _clientFlags;
00098
00099 handle = PQconnectdb( buf.str().c_str() );
00100
00101 if( PQstatus( handle ) != CONNECTION_OK )
00102 {
00103 string ex = "Failed to connect to database: ";
00104 ex += PQerrorMessage( handle );
00105 close();
00106 throw SqlDatabaseOpenException( ex );
00107 }
00108 }
00109 }
00110
00111 SqlResult PostgresContext::query( const string &sql ) const
00112 {
00113 PGresult *rawResult = 0;
00114 SqlResult result;
00115
00116 if( !( rawResult = PQexec( handle, sql.c_str() ) ) )
00117 {
00118 string ex = "Bad SQL statement: ";
00119 ex += sql;
00120 ex += "\nPostgreSQL message: ";
00121 ex += PQerrorMessage( handle );
00122 throw SqlDatabaseBadStatementException( ex );
00123 }
00124
00125 ExecStatusType retValue = PQresultStatus( rawResult );
00126
00127 if( retValue == PGRES_TUPLES_OK )
00128 {
00129 int numRows = PQntuples( rawResult );
00130 int numColumns = PQnfields( rawResult );
00131
00132 for( int r = 0; r < numRows; ++r )
00133 {
00134 SqlRow *row = new SqlRow( numColumns );
00135 result.add( row );
00136
00137 for( int c = 0; c < numColumns; ++c )
00138 {
00139 row->add( PQgetvalue( rawResult, r, c ) );
00140 }
00141 }
00142 }
00143 else if( retValue == PGRES_BAD_RESPONSE
00144 || retValue == PGRES_FATAL_ERROR
00145 || retValue == PGRES_EMPTY_QUERY )
00146
00147 {
00148 string ex = sql;
00149 ex += "\nPostgreSQL message: ";
00150 ex += PQresStatus( retValue );
00151 ex += ": ";
00152 ex += PQerrorMessage( handle );
00153 throw SqlDatabaseUnknownException( ex );
00154 }
00155
00156 PQclear( rawResult );
00157 return result;
00158 }