>
> I am able to find couple
> of examples for dynamic sql programming through ecpg. But i want to
> do dynamic sql programming through libpq.
> If anyone has programs doing the dynamic sql programmming using the
> libpq libraries please mail to me.
>
Attached you'll find my encapsulated library of postgres functions,
which I use for all queries resp. commands.
Regards, Christoph

/*-------------------------------------------------------------------------
 *
 * libpq-myfe.h 
 *
 *
 * Christoph Haller, D.T.I. 
 *
 * Created Sep 2001 
 *
 *-------------------------------------------------------------------------
 */
#include "libpq-fe.h"

#ifndef LIBPQ_MYFE_H
#define LIBPQ_MYFE_H

int PGSQL_command(PGconn *thisconnec, PGresult *thisresul, 
                  char *thiscommand);
int PGSQL_process(PGconn *thisconnec, PGresult **thisresul, 
                  char *thiscommand);
int PGSQL_begin(PGconn *thisconnec);

int PGSQL_declare_cursor1(PGconn *thisconnec, PGresult *thisresul, 
                          char *thisselect);
int PGSQL_fetch_all1(PGconn *thisconnec, PGresult **thisresul);
int PGSQL_close_cursor1(PGconn *thisconnec, PGresult *thisresul);

int PGSQL_commit(PGconn *thisconnec);
int PGSQL_rollback(PGconn *thisconnec);

int PGSQL_declare_cursor2(PGconn *thisconnec, PGresult *thisresul, 
                          char *thisselect);
int PGSQL_fetch_all2(PGconn *thisconnec, PGresult **thisresul);
int PGSQL_close_cursor2(PGconn *thisconnec, PGresult *thisresul);

int PGSQL_declare_bincsr1(PGconn *thisconnec, PGresult *thisresul, 
                          char *thisselect);
int PGSQL_fetch_binall1(PGconn *thisconnec, PGresult **thisresul);
int PGSQL_close_bincsr1(PGconn *thisconnec, PGresult *thisresul);

int PGSQL_binprocess(PGconn *thisconnec, PGresult **thisresul,
                     char *thiscommand);

#endif   /* LIBPQ_MYFE_H */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "libpq-myfe.h"

char *strdup(const char *s);

#ifdef PostgreSQL_6_5_3
const char *PGSQL_UNIQUE_INDEX_VIOLATED = /* PostgreSQL 6.5.3 */
"ERROR:  Cannot insert a duplicate key into a unique index" ;
#endif /* PostgreSQL_6_5_3 */
const char *PGSQL_UNIQUE_INDEX_VIOLATED = /* PostgreSQL 7.1.2 */
"ERROR:  Cannot insert a duplicate key into unique index " ;

/*
** procedure:   trim_sequence 
** purpose:     delete space sequences within a given string 
**              delete spaces only within the given length 
**              the given string does not have to be null terminated 
**              this function is secure:
**              - one space always remains 
**              - no space, no action 
**              - several space sequences are processed 
**              - deleting stops if a null character is found 
**                and the given length is not reached 
**
** parameters:  seq             - the string to trim 
**              seq_len         - the length of string to trim 
** returns:     the trimmed string 
*/
#  if defined(__STDC__) || defined(__cplusplus)
char *trim_sequence(char *seq,size_t seq_len)
#  else /* __STDC__ || __cplusplus */
char *trim_sequence(seq,seq_len)
   char *seq;size_t seq_len;
#  endif /* __STDC__ || __cplusplus */
{
   char space=' ';              /* the trim character */
   char *first=seq;             /* ptr to the 1st space */
   char *last;                  /* ptr to the last space */
   size_t seq_pos=0;            /* index within sequence */
   
   /* while not end of sequence ... */
   while(seq_pos<seq_len) {
      /* find first space */
      /* if there is no space break from loop */
      if(!(first=strchr(first,space))) break;
      /* assume last space to be next char after first */
      last=++first;
      /* while sequence not terminated by null and
         current char evaluates to space and
         sequence end not reached -> continue search */
      while(last&&*last==space&&last-seq<seq_len) last++;
      /* if there is more than one space */
      if(last>first) {
         *first=NULL; /* set temporary termination */
         strcat(seq,last); /* append the following subsequence */
      }
      seq_pos=last-seq; /* update sequence index */
   }
   
   return seq; /* return the trimmed sequence */
} /* trim_sequence() */

