mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Erk, the whole directory structure changed on us here...
This commit is contained in:
		
							
								
								
									
										16
									
								
								src/interfaces/ecpg/include/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/interfaces/ecpg/include/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
# Generated automatically from Makefile.in by configure.
 | 
			
		||||
SRCDIR= ../../..
 | 
			
		||||
include $(SRCDIR)/Makefile.global
 | 
			
		||||
 | 
			
		||||
all clean::
 | 
			
		||||
	@echo Nothing to be done.
 | 
			
		||||
 | 
			
		||||
install::
 | 
			
		||||
	install ecpglib.h $(HEADERDIR)	
 | 
			
		||||
	install ecpgtype.h $(HEADERDIR)	
 | 
			
		||||
	install sqlca.h $(HEADERDIR)	
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(HEADERDIR)/ecpglib.h
 | 
			
		||||
	rm -f $(HEADERDIR)/ecpgtype.h
 | 
			
		||||
	rm -f $(HEADERDIR)/sqlca.h
 | 
			
		||||
							
								
								
									
										15
									
								
								src/interfaces/ecpg/include/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/interfaces/ecpg/include/Makefile.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
SRCDIR= ../../..
 | 
			
		||||
include $(SRCDIR)/Makefile.global
 | 
			
		||||
 | 
			
		||||
all clean::
 | 
			
		||||
	@echo Nothing to be done.
 | 
			
		||||
 | 
			
		||||
install::
 | 
			
		||||
	install ecpglib.h $(HEADERDIR)	
 | 
			
		||||
	install ecpgtype.h $(HEADERDIR)	
 | 
			
		||||
	install sqlca.h $(HEADERDIR)	
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(HEADERDIR)/ecpglib.h
 | 
			
		||||
	rm -f $(HEADERDIR)/ecpgtype.h
 | 
			
		||||
	rm -f $(HEADERDIR)/sqlca.h
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#include <c.h>
 | 
			
		||||
 | 
			
		||||
void ECPGdebug(int);
 | 
			
		||||
void ECPGdebug(int, FILE *);
 | 
			
		||||
bool ECPGconnect(const char * dbname);
 | 
			
		||||
bool ECPGdo(int, char *, ...);
 | 
			
		||||
bool ECPGcommit(int);
 | 
			
		||||
@@ -32,13 +32,13 @@
 | 
			
		||||
enum ECPGttype {
 | 
			
		||||
    ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short, 
 | 
			
		||||
    ECPGt_int, ECPGt_unsigned_int, ECPGt_long, ECPGt_unsigned_long,
 | 
			
		||||
    ECPGt_bool,
 | 
			
		||||
    ECPGt_float, ECPGt_double,
 | 
			
		||||
    ECPGt_varchar, ECPGt_varchar2,
 | 
			
		||||
    ECPGt_array,
 | 
			
		||||
    ECPGt_record,
 | 
			
		||||
    ECPGt_EOIT,			/* End of insert types. */
 | 
			
		||||
    ECPGt_EORT			/* End of result types. */
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2)
 | 
			
		||||
@@ -1,19 +1,21 @@
 | 
			
		||||
# Generated automatically from Makefile.in by configure.
 | 
			
		||||
TOPDIR=/home/meskes/data/computer/databases/postgres/pgsql/src/interfaces/ecpg/../..
 | 
			
		||||
PQ_INCLUDE=-I$(TOPDIR)/include -I$(TOPDIR)/interfaces/libpq
 | 
			
		||||
POSTGRES_LIB=$(POSTGRESTOP)/lib
 | 
			
		||||
SRCDIR= ../../..
 | 
			
		||||
include $(SRCDIR)/Makefile.global
 | 
			
		||||
 | 
			
		||||
PQ_INCLUDE=-I$(SRCDIR)/include -I$(SRCDIR)/interfaces/libpq
 | 
			
		||||
 | 
			
		||||
all: lib
 | 
			
		||||
 | 
			
		||||
lib: libecpg.a
 | 
			
		||||
 | 
			
		||||
clean::
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o *.a core a.out *~
 | 
			
		||||
 | 
			
		||||
install:: libecpg.a
 | 
			
		||||
	install -m644 libecpg.a $(POSTGRES_LIB)
 | 
			
		||||
install: libecpg.a
 | 
			
		||||
	install -m 644 libecpg.a $(LIBDIR)
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(POSTGRES_LIB)/libecpg.a
 | 
			
		||||
	rm -f $(LIBDIR)/libecpg.a
 | 
			
		||||
 | 
			
		||||
# Rules that do something
 | 
			
		||||
libecpg.a : libecpg.a(ecpglib.o) libecpg.a(typename.o)
 | 
			
		||||
@@ -1,18 +1,20 @@
 | 
			
		||||
TOPDIR=@TOPSRC@
 | 
			
		||||
PQ_INCLUDE=-I$(TOPDIR)/include -I$(TOPDIR)/interfaces/libpq
 | 
			
		||||
POSTGRES_LIB=$(POSTGRESTOP)/lib
 | 
			
		||||
SRCDIR= ../../..
 | 
			
		||||
include $(SRCDIR)/Makefile.global
 | 
			
		||||
 | 
			
		||||
PQ_INCLUDE=-I$(SRCDIR)/include -I$(SRCDIR)/interfaces/libpq
 | 
			
		||||
 | 
			
		||||
all: lib
 | 
			
		||||
 | 
			
		||||
lib: libecpg.a
 | 
			
		||||
 | 
			
		||||
clean::
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o *.a core a.out *~
 | 
			
		||||
 | 
			
		||||
install:: libecpg.a
 | 
			
		||||
	install -m644 libecpg.a $(POSTGRES_LIB)
 | 
			
		||||
install: libecpg.a
 | 
			
		||||
	install -m 644 libecpg.a $(LIBDIR)
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(POSTGRES_LIB)/libecpg.a
 | 
			
		||||
	rm -f $(LIBDIR)/libecpg.a
 | 
			
		||||
 | 
			
		||||
# Rules that do something
 | 
			
		||||
libecpg.a : libecpg.a(ecpglib.o) libecpg.a(typename.o)
 | 
			
		||||
							
								
								
									
										648
									
								
								src/interfaces/ecpg/lib/ecpglib.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										648
									
								
								src/interfaces/ecpg/lib/ecpglib.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,648 @@
 | 
			
		||||
/* Copyright comment */
 | 
			
		||||
/*
 | 
			
		||||
 * The aim is to get a simpler inteface to the database routines.
 | 
			
		||||
 * All the tidieous messing around with tuples is supposed to be hidden
 | 
			
		||||
 * by this function.
 | 
			
		||||
 */
 | 
			
		||||
/* Author: Linus Tolke
 | 
			
		||||
   (actually most if the code is "borrowed" from the distribution and just
 | 
			
		||||
   slightly modified)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Taken over as part of PostgreSQL by Michael Meskes <meskes@debian.org>
 | 
			
		||||
   on Feb. 5th, 1998 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <ecpgtype.h>
 | 
			
		||||
#include <ecpglib.h>
 | 
			
		||||
#include <sqlca.h>
 | 
			
		||||
#include <libpq-fe.h>
 | 
			
		||||
#include <libpq/pqcomm.h>
 | 
			
		||||
 | 
			
		||||
static PGconn *simple_connection;
 | 
			
		||||
static int	simple_debug = 0;
 | 
			
		||||
static FILE *debugstream = NULL;
 | 
			
		||||
static int	committed = true;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
register_error(int code, char *fmt,...)
 | 
			
		||||
{
 | 
			
		||||
	va_list		args;
 | 
			
		||||
 | 
			
		||||
	sqlca.sqlcode = code;
 | 
			
		||||
	va_start(args, fmt);
 | 
			
		||||
	vsprintf(sqlca.sqlerrm.sqlerrmc, fmt, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
	sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function returns a newly malloced string that has the ' and \
 | 
			
		||||
   in the argument quoted with \.
 | 
			
		||||
 */
 | 
			
		||||
static
 | 
			
		||||
char	   *
 | 
			
		||||
