void issue(const std::string& command) {
      PQclear(res);
#ifdef DEBUG
      std::cout << "Command.issue mit " << command << std::endl;
#endif
      res = PQexec(conn, command.c_str());
#ifdef DEBUG
      std::cout << "PQexec erfolgreich, *res = " << res << std::endl;
#endif
      ExecStatusType status(PQresultStatus(res));
#ifdef DEBUG
      std::cout << "PQresultStatus erfolgreich, status = " << status << std::endl;
#endif
      if (status != PGRES_COMMAND_OK) {
#ifdef DEBUG
	std::cout << "status != PGRES_COMMAND_OK" << std::endl;
	std::cout << "PQresultErrorMessage(res): " << PQresultErrorMessage(res) << std::endl;
	std::cout << "conn.getName(): " << conn.getName() << std::endl;
	std::cout << "PQresStatus(status): " << PQresStatus(status) << std::endl;
#endif
	throw Error::command_failed(PQresultErrorMessage(res), conn.getName(), PQresStatus(status));
      }
#ifdef DEBUG
      std::cout << "PGRES_COMMAND_OK" << std::endl;
#endif
    }
Exemple #2
0
/* load rows directly from network buffer */
static void exec_query_zero_copy(struct Context *ctx, const char *q)
{
	PGconn *db = ctx->db;
	PGresult *r;
	ExecStatusType s;
	PGdataValue *cols;

	ctx->count = 0;

	if (!PQsendQuery(db, q))
		die(db, "PQsendQuery");

	if (!PQsetSingleRowMode(db))
		die(NULL, "PQsetSingleRowMode");

	/* loop until all resultset is done */
	while (PQgetRowData(db, &r, &cols)) {
		proc_row_zcopy(ctx, r, cols);
	}

	/* get final result */
	r = PQgetResult(db);
	s = PQresultStatus(r);
	switch (s) {
	case PGRES_TUPLES_OK:
		//printf("query successful, got %d rows\n", ctx->count);
		ctx->count = 0;
		break;
	default:
		printf("result: %s\n", PQresStatus(s));
		break;
	}
	PQclear(r);
}
Exemple #3
0
/*
 * call-seq:
 *    res.res_status( status ) -> String
 *
 * Returns the string representation of status +status+.
 *
*/
static VALUE
pgresult_res_status(VALUE self, VALUE status)
{
	VALUE ret = rb_tainted_str_new2(PQresStatus(NUM2INT(status)));
	ASSOCIATE_INDEX(ret, self);
	return ret;
}
Exemple #4
0
void doSQL(PGconn *conn, char *command)
{
  PGresult *result;

  printf("%s\n", command);

  result = PQexec(conn, command);
  printf("status is %s\n", PQresStatus(PQresultStatus(result)));
  printf("#rows affected %s\n", PQcmdTuples(result));
  printf("result message: %s\n", PQresultErrorMessage(result));

  switch(PQresultStatus(result)) {
  case PGRES_TUPLES_OK:
    {
      int r, n;
      int nrows = PQntuples(result);
      int nfields = PQnfields(result);
      printf("number of rows returned = %d\n", nrows);
      printf("number of fields returned = %d\n", nfields);
      for(r = 0; r < nrows; r++) {
	for(n = 0; n < nfields; n++)
	  printf(" %s = %s(%d),", 
		 PQfname(result, n), 
		 PQgetvalue(result, r, n),
		 PQgetlength(result, r, n));
	printf("\n");
      }
    }
  }
  PQclear(result);
}
/* Reads the next result row from the snapshot query, parses and processes it.
 * Blocks until a new row is available, if necessary. */
