Erk, the whole directory structure changed on us here...
authorMarc G. Fournier
Tue, 10 Feb 1998 16:44:17 +0000 (16:44 +0000)
committerMarc G. Fournier
Tue, 10 Feb 1998 16:44:17 +0000 (16:44 +0000)
31 files changed:
src/interfaces/ecpg/include/Makefile [new file with mode: 0644]
src/interfaces/ecpg/include/Makefile.in [new file with mode: 0644]
src/interfaces/ecpg/include/ecpglib.h [moved from src/interfaces/ecpg/src/include/ecpglib.h with 94% similarity]
src/interfaces/ecpg/include/ecpgtype.h [moved from src/interfaces/ecpg/src/include/ecpgtype.h with 98% similarity]
src/interfaces/ecpg/include/sqlca.h [moved from src/interfaces/ecpg/src/include/sqlca.h with 100% similarity]
src/interfaces/ecpg/lib/Makefile [moved from src/interfaces/ecpg/src/lib/Makefile with 61% similarity]
src/interfaces/ecpg/lib/Makefile.in [moved from src/interfaces/ecpg/src/lib/Makefile.in with 64% similarity]
src/interfaces/ecpg/lib/ecpglib.c [new file with mode: 0644]
src/interfaces/ecpg/lib/typename.c [moved from src/interfaces/ecpg/src/lib/typename.c with 94% similarity]
src/interfaces/ecpg/preproc/Makefile [moved from src/interfaces/ecpg/src/preproc/Makefile with 51% similarity]
src/interfaces/ecpg/preproc/Makefile.in [new file with mode: 0644]
src/interfaces/ecpg/preproc/ecpg.c [moved from src/interfaces/ecpg/src/preproc/ecpg.c with 84% similarity]
src/interfaces/ecpg/preproc/pgc.l [moved from src/interfaces/ecpg/src/preproc/pgc.l with 94% similarity]
src/interfaces/ecpg/preproc/preproc.y [moved from src/interfaces/ecpg/src/preproc/preproc.y with 90% similarity]
src/interfaces/ecpg/preproc/type.c [moved from src/interfaces/ecpg/src/preproc/type.c with 87% similarity]
src/interfaces/ecpg/preproc/type.h [moved from src/interfaces/ecpg/src/preproc/type.h with 100% similarity]
src/interfaces/ecpg/preproc/y.tab.h [new file with mode: 0644]
src/interfaces/ecpg/src/include/Makefile [deleted file]
src/interfaces/ecpg/src/include/Makefile.in [deleted file]
src/interfaces/ecpg/src/lib/ecpglib.c [deleted file]
src/interfaces/ecpg/src/preproc/Makefile.in [deleted file]
src/interfaces/ecpg/src/preproc/ecpg.in [deleted file]
src/interfaces/ecpg/src/test/Makefile [deleted file]
src/interfaces/ecpg/src/test/test2 [deleted file]
src/interfaces/ecpg/src/test/test2.c [deleted file]
src/interfaces/ecpg/src/test/test2.qc [deleted file]
src/interfaces/ecpg/test/Makefile [new file with mode: 0644]
src/interfaces/ecpg/test/Ptest1.c [moved from src/interfaces/ecpg/src/test/Ptest1.c with 100% similarity]
src/interfaces/ecpg/test/perftest.pgc [new file with mode: 0644]
src/interfaces/ecpg/test/test1.c [moved from src/interfaces/ecpg/src/test/test1.c with 100% similarity]
src/interfaces/ecpg/test/test2.pgc [new file with mode: 0644]

diff --git a/src/interfaces/ecpg/include/Makefile b/src/interfaces/ecpg/include/Makefile
new file mode 100644 (file)
index 0000000..08bc9df
--- /dev/null
@@ -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
diff --git a/src/interfaces/ecpg/include/Makefile.in b/src/interfaces/ecpg/include/Makefile.in
new file mode 100644 (file)
index 0000000..2f5c63a
--- /dev/null
@@ -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
similarity index 94%
rename from src/interfaces/ecpg/src/include/ecpglib.h
rename to src/interfaces/ecpg/include/ecpglib.h
index b880182e0bdf9771fe323b7fe8e637ef3be80faa..1fb35f8dfee58431311892ee8ad5f9e2d1b5936c 100644 (file)
@@ -1,6 +1,6 @@
 #include 
 
-void ECPGdebug(int);
+void ECPGdebug(int, FILE *);
 bool ECPGconnect(const char * dbname);
 bool ECPGdo(int, char *, ...);
 bool ECPGcommit(int);
similarity index 98%
rename from src/interfaces/ecpg/src/include/ecpgtype.h
rename to src/interfaces/ecpg/include/ecpgtype.h
index cc56b78cbb3d90c505b530722a9bf1dbba21b72d..496c934f4f4cbba98057fabd0858d91eb39e6c02 100644 (file)
 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)
similarity index 61%
rename from src/interfaces/ecpg/src/lib/Makefile
rename to src/interfaces/ecpg/lib/Makefile
index d227f6df3649ff6da64667721cd9b74e24862392..e3722e8aec1b3ec5d3fc155fddb44d300e838946 100644 (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)
similarity index 64%
rename from src/interfaces/ecpg/src/lib/Makefile.in
rename to src/interfaces/ecpg/lib/Makefile.in
index 07d126bd5c6470cb9bac068f84a0fea7ab8600ea..7ed351ab7a9b2ba601267475c49fdb19f43be15a 100644 (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)
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
new file mode 100644 (file)
index 0000000..80e9b0f
--- /dev/null
@@ -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 
+   on Feb. 5th, 1998 */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+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);
+   }
+}
similarity index 94%
rename from src/interfaces/ecpg/src/lib/typename.c
rename to src/interfaces/ecpg/lib/typename.c
index c1789572057c00173ec8602bb2a5fd06bf6fe501..55756037b30d51b8969667b6c9a9e6a0d98f6c50 100644 (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();
     }