quote_postgres(char *arg)
 | 
			
		||||
{
 | 
			
		||||
	char	   *res = (char *) malloc(2 * strlen(arg) + 1);
 | 
			
		||||
	int			i,
 | 
			
		||||
				ri;
 | 
			
		||||
 | 
			
		||||
	for (i = 0, ri = 0; arg[i]; i++, ri++)
 | 
			
		||||
	{
 | 
			
		||||
		switch (arg[i])
 | 
			
		||||
		{
 | 
			
		||||
			case '\'':
 | 
			
		||||
			case '\\':
 | 
			
		||||
				res[ri++] = '\\';
 | 
			
		||||
			default:
 | 
			
		||||
				;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		res[ri] = arg[i];
 | 
			
		||||
	}
 | 
			
		||||
	res[ri] = '\0';
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGdo(int lineno, char *query,...)
 | 
			
		||||
{
 | 
			
		||||
	va_list		ap;
 | 
			
		||||
	bool		status = false;
 | 
			
		||||
	char	   *copiedquery;
 | 
			
		||||
	PGresult   *results;
 | 
			
		||||
	PGnotify   *notify;
 | 
			
		||||
	enum ECPGttype type;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, query);
 | 
			
		||||
 | 
			
		||||
	sqlca.sqlcode = 0;
 | 
			
		||||
	copiedquery = strdup(query);
 | 
			
		||||
 | 
			
		||||
	type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Now, if the type is one of the fill in types then we take the argument
 | 
			
		||||
	 * and enter that in the string at the first %s position. Then if there
 | 
			
		||||
	 * are any more fill in types we fill in at the next and so on.
 | 
			
		||||
	 */
 | 
			
		||||
	while (type != ECPGt_EOIT)
 | 
			
		||||
	{
 | 
			
		||||
		void	   *value = NULL;
 | 
			
		||||
		short		varcharsize;
 | 
			
		||||
		short		size;
 | 
			
		||||
		short		arrsize;
 | 
			
		||||
 | 
			
		||||
		char	   *newcopy;
 | 
			
		||||
		char	   *mallocedval = NULL;
 | 
			
		||||
		char	   *tobeinserted = NULL;
 | 
			
		||||
		char	   *p;
 | 
			
		||||
		char		buff[20];
 | 
			
		||||
 | 
			
		||||
		/* Some special treatment is needed for records since we want their
 | 
			
		||||
		   contents to arrive in a comma-separated list on insert (I think). */
 | 
			
		||||
 | 
			
		||||
		value = va_arg(ap, void *);
 | 
			
		||||
		varcharsize = va_arg(ap, short);
 | 
			
		||||
		size = va_arg(ap, short);
 | 
			
		||||
		arrsize = va_arg(ap, short);
 | 
			
		||||
 | 
			
		||||
		switch (type)
 | 
			
		||||
		{
 | 
			
		||||
			case ECPGt_char:
 | 
			
		||||
			case ECPGt_short:
 | 
			
		||||
			case ECPGt_int:
 | 
			
		||||
				sprintf(buff, "%d", *(int *) value);
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_unsigned_char:
 | 
			
		||||
			case ECPGt_unsigned_short:
 | 
			
		||||
			case ECPGt_unsigned_int:
 | 
			
		||||
				sprintf(buff, "%d", *(unsigned int *) value);
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_long:
 | 
			
		||||
				sprintf(buff, "%ld", *(long *) value);
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_unsigned_long:
 | 
			
		||||
				sprintf(buff, "%ld", *(unsigned long *) value);
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_float:
 | 
			
		||||
				sprintf(buff, "%.14g", *(float *) value);
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_double:
 | 
			
		||||
				sprintf(buff, "%.14g", *(double *) value);
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_bool:
 | 
			
		||||
				sprintf(buff, "'%c'", (*(char *) value ? 't' : 'f'));
 | 
			
		||||
				tobeinserted = buff;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case ECPGt_varchar:
 | 
			
		||||
			case ECPGt_varchar2:
 | 
			
		||||
				{
 | 
			
		||||
					struct ECPGgeneric_varchar *var =
 | 
			
		||||
					(struct ECPGgeneric_varchar *) value;
 | 
			
		||||
 | 
			
		||||
					newcopy = (char *) malloc(var->len + 1);
 | 
			
		||||
					strncpy(newcopy, var->arr, var->len);
 | 
			
		||||
					newcopy[var->len] = '\0';
 | 
			
		||||
 | 
			
		||||
					mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
 | 
			
		||||
					strcpy(mallocedval, "'");
 | 
			
		||||
					strcat(mallocedval, quote_postgres(newcopy));
 | 
			
		||||
					strcat(mallocedval, "'");
 | 
			
		||||
 | 
			
		||||
					free(newcopy);
 | 
			
		||||
 | 
			
		||||
					tobeinserted = mallocedval;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
				/* Not implemented yet */
 | 
			
		||||
				register_error(-1, "Unsupported type %s on line %d.",
 | 
			
		||||
							   ECPGtype_name(type), lineno);
 | 
			
		||||
				return false;
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Now tobeinserted points to an area that is to be inserted at
 | 
			
		||||
		   the first %s
 | 
			
		||||
		 */
 | 
			
		||||
		newcopy = (char *) malloc(strlen(copiedquery)
 | 
			
		||||
								  + strlen(tobeinserted)
 | 
			
		||||
								  + 1);
 | 
			
		||||
		strcpy(newcopy, copiedquery);
 | 
			
		||||
		if ((p = strstr(newcopy, ";;")) == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			/* We have an argument but we dont have the matched up string
 | 
			
		||||
			   in the string
 | 
			
		||||
			 */
 | 
			
		||||
			register_error(-1, "Too many arguments line %d.", lineno);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			strcpy(p, tobeinserted);
 | 
			
		||||
			/* The strange thing in the second argument is the rest of the
 | 
			
		||||
			   string from the old string */
 | 
			
		||||
			strcat(newcopy,
 | 
			
		||||
				   copiedquery
 | 
			
		||||
				   + (p - newcopy)
 | 
			
		||||
				   + 2 /* Length of ;; */ );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Now everything is safely copied to the newcopy. Lets free the
 | 
			
		||||
		   oldcopy and let the copiedquery get the value from the newcopy.
 | 
			
		||||
		 */
 | 
			
		||||
		if (mallocedval != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			free(mallocedval);
 | 
			
		||||
			mallocedval = NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		free(copiedquery);
 | 
			
		||||
		copiedquery = newcopy;
 | 
			
		||||
 | 
			
		||||
		type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check if there are unmatched things left. */
 | 
			
		||||
	if (strstr(copiedquery, ";;") != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		register_error(-1, "Too few arguments line %d.", lineno);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Now then request is built. */
 | 
			
		||||
 | 
			
		||||
	if (committed)
 | 
			
		||||
	{
 | 
			
		||||
		if ((results = PQexec(simple_connection, "begin")) == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			register_error(-1, "Error starting transaction line %d.", lineno);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		PQclear(results);
 | 
			
		||||
		committed = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ECPGlog("ECPGdo line %d: QUERY: %s\n", lineno, copiedquery);
 | 
			
		||||
	results = PQexec(simple_connection, copiedquery);
 | 
			
		||||
	free(copiedquery);
 | 
			
		||||
 | 
			
		||||
	if (results == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		ECPGlog("ECPGdo line %d: error: %s", lineno,
 | 
			
		||||
				PQerrorMessage(simple_connection));
 | 
			
		||||
		register_error(-1, "Postgres error: %s line %d.",
 | 
			
		||||
					   PQerrorMessage(simple_connection), lineno);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		switch (PQresultStatus(results))
 | 
			
		||||
		{
 | 
			
		||||
				int			m,
 | 
			
		||||
							n,
 | 
			
		||||
							x;
 | 
			
		||||
 | 
			
		||||
			case PGRES_TUPLES_OK:
 | 
			
		||||
				/* XXX Cheap Hack. For now, we see only the last group
 | 
			
		||||
				 * of tuples.  This is clearly not the right
 | 
			
		||||
				 * way to do things !!
 | 
			
		||||
				 */
 | 
			
		||||
 | 
			
		||||
				m = PQnfields(results);
 | 
			
		||||
				n = PQntuples(results);
 | 
			
		||||
 | 
			
		||||
				if (n < 1)
 | 
			
		||||
				{
 | 
			
		||||
					ECPGlog("ECPGdo lineno %d: Incorrect number of matches: %d\n",
 | 
			
		||||
							lineno, n);
 | 
			
		||||
					register_error(1, "Data not found line %d.", lineno);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (n > 1)
 | 
			
		||||
				{
 | 
			
		||||
					ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n",
 | 
			
		||||
							lineno, n);
 | 
			
		||||
					register_error(-1, "To many matches line %d.", lineno);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				status = true;
 | 
			
		||||
 | 
			
		||||
				for (x = 0; x < m && status; x++)
 | 
			
		||||
				{
 | 
			
		||||
					void	   *value = NULL;
 | 
			
		||||
					short		varcharsize;
 | 
			
		||||
					short		size;
 | 
			
		||||
					short		arrsize;
 | 
			
		||||
 | 
			
		||||
					char	   *pval = PQgetvalue(results, 0, x);
 | 
			
		||||
 | 
			
		||||
					/*long int	* res_int;
 | 
			
		||||
					   char    ** res_charstar;
 | 
			
		||||
					   char    * res_char;
 | 
			
		||||
					   int	   res_len; */
 | 
			
		||||
					char	   *scan_length;
 | 
			
		||||
 | 
			
		||||
					ECPGlog("ECPGdo line %d: RESULT: %s\n", lineno, pval ? pval : "");
 | 
			
		||||
 | 
			
		||||
					/* No the pval is a pointer to the value. */
 | 
			
		||||
					/* We will have to decode the value */
 | 
			
		||||
					type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
					value = va_arg(ap, void *);
 | 
			
		||||
					varcharsize = va_arg(ap, short);
 | 
			
		||||
					size = va_arg(ap, short);
 | 
			
		||||
					arrsize = va_arg(ap, short);
 | 
			
		||||
 | 
			
		||||
					switch (type)
 | 
			
		||||
					{
 | 
			
		||||
							long		res;
 | 
			
		||||
							unsigned long ures;
 | 
			
		||||
							double		dres;
 | 
			
		||||
 | 
			
		||||
						case ECPGt_char:
 | 
			
		||||
						case ECPGt_short:
 | 
			
		||||
						case ECPGt_int:
 | 
			
		||||
						case ECPGt_long:
 | 
			
		||||
							if (pval)
 | 
			
		||||
							{
 | 
			
		||||
								res = strtol(pval, &scan_length, 10);
 | 
			
		||||
								if (*scan_length != '\0')		/* Garbage left */
 | 
			
		||||
								{
 | 
			
		||||
									register_error(-1, "Not correctly formatted int type: %s line %d.",
 | 
			
		||||
												   pval, lineno);
 | 
			
		||||
									status = false;
 | 
			
		||||
									res = 0L;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							else
 | 
			
		||||
								res = 0L;
 | 
			
		||||
 | 
			
		||||
							/* Again?! Yes */
 | 
			
		||||
							switch (type)
 | 
			
		||||
							{
 | 
			
		||||
								case ECPGt_char:
 | 
			
		||||
									*(char *) value = (char) res;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_short:
 | 
			
		||||
									*(short *) value = (short) res;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_int:
 | 
			
		||||
									*(int *) value = (int) res;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_long:
 | 
			
		||||
									*(long *) value = res;
 | 
			
		||||
									break;
 | 
			
		||||
								default:
 | 
			
		||||
									/* Cannot happen */
 | 
			
		||||
									break;
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case ECPGt_unsigned_char:
 | 
			
		||||
						case ECPGt_unsigned_short:
 | 
			
		||||
						case ECPGt_unsigned_int:
 | 
			
		||||
						case ECPGt_unsigned_long:
 | 
			
		||||
							if (pval)
 | 
			
		||||
							{
 | 
			
		||||
								ures = strtoul(pval, &scan_length, 10);
 | 
			
		||||
								if (*scan_length != '\0')		/* Garbage left */
 | 
			
		||||
								{
 | 
			
		||||
									register_error(-1, "Not correctly formatted unsigned type: %s line %d.",
 | 
			
		||||
												   pval, lineno);
 | 
			
		||||
									status = false;
 | 
			
		||||
									ures = 0L;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							else
 | 
			
		||||
								ures = 0L;
 | 
			
		||||
 | 
			
		||||
							/* Again?! Yes */
 | 
			
		||||
							switch (type)
 | 
			
		||||
							{
 | 
			
		||||
								case ECPGt_unsigned_char:
 | 
			
		||||
									*(unsigned char *) value = (unsigned char) ures;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_unsigned_short:
 | 
			
		||||
									*(unsigned short *) value = (unsigned short) ures;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_unsigned_int:
 | 
			
		||||
									*(unsigned int *) value = (unsigned int) ures;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_unsigned_long:
 | 
			
		||||
									*(unsigned long *) value = ures;
 | 
			
		||||
									break;
 | 
			
		||||
								default:
 | 
			
		||||
									/* Cannot happen */
 | 
			
		||||
									break;
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
						case ECPGt_float:
 | 
			
		||||
						case ECPGt_double:
 | 
			
		||||
							if (pval)
 | 
			
		||||
							{
 | 
			
		||||
								dres = strtod(pval, &scan_length);
 | 
			
		||||
								if (*scan_length != '\0')		/* Garbage left */
 | 
			
		||||
								{
 | 
			
		||||
									register_error(-1, "Not correctly formatted floating point type: %s line %d.",
 | 
			
		||||
												   pval, lineno);
 | 
			
		||||
									status = false;
 | 
			
		||||
									dres = 0.0;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							else
 | 
			
		||||
								dres = 0.0;
 | 
			
		||||
 | 
			
		||||
							/* Again?! Yes */
 | 
			
		||||
							switch (type)
 | 
			
		||||
							{
 | 
			
		||||
								case ECPGt_float:
 | 
			
		||||
									*(float *) value = dres;
 | 
			
		||||
									break;
 | 
			
		||||
								case ECPGt_double:
 | 
			
		||||
									*(double *) value = dres;
 | 
			
		||||
									break;
 | 
			
		||||
								default:
 | 
			
		||||
									/* Cannot happen */
 | 
			
		||||
									break;
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case ECPGt_bool:
 | 
			
		||||
							if (pval)
 | 
			
		||||
							{
 | 
			
		||||
								if (pval[0] == 'f' && pval[1] == '\0')
 | 
			
		||||
								{
 | 
			
		||||
									*(char *) value = false;
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
								else if (pval[0] == 't' && pval[1] == '\0')
 | 
			
		||||
								{
 | 
			
		||||
									*(char *) value = true;
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							register_error(-1, "Unable to convert %s to bool on line %d.",
 | 
			
		||||
										   (pval ? pval : "NULL"),
 | 
			
		||||
										   lineno);
 | 
			
		||||
							return false;
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case ECPGt_varchar:
 | 
			
		||||
							{
 | 
			
		||||
								struct ECPGgeneric_varchar *var =
 | 
			
		||||
								(struct ECPGgeneric_varchar *) value;
 | 
			
		||||
 | 
			
		||||
								strncpy(var->arr, pval, varcharsize);
 | 
			
		||||
								var->len = strlen(pval);
 | 
			
		||||
								if (var->len > varcharsize)
 | 
			
		||||
									var->len = varcharsize;
 | 
			
		||||
							}
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						case ECPGt_EORT:
 | 
			
		||||
							ECPGlog("ECPGdo line %d: Too few arguments.\n", lineno);
 | 
			
		||||
							register_error(-1, "Too few arguments line %d.", lineno);
 | 
			
		||||
							status = false;
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						default:
 | 
			
		||||
							register_error(-1, "Unsupported type %s on line %d.",
 | 
			
		||||
										   ECPGtype_name(type), lineno);
 | 
			
		||||
							return false;
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
 | 
			
		||||
				if (status && type != ECPGt_EORT)
 | 
			
		||||
				{
 | 
			
		||||
					register_error(-1, "Too many arguments line %d.", lineno);
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				PQclear(results);
 | 
			
		||||
				break;
 | 
			
		||||
			case PGRES_EMPTY_QUERY:
 | 
			
		||||
				/* do nothing */
 | 
			
		||||
				register_error(-1, "Empty query line %d.", lineno);
 | 
			
		||||
				break;
 | 
			
		||||
			case PGRES_COMMAND_OK:
 | 
			
		||||
				status = true;
 | 
			
		||||
				ECPGlog("ECPGdo line %d Ok: %s\n", lineno, PQcmdStatus(results));
 | 
			
		||||
				break;
 | 
			
		||||
			case PGRES_NONFATAL_ERROR:
 | 
			
		||||
			case PGRES_FATAL_ERROR:
 | 
			
		||||
			case PGRES_BAD_RESPONSE:
 | 
			
		||||
				ECPGlog("ECPGdo line %d: Error: %s",
 | 
			
		||||
						lineno, PQerrorMessage(simple_connection));
 | 
			
		||||
				register_error(-1, "Error: %s line %d.",
 | 
			
		||||
							   PQerrorMessage(simple_connection), lineno);
 | 
			
		||||
				break;
 | 
			
		||||
			case PGRES_COPY_OUT:
 | 
			
		||||
				ECPGlog("ECPGdo line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
 | 
			
		||||
				PQendcopy(results->conn);
 | 
			
		||||
				break;
 | 
			
		||||
			case PGRES_COPY_IN:
 | 
			
		||||
				ECPGlog("ECPGdo line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
 | 
			
		||||
				PQendcopy(results->conn);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				ECPGlog("ECPGdo line %d: Got something else, postgres error.\n",
 | 
			
		||||
						lineno);
 | 
			
		||||
				register_error(-1, "Postgres error line %d.", lineno);
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	/* check for asynchronous returns */
 | 
			
		||||
	notify = PQnotifies(simple_connection);
 | 
			
		||||
	if (notify)
 | 
			
		||||
	{
 | 
			
		||||
		ECPGlog("ECPGdo line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
 | 
			
		||||
				lineno, notify->relname, notify->be_pid);
 | 
			
		||||
		free(notify);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGcommit(int lineno)
 | 
			
		||||
{
 | 
			
		||||
	PGresult   *res;
 | 
			
		||||
 | 
			
		||||
	ECPGlog("ECPGcommit line %d\n", lineno);
 | 
			
		||||
	if ((res = PQexec(simple_connection, "end")) == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		register_error(-1, "Error committing line %d.", lineno);
 | 
			
		||||
		return (FALSE);
 | 
			
		||||
	}
 | 
			
		||||
	PQclear(res);
 | 
			
		||||
	committed = 1;
 | 
			
		||||
	return (TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGrollback(int lineno)
 | 
			
		||||
{
 | 
			
		||||
	PGresult   *res;
 | 
			
		||||
 | 
			
		||||
	ECPGlog("ECPGrollback line %d\n", lineno);
 | 
			
		||||
	if ((res = PQexec(simple_connection, "abort")) == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		register_error(-1, "Error rolling back line %d.", lineno);
 | 
			
		||||
		return (FALSE);
 | 
			
		||||
	}
 | 
			
		||||
	PQclear(res);
 | 
			
		||||
	committed = 1;
 | 
			
		||||
	return (TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGsetdb(PGconn *newcon)
 | 
			
		||||
{
 | 
			
		||||
	ECPGfinish();
 | 
			
		||||
	simple_connection = newcon;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGconnect(const char *dbname)
 | 
			
		||||
{
 | 
			
		||||
	char	   *name = strdup(dbname);
 | 
			
		||||
 | 
			
		||||
	ECPGlog("ECPGconnect: opening database %s\n", name);
 | 
			
		||||
 | 
			
		||||
	sqlca.sqlcode = 0;
 | 
			
		||||
 | 
			
		||||
	ECPGsetdb(PQsetdb(NULL, NULL, NULL, NULL, name));
 | 
			
		||||
 | 
			
		||||
	free(name);
 | 
			
		||||
	name = NULL;
 | 
			
		||||
 | 
			
		||||
	if (PQstatus(simple_connection) == CONNECTION_BAD)
 | 
			
		||||
	{
 | 
			
		||||
		ECPGfinish();
 | 
			
		||||
		ECPGlog("ECPGconnect: could not open database %s\n", dbname);
 | 
			
		||||
		register_error(-1, "ECPGconnect: could not open database %s.", dbname);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGstatus()
 | 
			
		||||
{
 | 
			
		||||
	return PQstatus(simple_connection) != CONNECTION_BAD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGfinish()
 | 
			
		||||
{
 | 
			
		||||
	if (simple_connection != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		ECPGlog("ECPGfinish: finishing.\n");
 | 
			
		||||
		PQfinish(simple_connection);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		ECPGlog("ECPGfinish: called an extra time.\n");
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ECPGdebug(int n, FILE *dbgs)
 | 
			
		||||
{
 | 
			
		||||
	simple_debug = n;
 | 
			
		||||
	debugstream = dbgs;
 | 
			
		||||
	ECPGlog("ECPGdebug: set to %d\n", simple_debug);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ECPGlog(const char *format,...)
 | 
			
		||||
{
 | 
			
		||||
	va_list		ap;
 | 
			
		||||
 | 
			
		||||
	if (simple_debug)
 | 
			
		||||
	{
 | 
			
		||||
		char	   *f = (char *) malloc(strlen(format) + 100);
 | 
			
		||||
 | 
			
		||||
		sprintf(f, "[%d]: %s", getpid(), format);
 | 
			
		||||
 | 
			
		||||
		va_start(ap, format);
 | 
			
		||||
		vfprintf(debugstream, f, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
 | 
			
		||||
		free(f);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -17,6 +17,7 @@ ECPGtype_name(enum ECPGttype typ)
 | 
			
		||||
    case ECPGt_unsigned_long:	return "unsigned long";
 | 
			
		||||
    case ECPGt_float:		return "float";
 | 
			
		||||
    case ECPGt_double:		return "double";
 | 
			
		||||
    case ECPGt_bool:		return "bool";
 | 
			
		||||
    default:
 | 
			
		||||
	abort();
 | 
			
		||||
    }
 | 
			
		||||
@@ -1,36 +1,32 @@
 | 
			
		||||
# Generated automatically from Makefile.in by configure.
 | 
			
		||||
POSTGRESTOP=@POSTGRESERVER@
 | 
			
		||||
POSTGRES_BIN=$(POSTGRESTOP)/bin
 | 
			
		||||
POSTGRES_LIB=$(POSTGRESTOP)/lib
 | 
			
		||||
SRCDIR= ../../..
 | 
			
		||||
include $(SRCDIR)/Makefile.global
 | 
			
		||||
 | 
			
		||||
CC=gcc
 | 
			
		||||
LEX=flex
 | 
			
		||||
LEXLIB=-lfl
 | 
			
		||||
YACC=bison -y
 | 
			
		||||
 | 
			
		||||
YACC=/usr/bin/bison
 | 
			
		||||
YFLAGS=-y -d
 | 
			
		||||
 | 
			
		||||
CFLAGS=-I../include -O2 -g -Wall
 | 
			
		||||
 | 
			
		||||
all:: ecpg
 | 
			
		||||
 | 
			
		||||
clean::
 | 
			
		||||
	rm -f *.o core a.out ecpg y.tab.h y.tab.c *~
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o core a.out ecpg preproc.tab.h y.tab.c *~
 | 
			
		||||
 | 
			
		||||
install:: all
 | 
			
		||||
	install -c -d -m755 $(POSTGRES_LIB)/ecpg
 | 
			
		||||
	install -c -m555 preproc $(POSTGRES_LIB)/ecpg
 | 
			
		||||
	install -c -m555 ecpg $(POSTGRES_BIN)
 | 
			
		||||
install: all
 | 
			
		||||
	install -c -m 755 ecpg $(BINDIR)
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(POSTGRES_BIN)/ecpg
 | 
			
		||||
	rm -f $(POSTGRES_LIB)/ecpg/preproc
 | 
			
		||||
uninstall:
 | 
			
		||||
	rm -f $(BINDIR)/ecpg
 | 
			
		||||
 | 
			
		||||
# Rule that really do something.
 | 
			
		||||
ecpg: y.tab.o pgc.o type.o ecpg.o
 | 
			
		||||
	$(CC) -g -O2 -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o -L../lib -lecpg $(LEXLIB)
 | 
			
		||||
 | 
			
		||||
y.tab.h y.tab.c: preproc.y
 | 
			
		||||
	$(YACC) -d $<
 | 
			
		||||
	$(YACC) $(YFLAGS) $<
 | 
			
		||||
 | 
			
		||||
y.tab.o : y.tab.h ../include/ecpgtype.h
 | 
			
		||||
type.o : ../include/ecpgtype.h
 | 
			
		||||
							
								
								
									
										32
									
								
								src/interfaces/ecpg/preproc/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/interfaces/ecpg/preproc/Makefile.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
SRCDIR= ../../..
 | 
			
		||||
include $(SRCDIR)/Makefile.global
 | 
			
		||||
 | 
			
		||||
CC=@CC@
 | 
			
		||||
LEX=@LEX@
 | 
			
		||||
LEXLIB=@LEXLIB@
 | 
			
		||||
YACC=@YACC@
 | 
			
		||||
YFLAGS=@YFLAGS@
 | 
			
		||||
 | 
			
		||||
CFLAGS=-I../include -O2 -g -Wall
 | 
			
		||||
 | 
			
		||||
all:: ecpg
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o core a.out ecpg preproc.tab.h y.tab.c *~
 | 
			
		||||
 | 
			
		||||
install: all
 | 
			
		||||
	install -c -m 755 ecpg $(BINDIR)
 | 
			
		||||
 | 
			
		||||
uninstall:
 | 
			
		||||
	rm -f $(BINDIR)/ecpg
 | 
			
		||||
 | 
			
		||||
# Rule that really do something.
 | 
			
		||||
ecpg: y.tab.o pgc.o type.o ecpg.o
 | 
			
		||||
	$(CC) -g -O2 -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o -L../lib -lecpg $(LEXLIB)
 | 
			
		||||
 | 
			
		||||
y.tab.h y.tab.c: preproc.y
 | 
			
		||||
	$(YACC) $(YFLAGS) $<
 | 
			
		||||
 | 
			
		||||
y.tab.o : y.tab.h ../include/ecpgtype.h
 | 
			
		||||
type.o : ../include/ecpgtype.h
 | 
			
		||||
pgc.o : ../include/ecpgtype.h
 | 
			
		||||
@@ -8,10 +8,9 @@
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
 | 
			
		||||
extern void lex_init(void);
 | 
			
		||||
extern FILE *yyin,
 | 
			
		||||
		   *yyout;
 | 
			
		||||
 | 
			
		||||
int			yyparse(void);
 | 
			
		||||
extern FILE *yyin, *yyout;
 | 
			
		||||
extern char * input_filename;
 | 
			
		||||
extern int yyparse(void);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
usage(char *progname)
 | 
			
		||||
@@ -22,7 +21,8 @@ usage(char *progname)
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *const argv[])
 | 
			
		||||
{
 | 
			
		||||
	char		c, out_option = 0;
 | 
			
		||||
	char		c,
 | 
			
		||||
				out_option = 0;
 | 
			
		||||
	int			fnr;
 | 
			
		||||
 | 
			
		||||
	while ((c = getopt(argc, argv, "o:")) != EOF)
 | 
			
		||||
@@ -58,7 +58,8 @@ main(int argc, char *const argv[])
 | 
			
		||||
 | 
			
		||||
		ptr2ext = strrchr(filename, '.');
 | 
			
		||||
		/* no extension or extension not equal .pgc */
 | 
			
		||||
		if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0) {
 | 
			
		||||
		if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0)
 | 
			
		||||
		{
 | 
			
		||||
			ptr2ext = filename + strlen(filename);
 | 
			
		||||
			ptr2ext[0] = '.';
 | 
			
		||||
		}
 | 
			
		||||
@@ -67,17 +68,18 @@ main(int argc, char *const argv[])
 | 
			
		||||
		ptr2ext[1] = 'c';
 | 
			
		||||
		ptr2ext[2] = '\0';
 | 
			
		||||
 | 
			
		||||
		if (out_option == 0)		/* calculate the output name */
 | 
			
		||||
		if (out_option == 0)	/* calculate the output name */
 | 
			
		||||
		{
 | 
			
		||||
			yyout = fopen(filename, "w");
 | 
			
		||||
			if (yyout == NULL) {
 | 
			
		||||
			if (yyout == NULL)
 | 
			
		||||
			{
 | 
			
		||||
				perror(filename);
 | 
			
		||||
				free(filename);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		yyin = fopen(argv[fnr], "r");
 | 
			
		||||
		yyin = fopen(input_filename = argv[fnr], "r");
 | 
			
		||||
		if (yyin == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			perror(argv[fnr]);
 | 
			
		||||
@@ -95,7 +97,7 @@ main(int argc, char *const argv[])
 | 
			
		||||
 | 
			
		||||
			fclose(yyin);
 | 
			
		||||
			if (out_option == 0)
 | 
			
		||||
				fclose (yyout);
 | 
			
		||||
				fclose(yyout);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		free(filename);
 | 
			
		||||
@@ -3,8 +3,11 @@
 | 
			
		||||
#include "type.h"
 | 
			
		||||
#include "y.tab.h"
 | 
			
		||||
 | 
			
		||||
#define dbg(arg)	fprintf(stderr, "DEBUG: %s\n", #arg);
 | 
			
		||||
extern int debugging;
 | 
			
		||||
 | 
			
		||||
#define dbg(arg)       if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg);
 | 
			
		||||
%}
 | 
			
		||||
%option yylineno
 | 
			
		||||
%s C SQL
 | 
			
		||||
ccomment	\/\*([^*]|\*[^/]|\*\*[^/])*\*\/
 | 
			
		||||
ws	([ \t\n][ \t\n]*|{ccomment})*
 | 
			
		||||
@@ -53,7 +56,8 @@ int			{ dbg(S_INT); return S_INT; }
 | 
			
		||||
char			{ dbg(S_CHAR); return S_CHAR; }
 | 
			
		||||
float			{ dbg(S_FLOAT); return S_FLOAT; }
 | 
			
		||||
double			{ dbg(S_DOUBLE); return S_DOUBLE; }
 | 
			
		||||
			  
 | 
			
		||||
bool                   { dbg(S_BOOL); return S_BOOL; }
 | 
			
		||||
 | 
			
		||||
{string}		{ dbg(SQL_STRING); return SQL_STRING; }
 | 
			
		||||
<SQL>{ws}		; 
 | 
			
		||||
{symbol}		{ dbg(S_SYMBOL); return S_SYMBOL; }
 | 
			
		||||
@@ -100,12 +104,12 @@ double			{ dbg(S_DOUBLE); return S_DOUBLE; }
 | 
			
		||||
.			{ dbg(.); return S_ANYTHING; }
 | 
			
		||||
%%
 | 
			
		||||
void
 | 
			
		||||
lex_init()
 | 
			
		||||
lex_init(void)
 | 
			
		||||
{
 | 
			
		||||
    BEGIN C;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int yywrap() 
 | 
			
		||||
int yywrap(void) 
 | 
			
		||||
{ 
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -8,8 +8,26 @@
 | 
			
		||||
void yyerror(char *);
 | 
			
		||||
extern FILE * yyout;
 | 
			
		||||
extern char * yytext;
 | 
			
		||||
extern int yylineno;
 | 
			
		||||
extern int yyleng;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Variables containing simple states.
 | 
			
		||||
 */
 | 
			
		||||
int    debugging = 0;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Handle the filename and line numbering.
 | 
			
		||||
 */
 | 
			
		||||
char * input_filename = NULL;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
output_line_number()
 | 
			
		||||
{
 | 
			
		||||
    if (input_filename)
 | 
			
		||||
       fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Handling of the variables.
 | 
			
		||||
 */
 | 
			
		||||
@@ -144,7 +162,7 @@ dump_variables(struct arguments * list)
 | 
			
		||||
%token <tagname> S_VARCHAR S_VARCHAR2
 | 
			
		||||
%token <tagname> S_EXTERN S_STATIC
 | 
			
		||||
%token <tagname> S_UNSIGNED S_SIGNED
 | 
			
		||||
%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE
 | 
			
		||||
%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
 | 
			
		||||
%token <tagname> '[' ']' ';' ','
 | 
			
		||||
 | 
			
		||||
%type <type> type type_detailed varchar_type simple_type array_type
 | 
			
		||||
@@ -175,10 +193,12 @@ sqldeclaration : sql_startdeclare
 | 
			
		||||
		 sql_enddeclare;
 | 
			
		||||
 | 
			
		||||
sql_startdeclare : SQL_START SQL_BEGIN SQL_DECLARE SQL_SECTION SQL_SEMI	{
 | 
			
		||||
    printf("/* exec sql begin declare section */\n"); 
 | 
			
		||||
    fprintf(yyout, "/* exec sql begin declare section */\n"); 
 | 
			
		||||
    output_line_number();
 | 
			
		||||
};
 | 
			
		||||
sql_enddeclare : SQL_START SQL_END SQL_DECLARE SQL_SECTION SQL_SEMI {
 | 
			
		||||
    printf("/* exec sql end declare section */\n"); 
 | 
			
		||||
    fprintf(yyout,"/* exec sql end declare section */\n"); 
 | 
			
		||||
    output_line_number();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
variable_declarations : /* empty */
 | 
			
		||||
@@ -235,7 +255,8 @@ simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
 | 
			
		||||
	   | S_LONG { $<type_enum>$ = ECPGt_long; }
 | 
			
		||||
           | S_UNSIGNED S_LONG { $<type_enum>$ = ECPGt_unsigned_long; }
 | 
			
		||||
           | S_FLOAT { $<type_enum>$ = ECPGt_float; }
 | 
			
		||||
           | S_DOUBLE { $<type_enum>$ = ECPGt_double; };
 | 
			
		||||
           | S_DOUBLE { $<type_enum>$ = ECPGt_double; }
 | 
			
		||||
	   | S_BOOL { $<type_enum>$ = ECPGt_bool; };
 | 
			
		||||
 | 
			
		||||
maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); }
 | 
			
		||||
		       | S_STATIC { fwrite(yytext, yyleng, 1, yyout); }
 | 
			
		||||
@@ -248,17 +269,17 @@ index : '[' length ']' {
 | 
			
		||||
length : S_LENGTH { $<indexsize>$ = atoi(yytext); }
 | 
			
		||||
 | 
			
		||||
sqlinclude : SQL_START SQL_INCLUDE { fprintf(yyout, "#include \""); }
 | 
			
		||||
	filename SQL_SEMI { fprintf(yyout, ".h\""); };
 | 
			
		||||
	filename SQL_SEMI { fprintf(yyout, ".h\""); output_line_number(); };
 | 
			
		||||
 | 
			
		||||
filename : cthing
 | 
			
		||||
	 | filename cthing;
 | 
			
		||||
 | 
			
		||||
sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect(\""); }
 | 
			
		||||
	SQL_STRING { fwrite(yytext + 1, yyleng - 2, 1, yyout); }
 | 
			
		||||
	SQL_SEMI { fprintf(yyout, "\");"); };
 | 
			
		||||
	SQL_SEMI { fprintf(yyout, "\");"); output_line_number(); };
 | 
			
		||||
 | 
			
		||||
/* Open is an open cursor. Removed. */
 | 
			
		||||
sqlopen : SQL_START SQL_OPEN sqlgarbage SQL_SEMI { };
 | 
			
		||||
sqlopen : SQL_START SQL_OPEN sqlgarbage SQL_SEMI { output_line_number(); };
 | 
			
		||||
 | 
			
		||||
sqlgarbage : /* Empty */
 | 
			
		||||
	   | sqlgarbage sqlanything;
 | 
			
		||||
@@ -266,9 +287,11 @@ sqlgarbage : /* Empty */
 | 
			
		||||
 | 
			
		||||
sqlcommit : SQL_START SQL_COMMIT SQL_SEMI {
 | 
			
		||||
    fprintf(yyout, "ECPGcommit(__LINE__);"); 
 | 
			
		||||
    output_line_number();
 | 
			
		||||
};
 | 
			
		||||
sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI {
 | 
			
		||||
    fprintf(yyout, "ECPGrollback(__LINE__);");
 | 
			
		||||
    output_line_number();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
sqlstatement : SQL_START { /* Reset stack */
 | 
			
		||||
@@ -283,6 +306,7 @@ sqlstatement : SQL_START { /* Reset stack */
 | 
			
		||||
    fprintf(yyout, "ECPGt_EOIT, ");
 | 
			
		||||
    dump_variables(argsresult);
 | 
			
		||||
    fprintf(yyout, "ECPGt_EORT );");
 | 
			
		||||
    output_line_number();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
sqlstatement_words : sqlstatement_word
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "type.h"
 | 
			
		||||
 | 
			
		||||
@@ -134,55 +133,59 @@ ECPGdump_a_simple(FILE * o, const char * name, enum ECPGttype typ,
 | 
			
		||||
    switch (typ)
 | 
			
		||||
    {
 | 
			
		||||
    case ECPGt_char:
 | 
			
		||||
	fprintf(o, "ECPGt_char,&%s,0,%d,%s, ", name, arrsiz, 
 | 
			
		||||
	fprintf(o, "\n\tECPGt_char,&%s,0,%d,%s, ", name, arrsiz, 
 | 
			
		||||
		siz == NULL ? "sizeof(char)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_unsigned_char:
 | 
			
		||||
	fprintf(o, "ECPGt_unsigned_char,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_unsigned_char,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(unsigned char)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_short:
 | 
			
		||||
	fprintf(o, "ECPGt_short,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_short,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(short)" : siz);
 | 
			
		||||
	break; 
 | 
			
		||||
    case ECPGt_unsigned_short:
 | 
			
		||||
	fprintf(o, 
 | 
			
		||||
		"ECPGt_unsigned_short,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		"\n\tECPGt_unsigned_short,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(unsigned short)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_int:
 | 
			
		||||
	fprintf(o, "ECPGt_int,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_int,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(int)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_unsigned_int:
 | 
			
		||||
	fprintf(o, "ECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(unsigned int)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_long:
 | 
			
		||||
	fprintf(o, "ECPGt_long,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_long,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(long)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_unsigned_long:
 | 
			
		||||
	fprintf(o, "ECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_unsigned_int,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(unsigned int)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_float:
 | 
			
		||||
	fprintf(o, "ECPGt_float,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_float,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(float)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_double:
 | 
			
		||||
	fprintf(o, "ECPGt_double,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
	fprintf(o, "\n\tECPGt_double,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(double)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_bool:
 | 
			
		||||
	fprintf(o, "\n\tECPGt_bool,&%s,0,%d,%s, ", name, arrsiz,
 | 
			
		||||
		siz == NULL ? "sizeof(bool)" : siz);
 | 
			
		||||
	break;
 | 
			
		||||
    case ECPGt_varchar:
 | 
			
		||||
    case ECPGt_varchar2:
 | 
			
		||||
	if (siz == NULL)
 | 
			
		||||
	    fprintf(o, "ECPGt_varchar,&%s,%d,%d,sizeof(struct varchar_%s), ", 
 | 
			
		||||
	    fprintf(o, "\n\tECPGt_varchar,&%s,%d,%d,sizeof(struct varchar_%s), ", 
 | 
			
		||||
		    name,
 | 
			
		||||
		    varcharsize,
 | 
			
		||||
		    arrsiz, name);
 | 
			
		||||
	else
 | 
			
		||||
	    fprintf(o, "ECPGt_varchar,&%s,%d,%d,%s, ", 
 | 
			
		||||
	    fprintf(o, "\n\tECPGt_varchar,&%s,%d,%d,%s, ", 
 | 
			
		||||
		    name, 
 | 
			
		||||
		    varcharsize,
 | 
			
		||||
		    arrsiz, siz);
 | 
			
		||||
							
								
								
									
										39
									
								
								src/interfaces/ecpg/preproc/y.tab.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/interfaces/ecpg/preproc/y.tab.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
typedef union {
 | 
			
		||||
    int				tagname;
 | 
			
		||||
    struct ECPGtemp_type	type;
 | 
			
		||||
    char *			symbolname;
 | 
			
		||||
    int				indexsize;
 | 
			
		||||
    enum ECPGttype		type_enum;
 | 
			
		||||
} YYSTYPE;
 | 
			
		||||
#define	SQL_START	258
 | 
			
		||||
#define	SQL_SEMI	259
 | 
			
		||||
#define	SQL_STRING	260
 | 
			
		||||
#define	SQL_INTO	261
 | 
			
		||||
#define	SQL_BEGIN	262
 | 
			
		||||
#define	SQL_END	263
 | 
			
		||||
#define	SQL_DECLARE	264
 | 
			
		||||
#define	SQL_SECTION	265
 | 
			
		||||
#define	SQL_INCLUDE	266
 | 
			
		||||
#define	SQL_CONNECT	267
 | 
			
		||||
#define	SQL_OPEN	268
 | 
			
		||||
#define	SQL_COMMIT	269
 | 
			
		||||
#define	SQL_ROLLBACK	270
 | 
			
		||||
#define	S_SYMBOL	271
 | 
			
		||||
#define	S_LENGTH	272
 | 
			
		||||
#define	S_ANYTHING	273
 | 
			
		||||
#define	S_VARCHAR	274
 | 
			
		||||
#define	S_VARCHAR2	275
 | 
			
		||||
#define	S_EXTERN	276
 | 
			
		||||
#define	S_STATIC	277
 | 
			
		||||
#define	S_UNSIGNED	278
 | 
			
		||||
#define	S_SIGNED	279
 | 
			
		||||
#define	S_LONG	280
 | 
			
		||||
#define	S_SHORT	281
 | 
			
		||||
#define	S_INT	282
 | 
			
		||||
#define	S_CHAR	283
 | 
			
		||||
#define	S_FLOAT	284
 | 
			
		||||
#define	S_DOUBLE	285
 | 
			
		||||
#define	S_BOOL	286
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern YYSTYPE yylval;
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
# Generated automatically from Makefile.in by configure.
 | 
			
		||||
POSTGRESTOP=@POSTGRESERVER@
 | 
			
		||||
POSTGRES_INCLUDE=$(POSTGRESTOP)/include
 | 
			
		||||
 | 
			
		||||
all clean::
 | 
			
		||||
	@echo Nothing to be done.
 | 
			
		||||
 | 
			
		||||
install::
 | 
			
		||||
	install ecpglib.h $(POSTGRES_INCLUDE)	
 | 
			
		||||
	install ecpgtype.h $(POSTGRES_INCLUDE)	
 | 
			
		||||
	install sqlca.h $(POSTGRES_INCLUDE)	
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(POSTGRES_INCLUDE)/ecpglib.h
 | 
			
		||||
	rm -f $(POSTGRES_INCLUDE)/ecpgtype.h
 | 
			
		||||
	rm -f $(POSTGRES_INCLUDE)/sqlca.h
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
POSTGRESTOP=@POSTGRESERVER@
 | 
			
		||||
POSTGRES_INCLUDE=$(POSTGRESTOP)/include
 | 
			
		||||
 | 
			
		||||
all clean::
 | 
			
		||||
	@echo Nothing to be done.
 | 
			
		||||
 | 
			
		||||
install::
 | 
			
		||||
	install ecpglib.h $(POSTGRES_INCLUDE)	
 | 
			
		||||
	install ecpgtype.h $(POSTGRES_INCLUDE)	
 | 
			
		||||
	install sqlca.h $(POSTGRES_INCLUDE)	
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(POSTGRES_INCLUDE)/ecpglib.h
 | 
			
		||||
	rm -f $(POSTGRES_INCLUDE)/ecpgtype.h
 | 
			
		||||
	rm -f $(POSTGRES_INCLUDE)/sqlca.h
 | 
			
		||||
@@ -1,609 +0,0 @@
 | 
			
		||||
/* Copyright comment */
 | 
			
		||||
/*
 | 
			
		||||
 * The aim is to get a simpler inteface to the database routines.
 | 
			
		||||
 * All the tidieous messing around with tuples is supposed to be hidden
 | 
			
		||||
 * by this function.
 | 
			
		||||
 */
 | 
			
		||||
/* Author: Linus Tolke 
 | 
			
		||||
   (actually most if the code is "borrowed" from the distribution and just
 | 
			
		||||
    slightly modified)
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/* Taken over as part of PostgreSQL by Michael Meskes <meskes@debian.org>
 | 
			
		||||
   on Feb. 5th, 1998 */
 | 
			
		||||
   
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <ecpgtype.h>
 | 
			
		||||
#include <ecpglib.h>
 | 
			
		||||
#include <sqlca.h>
 | 
			
		||||
#include <libpq-fe.h>
 | 
			
		||||
#include <libpq/pqcomm.h>
 | 
			
		||||
 | 
			
		||||
static PGconn *	simple_connection;
 | 
			
		||||
static int	simple_debug = 0;
 | 
			
		||||
static int	committed = true;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
register_error(int code, char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
 | 
			
		||||
    sqlca.sqlcode = code;
 | 
			
		||||
    va_start (args, fmt);
 | 
			
		||||
    vsprintf (sqlca.sqlerrm.sqlerrmc, fmt, args);
 | 
			
		||||
    va_end (args);
 | 
			
		||||
    sqlca.sqlerrm.sqlerrml = strlen (sqlca.sqlerrm.sqlerrmc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function returns a newly malloced string that has the ' and \
 | 
			
		||||
   in the argument quoted with \.
 | 
			
		||||
 */
 | 
			
		||||
static
 | 
			
		||||
char *
 | 
			
		||||
quote_postgres(char * arg)
 | 
			
		||||
{
 | 
			
		||||
    char * res = (char *)malloc(2 * strlen(arg) + 1);
 | 
			
		||||
    int i, ri;
 | 
			
		||||
 | 
			
		||||
    for (i = 0, ri = 0; arg[i]; i++, ri++)
 | 
			
		||||
    {
 | 
			
		||||
        switch (arg[i])
 | 
			
		||||
	{
 | 
			
		||||
	case '\'':
 | 
			
		||||
	case '\\':
 | 
			
		||||
	    res[ri++] = '\\';
 | 
			
		||||
	default:
 | 
			
		||||
	    ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res[ri] = arg[i];
 | 
			
		||||
    }
 | 
			
		||||
    res[ri] = '\0';
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGdo(int lineno, char * query, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list ap;
 | 
			
		||||
    bool status = false;
 | 
			
		||||
    char * copiedquery;
 | 
			
		||||
    PGresult *	results;
 | 
			
		||||
    PGnotify *	notify;
 | 
			
		||||
    enum ECPGttype type;
 | 
			
		||||
 | 
			
		||||
    va_start(ap, query);
 | 
			
		||||
 | 
			
		||||
    sqlca.sqlcode = 0;
 | 
			
		||||
    copiedquery = strdup(query);
 | 
			
		||||
 | 
			
		||||
    type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Now, if the type is one of the fill in types then we take the argument
 | 
			
		||||
     * and enter that in the string at the first %s position. Then if there
 | 
			
		||||
     * are any more fill in types we fill in at the next and so on.
 | 
			
		||||
     */
 | 
			
		||||
    while (type != ECPGt_EOIT)
 | 
			
		||||
    {
 | 
			
		||||
	void * value = NULL;
 | 
			
		||||
	short varcharsize;
 | 
			
		||||
	short size;
 | 
			
		||||
	short arrsize;
 | 
			
		||||
 | 
			
		||||
        char * newcopy;
 | 
			
		||||
	char * mallocedval = NULL;
 | 
			
		||||
	char * tobeinserted = NULL;
 | 
			
		||||
	char * p;
 | 
			
		||||
	char buff[20];
 | 
			
		||||
 | 
			
		||||
	/* Some special treatment is needed for records since we want their
 | 
			
		||||
	   contents to arrive in a comma-separated list on insert (I think). */
 | 
			
		||||
 | 
			
		||||
	value = va_arg(ap, void *);
 | 
			
		||||
	varcharsize = va_arg(ap, short);
 | 
			
		||||
	size = va_arg(ap, short);
 | 
			
		||||
	arrsize = va_arg(ap, short);
 | 
			
		||||
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case ECPGt_char:
 | 
			
		||||
	case ECPGt_short:
 | 
			
		||||
	case ECPGt_int:
 | 
			
		||||
	    sprintf(buff, "%d", *(int*)value);
 | 
			
		||||
	    tobeinserted = buff;
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	case ECPGt_unsigned_char:
 | 
			
		||||
	case ECPGt_unsigned_short:
 | 
			
		||||
	case ECPGt_unsigned_int:
 | 
			
		||||
	    sprintf(buff, "%d", *(unsigned int*)value);
 | 
			
		||||
	    tobeinserted = buff;
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	case ECPGt_long:
 | 
			
		||||
	    sprintf(buff, "%ld", *(long*)value);
 | 
			
		||||
	    tobeinserted = buff;
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	case ECPGt_unsigned_long:
 | 
			
		||||
	    sprintf(buff, "%ld", *(unsigned long*)value);
 | 
			
		||||
	    tobeinserted = buff;
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	case ECPGt_float:
 | 
			
		||||
	    sprintf(buff, "%.14g", *(float*)value);
 | 
			
		||||
	    tobeinserted = buff;
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	case ECPGt_double:
 | 
			
		||||
	    sprintf(buff, "%.14g", *(double*)value);
 | 
			
		||||
	    tobeinserted = buff;
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	case ECPGt_varchar:
 | 
			
		||||
	case ECPGt_varchar2:
 | 
			
		||||
	    {
 | 
			
		||||
		struct ECPGgeneric_varchar * var =
 | 
			
		||||
		    (struct ECPGgeneric_varchar*)value;
 | 
			
		||||
 | 
			
		||||
		newcopy = (char *)malloc(var->len + 1);
 | 
			
		||||
		strncpy(newcopy, var->arr, var->len);
 | 
			
		||||
		newcopy[var->len] = '\0';
 | 
			
		||||
	    
 | 
			
		||||
		mallocedval = (char *)malloc(2 * strlen(newcopy) + 3);
 | 
			
		||||
		strcpy(mallocedval, "'");
 | 
			
		||||
		strcat(mallocedval, quote_postgres(newcopy));
 | 
			
		||||
		strcat(mallocedval, "'");
 | 
			
		||||
 | 
			
		||||
		free(newcopy);
 | 
			
		||||
 | 
			
		||||
		tobeinserted = mallocedval;
 | 
			
		||||
	    }
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
	    /* Not implemented yet */
 | 
			
		||||
	    register_error(-1, "Unsupported type %s on line %d.",
 | 
			
		||||
			   ECPGtype_name(type), lineno);
 | 
			
		||||
	    return false;
 | 
			
		||||
	    break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Now tobeinserted points to an area that is to be inserted at 
 | 
			
		||||
	   the first %s 
 | 
			
		||||
	 */
 | 
			
		||||
	newcopy = (char *)malloc(strlen(copiedquery) 
 | 
			
		||||
				 + strlen(tobeinserted) 
 | 
			
		||||
				 + 1);
 | 
			
		||||
	strcpy(newcopy, copiedquery);
 | 
			
		||||
	if ((p = strstr(newcopy, ";;")) == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	    /* We have an argument but we dont have the matched up string 
 | 
			
		||||
	       in the string
 | 
			
		||||
	     */
 | 
			
		||||
	    register_error(-1, "Too many arguments line %d.", lineno);
 | 
			
		||||
	    return false;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
	    strcpy(p, tobeinserted);
 | 
			
		||||
	    /* The strange thing in the second argument is the rest of the
 | 
			
		||||
	       string from the old string */
 | 
			
		||||
	    strcat(newcopy, 
 | 
			
		||||
		   copiedquery
 | 
			
		||||
		   + ( p - newcopy ) 
 | 
			
		||||
		   + 2 /* Length of ;; */);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Now everything is safely copied to the newcopy. Lets free the
 | 
			
		||||
	   oldcopy and let the copiedquery get the value from the newcopy.
 | 
			
		||||
	 */
 | 
			
		||||
	if (mallocedval != NULL)
 | 
			
		||||
	{
 | 
			
		||||
	    free(mallocedval);
 | 
			
		||||
	    mallocedval = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(copiedquery);
 | 
			
		||||
	copiedquery = newcopy;
 | 
			
		||||
 | 
			
		||||
        type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Check if there are unmatched things left. */
 | 
			
		||||
    if (strstr(copiedquery, ";;") != NULL)
 | 
			
		||||
    {
 | 
			
		||||
	register_error(-1, "Too few arguments line %d.", lineno);
 | 
			
		||||
	return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Now then request is built. */
 | 
			
		||||
 | 
			
		||||
    if (committed)
 | 
			
		||||
    {
 | 
			
		||||
	if ((results = PQexec (simple_connection, "begin")) == NULL) {
 | 
			
		||||
	    register_error(-1, "Error starting transaction line %d.", lineno);
 | 
			
		||||
	    return false;
 | 
			
		||||
	}
 | 
			
		||||
	PQclear (results);
 | 
			
		||||
	committed = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ECPGlog("ECPGdo line %d: QUERY: %s\n", lineno, copiedquery);
 | 
			
		||||
    results = PQexec(simple_connection, copiedquery); 
 | 
			
		||||
    free(copiedquery);
 | 
			
		||||
 | 
			
		||||
    if (results == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        ECPGlog("ECPGdo line %d: error: %s", lineno, 
 | 
			
		||||
		PQerrorMessage(simple_connection));
 | 
			
		||||
	register_error(-1, "Postgres error: %s line %d.",
 | 
			
		||||
		       PQerrorMessage(simple_connection), lineno);
 | 
			
		||||
    }
 | 
			
		||||
    else switch(PQresultStatus(results)) 
 | 
			
		||||
    {
 | 
			
		||||
        int m,n,x;
 | 
			
		||||
 | 
			
		||||
    case PGRES_TUPLES_OK:
 | 
			
		||||
	/* XXX Cheap Hack. For now, we see only the last group
 | 
			
		||||
	 * of tuples.  This is clearly not the right
 | 
			
		||||
	 * way to do things !!
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	m = PQnfields(results);
 | 
			
		||||
	n = PQntuples(results);
 | 
			
		||||
    
 | 
			
		||||
	if (n < 1)
 | 
			
		||||
	{
 | 
			
		||||
	    ECPGlog("ECPGdo lineno %d: Incorrect number of matches: %d\n", 
 | 
			
		||||
		    lineno, n);
 | 
			
		||||
	    register_error(1, "Data not found line %d.", lineno);
 | 
			
		||||
	    break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (n > 1)
 | 
			
		||||
	{
 | 
			
		||||
	    ECPGlog("ECPGdo line %d: Incorrect number of matches: %d\n", 
 | 
			
		||||
		    lineno, n);
 | 
			
		||||
	    register_error(-1, "To many matches line %d.", lineno);
 | 
			
		||||
	    break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	status = true;
 | 
			
		||||
 | 
			
		||||
	for (x = 0; x < m && status; x++) 
 | 
			
		||||
	{
 | 
			
		||||
	    void * value = NULL;
 | 
			
		||||
	    short varcharsize;
 | 
			
		||||
	    short size;
 | 
			
		||||
	    short arrsize;
 | 
			
		||||
 | 
			
		||||
	    char 	*pval = PQgetvalue(results,0,x);
 | 
			
		||||
	    /*long int	* res_int;
 | 
			
		||||
	    char 	** res_charstar;
 | 
			
		||||
	    char	* res_char;
 | 
			
		||||
	    int		res_len;*/
 | 
			
		||||
	    char	* scan_length;
 | 
			
		||||
 | 
			
		||||
	    ECPGlog("ECPGdo line %d: RESULT: %s\n", lineno, pval ? pval : "");
 | 
			
		||||
 | 
			
		||||
	    /* No the pval is a pointer to the value. */
 | 
			
		||||
	    /* We will have to decode the value */
 | 
			
		||||
	    type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
	    value = va_arg(ap, void *);
 | 
			
		||||
	    varcharsize = va_arg(ap, short);
 | 
			
		||||
	    size = va_arg(ap, short);
 | 
			
		||||
	    arrsize = va_arg(ap, short);
 | 
			
		||||
 | 
			
		||||
	    switch (type)
 | 
			
		||||
	    {
 | 
			
		||||
		long res;
 | 
			
		||||
		unsigned long ures;
 | 
			
		||||
		double dres;
 | 
			
		||||
 | 
			
		||||
	    case ECPGt_char:
 | 
			
		||||
	    case ECPGt_short:
 | 
			
		||||
	    case ECPGt_int:
 | 
			
		||||
	    case ECPGt_long:
 | 
			
		||||
		if (pval)
 | 
			
		||||
		{
 | 
			
		||||
		    res = strtol(pval, &scan_length, 10);
 | 
			
		||||
		    if (*scan_length != '\0') /* Garbage left */
 | 
			
		||||
		    {
 | 
			
		||||
			register_error(-1, "Not correctly formatted int type: %s line %d.",
 | 
			
		||||
				       pval, lineno);
 | 
			
		||||
			status = false;
 | 
			
		||||
			res = 0L;
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		    res = 0L;
 | 
			
		||||
 | 
			
		||||
		/* Again?! Yes */
 | 
			
		||||
		switch (type)
 | 
			
		||||
		{
 | 
			
		||||
		case ECPGt_char:
 | 
			
		||||
		    *(char *)value = (char)res;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_short:
 | 
			
		||||
		    *(short *)value = (short)res;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_int:
 | 
			
		||||
		    *(int *)value = (int)res;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_long:
 | 
			
		||||
		    *(long *)value = res;
 | 
			
		||||
		    break;
 | 
			
		||||
		default:
 | 
			
		||||
		    /* Cannot happen */
 | 
			
		||||
		    break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	    case ECPGt_unsigned_char:
 | 
			
		||||
	    case ECPGt_unsigned_short:
 | 
			
		||||
	    case ECPGt_unsigned_int:
 | 
			
		||||
	    case ECPGt_unsigned_long:
 | 
			
		||||
		if (pval)
 | 
			
		||||
		{
 | 
			
		||||
		    ures = strtoul(pval, &scan_length, 10);
 | 
			
		||||
		    if (*scan_length != '\0') /* Garbage left */
 | 
			
		||||
		    {
 | 
			
		||||
			register_error(-1, "Not correctly formatted unsigned type: %s line %d.",
 | 
			
		||||
				       pval, lineno);
 | 
			
		||||
			status = false;
 | 
			
		||||
			ures = 0L;
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		    ures = 0L;
 | 
			
		||||
 | 
			
		||||
		/* Again?! Yes */
 | 
			
		||||
		switch (type)
 | 
			
		||||
		{
 | 
			
		||||
		case ECPGt_unsigned_char:
 | 
			
		||||
		    *(unsigned char *)value = (unsigned char)ures;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_unsigned_short:
 | 
			
		||||
		    *(unsigned short *)value = (unsigned short)ures;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_unsigned_int:
 | 
			
		||||
		    *(unsigned int *)value = (unsigned int)ures;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_unsigned_long:
 | 
			
		||||
		    *(unsigned long *)value = ures;
 | 
			
		||||
		    break;
 | 
			
		||||
		default:
 | 
			
		||||
		    /* Cannot happen */
 | 
			
		||||
		    break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	    case ECPGt_float:
 | 
			
		||||
	    case ECPGt_double:
 | 
			
		||||
		if (pval)
 | 
			
		||||
		{
 | 
			
		||||
		    dres = strtod(pval, &scan_length);
 | 
			
		||||
		    if (*scan_length != '\0') /* Garbage left */
 | 
			
		||||
		    {
 | 
			
		||||
			register_error(-1, "Not correctly formatted floating point type: %s line %d.",
 | 
			
		||||
				       pval, lineno);
 | 
			
		||||
			status = false;
 | 
			
		||||
			dres = 0.0;
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		    dres = 0.0;
 | 
			
		||||
 | 
			
		||||
		/* Again?! Yes */
 | 
			
		||||
		switch (type)
 | 
			
		||||
		{
 | 
			
		||||
		case ECPGt_float:
 | 
			
		||||
		    *(float *)value = (float)res;
 | 
			
		||||
		    break;
 | 
			
		||||
		case ECPGt_double:
 | 
			
		||||
		    *(double *)value = res;
 | 
			
		||||
		    break;
 | 
			
		||||
		default:
 | 
			
		||||
		    /* Cannot happen */
 | 
			
		||||
		    break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	    case ECPGt_varchar:
 | 
			
		||||
		{
 | 
			
		||||
		    struct ECPGgeneric_varchar * var = 
 | 
			
		||||
			(struct ECPGgeneric_varchar*)value;
 | 
			
		||||
 | 
			
		||||
		    strncpy(var->arr, pval, varcharsize);
 | 
			
		||||
		    var->len = strlen(pval);
 | 
			
		||||
		    if (var->len > varcharsize)
 | 
			
		||||
			var->len = varcharsize;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	    case ECPGt_EORT:
 | 
			
		||||
	        ECPGlog("ECPGdo line %d: Too few arguments.\n", lineno);
 | 
			
		||||
		register_error(-1, "Too few arguments line %d.", lineno);
 | 
			
		||||
		status = false;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	    default:
 | 
			
		||||
		register_error(-1, "Unsupported type %s on line %d.",
 | 
			
		||||
			       ECPGtype_name(type), lineno);
 | 
			
		||||
		return false;
 | 
			
		||||
		break;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	type = va_arg(ap, enum ECPGttype);
 | 
			
		||||
 | 
			
		||||
	if (status && type != ECPGt_EORT)
 | 
			
		||||
	{
 | 
			
		||||
	    register_error(-1, "Too many arguments line %d.", lineno);
 | 
			
		||||
	    return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	PQclear(results);
 | 
			
		||||
	break;
 | 
			
		||||
    case PGRES_EMPTY_QUERY:
 | 
			
		||||
        /* do nothing */
 | 
			
		||||
	register_error(-1, "Empty query line %d.", lineno);
 | 
			
		||||
        break;
 | 
			
		||||
    case PGRES_COMMAND_OK:
 | 
			
		||||
        status = true;
 | 
			
		||||
        ECPGlog("ECPGdo line %d Ok: %s\n", lineno, PQcmdStatus(results));
 | 
			
		||||
	break;
 | 
			
		||||
    case PGRES_NONFATAL_ERROR:
 | 
			
		||||
    case PGRES_FATAL_ERROR:
 | 
			
		||||
    case PGRES_BAD_RESPONSE:
 | 
			
		||||
        ECPGlog("ECPGdo line %d: Error: %s",
 | 
			
		||||
		lineno, PQerrorMessage(simple_connection));
 | 
			
		||||
	register_error(-1, "Error: %s line %d.", 
 | 
			
		||||
		       PQerrorMessage(simple_connection), lineno);
 | 
			
		||||
	break;
 | 
			
		||||
    case PGRES_COPY_OUT:
 | 
			
		||||
        ECPGlog("ECPGdo line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
 | 
			
		||||
        PQendcopy(results->conn);
 | 
			
		||||
	break;
 | 
			
		||||
    case PGRES_COPY_IN:
 | 
			
		||||
        ECPGlog("ECPGdo line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
 | 
			
		||||
        PQendcopy(results->conn);
 | 
			
		||||
	break;
 | 
			
		||||
    default:
 | 
			
		||||
        ECPGlog("ECPGdo line %d: Got something else, postgres error.\n", 
 | 
			
		||||
		lineno);
 | 
			
		||||
	register_error(-1, "Postgres error line %d.", lineno);
 | 
			
		||||
	break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* check for asynchronous returns */
 | 
			
		||||
    notify = PQnotifies(simple_connection);
 | 
			
		||||
    if (notify) {
 | 
			
		||||
        ECPGlog("ECPGdo line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
 | 
			
		||||
		lineno, notify->relname, notify->be_pid);
 | 
			
		||||
	free(notify);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    va_end(ap);
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGcommit(int lineno)
 | 
			
		||||
{
 | 
			
		||||
    PGresult *res;
 | 
			
		||||
 | 
			
		||||
    ECPGlog("ECPGcommit line %d\n", lineno);
 | 
			
		||||
    if ((res = PQexec (simple_connection, "end")) == NULL) {
 | 
			
		||||
	register_error(-1, "Error committing line %d.", lineno);
 | 
			
		||||
	return (FALSE);
 | 
			
		||||
    }
 | 
			
		||||
    PQclear (res);
 | 
			
		||||
    committed = 1;
 | 
			
		||||
    return (TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGrollback(int lineno)
 | 
			
		||||
{
 | 
			
		||||
    PGresult *res;
 | 
			
		||||
 | 
			
		||||
    ECPGlog("ECPGrollback line %d\n", lineno);
 | 
			
		||||
    if ((res = PQexec (simple_connection, "abort")) == NULL) {
 | 
			
		||||
	register_error(-1, "Error rolling back line %d.", lineno);
 | 
			
		||||
	return (FALSE);
 | 
			
		||||
    }
 | 
			
		||||
    PQclear (res);
 | 
			
		||||
    committed = 1;
 | 
			
		||||
    return(TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGsetdb(PGconn * newcon)
 | 
			
		||||
{
 | 
			
		||||
    ECPGfinish();
 | 
			
		||||
    simple_connection = newcon;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGconnect(const char * dbname)
 | 
			
		||||
{
 | 
			
		||||
    char * name = strdup(dbname);
 | 
			
		||||
    ECPGlog("ECPGconnect: opening database %s\n", name);
 | 
			
		||||
 | 
			
		||||
    sqlca.sqlcode = 0;
 | 
			
		||||
 | 
			
		||||
    ECPGsetdb(PQsetdb(NULL, NULL, NULL, NULL, name));
 | 
			
		||||
 | 
			
		||||
    free(name);
 | 
			
		||||
    name = NULL;
 | 
			
		||||
 | 
			
		||||
    if (PQstatus(simple_connection) == CONNECTION_BAD)
 | 
			
		||||
    {
 | 
			
		||||
        ECPGfinish();
 | 
			
		||||
	ECPGlog("ECPGconnect: could not open database %s\n", dbname);
 | 
			
		||||
	register_error(-1, "ECPGconnect: could not open database %s.", dbname);
 | 
			
		||||
	return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGstatus()
 | 
			
		||||
{
 | 
			
		||||
    return PQstatus(simple_connection) != CONNECTION_BAD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ECPGfinish()
 | 
			
		||||
{
 | 
			
		||||
    if (simple_connection != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        ECPGlog("ECPGfinish: finishing.\n");
 | 
			
		||||
        PQfinish(simple_connection);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        ECPGlog("ECPGfinish: called an extra time.\n");
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ECPGdebug(int n)
 | 
			
		||||
{
 | 
			
		||||
    simple_debug = n;
 | 
			
		||||
    ECPGlog("ECPGdebug: set to %d\n", simple_debug);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ECPGlog(const char * format, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list ap;
 | 
			
		||||
    if (simple_debug) 
 | 
			
		||||
    {
 | 
			
		||||
        char * f = (char *) malloc(strlen(format) + 100);
 | 
			
		||||
 | 
			
		||||
	sprintf(f, "[%d]: %s", getpid(), format);
 | 
			
		||||
 | 
			
		||||
	va_start(ap, format);
 | 
			
		||||
        vfprintf(stderr, f, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	free(f);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
POSTGRESTOP=@POSTGRESERVER@
 | 
			
		||||
POSTGRES_BIN=$(POSTGRESTOP)/bin
 | 
			
		||||
POSTGRES_LIB=$(POSTGRESTOP)/lib
 | 
			
		||||
 | 
			
		||||
CC=@CC@
 | 
			
		||||
LEX=@LEX@
 | 
			
		||||
LEXLIB=@LEXLIB@
 | 
			
		||||
YACC=@YACC@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CFLAGS=-I../include -O2 -g -Wall
 | 
			
		||||
 | 
			
		||||
all:: ecpg
 | 
			
		||||
 | 
			
		||||
clean::
 | 
			
		||||
	rm -f *.o core a.out ecpg y.tab.h y.tab.c *~
 | 
			
		||||
 | 
			
		||||
install:: all
 | 
			
		||||
	install -c -d -m755 $(POSTGRES_LIB)/ecpg
 | 
			
		||||
	install -c -m555 preproc $(POSTGRES_LIB)/ecpg
 | 
			
		||||
	install -c -m555 ecpg $(POSTGRES_BIN)
 | 
			
		||||
 | 
			
		||||
uninstall::
 | 
			
		||||
	rm -f $(POSTGRES_BIN)/ecpg
 | 
			
		||||
	rm -f $(POSTGRES_LIB)/ecpg/preproc
 | 
			
		||||
 | 
			
		||||
# Rule that really do something.
 | 
			
		||||
ecpg: y.tab.o pgc.o type.o ecpg.o
 | 
			
		||||
	$(CC) -g -O2 -Wall -o ecpg y.tab.o pgc.o type.o ecpg.o -L../lib -lecpg $(LEXLIB)
 | 
			
		||||
 | 
			
		||||
y.tab.h y.tab.c: preproc.y
 | 
			
		||||
	$(YACC) -d $<
 | 
			
		||||
 | 
			
		||||
y.tab.o : y.tab.h ../include/ecpgtype.h
 | 
			
		||||
type.o : ../include/ecpgtype.h
 | 
			
		||||
pgc.o : ../include/ecpgtype.h
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
INFILE=
 | 
			
		||||
OUTFILE=
 | 
			
		||||
 | 
			
		||||
for arg
 | 
			
		||||
do
 | 
			
		||||
    case "$arg" in
 | 
			
		||||
    iname=*)
 | 
			
		||||
	INFILE=`expr substr $arg 7 1000`
 | 
			
		||||
	;;
 | 
			
		||||
    oname=*)
 | 
			
		||||
	OUTFILE=`expr substr $arg 7 1000`
 | 
			
		||||
	;;
 | 
			
		||||
    *)
 | 
			
		||||
	echo Wrong argument $arg
 | 
			
		||||
	exit 1;
 | 
			
		||||
	;;
 | 
			
		||||
    esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
if [ -n "$INFILE" -a -n "$OUTFILE" ]
 | 
			
		||||
then
 | 
			
		||||
    exec @POSTGRESERVER@/lib/ecpg/preproc < $INFILE > $OUTFILE
 | 
			
		||||
else
 | 
			
		||||
    echo Missing arguments.
 | 
			
		||||
    echo usage: $0 iname=file oname=outfile
 | 
			
		||||
    exit 1;
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
exit 0;
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
test2: test2.c
 | 
			
		||||
	gcc -g -I ../include -I ../../../libpq -o test2 test2.c ../lib/libecpg.a ../../../libpq/libpq.a -lcrypt
 | 
			
		||||
test2.c: test2.pgc
 | 
			
		||||
	../preproc/ecpg test2.pgc
 | 
			
		||||
clean:
 | 
			
		||||
	/bin/rm test2 test2.c
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										14
									
								
								src/interfaces/ecpg/test/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/interfaces/ecpg/test/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
all: test2 perftest
 | 
			
		||||
 | 
			
		||||
test2: test2.c
 | 
			
		||||
	gcc -g -I ../include -I ../../../libpq -o test2 test2.c ../lib/libecpg.a ../../../libpq/libpq.a -lcrypt
 | 
			
		||||
test2.c: test2.pgc
 | 
			
		||||
	../preproc/ecpg test2.pgc
 | 
			
		||||
 | 
			
		||||
perftest: perftest.c
 | 
			
		||||
	gcc -g -I ../include -I ../../../libpq -o perftest perftest.c ../lib/libecpg.a ../../../libpq/libpq.a -lcrypt
 | 
			
		||||
perftest.c: perftest.pgc
 | 
			
		||||
	../preproc/ecpg perftest.pgc
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	/bin/rm test2 test2.c perftest perftest.c
 | 
			
		||||
							
								
								
									
										72
									
								
								src/interfaces/ecpg/test/perftest.pgc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/interfaces/ecpg/test/perftest.pgc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
exec sql include sqlca;
 | 
			
		||||
 | 
			
		||||
#define       SQLCODE    sqlca.sqlcode
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
db_error (char *msg)
 | 
			
		||||
{
 | 
			
		||||
	sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
 | 
			
		||||
	printf ("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc);
 | 
			
		||||
	exit (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main ()
 | 
			
		||||
{
 | 
			
		||||
exec sql begin declare section;
 | 
			
		||||
	long i;
 | 
			
		||||
exec sql end declare section;
 | 
			
		||||
	struct timeval tvs, tve;
 | 
			
		||||
 | 
			
		||||
	gettimeofday(&tvs, NULL);
 | 
			
		||||
 | 
			
		||||
	exec sql connect 'mm';
 | 
			
		||||
	if (SQLCODE)
 | 
			
		||||
		db_error ("connect");
 | 
			
		||||
 | 
			
		||||
	exec sql create table perftest(number int4, ascii char16);
 | 
			
		||||
	if (SQLCODE)
 | 
			
		||||
                db_error ("create t");
 | 
			
		||||
 | 
			
		||||
	exec sql create unique index number on perftest(number);
 | 
			
		||||
	if (SQLCODE)
 | 
			
		||||
                db_error ("create i");
 | 
			
		||||
 | 
			
		||||
	for (i = 0;i < 1407; i++)
 | 
			
		||||
	{
 | 
			
		||||
		exec sql begin declare section;
 | 
			
		||||
			char text[16];
 | 
			
		||||
		exec sql end declare section;
 | 
			
		||||
 | 
			
		||||
		sprintf(text, "%ld", i);
 | 
			
		||||
		exec sql insert into perftest(number, ascii) values (:i, :text);
 | 
			
		||||
		if (SQLCODE)
 | 
			
		||||
			db_error ("insert");
 | 
			
		||||
 | 
			
		||||
		exec sql commit;
 | 
			
		||||
		if (SQLCODE)	
 | 
			
		||||
			db_error ("commit");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	exec sql drop index number;
 | 
			
		||||
	if (SQLCODE)	
 | 
			
		||||
		db_error ("drop i");
 | 
			
		||||
 | 
			
		||||
	exec sql drop table perftest;
 | 
			
		||||
	if (SQLCODE)	
 | 
			
		||||
		db_error ("drop t");
 | 
			
		||||
 | 
			
		||||
	exec sql commit;
 | 
			
		||||
	if (SQLCODE)	
 | 
			
		||||
		db_error ("commit");
 | 
			
		||||
 | 
			
		||||
	gettimeofday(&tve, NULL);
 | 
			
		||||
 | 
			
		||||
	printf("I needed %ld seconds and %ld microseconds for this test\n", tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								src/interfaces/ecpg/test/test2.pgc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/interfaces/ecpg/test/test2.pgc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
exec sql include sqlca;
 | 
			
		||||
 | 
			
		||||
#define       SQLCODE    sqlca.sqlcode
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
db_error (char *msg)
 | 
			
		||||
{
 | 
			
		||||
	sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
 | 
			
		||||
	printf ("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc);
 | 
			
		||||
	exit (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main ()
 | 
			
		||||
{
 | 
			
		||||
exec sql begin declare section;
 | 
			
		||||
	varchar text[8];
 | 
			
		||||
	int count;
 | 
			
		||||
	double control;
 | 
			
		||||
exec sql end declare section;
 | 
			
		||||
 | 
			
		||||
	exec sql connect 'mm';
 | 
			
		||||
	if (SQLCODE)
 | 
			
		||||
		db_error ("connect");
 | 
			
		||||
 | 
			
		||||
	exec sql declare cur cursor for 
 | 
			
		||||
		select text, control, count from test;
 | 
			
		||||
	if (SQLCODE) db_error ("declare");
 | 
			
		||||
 | 
			
		||||
	exec sql open cur;
 | 
			
		||||
	if (SQLCODE)
 | 
			
		||||
		db_error ("open");
 | 
			
		||||
 | 
			
		||||
	while (1) {
 | 
			
		||||
		exec sql fetch in cur into :text, :control, :count;
 | 
			
		||||
		if (SQLCODE)
 | 
			
		||||
			break;
 | 
			
		||||
		printf ("%8.8s %d %f\n", text.arr, count, control);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (SQLCODE < 0)
 | 
			
		||||
		db_error ("fetch");
 | 
			
		||||
 | 
			
		||||
	exec sql close cur;
 | 
			
		||||
	if (SQLCODE) db_error ("close");
 | 
			
		||||
	exec sql commit;
 | 
			
		||||
	if (SQLCODE) db_error ("commit");
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user