testlibpq3.cc 3.46 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*
 * testlibpq3.cc
 * 	Test the C++ version of LIBPQ, the POSTGRES frontend library.
 *   tests the binary cursor interface
 *
 *
 *
 populate a database by doing the following:
 
CREATE TABLE test1 (i int4, d float4, p polygon);

INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);

INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);

 the expected output is:

tuple 0: got
 i = (4 bytes) 1,
 d = (4 bytes) 3.567000,
 p = (4 bytes) 2 points         boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
tuple 1: got
 i = (4 bytes) 2,
 d = (4 bytes) 89.050003,
 p = (4 bytes) 2 points         boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)

 *
 */
#include <stdio.h>
#include "libpq++.H"
extern "C" {
#include "utils/geo-decls.h" /* for the POLYGON type */
}

main()
{
  char* dbName;
  int i_fnum, d_fnum, p_fnum;
39
  int i;
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

  /* begin, by creating the parameter environtment for a backend
     connection. When no parameters are given then the system will
     try to use reasonable defaults by looking up environment variables 
     or, failing that, using hardwired constants */
  PGenv env;
  PGdatabase* data;

  dbName = getenv("USER"); /* change this to the name of your test database */

  /* make a connection to the database */
  data = new PGdatabase(&env, dbName);

  /* check to see that the backend connection was successfully made */
  if (data->status() == CONNECTION_BAD) {
    fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
    fprintf(stderr,"%s",data->errormessage());
    delete data;
    exit(1);
  }

  /* start a transaction block */
  if (data->exec("BEGIN") != PGRES_COMMAND_OK) {
    fprintf(stderr,"BEGIN command failed\n");
    delete data;
    exit(1);
  }

  /* fetch instances from the pg_database, the system catalog of databases*/
  if (data->exec("DECLARE mycursor BINARY CURSOR FOR select * from test1")
      != PGRES_COMMAND_OK) {
    fprintf(stderr,"DECLARE CURSOR command failed\n");
    delete data;
    exit(1);
  }

  if (data->exec("FETCH ALL in mycursor") != PGRES_TUPLES_OK) {
    fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
    delete data;
    exit(1);
  }
 
  i_fnum = data->fieldnum("i");
  d_fnum = data->fieldnum("d");
  p_fnum = data->fieldnum("p");
  
/*
  for (i=0;i<3;i++) {
      printf("type[%d] = %d, size[%d] = %d\n",
	     i, data->fieldtype(i), 
	     i, data->fieldsize(i));
  }
*/

  for (i=0; i < data->ntuples(); i++) {
    int *ival; 
    float *dval;
    int plen;
    POLYGON* pval;
    /* we hard-wire this to the 3 fields we know about */
    ival = (int*)data->getvalue(i,i_fnum);
    dval = (float*)data->getvalue(i,d_fnum);
    plen = data->getlength(i,p_fnum);

    /* plen doesn't include the length field so need to increment by VARHDSZ*/
    pval = (POLYGON*) malloc(plen + VARHDRSZ); 
    pval->size = plen;
    memmove((char*)&pval->npts, data->getvalue(i,p_fnum), plen);
    printf("tuple %d: got\n", i);
    printf(" i = (%d bytes) %d,\n",
	   data->getlength(i,i_fnum), *ival);
    printf(" d = (%d bytes) %f,\n",
	   data->getlength(i,d_fnum), *dval);
    printf(" p = (%d bytes) %d points \tboundbox = (hi=%f/%f, lo = %f,%f)\n",
	   data->getlength(i,d_fnum),
	   pval->npts,
	   pval->boundbox.xh,
	   pval->boundbox.yh,
	   pval->boundbox.xl,
	   pval->boundbox.yl);
  }
  
  /* close the portal */
  data->exec("CLOSE mycursor");

  /* end the transaction */
  data->exec("END");

  /* close the connection to the database and cleanup */
  delete data;
}