similarity index 51%
rename from src/interfaces/ecpg/src/preproc/Makefile
rename to src/interfaces/ecpg/preproc/Makefile
index 9a53fb1b4322e828b7daf0a7f1b754862dd5a084..8cc8b7cb3aa27e7bf7a75d43c319951ec224e345 100644 (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
diff --git a/src/interfaces/ecpg/preproc/Makefile.in b/src/interfaces/ecpg/preproc/Makefile.in
new file mode 100644 (file)
index 0000000..f3cb049
--- /dev/null
@@ -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
similarity index 84%
rename from src/interfaces/ecpg/src/preproc/ecpg.c
rename to src/interfaces/ecpg/preproc/ecpg.c
index a7d96072af9101709e654b16228e3296924d3d65..08f4a3952505eb6ad8b90cc412badbb836e1c5e4 100644 (file)
@@ -8,10 +8,9 @@
 #include 
 
 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);
similarity index 94%
rename from src/interfaces/ecpg/src/preproc/pgc.l
rename to src/interfaces/ecpg/preproc/pgc.l
index 857561df9c5d6586fc7054e3171330201e950189..7ab3c5764f20e8ffc6212c5c8e3a4498e6df4e66 100644 (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; }
 {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;
 }
similarity index 90%
rename from src/interfaces/ecpg/src/preproc/preproc.y
rename to src/interfaces/ecpg/preproc/preproc.y
index f53c9a561333a15aa7ff88f544fc5b83804eccbd..b5a30c0d196b4cf929dd802adc60eedd545c0e27 100644 (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  S_VARCHAR S_VARCHAR2
 %token  S_EXTERN S_STATIC
 %token  S_UNSIGNED S_SIGNED
-%token  S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE
+%token  S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
 %token  '[' ']' ';' ','
 
 %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 { $$ = ECPGt_char; }
       | S_LONG { $$ = ECPGt_long; }
            | S_UNSIGNED S_LONG { $$ = ECPGt_unsigned_long; }
            | S_FLOAT { $$ = ECPGt_float; }
-           | S_DOUBLE { $$ = ECPGt_double; };
+           | S_DOUBLE { $$ = ECPGt_double; }
+      | S_BOOL { $$ = 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 { $$ = 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
similarity index 87%
rename from src/interfaces/ecpg/src/preproc/type.c
rename to src/interfaces/ecpg/preproc/type.c
index a54cbd801db69b90a0307af33c7a4aad5f84845a..e3ee2f003ab303e24a97073358f6b429cf32db39 100644 (file)
@@ -1,6 +1,5 @@
 #include 
 #include 
-#include 
 
 #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);
diff --git a/src/interfaces/ecpg/preproc/y.tab.h b/src/interfaces/ecpg/preproc/y.tab.h
new file mode 100644 (file)
index 0000000..b2fadd6
--- /dev/null
@@ -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;
diff --git a/src/interfaces/ecpg/src/include/Makefile b/src/interfaces/ecpg/src/include/Makefile
deleted file mode 100644 (file)
index 3b001ab..0000000
+++ /dev/null
@@ -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
diff --git a/src/interfaces/ecpg/src/include/Makefile.in b/src/interfaces/ecpg/src/include/Makefile.in
deleted file mode 100644 (file)
index 80e0451..0000000
+++ /dev/null
@@ -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
diff --git a/src/interfaces/ecpg/src/lib/ecpglib.c b/src/interfaces/ecpg/src/lib/ecpglib.c
deleted file mode 100644 (file)
index d2c078e..0000000
+++ /dev/null
@@ -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 
-   on Feb. 5th, 1998 */
-   
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-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);
-    }
-}
diff --git a/src/interfaces/ecpg/src/preproc/Makefile.in b/src/interfaces/ecpg/src/preproc/Makefile.in
deleted file mode 100644 (file)
index 2dca134..0000000
+++ /dev/null
@@ -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
diff --git a/src/interfaces/ecpg/src/preproc/ecpg.in b/src/interfaces/ecpg/src/preproc/ecpg.in
deleted file mode 100644 (file)
index b032cad..0000000
+++ /dev/null
@@ -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;
diff --git a/src/interfaces/ecpg/src/test/Makefile b/src/interfaces/ecpg/src/test/Makefile
deleted file mode 100644 (file)
index 219fb54..0000000
+++ /dev/null
@@ -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
diff --git a/src/interfaces/ecpg/src/test/test2 b/src/interfaces/ecpg/src/test/test2
deleted file mode 100755 (executable)
index 34b8680..0000000
Binary files a/src/interfaces/ecpg/src/test/test2 and /dev/null differ
diff --git a/src/interfaces/ecpg/src/test/test2.c b/src/interfaces/ecpg/src/test/test2.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/interfaces/ecpg/src/test/test2.qc b/src/interfaces/ecpg/src/test/test2.qc
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile
new file mode 100644 (file)
index 0000000..0ec0089
--- /dev/null
@@ -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
diff --git a/src/interfaces/ecpg/test/perftest.pgc b/src/interfaces/ecpg/test/perftest.pgc
new file mode 100644 (file)
index 0000000..9fb63fe
--- /dev/null
@@ -0,0 +1,72 @@
+#include 
+#include 
+#include 
+
+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);
+}
diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc
new file mode 100644 (file)
index 0000000..5e94495
--- /dev/null
@@ -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);
+}