int PGSQL_command(PGconn *thisconnec, PGresult *thisresul, 
                          char *thiscommand)
{
   int result = EXIT_SUCCESS;
   
   trim_sequence(thiscommand, strlen(thiscommand));
   
   thisresul = PQexec(thisconnec, thiscommand);
   if (!thisresul || PQresultStatus(thisresul) != PGRES_COMMAND_OK)
   {
      fprintf(stderr, "'%s' command failed\n%s\n", thiscommand, 
              PQresultErrorMessage(thisresul));
      result = -EXIT_FAILURE;
   }
   else
   {
      result = atoi(PQcmdTuples(thisresul));
   }
   /* PQclear PGresult whenever it is no longer needed to avoid memory leaks */
   PQclear(thisresul);
   return result;
}

int PGSQL_process(PGconn *thisconnec, PGresult **thisresul, 
                          char *thiscommand)
{
   int result = EXIT_SUCCESS;
   
   trim_sequence(thiscommand, strlen(thiscommand));
   
   *thisresul = PQexec(thisconnec, thiscommand);
   if (!*thisresul || PQresultStatus(*thisresul) != PGRES_TUPLES_OK)
   {
      fprintf(stderr, "'%s' command failed\n%s\n", thiscommand, 
              PQresultErrorMessage(*thisresul));
      result = -EXIT_FAILURE;
   }
   else
   {
      result = PQntuples(*thisresul);
   }
   /* PQclear PGresult whenever it is no longer needed to avoid memory leaks */
   /*
   PQclear(thisresul);
   The calling function has to PQclear PGresult 
   use PGSQL_process to select 
   */
   return result;
}

int PGSQL_begin(PGconn *thisconnec)
{
   int result = EXIT_SUCCESS;
   PGresult *thisresul;
   
   /* start a transaction block */
   thisresul = PQexec(thisconnec, "BEGIN");
   if (!thisresul || PQresultStatus(thisresul) != PGRES_COMMAND_OK)
   {
      fprintf(stderr, "BEGIN command failed\n");
      result = -EXIT_FAILURE;
   }
   /* PQclear PGresult whenever it is no longer needed to avoid memory leaks */
   PQclear(thisresul);
   return result;
}

int PGSQL_declare_cursor1(PGconn *thisconnec, PGresult *thisresul, 
                          char *thisselect)
{
   int result = EXIT_SUCCESS;
   char *thiscommand = (char *)malloc( 32 + strlen(thisselect) );
   
   trim_sequence(thisselect, strlen(thisselect));
   
   sprintf(thiscommand, "DECLARE mycursor CURSOR FOR %s", thisselect);
   thisresul = PQexec(thisconnec, thiscommand);
   if (!thisresul || PQresultStatus(thisresul) != PGRES_COMMAND_OK)
   {
      fprintf(stderr, "DECLARE CURSOR command \n%s\nfailed \n%s\n", 
              thisselect, PQresultErrorMessage(thisresul));
      result = -EXIT_FAILURE;
   }
   /* PQclear PGresult whenever it is no longer needed to avoid memory leaks */
   PQclear(thisresul);
   free(thiscommand);
   return result;
}

int PGSQL_fetch_all1(PGconn *thisconnec, PGresult **thisresul)
{
   int result = EXIT_SUCCESS;
   
   *thisresul = PQexec(thisconnec, "FETCH ALL in mycursor");
   if (!*thisresul || PQresultStatus(*thisresul) != PGRES_TUPLES_OK)
   {
      fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
      result = -EXIT_FAILURE;
   }
   return result;
}

int PGSQL_close_cursor1(PGconn *thisconnec, PGresult *thisresul)
{
   int result = EXIT_SUCCESS;
   thisresul = PQexec(thisconnec, "CLOSE mycursor");
   PQclear(thisresul);
   return result;
}

int PGSQL_commit(PGconn *thisconnec)
{
   int result = EXIT_SUCCESS;
   PGresult *thisresul;
   thisresul = PQexec(thisconnec, "COMMIT");
   PQclear(thisresul);
   return result;
}

int PGSQL_rollback(PGconn *thisconnec)
{
   int result = EXIT_SUCCESS;
   PGresult *thisresul;
   thisresul = PQexec(thisconnec, "ROLLBACK");
   PQclear(thisresul);
   return result;
}