int snapshot_poll(client_context_t context) {
    int err = 0;
    PGresult *res = PQgetResult(context->sql_conn);

    /* null result indicates that there are no more rows */
    if (!res) {
        check(err, exec_sql(context, "COMMIT"));
        PQfinish(context->sql_conn);
        context->sql_conn = NULL;

        // Invoke the commit callback with xid==0 to indicate end of snapshot
        commit_txn_cb on_commit = context->repl.frame_reader->on_commit_txn;
        void *cb_context = context->repl.frame_reader->cb_context;
        if (on_commit) {
            check(err, on_commit(cb_context, context->repl.start_lsn, 0));
        }
        return 0;
    }

    ExecStatusType status = PQresultStatus(res);
    if (status != PGRES_SINGLE_TUPLE && status != PGRES_TUPLES_OK) {
        client_error(context, "While reading snapshot: %s: %s",
                PQresStatus(PQresultStatus(res)),
                PQresultErrorMessage(res));
        PQclear(res);
        return EIO;
    }

    int tuples = PQntuples(res);
    for (int tuple = 0; tuple < tuples; tuple++) {
        check(err, snapshot_tuple(context, res, tuple));
    }
    PQclear(res);
    return err;
}
std::string StatementException::compose(const std::string& text, PgSQL_STMT* h, const std::string& stmt)
{
	std::string str;
	str += "[Comment]: ";
	str += text;

	if (h != 0)
	{
		str += "\t[PgSQL_stmt_error]: ";
		str += PQresultErrorMessage(h);

		// FIXME:
		/*
		str += "\t[PgSQL_stmt_errno]: ";
		char buff[30];
		sprintf(buff, "%d", PQresultErrorField(h, fieldCode));
		str += buff;
*/
		str += "\t[PgSQL_stmt_sqlstate]: ";
		str += PQresStatus(PQresultStatus(h));
	}

	if (stmt.length() > 0)
	{
		str += "\t[statemnt]: ";
		str += stmt;
	}

	return str;
}
Exemple #7
0
void dlgDirectDbg::OnTargetComplete( wxCommandEvent &event )
{
	// Extract the result set handle from the event and log the status info

	PGresult    *result = (PGresult *)event.GetClientData();

	wxLogInfo( wxT( "OnTargetComplete() called\n" ));
	wxLogInfo( wxT( "%s\n" ), wxString(PQresStatus( PQresultStatus( result )), wxConvUTF8).c_str());

	// If the query failed, write the error message to the status line, otherwise, copy the result set into the grid
	if(( PQresultStatus( result ) == PGRES_NONFATAL_ERROR ) || ( PQresultStatus( result ) == PGRES_FATAL_ERROR ))
	{
		wxString    message( PQresultErrorMessage( result ), wxConvUTF8 );

		message.Replace( wxT( "\n" ), wxT( " " ));

		m_parent->getStatusBar()->SetStatusText( message, 1 );
		char *state = PQresultErrorField(result, PG_DIAG_SQLSTATE);

		// Don't bother telling the user that he aborted - he already knows!
		// Depending on the stage, m_conn might not be set all! so check for
		// that first
		if (m_conn)
		{
			if (state != NULL && strcmp(state, "57014"))
				wxLogError( wxT( "%s\n" ), wxString(PQerrorMessage(m_conn->getConnection()), wxConvUTF8).c_str());
			else
				wxLogInfo( wxT( "%s\n" ), wxString(PQerrorMessage(m_conn->getConnection()), wxConvUTF8).c_str());
		}
	}
	else
	{
		wxString message( PQcmdStatus( result ), wxConvUTF8 );

		message.Replace( wxT( "\r" ), wxT( "" ));
		message.Replace( wxT( "\n" ), wxT( " " ));

		m_parent->getStatusBar()->SetStatusText( message, 1 );

		// If this result set has any columns, add a result grid to the code window so
		// we can show the results to the user

		if( m_codeWindow && PQnfields( result ))
		{
			m_codeWindow->OnResultSet( result );
		}
	}

	if (m_codeWindow)
	{
		m_codeWindow->m_targetComplete = true;
		m_codeWindow->disableTools( );
	}

	// Do not show if aborted
	if ( m_codeWindow && m_codeWindow->m_targetAborted )
		return;

	this->Show( true );
}
Exemple #8
0
Fichier : be.c Projet : po1vo/aide
static int be_sql_readinit(psql_data* ret) {
  /* Yes.. we don't want to know about two first result.. 
     and we want no memoryleaking.
  */
  int i,j,nFields;
  char* s;
  char declare []="DECLARE aidecursor CURSOR FOR select * from ";
  
  s = (char*)malloc(strlen(declare)+strlen(ret->table)+1);
  s[0]=0;
  s=strcat(s,declare);
  s=strcat(s,ret->table);
  
  ret->res=PQexec(ret->conn,s);
		  
  if (!ret->res || PQresultStatus(ret->res) != PGRES_COMMAND_OK) {
    
    if (ret->res!=NULL) {
      error(255,"Psql error: %s\n",PQresStatus(PQresultStatus(ret->res)));
      PQclear(ret->res);
    }
    return RETFAIL;
  }
  PQclear(ret->res);
  
  ret -> res = PQexec(ret->conn, "FETCH ALL in aidecursor");
  
  if (!ret->res || PQresultStatus(ret->res) != PGRES_TUPLES_OK)
    {
      error(0, "FETCH ALL command didn't return tuples properly\n");
      PQclear(ret->res);
      abort();
    }
  
  
  /* first, print out the attribute names */
  nFields = PQnfields(ret->res);
  for (i = 0; i < nFields; i++)
    error(255,"%-15s", PQfname(ret->res, i));
  error(255,"\n\n");
  
  
  for(i=0;i<db_unknown;i++){
    ret->des[i]=PQfnumber(ret->res,db_names[i]);
    if (ret->des[i]!=-1) {
      error(255,"Field %i,%s \n",ret->des[i],db_names[i]);
    }
  }
  
  ret->curread=0;
  ret->maxread=PQntuples(ret->res);
  /* And now we know how many fields we have.. */
  
  error(10,"%i tuples\n",ret->maxread);
  
  return RETOK;
  
}
Exemple #9
0
static awk_value_t *
set_error(PGconn *conn, ExecStatusType status, awk_value_t *result)
{
  char buf[100];
  snprintf(buf, sizeof(buf), "ERROR %s%s",
	   ((PQstatus(conn) != CONNECTION_OK) ? "BADCONN " : ""),
	   PQresStatus(status));
  return make_string_malloc(buf, strlen(buf), result);
}
Exemple #10
0
/*
 * Get the max size of the relation across segments
 */
int64
cdbRelMaxSegSize(Relation rel)
{
	int64 size = 0;
	int i;
	CdbPgResults cdb_pgresults = {NULL, 0};
	StringInfoData buffer;

	char *schemaName;
	char *relName;

	/*
	 * Let's ask the QEs for the size of the relation
	 */
	initStringInfo(&buffer);

	schemaName = get_namespace_name(RelationGetNamespace(rel));
	if (schemaName == NULL)
		elog(ERROR, "cache lookup failed for namespace %d",
			 RelationGetNamespace(rel));
	relName = RelationGetRelationName(rel);

	/*
	 * Safer to pass names than oids, just in case they get out of sync between QD and QE,
	 * which might happen with a toast table or index, I think (but maybe not)
	 */
	appendStringInfo(&buffer, "select pg_relation_size('%s.%s')",
					 quote_identifier(schemaName), quote_identifier(relName));

	CdbDispatchCommand(buffer.data, DF_WITH_SNAPSHOT, &cdb_pgresults);

	for (i = 0; i < cdb_pgresults.numResults; i++)
	{
		struct pg_result * pgresult = cdb_pgresults.pg_results[i];
		if (PQresultStatus(pgresult) != PGRES_TUPLES_OK)
		{
			cdbdisp_clearCdbPgResults(&cdb_pgresults);
			elog(ERROR,"cdbRelMaxSegSize: resultStatus not tuples_Ok: %s %s",
				 PQresStatus(PQresultStatus(pgresult)),PQresultErrorMessage(pgresult));
		}
		else
		{
			Assert(PQntuples(pgresult) == 1);
			int64 tempsize = 0;
			(void) scanint8(PQgetvalue(pgresult, 0, 0), false, &tempsize);
			if (tempsize > size)
				size = tempsize;
		}
	}

	pfree(buffer.data);

	cdbdisp_clearCdbPgResults(&cdb_pgresults);

	return size;
}
Exemple #11
0
static const char *
esql_postgresql_error_get(Esql *e)
{
   const char *p;

   p = PQerrorMessage(e->backend.db);
   if ((!p) || (!*p))
     p = PQresStatus(PQresultStatus(e->res->backend.res));

   return p;
}
char * pq_escape (PGconn* cxn, const char* input, int len)
{
    char *output;

    output = PQescapeLiteral(cxn, input, len);

    if (output == NULL)
        LOGSTDERR(ERROR, PQresStatus(PGRES_FATAL_ERROR),
                  "Failed to escape string: %s", input);

    // free output in caller
    return(output);
}
Exemple #13
0
/*************************************************************************
 *
 *	Function: sql_query
 *
 *	Purpose: Issue a query to the database
 *
 *************************************************************************/
