Table of contents Next: connecting

Overview

The pgstream library is a C++ layer that comes on top of the C libpq library.
It aims at enabling programmers to write more concise and less error prone code than when using the C API.
It is targeted at PostgreSQL v7.4 and higher.

Features

Comparison of C++/pgstream code over libpq C code

Here is a small example of a function using pgstream. It connects to a database and then updates a sample table of words by replacing a word with another, using a query with inline parameters.

#include <iostream>
#include <pgstream.h>

int replace(const char* oldword, const char* newword)
{
  pg_cnx cnx;
  try {
    cnx.connect("dbname=test");
    pg_stream s("UPDATE words SET wordtext=:nw WHERE wordtext=:ow", cnx);
    s <<  newword << oldword;
    return 1;
  }
  catch (pg_excpt e) {
    std::cerr << e.errmsg();
    return 0;
  }
}

Here's the same program written with the C API. Notice that it's almost four times longer than the C++ version, and harder to read. Yet both versions are functionaly equivalent, including the behavior shown upon memory or database errors.

This example illustrates the main point of the pgstream library, which is to take care of the tricky details around libpq calls so that its user can focus on the logic of the database code.

#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>

int replace(const char* oldword, const char* newword)
{
  const char* query_fmt = "UPDATE words SET wordtext='%s' WHERE wordtext='%s'";
  int ret=0;
  PGconn* cnx=NULL;
  PGresult* res=NULL;
  char* query_buf=NULL;
  char* ow_buf=NULL;
  char* nw_buf=NULL;
  size_t s1,s2;

  cnx=PQconnectdb("dbname=test");
  if (!cnx || PQstatus(cnx) != CONNECTION_OK) {
    fprintf(stderr, "%s", PQerrorMessage(cnx));
    if (cnx)
      PQfinish(cnx);
    return 0;
  }
  s1 = strlen(oldword);
  s2 = strlen(newword);
  ow_buf = (char*)malloc(s1*2+1);
  nw_buf = (char*)malloc(s2*2+1);
  query_buf = (char*)malloc(strlen(query_fmt)+s1+s2+1);
  if (!ow_buf || !nw_buf || !query_buf) {
    PQfinish(cnx);
    fprintf(stderr, "no memory\n");
    ret=0;
  }
  else {
    PQescapeString(ow_buf, oldword, s1);
    PQescapeString(nw_buf, newword, s2);
    sprintf(query_buf, query_fmt, nw_buf, ow_buf);
    res = PQexec(cnx, query_buf);
    if (!res) {
      fprintf(stderr, "no memory\n");
      ret=0;
    }
    else {
      if (PQresultStatus(res) != PGRES_COMMAND_OK) {
	ret=0;
	fprintf(stderr, "%s", PQerrorMessage(cnx));
      }
      else
	ret=1;
    }
  }

  if (ow_buf)
    free(ow_buf);
  if (nw_buf)
    free(nw_buf);
  if (query_buf)
    free(query_buf);
  if (res)
    PQclear(res);
  PQfinish(cnx);
  return ret;
}

  Table of contents Next: connecting