bool PDOPgSqlStatement::getColumnMeta(int64_t colno, Array &return_value){ if (!m_result){ return false; } if(colno < 0 || colno >= column_count){ return false; } Oid coltype = m_pgsql_column_types[colno]; return_value.add(String("pgsql:oid"), (long)coltype); std::string q = strprintf("SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", coltype); PQ::Result res = m_server->exec(q); ExecStatusType status = res.status(); if(status != PGRES_TUPLES_OK){ return true; } if(res.numTuples() != 1){ return true; } return_value.add(String("native_type"), String(res.getValue(0, 0))); return true; }
int64_t PDOPgSqlConnection::doer(const String& sql){ testConnection(); const char* query = sql.data(); PQ::Result res = m_server->exec(query); if(!res){ // I think this error should be handled in a different way perhaps? handleError(nullptr, "XX000", "Invalid result data"); return -1; } ExecStatusType status = m_lastExec = res.status(); int64_t ret; if(status == PGRES_COMMAND_OK){ ret = (int64_t)res.cmdTuples(); } else if(status == PGRES_TUPLES_OK) { ret = 0L; } else { HANDLE_ERROR(nullptr, res); return -1L; } this->pgoid = res.oidValue(); return ret; }
bool PDOPgSqlConnection::transactionCommand(const char* command){ testConnection(); PQ::Result res = m_server->exec(command); if(!res){ // I think this error should be handled in a different way perhaps? handleError(nullptr, "XX000", "Invalid result data"); return -1; } ExecStatusType status = m_lastExec = res.status(); if(status == PGRES_COMMAND_OK){ return true; } HANDLE_ERROR(nullptr, res); return false; }
String PDOPgSqlConnection::lastId(const char *name){ if (name == nullptr || strlen(name) == 0){ // This branch of code doesn't seem to ever do anything useful // however it does pretty much the same as the zend implementation // and that doesn't seem to provide anything useful either if(this->pgoid == InvalidOid){ return empty_string(); } return String((long)this->pgoid); } else { const char *values[1]; values[0] = name; PQ::Result res = m_server->exec("SELECT CURRVAL($1)", 1, values); ExecStatusType status = res.status(); if(res && (status == PGRES_TUPLES_OK)){ return String(res.getValue(0, 0), CopyString); } else { HANDLE_ERROR(nullptr, res); return empty_string(); } } }
int PDOPgSqlConnection::getAttribute(int64_t attr, Variant &value){ switch(attr){ case PDO_ATTR_CLIENT_VERSION: value = String(PG_VERSION); break; case PDO_ATTR_SERVER_VERSION: if(m_server->protocolVersion() >= 3){ // Postgres 7.4 or later value = String(m_server->parameterStatus("server_version"), CopyString); } else { PQ::Result res = m_server->exec("SELECT VERSION()"); if(res && res.status() == PGRES_TUPLES_OK){ value = String((char *)res.getValue(0, 0), CopyString); } } break; case PDO_ATTR_CONNECTION_STATUS: switch(m_server->status()){ case CONNECTION_STARTED: value = String("Waiting for connection to be made.", CopyString); break; case CONNECTION_MADE: case CONNECTION_OK: value = String("Connection OK; waiting to send.", CopyString); break; case CONNECTION_AWAITING_RESPONSE: value = String("Waiting for a response from the server.", CopyString); break; case CONNECTION_AUTH_OK: value = String( "Received authentication; waiting for backend start-up to finish.", CopyString ); break; #ifdef CONNECTION_SSL_STARTUP case CONNECTION_SSL_STARTUP: value = String("Negotiating SSL encryption.", CopyString); break; #endif case CONNECTION_SETENV: value = String( "Negotiating environment-driven parameter settings.", CopyString ); break; case CONNECTION_BAD: default: value = String("Bad connection.", CopyString); break; } break; case PDO_ATTR_SERVER_INFO: { int spid = m_server->backendPID(); std::stringstream result; result << "PID: "; result << spid; result << "; Client Encoding: "; result << m_server->parameterStatus("client_encoding"); result << "; Is Superusser: "; result << m_server->parameterStatus("is_superuser"); result << "; Session Authorization: "; result << m_server->parameterStatus("session_authorization"); result << "; Date Style: "; result << m_server->parameterStatus("DateStyle"); value = String(result.str()); } break; default: return 0; } return 1; }