static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {

	rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;

	if (config->sqltrace)
		radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr);

	if (pg_sock->conn == NULL) {
		radlog(L_ERR, "rlm_sql_postgresql: Socket not connected");
		return SQL_DOWN;
	}

	pg_sock->result = PQexec(pg_sock->conn, querystr);
		/* Returns a result pointer or possibly a NULL pointer.
		 * A non-NULL pointer will generally be returned except in
		 * out-of-memory conditions or serious errors such as inability
		 * to send the command to the backend. If a NULL is returned,
		 *  it should be treated like a PGRES_FATAL_ERROR result.
		 * Use PQerrorMessage to get more information about the error.
		 */
	if (!pg_sock->result)
	{
		radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
				PQerrorMessage(pg_sock->conn));
		return  SQL_DOWN;
	} else {
		ExecStatusType status = PQresultStatus(pg_sock->result);

		radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status));

		radlog(L_DBG, "rlm_sql_postgresql: affected rows = %s",
				PQcmdTuples(pg_sock->result));

		if (!status_is_ok(status))
			return sql_check_error(status);

		if (strncasecmp("select", querystr, 6) != 0) {
			/* store the number of affected rows because the sql module
			 * calls finish_query before it retrieves the number of affected
			 * rows from the driver */
			pg_sock->affected_rows = affected_rows(pg_sock->result);
			return 0;
		} else {
			if ((sql_store_result(sqlsocket, config) == 0)
					&& (sql_num_fields(sqlsocket, config) >= 0))
				return 0;
			else
				return -1;
		}
	}
}
Exemple #14
0
static int _pgsql_exec(void *conn, const char *cmd, char *value, size_t size,
		       size_t *value_len, const sasl_utils_t *utils)
{
    PGresult *result;
    int row_count;
    ExecStatusType status;
    
    /* run the query */
    result = PQexec(conn, cmd);
    
    /* check the status */
    status = PQresultStatus(result);
    if (status == PGRES_COMMAND_OK) {
	/* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */
	PQclear(result);
	return 0;
    }
    else if (status != PGRES_TUPLES_OK) {
	/* error */
	utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s ",
		   PQresStatus(status));
	PQclear(result);
	return -1;
    }
    
    /* quick row check */
    row_count = PQntuples(result);
    if (!row_count) {
	/* umm nothing found */
	utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found");
	PQclear(result);
	return -1;
    }
    if (row_count > 1) {
	utils->log(NULL, SASL_LOG_WARN,
		   "sql plugin: found duplicate row for query %s", cmd);
    }
    
    /* now get the result set value and value_len */
    /* we only fetch one because we don't care about the rest */
    if (value) {
	strncpy(value, PQgetvalue(result,0,0), size-2);
	value[size-1] = '\0';
	if (value_len) *value_len = strlen(value);
    }
    
    /* free result */
    PQclear(result);
    return 0;
}
Exemple #15
0
static void
esql_postgresql_res(Esql_Res *res)
{
   Esql_Row *r;
   PGresult *pres;
   int i;

   pres = res->backend.res = PQgetResult(res->e->backend.db);
   EINA_SAFETY_ON_NULL_RETURN(pres);

   switch (PQresultStatus(pres))
     {
      case PGRES_COMMAND_OK:
        {
           const char *a;

           a = PQcmdTuples(pres);
           if (a && (*a))
             res->affected = strtol(a, NULL, 10);
           res->id = PQoidValue(pres);
        }
        return;
      case PGRES_TUPLES_OK:
        break;
      default:
        res->error = PQresultErrorMessage(pres);
        ERR("Error %s:'%s'!", PQresStatus(PQresultStatus(pres)), res->error);
        return;
     }
   res->desc = esql_module_desc_get(PQntuples(pres), (Esql_Module_Setup_Cb)esql_module_setup_cb, res);
   for (i = 0; i < res->row_count; i++)
     {
        r = esql_row_calloc(1);
        EINA_SAFETY_ON_NULL_RETURN(r);
        r->res = res;
        esql_postgresql_row_init(r, i);
        res->rows = eina_inlist_append(res->rows, EINA_INLIST_GET(r));
     }
}
Exemple #16
0
/* load each row as PGresult */
static void exec_query_single_row(struct Context *ctx, const char *q)
{
	PGconn *db = ctx->db;
	PGresult *r;
	ExecStatusType s;

	ctx->count = 0;

	if (!PQsendQuery(db, q))
		die(db, "PQsendQuery");

	if (!PQsetSingleRowMode(db))
		die(NULL, "PQsetSingleRowMode");

	/* loop until all resultset is done */
	while (1) {
		/* get next result */
		r = PQgetResult(db);
		if (!r)
			break;
		s = PQresultStatus(r);
		switch (s) {
			case PGRES_TUPLES_OK:
				//printf("query successful, got %d rows\n", ctx->count);
				ctx->count = 0;
				break;
			case PGRES_SINGLE_TUPLE:
				/* process first (only) row */
				proc_row(ctx, r, 0);
				break;
			default:
				fprintf(stderr, "result: %s\n", PQresStatus(s));
				exit(1);
				break;
		}

		PQclear(r);
	}
}
Exemple #17
0
int execute_query_statement_singlevalue(char* dst, char* stmt) {
	int result = 0;
	char connect_string[MAX_STATEMENT];
       	snprintf(connect_string, MAX_STATEMENT, "hostaddr = '%s' port = '%s' dbname = '%s' user = '******' password = '******' connect_timeout = '10'", lg_psql.hostaddr, lg_psql.port, lg_psql.dbname, lg_psql.user, lg_psql.pw);
	PGconn* psql  = PQconnectdb(connect_string);
	if (!psql) {
                msg(MSG_FATAL,"libpq error : PQconnectdb returned NULL.\n\n");
                return result;
        }

        if (PQstatus(psql) != CONNECTION_OK) {
                msg(MSG_FATAL,"libpq error: PQstatus(psql) != CONNECTION_OK\n\n");
                return result;
        }

	PGresult *res = PQexec(psql, stmt);
                
	if (PQresultStatus(res) != PGRES_TUPLES_OK)
		{
		msg(MSG_FATAL,"Status: %s",PQresStatus(PQresultStatus(res)));
		msg(MSG_FATAL,"%s",PQresultErrorMessage(res));
		}
	else {
		if (PQntuples(res) > 0 && PQnfields(res) > 0) {
		result = 1;
		char* value =  PQgetvalue(res,0,0);
		msg(MSG_DEBUG,"we have value: %s",value);
		strcpy(dst,value);
		}
		
	 }

	
	PQfinish(psql);


	return result;
}
Exemple #18
0
int execute_one_statement(const char* stmt_to_exec,PGresult** res_ptr) 
{
  int retcode=1;
 
  PGresult* local_result;
  const char* str_res=NULL;
  printf("about to execute %s\n",stmt_to_exec);
  local_result=PQexec(conn,stmt_to_exec);
  *res_ptr=local_result;

if(!local_result)
    {
      printf("PQexec command failed, no error code.\n");
      retcode=0;
    }
  else
    {
      switch(PQresultStatus(local_result))
	{
	case PGRES_COMMAND_OK:
	  str_res=PQcmdTuples(local_result);
	  printf("Command executed ok,%s rows affected\n",str_res);
	  break;
	case PGRES_TUPLES_OK:
        printf("Query may have returned data,%d rows returned\n",PQntuples(local_result));
	break;
	default:
	  printf("Command failed with code %s,error message %s\n",
		 PQresStatus(PQresultStatus(local_result)),
		 PQresultErrorMessage(local_result));
	  PQclear(local_result);
	  retcode=0;
	  break;
	}
    }  
    
 return retcode;
}
void execSql(PGconn *connection, char *query){
	PGresult *status;
	system("clear");
	printf("wykonywanie polecenia : \n%s \n\n",query);
	status=PQexec(connection,query);
	printf("Status polecenia: %s \n",PQresStatus(PQresultStatus(status)));
	printf("%s \n",PQresultErrorMessage(status));
    switch(PQresultStatus(status)) {
	  case PGRES_TUPLES_OK:
		{
		  int rec_num, col_num;
		  int cols = PQnfields(status);
		  int records   = PQntuples(status);
		  for(rec_num = 0; rec_num < records; rec_num++) {
			for(col_num = 0; col_num < cols; col_num++)
			  printf(" %s = %s", PQfname(status, col_num),PQgetvalue(status,rec_num,col_num));
			printf("\n\n");
		  }
		}
	  }
	  PQclear(status);
	 
	 
}
Exemple #20
0
/* load everything to single PGresult */
static void exec_query_full(struct Context *ctx, const char *q)
{
	PGconn *db = ctx->db;
	PGresult *r;
	ExecStatusType s;
	int i;

	ctx->count = 0;

	if (!PQsendQuery(db, q))
		die(db, "PQsendQuery");

	/* get next result */
	r = PQgetResult(db);
	s = PQresultStatus(r);
	if (s != PGRES_TUPLES_OK)
		die(db, PQresStatus(s));

	for (i = 0; i < PQntuples(r); i++) {
		proc_row(ctx, r, i);
		ctx->count++;
	}
	PQclear(r);
}
Exemple #21
0
bool PgQuery::sendQueryDirect (const string & query)
{
  DEBUG (DEBUG_DB, "[" << this << "->" << __FUNCTION__ << "] " << query);

  if (!_conn)
  {
    ERROR ("[" << this << "->" << __FUNCTION__ << "] " << "NULL connection.");
    return false;
  }

  if (_res)
    {
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQclear(" << _res << ")");
      PQclear (_res);
    }

  _res = PQexec (_conn->_pgconn, query.c_str ());
  DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQexec(" << _conn->_pgconn << ", " << query << ") = " << _res);

  int status = PQresultStatus (_res);
  DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQresultStatus(" << _res << ") = " << PQresStatus((ExecStatusType)status));

  if ((status != PGRES_COMMAND_OK) && (status != PGRES_TUPLES_OK))
    {
      ERROR ("[" << this << "->" << __FUNCTION__ << "] " << PQerrorMessage (_conn->_pgconn));
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQclear(" << _res << ")");
      PQclear (_res);
      _res = NULL;
      return false;
    }

  _current_row = 0;

  return true;
}
Exemple #22
0
bool PgQuery::fetch ()
{
  if (_current_row == 0)
    {
      int status = PQresultStatus (_res);
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQresultStatus(" << _res << ") = " << PQresStatus((ExecStatusType)status));

      if (status != PGRES_TUPLES_OK)
        {
          DEBUG (DEBUG_DB, "[" << this << "->" << __FUNCTION__ << "] No results");
          return false;
        }
    }
  int num_rows = PQntuples (_res);
  DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQntuples(" << _res << ") = " << num_rows);

  if (_current_row >= num_rows)
    {
      DEBUG (DEBUG6, "[" << this << "->" << __FUNCTION__ << "] = No rows");
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQclear(" << _res << ")");
      _current_row = 0;
      PQclear (_res);
      _res = NULL;
      return false;
    }

  bool ok = true;
  int res_len;
  int use_len;
  char *val;
  for (uint i=0; i<_columns.size (); i++)
    {
      val = PQgetvalue(_res, _current_row, i);

      switch (_columns[i].t)
        {
          case DBQuery::T_CHAR:
            res_len = PQgetlength (_res, _current_row, i);
            use_len = (res_len<_columns[i].len)?(res_len):(_columns[i].len);
            strncpy((char*)_columns[i].dst, val, use_len);
            ((char*)_columns[i].dst)[use_len] = 0;
            break;
          case DBQuery::T_LONG:
            if (sscanf(val, "%ld", (long*)_columns[i].dst) != 1)
              ok = false;
            break;
          case DBQuery::T_LONGLONG:
            if (sscanf(val, "%lld", (long long*)_columns[i].dst) != 1)
              ok = false;
            break;
          default:
            ok = false;
            break;
        }
      if (!ok)
        break;
    }

  _current_row++;

  return ok;
}
Exemple #23
0
bool PgQuery::sendQuery ()
{
  int status;
  uint i;

  if (_res)
    {
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQclear(" << _res << ")");
      PQclear (_res);
      _res = NULL;
    }

  if (!_prepeared && (_params.size () > 0))
    {
      _res = PQprepare(_conn->_pgconn, _query_name.c_str (), _prepeared_query.c_str (), _params.size (), NULL);
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQprepare(" << _conn->_pgconn << ", " << _query_name << ", " << _prepeared_query << ", " << _params.size () << ") = " << _res);

      status = PQresultStatus (_res);
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQresultStatus(" << _res << ") = " << PQresStatus((ExecStatusType)status));
      DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQclear(" << _res << ")");
      PQclear (_res);
      _res = NULL;

      if ((status != PGRES_COMMAND_OK) && (status != PGRES_TUPLES_OK))
        {
          ERROR ("[" << this << "->" << __FUNCTION__ << "] " << PQerrorMessage (_conn->_pgconn));
          return false;
        }

      _param_real_len = (int*)malloc(sizeof(int)*_params.size ());
      _param_values = (char**)malloc(sizeof(char*)*_params.size ());
      _param_formats = (int*)malloc(sizeof(int)*_params.size ());
      for (i=0; i<_params.size(); i++)
        {
          switch (_params[i].t)
            {
              case DBQuery::T_CHAR:
                break;
              case DBQuery::T_LONG:
                _param_values[i] = (char*)malloc(32);
                break;
              case DBQuery::T_LONGLONG:
                _param_values[i] = (char*)malloc(64);
                break;
            }
          _param_real_len[i] = 0;
          _param_formats[i] = 0;
        }

      _prepeared = true;
    }

  // обновляем привязанный массив в соответствии с текущими значениями буферов маркеров
  if (!_params.empty())
    {
      for (i=0; i<_params.size(); i++)
        {
          switch (_params[i].t)
            {
              case DBQuery::T_CHAR:
                _param_values[i] = (char*)_params[i].dst;
                break;
              case DBQuery::T_LONG:
                sprintf(_param_values[i], "%ld", *(long*)_params[i].dst);
                break;
              case DBQuery::T_LONGLONG:
                sprintf(_param_values[i], "%Ld", *(long long*)_params[i].dst);
                break;
            }
        }
    }

  _res = PQexecPrepared(_conn->_pgconn, _query_name.c_str (), _params.size (), _param_values, _param_real_len, _param_formats, 0);
  DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQexecPrepared(" << _conn->_pgconn << ", " << _query_name << ", " << _params.size () << ") = " << _res);

  status = PQresultStatus (_res);
  DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQresultStatus(" << _res << ") = " << PQresStatus((ExecStatusType)status));

/*
  DEBUG (DEBUG9, "[" << this << "->" << __FUNCTION__ << "] PQclear(" << _res << ")");
  PQclear (_res);
  _res = NULL;
*/

  if ((status != PGRES_COMMAND_OK) && (status != PGRES_TUPLES_OK))
    {
      ERROR ("[" << this << "->" << __FUNCTION__ << "] " << PQerrorMessage (_conn->_pgconn));
      return false;
    }

  return true;
}
Exemple #24
0
static struct ast_variable *realtime_pgsql(const char *database, const char *table, va_list ap)
{
	PGresult *result = NULL;
	int num_rows = 0;
	char sql[256];
	char *stringp;
	char *chunk;
	char *op;
	const char *newparam, *newval;
	struct ast_variable *var = NULL, *prev = NULL;

