Example #1
0
int
pgConnection::logon(const char* conninfo)
{
  m_pgConn = PQconnectdb(conninfo);
  if (!m_pgConn) {
    throw db_excpt("connect", "not enough memory");
  }
  DBG_PRINTF(5,"logon m_pgConn=0x%p", m_pgConn);
  if (PQstatus(m_pgConn) == CONNECTION_BAD) {
    throw db_excpt("connect", PQerrorMessage(m_pgConn));
  }

  /* If the user has set PGCLIENTENCODING in its environment, then we decide
     to do no translation behind the postgresql client layer, since we
     assume that the user knows what he's doing. In the future, we may
     decide for a fixed encoding (that would be unicode/utf8, most
     probably) and override PGCLIENTENCODING. */
  if (!getenv("PGCLIENTENCODING")) {
    PGresult* res=PQexec(m_pgConn, "SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname=current_database()");
    if (res && PQresultStatus(res)==PGRES_TUPLES_OK) {
      const char* enc=(const char*)PQgetvalue(res,0,0);
      // pgsql versions under 8.1 return 'UNICODE', >=8.1 return 'UTF8'
      // we keep UTF8
      if (!strcmp(enc,"UNICODE"))
        enc="UTF8";
      set_encoding(enc);
    }
    if (res)
      PQclear(res);
  }
  PQclear(PQexec(m_pgConn, "SET standard_conforming_strings=on"));
  return 1;
}
void
sql_stream::check_binds()
{
  if (m_bExecuted && m_nArgPos==(int)m_vars.size()) {
    // reset the query for another execution
    reset_results();
  }
  if (m_nArgPos>=(int)m_vars.size())
    throw db_excpt(m_queryBuf, "Mismatch between bound variables and query");
}
void
sql_stream::execute()
{
  /* in the general case execute() will be called implicitly as soon
     as all the variables are bound. However the user code might want
     to call it explicitly to have a better control over the execution
     workflow. That's why in the case of a second call to execute() we
     choose not to throw any error and instead just return, except if
     m_auto_exec is false in which case execute() is always
     explicit */

  if (m_bExecuted && m_auto_exec)
    return;

  if (m_nArgPos<(int)m_vars.size())
    throw db_excpt(m_queryBuf, QString("Not all variables are bound (%1 out of %2)").arg(m_nArgPos).arg(m_vars.size()));

  DBG_PRINTF(5,"execute: %s", m_queryBuf);
  m_pgRes=PQexec(m_db.connection(), m_queryBuf);
  if (!m_pgRes)
    throw db_excpt(m_queryBuf, PQerrorMessage(m_db.connection()));
  if (PQresultStatus(m_pgRes)!=PGRES_TUPLES_OK && PQresultStatus(m_pgRes)!=PGRES_COMMAND_OK) {
    throw db_excpt(m_queryBuf, PQresultErrorMessage(m_pgRes),
		   QString(PQresultErrorField(m_pgRes, PG_DIAG_SQLSTATE)));
  }
  const char* t=PQcmdTuples(m_pgRes);
  if (t && *t) {
    m_affected_rows=atoi(t);
  }
  else
    m_affected_rows=0;
    
  m_rowNumber=0;
  m_colNumber=0;
  m_bExecuted=1;
}
void
sql_stream::check_eof()
{
  if (eof())
    throw db_excpt(m_queryBuf, "End of stream reached");
}