Using libpq with C++

344 views
Skip to first unread message

Ben Christel

unread,
May 4, 2017, 7:59:42 PM5/4/17
to Greenplum Developers, Amil Khanzada, Nikhil Kak, David Sharp
Hello all,

We have a project written in C that interfaces with Greenplum via libpq and are considering incrementally transitioning it to C++. We're wondering if we can continue to use libpq and call it from our C++ code.

Here is the header from the version of libpq that we have:

/*-------------------------------------------------------------------------
 *
 * libpq-fe.h
 *        This file contains definitions for structures and
 *        externs for functions used by frontend postgres applications.
 *
 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.152 2010/02/26 02:01:33 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */

Here is a representative example of how we currently use libpq:

static PGresult* gpdb_execute_query(PGconn *conn, const char *query)
{
   PGresult *res;

   if((res = PQexec(conn, query)) == NULL) {
      LTRACE("PQexec(%s): %s", query, PQresultErrorMessage(res));
      return NULL;
   }

   /* See libpq-fe.h, enum ExecStatusType */
   switch(PQresultStatus(res)) {
      case PGRES_BAD_RESPONSE:
      case PGRES_FATAL_ERROR:
         /* we know for certain that these codes mean that the query failed,
          * and we should log the error message */
         LTRACE("tid 0x%lx Query '%s' not successful: %s", pthread_self(),
               query, PQresultErrorMessage(res));
         break;
      case PGRES_NONFATAL_ERROR:
         /* Log message from queries that succeeded with warnings */
         LTRACE("tid 0x%lx Query '%s' succeeded with warnings: %s", pthread_self(),
               query, PQresultErrorMessage(res));
         break;
         /* For all remaining codes, it is up to the caller to determine whether or
          * not an error occured, and to log it appropriately */
      default:
         break;
   }

   return res;
}

Are there any pitfalls in calling libpq from C++ that we should be aware of?

We are aware of libpq++ and are considering switching to it, but we want to make sure that it will add value over libpq. In particular, we'd like to be able to write tests that mock out the database and return result sets (possibly also test doubles) that we construct in our tests. Does libpq++ make that easier than libpq?

Thanks,

Ben, Amil, Nikhil, and David

Heikki Linnakangas

unread,
May 5, 2017, 1:35:07 AM5/5/17
to Ben Christel, Greenplum Developers, Amil Khanzada, Nikhil Kak, David Sharp
On 05/05/2017 02:59 AM, Ben Christel wrote:
> Hello all,
>
> We have a project written in C that interfaces with Greenplum via libpq and
> are considering incrementally transitioning it to C++. We're wondering if
> we can continue to use libpq and call it from our C++ code.

Sure, no problem!

> We are aware of libpq++ and are considering switching to it, but we want to
> make sure that it will add value over libpq. In particular, we'd like to be
> able to write tests that mock out the database and return result sets
> (possibly also test doubles) that we construct in our tests. Does libpq++
> make that easier than libpq?

Hmm. I don't think libpq++ has been maintained for many many years. But
there is libpqxx (pqxx.org), that is active. I'm not too familiar with
those libraries, but I don't think they provide anything special for
mocking the database.

libpq has functions PQmakeEmptyPGresult() and PQsetvalue(), that you can
use to construct PGresult result set objects in your mock code.

- Heikki

Amil Khanzada

unread,
May 5, 2017, 6:39:21 PM5/5/17
to Heikki Linnakangas, Ben Christel, Greenplum Developers, Nikhil Kak, David Sharp
Hi Heikki,

Thanks for the confirmation and info!

We are able to call libpq from C++ code, so we'll probably go that route.

Best,
Amil
Reply all
Reply to author
Forward
0 new messages