mirror of https://github.com/postgres/postgres
parent
5a2085392c
commit
3c44a132ea
@ -0,0 +1,71 @@ |
||||
.\" This is -*-nroff-*- |
||||
.\" XXX standard disclaimer belongs here.... |
||||
.\" $Header: /cvsroot/pgsql/src/interfaces/libpgeasy/Attic/libpgeasy.3,v 1.1 1999/10/12 14:06:49 momjian Exp $ |
||||
.TH PGEASY INTRO 08/08/98 PostgreSQL PostgreSQL |
||||
.SH DESCRIPTION |
||||
Pgeasy allows you to cleanly interface to the libpq library, |
||||
more like a 4gl SQL interface. |
||||
.PP |
||||
It consists of set of simplified C functions that encapsulate the |
||||
functionality of libpq. |
||||
The functions are: |
||||
|
||||
.nf |
||||
PGresult *doquery(char *query); |
||||
PGconn *connectdb(); |
||||
void disconnectdb(); |
||||
|
||||
int fetch(void *param,...); |
||||
int fetchwithnulls(void *param,...); |
||||
void reset_fetch(); |
||||
|
||||
void on_error_continue(); |
||||
void on_error_stop(); |
||||
|
||||
PGresult *get_result(); |
||||
void set_result(PGresult *newres); |
||||
void unset_result(PGresult *oldres); |
||||
.fi |
||||
.PP |
||||
Many functions return a structure or value, so you can do more work |
||||
with the result if required. |
||||
.PP |
||||
You basically connect to the database with |
||||
.BR connectdb , |
||||
issue your query with |
||||
.BR doquery , |
||||
fetch the results with |
||||
.BR fetch , |
||||
and finish with |
||||
.BR disconnectdb . |
||||
.PP |
||||
For |
||||
.IR select |
||||
queries, |
||||
.BR fetch |
||||
allows you to pass pointers as parameters, and on return the variables |
||||
are filled with data from the binary cursor you opened. These binary |
||||
cursors can not be used if you are running the |
||||
.BR pgeasy |
||||
client on a system with a different architecture than the database |
||||
server. If you pass a NULL pointer parameter, the column is skipped. |
||||
.BR fetchwithnulls |
||||
allows you to retieve the |
||||
.IR null |
||||
status of the field by passing an |
||||
.IR int* |
||||
after each result pointer, which returns true or false if the field is null. |
||||
You can always use libpq functions on the PGresult pointer returned by |
||||
.BR doquery . |
||||
.BR reset_fetch |
||||
starts the fetch back at the beginning. |
||||
.PP |
||||
.BR get_result , |
||||
.BR set_result , |
||||
and |
||||
.BR unset_result |
||||
allow you to handle multiple result sets at the same time. |
||||
.PP |
||||
There are a variety of demonstration programs in the |
||||
.BR pgeasy |
||||
source directory. |
@ -0,0 +1,287 @@ |
||||
/*
|
||||
* pgeasy.c |
||||
* |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <stdarg.h> |
||||
|
||||
#include <libpq-fe.h> |
||||
#include "halt.h" |
||||
#include "libpgeasy.h" |
||||
|
||||
#define NUL '\0' |
||||
|
||||
#ifndef TRUE |
||||
#define TRUE 1 |
||||
#endif |
||||
|
||||
#ifndef FALSE |
||||
#define FALSE 0 |
||||
#endif |
||||
|
||||
/* GLOBAL VARIABLES */ |
||||
static PGconn *conn; |
||||
static PGresult *res = NULL; |
||||
|
||||
#define ON_ERROR_STOP 0 |
||||
#define ON_ERROR_CONTINUE 1 |
||||
|
||||
static int on_error_state = ON_ERROR_STOP; |
||||
|
||||
static in_result_block = FALSE; |
||||
static was_get_unset_result = FALSE; |
||||
|
||||
/* LOCAL VARIABLES */ |
||||
static int tuple; |
||||
|
||||
/*
|
||||
** |
||||
** connectdb - returns PGconn structure |
||||
** |
||||
*/ |
||||
PGconn * |
||||
connectdb(char *dbName, |
||||
char *pghost, |
||||
char *pgport, |
||||
char *pgoptions, |
||||
char *pgtty) |
||||
{ |
||||
/* make a connection to the database */ |
||||
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); |
||||
if (PQstatus(conn) == CONNECTION_BAD) |
||||
halt("Connection to database '%s' failed.\n%s\n", dbName, |
||||
PQerrorMessage(conn)); |
||||
return conn; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** disconnectdb |
||||
** |
||||
*/ |
||||
void |
||||
disconnectdb() |
||||
{ |
||||
PQfinish(conn); |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** doquery - returns PGresult structure |
||||
** |
||||
*/ |
||||
PGresult * |
||||
doquery(char *query) |
||||
{ |
||||
if (res != NULL && in_result_block == FALSE && was_get_unset_result == FALSE) |
||||
PQclear(res); |
||||
|
||||
was_get_unset_result = FALSE; |
||||
res = PQexec(conn, query); |
||||
|
||||
if (on_error_state == ON_ERROR_STOP && |
||||
(res == NULL || |
||||
PQresultStatus(res) == PGRES_BAD_RESPONSE || |
||||
PQresultStatus(res) == PGRES_NONFATAL_ERROR || |
||||
PQresultStatus(res) == PGRES_FATAL_ERROR)) |
||||
{ |
||||
if (res != NULL) |
||||
fprintf(stderr, "query error: %s\n", PQcmdStatus(res)); |
||||
else |
||||
fprintf(stderr, "connection error: %s\n", PQerrorMessage(conn)); |
||||
PQfinish(conn); |
||||
halt("failed request: %s\n", query); |
||||
} |
||||
tuple = 0; |
||||
return res; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** fetch - returns tuple number (starts at 0), or the value END_OF_TUPLES |
||||
** NULL pointers are skipped |
||||
** |
||||
*/ |
||||
int |
||||
fetch(void *param,...) |
||||
{ |
||||
va_list ap; |
||||
int arg, |
||||
num_fields; |
||||
|
||||
num_fields = PQnfields(res); |
||||
|
||||
if (tuple >= PQntuples(res)) |
||||
return END_OF_TUPLES; |
||||
|
||||
va_start(ap, param); |
||||
for (arg = 0; arg < num_fields; arg++) |
||||
{ |
||||
if (param != NULL) |
||||
{ |
||||
if (PQfsize(res, arg) == -1) |
||||
{ |
||||
memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg)); |
||||
((char *) param)[PQgetlength(res, tuple, arg)] = NUL; |
||||
} |
||||
else |
||||
memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg)); |
||||
} |
||||
param = va_arg(ap, char *); |
||||
} |
||||
va_end(ap); |
||||
return tuple++; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** fetchwithnulls - returns tuple number (starts at 0), |
||||
** or the value END_OF_TUPLES |
||||
** Returns TRUE or FALSE into null indicator variables |
||||
** NULL pointers are skipped |
||||
*/ |
||||
int |
||||
fetchwithnulls(void *param,...) |
||||
{ |
||||
va_list ap; |
||||
int arg, |
||||
num_fields; |
||||
|
||||
num_fields = PQnfields(res); |
||||
|
||||
if (tuple >= PQntuples(res)) |
||||
return END_OF_TUPLES; |
||||
|
||||
va_start(ap, param); |
||||
for (arg = 0; arg < num_fields; arg++) |
||||
{ |
||||
if (param != NULL) |
||||
{ |
||||
if (PQfsize(res, arg) == -1) |
||||
{ |
||||
memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg)); |
||||
((char *) param)[PQgetlength(res, tuple, arg)] = NUL; |
||||
} |
||||
else |
||||
memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg)); |
||||
} |
||||
param = va_arg(ap, char *); |
||||
if (PQgetisnull(res, tuple, arg) != 0) |
||||
*(int *) param = 1; |
||||
else |
||||
*(int *) param = 0; |
||||
param = va_arg(ap, char *); |
||||
} |
||||
va_end(ap); |
||||
return tuple++; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** on_error_stop |
||||
** |
||||
*/ |
||||
void |
||||
on_error_stop() |
||||
{ |
||||
on_error_state = ON_ERROR_STOP; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** on_error_continue |
||||
** |
||||
*/ |
||||
void |
||||
on_error_continue() |
||||
{ |
||||
on_error_state = ON_ERROR_CONTINUE; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
** |
||||
** get_result |
||||
** |
||||
*/ |
||||
PGresult * |
||||
get_result() |
||||
{ |
||||
char *cmdstatus = PQcmdStatus(res); |
||||
|
||||
was_get_unset_result = TRUE; |
||||
|
||||
/* we have to store the fetch location somewhere */ |
||||
cmdstatus[0] = NUL; |
||||
memcpy(&cmdstatus[1], &tuple, sizeof(tuple)); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** set_result |
||||
** |
||||
*/ |
||||
void |
||||
set_result(PGresult *newres) |
||||
{ |
||||
|
||||
char *cmdstatus = PQcmdStatus(res); |
||||
|
||||
if (newres == NULL) |
||||
halt("set_result called with null result pointer\n"); |
||||
|
||||
if (res != NULL && was_get_unset_result == FALSE) |
||||
if (in_result_block == FALSE) |
||||
PQclear(res); |
||||
else |
||||
{ |
||||
cmdstatus[0] = NUL; |
||||
memcpy(&cmdstatus[1], &tuple, sizeof(tuple)); |
||||
} |
||||
|
||||
in_result_block = TRUE; |
||||
was_get_unset_result = FALSE; |
||||
|
||||
cmdstatus = PQcmdStatus(newres); |
||||
memcpy(&tuple, &cmdstatus[1], sizeof(tuple)); |
||||
|
||||
res = newres; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
** |
||||
** unset_result |
||||
** |
||||
*/ |
||||
void |
||||
unset_result(PGresult *oldres) |
||||
{ |
||||
char *cmdstatus = PQcmdStatus(oldres); |
||||
|
||||
if (oldres == NULL) |
||||
halt("unset_result called with null result pointer\n"); |
||||
|
||||
if (in_result_block == FALSE) |
||||
halt("Unset of result without being set.\n"); |
||||
|
||||
was_get_unset_result = TRUE; |
||||
cmdstatus[0] = NUL; |
||||
memcpy(&cmdstatus[1], &tuple, sizeof(tuple)); |
||||
in_result_block = FALSE; |
||||
} |
||||
|
||||
/*
|
||||
** |
||||
** reset_fetch |
||||
** |
||||
*/ |
||||
void |
||||
reset_fetch() |
||||
{ |
||||
tuple = 0; |
||||
} |
@ -0,0 +1,22 @@ |
||||
/*
|
||||
* pglib.h |
||||
* |
||||
*/ |
||||
|
||||
PGresult *doquery(char *query); |
||||
PGconn *connectdb(char *dbName, |
||||
char *pghost, |
||||
char *pgport, |
||||
char *pgoptions, |
||||
char *pgtty); |
||||
void disconnectdb(void); |
||||
int fetch(void *param,...); |
||||
int fetchwithnulls(void *param,...); |
||||
void on_error_continue(void); |
||||
void on_error_stop(void); |
||||
PGresult *get_result(void); |
||||
void set_result(PGresult *newres); |
||||
void unset_result(PGresult *oldres); |
||||
void reset_fetch(void); |
||||
|
||||
#define END_OF_TUPLES (-1) |
Loading…
Reference in new issue