	if (!table) {
		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
		return NULL;
	}

	/* Get the first parameter and first value in our list of passed paramater/value pairs */
	newparam = va_arg(ap, const char *);
	newval = va_arg(ap, const char *);
	if (!newparam || !newval) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
		if (pgsqlConn) {
			PQfinish(pgsqlConn);
			pgsqlConn = NULL;
		};
		return NULL;
	}

	/* Create the first part of the query using the first parameter/value pairs we just extracted
	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
	op = strchr(newparam, ' ') ? "" : " =";

	snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op,
			 newval);
	while ((newparam = va_arg(ap, const char *))) {
		newval = va_arg(ap, const char *);
		if (!strchr(newparam, ' '))
			op = " =";
		else
			op = "";
		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam,
				 op, newval);
	}
	va_end(ap);

	/* We now have our complete statement; Lets connect to the server and execute it. */
	ast_mutex_lock(&pgsql_lock);
	if (!pgsql_reconnect(database)) {
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	}

	if (!(result = PQexec(pgsqlConn, sql))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
				PQerrorMessage(pgsqlConn));
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	} else {
		ExecStatusType result_status = PQresultStatus(result);
		if (result_status != PGRES_COMMAND_OK
			&& result_status != PGRES_TUPLES_OK
			&& result_status != PGRES_NONFATAL_ERROR) {
			ast_log(LOG_WARNING,
					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
					PQresultErrorMessage(result), PQresStatus(result_status));
			ast_mutex_unlock(&pgsql_lock);
			return NULL;
		}
	}

	ast_log(LOG_DEBUG, "1Postgresql RealTime: Result=%p Query: %s\n", result, sql);

	if ((num_rows = PQntuples(result)) > 0) {
		int i = 0;
		int rowIndex = 0;
		int numFields = PQnfields(result);
		char **fieldnames = NULL;

		ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows);

		if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) {
			ast_mutex_unlock(&pgsql_lock);
			PQclear(result);
			return NULL;
		}
		for (i = 0; i < numFields; i++)
			fieldnames[i] = PQfname(result, i);
		for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
			for (i = 0; i < numFields; i++) {
				stringp = PQgetvalue(result, rowIndex, i);
				while (stringp) {
					chunk = strsep(&stringp, ";");
					if (chunk && !ast_strlen_zero(ast_strip(chunk))) {
						if (prev) {
							prev->next = ast_variable_new(fieldnames[i], chunk);
							if (prev->next) {
								prev = prev->next;
							}
						} else {
							prev = var = ast_variable_new(fieldnames[i], chunk);
						}
					}
				}
			}
		}
		free(fieldnames);
	} else {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Could not find any rows in table %s.\n", table);
	}

	ast_mutex_unlock(&pgsql_lock);
	PQclear(result);

	return var;
}
Exemple #25
0
static int
perform_pgsql_search(uschar *query, uschar *server, uschar **resultptr,
  uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
{
PGconn *pg_conn = NULL;
PGresult *pg_result = NULL;

int i;
int ssize = 0;
int offset = 0;
int yield = DEFER;
unsigned int num_fields, num_tuples;
uschar *result = NULL;
pgsql_connection *cn;
uschar *server_copy = NULL;
uschar *sdata[3];

/* Disaggregate the parameters from the server argument. The order is host or
path, database, user, password. We can write to the string, since it is in a
nextinlist temporary buffer. The copy of the string that is used for caching
has the password removed. This copy is also used for debugging output. */

for (i = 2; i >= 0; i--)
  {
  uschar *pp = Ustrrchr(server, '/');
  if (pp == NULL)
    {
    *errmsg = string_sprintf("incomplete pgSQL server data: %s",
      (i == 2)? server : server_copy);
    *defer_break = TRUE;
    return DEFER;
    }
  *pp++ = 0;
  sdata[i] = pp;
  if (i == 2) server_copy = string_copy(server);  /* sans password */
  }

/* The total server string has now been truncated so that what is left at the
start is the identification of the server (host or path). See if we have a
cached connection to the server. */

for (cn = pgsql_connections; cn != NULL; cn = cn->next)
  {
  if (Ustrcmp(cn->server, server_copy) == 0)
    {
    pg_conn = cn->handle;
    break;
    }
  }

/* If there is no cached connection, we must set one up. */

if (cn == NULL)
  {
  uschar *port = US"";

  /* For a Unix domain socket connection, the path is in parentheses */

  if (*server == '(')
    {
    uschar *last_slash, *last_dot, *p;

    p = ++server;
    while (*p != 0 && *p != ')') p++;
    *p = 0;

    last_slash = Ustrrchr(server, '/');
    last_dot = Ustrrchr(server, '.');

    DEBUG(D_lookup) debug_printf("PGSQL new connection: socket=%s "
      "database=%s user=%s\n", server, sdata[0], sdata[1]);

    /* A valid socket name looks like this: /var/run/postgresql/.s.PGSQL.5432
    We have to call PQsetdbLogin with '/var/run/postgresql' as the hostname
    argument and put '5432' into the port variable. */

    if (last_slash == NULL || last_dot == NULL)
      {
      *errmsg = string_sprintf("PGSQL invalid filename for socket: %s",
        server);
      *defer_break = TRUE;
      return DEFER;
      }

    /* Terminate the path name and set up the port: we'll have something like
    server = "/var/run/postgresql" and port = "5432". */

    *last_slash = 0;
    port = last_dot + 1;
    }

  /* Host connection; sort out the port */

  else
    {
    uschar *p;
    if ((p = Ustrchr(server, ':')) != NULL)
      {
      *p++ = 0;
      port = p;
      }

    if (Ustrchr(server, '/') != NULL)
      {
      *errmsg = string_sprintf("unexpected slash in pgSQL server hostname: %s",
        server);
      *defer_break = TRUE;
      return DEFER;
      }

    DEBUG(D_lookup) debug_printf("PGSQL new connection: host=%s port=%s "
      "database=%s user=%s\n", server, port, sdata[0], sdata[1]);
    }

  /* If the database is the empty string, set it NULL - the query must then
  define it. */

  if (sdata[0][0] == 0) sdata[0] = NULL;

  /* Get store for a new handle, initialize it, and connect to the server */

  pg_conn=PQsetdbLogin(
    /*  host      port  options tty   database       user       passwd */
    CS server, CS port,  NULL, NULL, CS sdata[0], CS sdata[1], CS sdata[2]);

  if(PQstatus(pg_conn) == CONNECTION_BAD)
    {
    store_reset(server_copy);
    *errmsg = string_sprintf("PGSQL connection failed: %s",
      PQerrorMessage(pg_conn));
    PQfinish(pg_conn);
    goto PGSQL_EXIT;
    }

  /* Set the client encoding to SQL_ASCII, which means that the server will
  not try to interpret the query as being in any fancy encoding such as UTF-8
  or other multibyte code that might cause problems with escaping. */

  PQsetClientEncoding(pg_conn, "SQL_ASCII");

  /* Set the notice processor to prevent notices from being written to stderr
  (which is what the default does). Our function (above) just produces debug
  output. */

  PQsetNoticeProcessor(pg_conn, notice_processor, NULL);

  /* Add the connection to the cache */

  cn = store_get(sizeof(pgsql_connection));
  cn->server = server_copy;
  cn->handle = pg_conn;
  cn->next = pgsql_connections;
  pgsql_connections = cn;
  }

/* Else use a previously cached connection */

else
  {
  DEBUG(D_lookup) debug_printf("PGSQL using cached connection for %s\n",
    server_copy);
  }

/* Run the query */

  pg_result = PQexec(pg_conn, CS query);
  switch(PQresultStatus(pg_result))
    {
    case PGRES_EMPTY_QUERY:
    case PGRES_COMMAND_OK:
    /* The command was successful but did not return any data since it was
     * not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the
     * high level code to not cache this query, and clean the current cache for
     * this handle by setting *do_cache FALSE. */
    result = string_copy(US PQcmdTuples(pg_result));
    offset = Ustrlen(result);
    *do_cache = FALSE;
    DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data "
      "but was successful. Rows affected: %s\n", result);

    case PGRES_TUPLES_OK:
    break;

    default:
    /* This was the original code:
    *errmsg = string_sprintf("PGSQL: query failed: %s\n",
                             PQresultErrorMessage(pg_result));
    This was suggested by a user:
    */

    *errmsg = string_sprintf("PGSQL: query failed: %s (%s) (%s)\n",
                             PQresultErrorMessage(pg_result),
                             PQresStatus(PQresultStatus(pg_result)), query);
    goto PGSQL_EXIT;
    }

/* Result is in pg_result. Find the number of fields returned. If this is one,
we don't add field names to the data. Otherwise we do. If the query did not
return anything we skip the for loop; this also applies to the case
PGRES_COMMAND_OK. */

num_fields = PQnfields(pg_result);
num_tuples = PQntuples(pg_result);

/* Get the fields and construct the result string. If there is more than one
row, we insert '\n' between them. */

for (i = 0; i < num_tuples; i++)
  {
  if (result != NULL)
    result = string_cat(result, &ssize, &offset, US"\n", 1);

   if (num_fields == 1)
    {
    result = string_cat(result, &ssize, &offset,
      US PQgetvalue(pg_result, i, 0), PQgetlength(pg_result, i, 0));
    }

   else
    {
    int j;
    for (j = 0; j < num_fields; j++)
      {
      uschar *tmp = US PQgetvalue(pg_result, i, j);
      result = lf_quote(US PQfname(pg_result, j), tmp, Ustrlen(tmp), result,
        &ssize, &offset);
      }
    }
  }

/* If result is NULL then no data has been found and so we return FAIL.
Otherwise, we must terminate the string which has been built; string_cat()
always leaves enough room for a terminating zero. */

if (result == NULL)
  {
  yield = FAIL;
  *errmsg = US"PGSQL: no data found";
  }
else
  {
  result[offset] = 0;
  store_reset(result + offset + 1);
  }

/* Get here by goto from various error checks. */

PGSQL_EXIT:

/* Free store for any result that was got; don't close the connection, as
it is cached. */

if (pg_result != NULL) PQclear(pg_result);

/* Non-NULL result indicates a sucessful result */

if (result != NULL)
  {
  *resultptr = result;
  return OK;
  }
else
  {
  DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
  return yield;      /* FAIL or DEFER */
  }
}
int db_postgres_store_result(const db_con_t* _con, db_res_t** _r)
{
	ExecStatusType pqresult;
	int rc = 0;

	*_r = db_new_result();
	if (*_r==NULL) {
		LM_ERR("failed to init new result\n");
		rc = -1;
		goto done;
	}

	pqresult = PQresultStatus(CON_RESULT(_con));
	
	LM_DBG("%p PQresultStatus(%s) PQgetResult(%p)\n", _con,
		PQresStatus(pqresult), CON_RESULT(_con));

	switch(pqresult) {
		case PGRES_COMMAND_OK:
		/* Successful completion of a command returning no data
		 * (such as INSERT or UPDATE). */
		rc = 0;
		break;

		case PGRES_TUPLES_OK:
			/* Successful completion of a command returning data
			 * (such as a SELECT or SHOW). */
			if (db_postgres_convert_result(_con, *_r) < 0) {
				LM_ERR("%p Error returned from convert_result()\n", _con);
				db_free_result(*_r);
				*_r = 0;
				rc = -4;
				break;
			}
			rc =  0;
			break;
		/* query failed */
		case PGRES_FATAL_ERROR:
			LM_ERR("%p - invalid query, execution aborted\n", _con);
			LM_ERR("%p: %s\n", _con, PQresStatus(pqresult));
			LM_ERR("%p: %s\n", _con, PQresultErrorMessage(CON_RESULT(_con)));
			db_free_result(*_r);
			*_r = 0;
			rc = -3;
			break;

		case PGRES_EMPTY_QUERY:
		/* notice or warning */
		case PGRES_NONFATAL_ERROR:
		/* status for COPY command, not used */
		case PGRES_COPY_OUT:
		case PGRES_COPY_IN:
		/* unexpected response */
		case PGRES_BAD_RESPONSE:
		default:
			LM_ERR("%p Probable invalid query\n", _con);
			LM_ERR("%p: %s\n", _con, PQresStatus(pqresult));
			LM_ERR("%p: %s\n", _con, PQresultErrorMessage(CON_RESULT(_con)));
			db_free_result(*_r);
			*_r = 0;
			rc = -4;
			break;
	}

done:
	free_query(_con);
	return (rc);
}
Exemple #27
0
/*
 * Our caller already sent the query associated with this step.  Wait for it
 * to either complete or (if given the STEP_NONBLOCK flag) to block while
 * waiting for a lock.  We assume that any lock wait will persist until we
 * have executed additional steps in the permutation.
 *
 * When calling this function on behalf of a given step for a second or later
 * time, pass the STEP_RETRY flag.  This only affects the messages printed.
 *
 * If the STEP_NONBLOCK flag was specified and the query is waiting to acquire
 * a lock, returns true.  Otherwise, returns false.
 */
