Erk, the whole directory structure changed on us here...

This commit is contained in:
Marc G. Fournier 1998-02-10 16:44:17 +00:00
parent a8313f9671
commit 38201e21d0
31 changed files with 985 additions and 778 deletions

View 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

View 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

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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)

View 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);
}
}

View File

@ -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();
}

View File

@ -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

View 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

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View 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;

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;

View File

@ -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.

View 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

View 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);
}

View 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);
}