int PGSQL_declare_cursor2(PGconn *thisconnec, PGresult *thisresul, 
                          char *thisselect)
{
   int result = EXIT_SUCCESS;
   char *thiscommand = (char *)malloc( 32 + strlen(thisselect) );
   
   trim_sequence(thisselect, strlen(thisselect));
   
   sprintf(thiscommand, "DECLARE mycursor2 CURSOR FOR %s", thisselect);
   thisresul = PQexec(thisconnec, thiscommand);
   if (!thisresul || PQresultStatus(thisresul) != PGRES_COMMAND_OK)
   {
      fprintf(stderr, "DECLARE CURSOR command \n%s\nfailed \n%s\n", 
              thisselect, PQresultErrorMessage(thisresul));
      result = -EXIT_FAILURE;
   }
   /* PQclear PGresult whenever it is no longer needed to avoid memory leaks */
   PQclear(thisresul);
   free(thiscommand);
   return result;
}

int PGSQL_fetch_all2(PGconn *thisconnec, PGresult **thisresul)
{
   int result = EXIT_SUCCESS;
   
   *thisresul = PQexec(thisconnec, "FETCH ALL in mycursor2");
   if (!*thisresul || PQresultStatus(*thisresul) != PGRES_TUPLES_OK)
   {
      fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
      result = -EXIT_FAILURE;
   }
   return result;
}

int PGSQL_close_cursor2(PGconn *thisconnec, PGresult *thisresul)
{
   int result = EXIT_SUCCESS;
   thisresul = PQexec(thisconnec, "CLOSE mycursor2");
   PQclear(thisresul);
   return result;
}

int PGSQL_declare_bincsr1(PGconn *thisconnec, PGresult *thisresul, 
                          char *thisselect)
{
   int result = EXIT_SUCCESS;
   char *thiscommand = (char *)malloc( 32 + strlen(thisselect) );
   
   trim_sequence(thisselect, strlen(thisselect));
   
   sprintf(thiscommand, "DECLARE mybcursor BINARY CURSOR FOR %s", thisselect);
   thisresul = PQexec(thisconnec, thiscommand);
   if (!thisresul || PQresultStatus(thisresul) != PGRES_COMMAND_OK)
   {
      fprintf(stderr, "DECLARE BINARY CURSOR command \n%s\nfailed \n%s\n", 
              thisselect, PQresultErrorMessage(thisresul));
      result = -EXIT_FAILURE;
   }
   /* PQclear PGresult whenever it is no longer needed to avoid memory leaks */
   PQclear(thisresul);
   free(thiscommand);
   return result;
}

int PGSQL_fetch_binall1(PGconn *thisconnec, PGresult **thisresul)
{
   int result = EXIT_SUCCESS;
   
   *thisresul = PQexec(thisconnec, "FETCH ALL in mybcursor");
   if (!*thisresul || PQresultStatus(*thisresul) != PGRES_TUPLES_OK)
   {
      fprintf(stderr, "FETCH ALL BINARY command didn't return tuples properly\n");
      result = -EXIT_FAILURE;
   }
   return result;
}

int PGSQL_close_bincsr1(PGconn *thisconnec, PGresult *thisresul)
{
   int result = EXIT_SUCCESS;
   thisresul = PQexec(thisconnec, "CLOSE mybcursor");
   PQclear(thisresul);
   return result;
}

int PGSQL_binprocess(PGconn *thisconnec, PGresult **thisresul, 
                          char *thiscommand)
{
   int result = EXIT_SUCCESS;
   
   result = PGSQL_declare_bincsr1(thisconnec, *thisresul, thiscommand);
   
   if (result < EXIT_SUCCESS)
   {
      return result;
   }
   
   result = PGSQL_fetch_binall1(thisconnec, thisresul);
   
   if (result < EXIT_SUCCESS)
   {
      return result;
   }
   /*
   PQclear(thisresul);
   The calling function has to PQclear PGresult 
   use PGSQL_binprocess to select 
   */
   
   {
      /* use a local PGresult to close the cursor because 
         the PGresult parameter 'thisresul' is needed by 
         the calling function 
      */
      PGresult   *local_pgresult;
      result = PGSQL_close_bincsr1(thisconnec, local_pgresult);
   }
   
   return result;
}

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to