static bool
try_complete_step(Step *step, int flags)
{
	PGconn	   *conn = conns[1 + step->session];
	fd_set		read_set;
	struct timeval timeout;
	int			sock = PQsocket(conn);
	int			ret;
	PGresult   *res;

	FD_ZERO(&read_set);

	while (flags & STEP_NONBLOCK && PQisBusy(conn))
	{
		FD_SET(sock, &read_set);
		timeout.tv_sec = 0;
		timeout.tv_usec = 10000;	/* Check for lock waits every 10ms. */

		ret = select(sock + 1, &read_set, NULL, NULL, &timeout);
		if (ret < 0)	/* error in select() */
		{
			fprintf(stderr, "select failed: %s\n", strerror(errno));
			exit_nicely();
		}
		else if (ret == 0)	/* select() timeout: check for lock wait */
		{
			int			ntuples;

			res = PQexecPrepared(conns[0], PREP_WAITING, 1,
								 &backend_pids[step->session + 1],
								 NULL, NULL, 0);
			if (PQresultStatus(res) != PGRES_TUPLES_OK)
			{
				fprintf(stderr, "lock wait query failed: %s",
						PQerrorMessage(conn));
				exit_nicely();
			}
			ntuples = PQntuples(res);
			PQclear(res);

			if (ntuples >= 1)	/* waiting to acquire a lock */
			{
				if (!(flags & STEP_RETRY))
					printf("step %s: %s <waiting ...>\n",
						   step->name, step->sql);
				return true;
			}
			/* else, not waiting: give it more time */
		}
		else if (!PQconsumeInput(conn)) /* select(): data available */
		{
			fprintf(stderr, "PQconsumeInput failed: %s", PQerrorMessage(conn));
			exit_nicely();
		}
	}

	if (flags & STEP_RETRY)
		printf("step %s: <... completed>\n", step->name);
	else
		printf("step %s: %s\n", step->name, step->sql);

	while ((res = PQgetResult(conn)))
	{
		switch (PQresultStatus(res))
		{
			case PGRES_COMMAND_OK:
				break;
			case PGRES_TUPLES_OK:
				printResultSet(res);
				break;
			case PGRES_FATAL_ERROR:
				/* Detail may contain xid values, so just show primary. */
				printf("%s:  %s\n", PQresultErrorField(res, PG_DIAG_SEVERITY),
					   PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY));
				break;
			default:
				printf("unexpected result status: %s\n",
					   PQresStatus(PQresultStatus(res)));
		}
		PQclear(res);
	}

	return false;
}
Exemple #28
0
static int update_pgsql(const char *database, const char *table, const char *keyfield,
						const char *lookup, va_list ap)
{
	PGresult *result = NULL;
	int numrows = 0;
	char sql[256];
	const char *newparam, *newval;

	if (!table) {
		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
		return -1;
	}

	/* Get the first parameter and first value in our list of passed paramater/value pairs */
	newparam = va_arg(ap, const char *);
	newval = va_arg(ap, const char *);
	if (!newparam || !newval) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
		if (pgsqlConn) {
			PQfinish(pgsqlConn);
			pgsqlConn = NULL;
		};
		return -1;
	}

	/* Create the first part of the query using the first parameter/value pairs we just extracted
	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */

	snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, newval);
	while ((newparam = va_arg(ap, const char *))) {
		newval = va_arg(ap, const char *);
		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam,
				 newval);
	}
	va_end(ap);
	snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield,
			 lookup);

	ast_log(LOG_DEBUG, "Postgresql RealTime: Update SQL: %s\n", sql);

	/* We now have our complete statement; Lets connect to the server and execute it. */
	ast_mutex_lock(&pgsql_lock);
	if (!pgsql_reconnect(database)) {
		ast_mutex_unlock(&pgsql_lock);
		return -1;
	}

	if (!(result = PQexec(pgsqlConn, sql))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
				PQerrorMessage(pgsqlConn));
		ast_mutex_unlock(&pgsql_lock);
		return -1;
	} else {
		ExecStatusType result_status = PQresultStatus(result);
		if (result_status != PGRES_COMMAND_OK
			&& result_status != PGRES_TUPLES_OK
			&& result_status != PGRES_NONFATAL_ERROR) {
			ast_log(LOG_WARNING,
					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
					PQresultErrorMessage(result), PQresStatus(result_status));
			ast_mutex_unlock(&pgsql_lock);
			return -1;
		}
	}

	numrows = atoi(PQcmdTuples(result));
	ast_mutex_unlock(&pgsql_lock);

	ast_log(LOG_DEBUG, "Postgresql RealTime: Updated %d rows on table: %s\n", numrows,
			table);

	/* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html
	 * An integer greater than zero indicates the number of rows affected
	 * Zero indicates that no records were updated
	 * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
	 */

	if (numrows >= 0)
		return (int) numrows;

	return -1;
}
/*
 * Our caller already sent the query associated with this step.  Wait for it
 * to either complete or (if given the STEP_NONBLOCK flag) to block while
 * waiting for a lock.	We assume that any lock wait will persist until we
 * have executed additional steps in the permutation.
 *
 * When calling this function on behalf of a given step for a second or later
 * time, pass the STEP_RETRY flag.	This only affects the messages printed.
 *
 * If the connection returns an error, the message is saved in step->errormsg.
 * Caller should call report_error_message shortly after this, to have it
 * printed and cleared.
 *
 * If the STEP_NONBLOCK flag was specified and the query is waiting to acquire
 * a lock, returns true.  Otherwise, returns false.
 */
static bool
try_complete_step(Step * step, int flags)
{
	PGconn	   *conn = conns[1 + step->session];
	fd_set		read_set;
	struct timeval timeout;
	int			sock = PQsocket(conn);
	int			ret;
	PGresult   *res;

	FD_ZERO(&read_set);

	while ((flags & STEP_NONBLOCK) && PQisBusy(conn))
	{
		FD_SET(sock, &read_set);
		timeout.tv_sec = 0;
		timeout.tv_usec = 10000;	/* Check for lock waits every 10ms. */

		ret = select(sock + 1, &read_set, NULL, NULL, &timeout);
		if (ret < 0)			/* error in select() */
		{
			if (errno == EINTR)
				continue;
			fprintf(stderr, "select failed: %s\n", strerror(errno));
			exit_nicely();
		}
		else if (ret == 0)		/* select() timeout: check for lock wait */
		{
			int			ntuples;

			res = PQexecPrepared(conns[0], PREP_WAITING, 1,
								 &backend_pids[step->session + 1],
								 NULL, NULL, 0);
			if (PQresultStatus(res) != PGRES_TUPLES_OK)
			{
				fprintf(stderr, "lock wait query failed: %s",
						PQerrorMessage(conn));
				exit_nicely();
			}
			ntuples = PQntuples(res);
			PQclear(res);

			if (ntuples >= 1)	/* waiting to acquire a lock */
			{
				if (!(flags & STEP_RETRY))
					printf("step %s: %s <waiting ...>\n",
						   step->name, step->sql);
				return true;
			}
			/* else, not waiting: give it more time */
		}
		else if (!PQconsumeInput(conn)) /* select(): data available */
		{
			fprintf(stderr, "PQconsumeInput failed: %s\n",
					PQerrorMessage(conn));
			exit_nicely();
		}
	}

	if (flags & STEP_RETRY)
		printf("step %s: <... completed>\n", step->name);
	else
		printf("step %s: %s\n", step->name, step->sql);

	while ((res = PQgetResult(conn)))
	{
		switch (PQresultStatus(res))
		{
			case PGRES_COMMAND_OK:
				break;
			case PGRES_TUPLES_OK:
				printResultSet(res);
				break;
			case PGRES_FATAL_ERROR:
				if (step->errormsg != NULL)
				{
					printf("WARNING: this step had a leftover error message\n");
					printf("%s\n", step->errormsg);
				}

				/*
				 * Detail may contain XID values, so we want to just show
				 * primary.  Beware however that libpq-generated error results
				 * may not contain subfields, only an old-style message.
				 */
				{
					const char *sev = PQresultErrorField(res,
														 PG_DIAG_SEVERITY);
					const char *msg = PQresultErrorField(res,
													PG_DIAG_MESSAGE_PRIMARY);

					if (sev && msg)
					{
						step->errormsg = malloc(5 + strlen(sev) + strlen(msg));
						sprintf(step->errormsg, "%s:  %s", sev, msg);
					}
					else
						step->errormsg = strdup(PQresultErrorMessage(res));
				}
				break;
			default:
				printf("unexpected result status: %s\n",
					   PQresStatus(PQresultStatus(res)));
		}
		PQclear(res);
	}

	return false;
}
Exemple #30
0
static struct ast_config *config_pgsql(const char *database, const char *table,
					   const char *file, struct ast_config *cfg,
					   int withcomments)
{
	PGresult *result = NULL;
	long num_rows;
	struct ast_variable *new_v;
	struct ast_category *cur_cat = NULL;
	char sqlbuf[1024] = "";
	char *sql;
	size_t sqlleft = sizeof(sqlbuf);
	char last[80] = "";
	int last_cat_metric = 0;

	last[0] = '\0';

	if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) {
		ast_log(LOG_WARNING, "Postgresql RealTime: Cannot configure myself.\n");
		return NULL;
	}

	ast_build_string(&sql, &sqlleft, "SELECT category, var_name, var_val, cat_metric FROM %s ", table);
	ast_build_string(&sql, &sqlleft, "WHERE filename='%s' and commented=0", file);
	ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");

	ast_log(LOG_DEBUG, "Postgresql RealTime: Static SQL: %s\n", sqlbuf);

	/* We now have our complete statement; Lets connect to the server and execute it. */
	ast_mutex_lock(&pgsql_lock);
	if (!pgsql_reconnect(database)) {
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	}

	if (!(result = PQexec(pgsqlConn, sqlbuf))) {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
		ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n",
				PQerrorMessage(pgsqlConn));
		ast_mutex_unlock(&pgsql_lock);
		return NULL;
	} else {
		ExecStatusType result_status = PQresultStatus(result);
		if (result_status != PGRES_COMMAND_OK
			&& result_status != PGRES_TUPLES_OK
			&& result_status != PGRES_NONFATAL_ERROR) {
			ast_log(LOG_WARNING,
					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql);
			ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n",
					PQresultErrorMessage(result), PQresStatus(result_status));
			ast_mutex_unlock(&pgsql_lock);
			return NULL;
		}
	}

	if ((num_rows = PQntuples(result)) > 0) {
		int rowIndex = 0;

		ast_log(LOG_DEBUG, "Postgresql RealTime: Found %ld rows.\n", num_rows);

		for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
			char *field_category = PQgetvalue(result, rowIndex, 0);
			char *field_var_name = PQgetvalue(result, rowIndex, 1);
			char *field_var_val = PQgetvalue(result, rowIndex, 2);
			char *field_cat_metric = PQgetvalue(result, rowIndex, 3);
			if (!strcmp(field_var_name, "#include")) {
				if (!ast_config_internal_load(field_var_val, cfg, 0)) {
					PQclear(result);
					ast_mutex_unlock(&pgsql_lock);
					return NULL;
				}
				continue;
			}

			if (strcmp(last, field_category) || last_cat_metric != atoi(field_cat_metric)) {
				cur_cat = ast_category_new(field_category);
				if (!cur_cat)
					break;
				strcpy(last, field_category);
				last_cat_metric = atoi(field_cat_metric);
				ast_category_append(cfg, cur_cat);
			}
			new_v = ast_variable_new(field_var_name, field_var_val);
			ast_variable_append(cur_cat, new_v);
		}
	} else {
		ast_log(LOG_WARNING,
				"Postgresql RealTime: Could not find config '%s' in database.\n", file);
	}

	PQclear(result);
	ast_mutex_unlock(&pgsql_lock);

	return cfg;
}