aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/lib
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2000-02-16 16:18:29 +0000
committerMichael Meskes <meskes@postgresql.org>2000-02-16 16:18:29 +0000
commit35ba9de276150fd3d589509a86ae651924f34cb3 (patch)
tree8d3c867e2fbb1bd7404036f7e798e9c113fa4859 /src/interfaces/ecpg/lib
parent988d53e5ea6d87a284e8d3c81829e86b89455fa9 (diff)
downloadpostgresql-35ba9de276150fd3d589509a86ae651924f34cb3.tar.gz
postgresql-35ba9de276150fd3d589509a86ae651924f34cb3.zip
*** empty log message ***
Diffstat (limited to 'src/interfaces/ecpg/lib')
-rw-r--r--src/interfaces/ecpg/lib/Makefile.in4
-rw-r--r--src/interfaces/ecpg/lib/dynamic.c290
-rw-r--r--src/interfaces/ecpg/lib/ecpglib.c25
3 files changed, 309 insertions, 10 deletions
diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index 296c3c5a409..947f9fd1a96 100644
--- a/src/interfaces/ecpg/lib/Makefile.in
+++ b/src/interfaces/ecpg/lib/Makefile.in
@@ -6,7 +6,7 @@
# Copyright (c) 1994, Regents of the University of California
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.57 2000/02/16 11:52:24 meskes Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.58 2000/02/16 16:18:05 meskes Exp $
#
#-------------------------------------------------------------------------
@@ -36,7 +36,7 @@ include $(SRCDIR)/Makefile.shlib
install: install-lib $(install-shlib-dep)
# Handmade dependencies in case make depend not done
-ecpglib.o : ecpglib.c ../include/ecpglib.h ../include/ecpgtype.h
+ecpglib.o : ecpglib.c ../include/ecpglib.h ../include/ecpgtype.h dynamic.c
typename.o : typename.c ../include/ecpgtype.h
diff --git a/src/interfaces/ecpg/lib/dynamic.c b/src/interfaces/ecpg/lib/dynamic.c
new file mode 100644
index 00000000000..ec8e927d649
--- /dev/null
+++ b/src/interfaces/ecpg/lib/dynamic.c
@@ -0,0 +1,290 @@
+/* dynamic SQL support routines
+ *
+ * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
+ *
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.1 2000/02/16 16:18:12 meskes Exp $
+ */
+
+/* I borrowed the include files from ecpglib.c, maybe we don't need all of them */
+
+#if 0
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <locale.h>
+
+#include <libpq-fe.h>
+#include <libpq/pqcomm.h>
+#include <ecpgtype.h>
+#include <ecpglib.h>
+#include <sqlca.h>
+#endif
+#include <sql3types.h>
+
+static struct descriptor
+{ char *name;
+ PGresult *result;
+ struct descriptor *next;
+} *all_descriptors=NULL;
+
+PGconn *ECPG_internal_get_connection(char *name);
+
+unsigned int ECPGDynamicType(Oid type)
+{ switch(type)
+ { case 16: return SQL3_BOOLEAN; /* bool */
+ case 21: return SQL3_SMALLINT; /* int2 */
+ case 23: return SQL3_INTEGER; /* int4 */
+ case 25: return SQL3_CHARACTER; /* text */
+ case 700: return SQL3_REAL; /* float4 */
+ case 701: return SQL3_DOUBLE_PRECISION; /* float8 */
+ case 1042: return SQL3_CHARACTER; /* bpchar */
+ case 1043: return SQL3_CHARACTER_VARYING; /* varchar */
+ case 1082: return SQL3_DATE_TIME_TIMESTAMP; /* date */
+ case 1083: return SQL3_DATE_TIME_TIMESTAMP; /* time */
+ case 1184: return SQL3_DATE_TIME_TIMESTAMP; /* datetime */
+ case 1296: return SQL3_DATE_TIME_TIMESTAMP; /* timestamp */
+ case 1700: return SQL3_NUMERIC; /* numeric */
+ default:
+ return -type;
+ }
+}
+
+unsigned int ECPGDynamicType_DDT(Oid type)
+{ switch(type)
+ {
+ case 1082: return SQL3_DDT_DATE; /* date */
+ case 1083: return SQL3_DDT_TIME; /* time */
+ case 1184: return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE; /* datetime */
+ case 1296: return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE; /* timestamp */
+ default:
+ return SQL3_DDT_ILLEGAL;
+ }
+}
+
+// like ECPGexecute
+static bool execute_descriptor(int lineno,const char *query
+ ,struct connection *con,PGresult **resultptr)
+{
+ bool status = false;
+ PGresult *results;
+ PGnotify *notify;
+
+ /* Now the request is built. */
+
+ if (con->committed && !con->autocommit)
+ {
+ if ((results = PQexec(con->connection, "begin transaction")) == NULL)
+ {
+ register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno);
+ return false;
+ }
+ PQclear(results);
+ con->committed = false;
+ }
+
+ ECPGlog("execute_descriptor line %d: QUERY: %s on connection %s\n", lineno, query, con->name);
+ results = PQexec(con->connection, query);
+
+ if (results == NULL)
+ {
+ ECPGlog("ECPGexecute line %d: error: %s", lineno,
+ PQerrorMessage(con->connection));
+ register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
+ PQerrorMessage(con->connection), lineno);
+ }
+ else
+ { *resultptr=results;
+ switch (PQresultStatus(results))
+ { int ntuples;
+ case PGRES_TUPLES_OK:
+ status = true;
+ sqlca.sqlerrd[2] = ntuples = PQntuples(results);
+ if (ntuples < 1)
+ {
+ ECPGlog("execute_descriptor line %d: Incorrect number of matches: %d\n",
+ lineno, ntuples);
+ register_error(ECPG_NOT_FOUND, "No data found line %d.", lineno);
+ status = false;
+ break;
+ }
+ break;
+#if 1 /* strictly these are not needed (yet) */
+ case PGRES_EMPTY_QUERY:
+ /* do nothing */
+ register_error(ECPG_EMPTY, "Empty query line %d.", lineno);
+ break;
+ case PGRES_COMMAND_OK:
+ status = true;
+ sqlca.sqlerrd[1] = atol(PQoidStatus(results));
+ sqlca.sqlerrd[2] = atol(PQcmdTuples(results));
+ ECPGlog("ECPGexecute line %d Ok: %s\n", lineno, PQcmdStatus(results));
+ break;
+ case PGRES_COPY_OUT:
+ ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", lineno);
+ PQendcopy(con->connection);
+ break;
+ case PGRES_COPY_IN:
+ ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", lineno);
+ PQendcopy(con->connection);
+ break;
+#else
+ case PGRES_EMPTY_QUERY:
+ case PGRES_COMMAND_OK:
+ case PGRES_COPY_OUT:
+ case PGRES_COPY_IN:
+ break;
+#endif
+ case PGRES_NONFATAL_ERROR:
+ case PGRES_FATAL_ERROR:
+ case PGRES_BAD_RESPONSE:
+ ECPGlog("ECPGexecute line %d: Error: %s",
+ lineno, PQerrorMessage(con->connection));
+ register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
+ PQerrorMessage(con->connection), lineno);
+ status = false;
+ break;
+ default:
+ ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
+ lineno);
+ register_error(ECPG_PGSQL, "Postgres error: %s line %d.",
+ PQerrorMessage(con->connection), lineno);
+ status = false;
+ break;
+ }
+ }
+
+ /* check for asynchronous returns */
+ notify = PQnotifies(con->connection);
+ if (notify)
+ {
+ ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
+ lineno, notify->relname, notify->be_pid);
+ free(notify);
+ }
+ return status;
+}
+
+/* like ECPGdo */
+static bool do_descriptor2(int lineno,const char *connection_name,
+ PGresult **resultptr, const char *query)
+{
+ struct connection *con = get_connection(connection_name);
+ bool status=true;
+ char *locale = setlocale(LC_NUMERIC, NULL);
+
+ /* Make sure we do NOT honor the locale for numeric input/output */
+ /* since the database wants teh standard decimal point */
+ setlocale(LC_NUMERIC, "C");
+
+ if (!ecpg_init(con, connection_name, lineno))
+ { setlocale(LC_NUMERIC, locale);
+ return(false);
+ }
+
+ /* are we connected? */
+ if (con == NULL || con->connection == NULL)
+ {
+ ECPGlog("ECPGdo: not connected to %s\n", con->name);
+ register_error(ECPG_NOT_CONN, "Not connected in line %d.", lineno);
+ setlocale(LC_NUMERIC, locale);
+ return false;
+ }
+
+ status = execute_descriptor(lineno,query,con,resultptr);
+
+ /* and reset locale value so our application is not affected */
+ setlocale(LC_NUMERIC, locale);
+ return (status);
+}
+
+bool ECPGdo_descriptor(int line,const char *connection,
+ const char *descriptor,const char *query)
+{
+ struct descriptor *i;
+ for (i=all_descriptors;i!=NULL;i=i->next)
+ { if (!strcmp(descriptor,i->name))
+ {
+ bool status;
+
+ /* free previous result */
+ if (i->result) PQclear(i->result);
+ i->result=NULL;
+
+ status=do_descriptor2(line,connection,&i->result,query);
+
+ if (!i->result) PQmakeEmptyPGresult(NULL, 0);
+ return (status);
+ }
+ }
+ ECPGraise(line,ECPG_UNKNOWN_DESCRIPTOR);
+ return false;
+}
+
+PGresult *ECPGresultByDescriptor(int line,const char *name)
+{
+ struct descriptor *i;
+ for (i=all_descriptors;i!=NULL;i=i->next)
+ { if (!strcmp(name,i->name)) return i->result;
+ }
+ ECPGraise(line,ECPG_UNKNOWN_DESCRIPTOR);
+ return 0;
+}
+
+
+bool ECPGdeallocate_desc(int line,const char *name)
+{
+ struct descriptor *i;
+ struct descriptor **lastptr=&all_descriptors;
+ for (i=all_descriptors;i;lastptr=&i->next,i=i->next)
+ { if (!strcmp(name,i->name))
+ { *lastptr=i->next;
+ free(i->name);
+ PQclear(i->result);
+ free(i);
+ return true;
+ }
+ }
+ ECPGraise(line,ECPG_UNKNOWN_DESCRIPTOR);
+ return false;
+}
+
+bool ECPGallocate_desc(int line,const char *name)
+{
+ struct descriptor *new=(struct descriptor *)malloc(sizeof(struct descriptor));
+
+ new->next=all_descriptors;
+ new->name=malloc(strlen(name)+1);
+ new->result=PQmakeEmptyPGresult(NULL, 0);
+ strcpy(new->name,name);
+ all_descriptors=new;
+ return true;
+}
+
+void ECPGraise(int line,int code)
+{ sqlca.sqlcode=code;
+ switch (code)
+ { case ECPG_NOT_FOUND:
+ snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+ "No data found line %d.",line);
+ break;
+ case ECPG_MISSING_INDICATOR:
+ snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+ "NULL value without indicator, line %d.",line);
+ break;
+ case ECPG_UNKNOWN_DESCRIPTOR:
+ snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+ "descriptor not found, line %d.",line);
+ break;
+ case ECPG_INVALID_DESCRIPTOR_INDEX:
+ snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+ "descriptor index out of range, line %d.",line);
+ break;
+ default:
+ snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc),
+ "SQL error #%d, line %d.",code,line);
+ break;
+ }
+}
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index 5074bc20e07..a6e2b23e01b 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -20,7 +20,6 @@
#include <ctype.h>
#include <locale.h>
-#include <libpq-fe.h>
#include <libpq/pqcomm.h>
#include <ecpgtype.h>
#include <ecpglib.h>
@@ -753,7 +752,7 @@ ECPGexecute(struct statement * stmt)
{
char *pval;
char *scan_length;
- char *array_query;
+ char *array_query;
if (var == NULL)
{
@@ -1127,36 +1126,44 @@ ECPGexecute(struct statement * stmt)
bool
ECPGdo(int lineno, const char *connection_name, char *query,...)
{
- va_list args;
- struct statement *stmt;
- struct connection *con = get_connection(connection_name);
- bool status;
- char *locale = setlocale(LC_NUMERIC, NULL);
+ va_list args;
+ struct statement *stmt;
+ struct connection *con = get_connection(connection_name);
+ bool status=true;
+ char *locale = setlocale(LC_NUMERIC, NULL);
/* Make sure we do NOT honor the locale for numeric input/output */
/* since the database wants teh standard decimal point */
setlocale(LC_NUMERIC, "C");
if (!ecpg_init(con, connection_name, lineno))
+ {
+ setlocale(LC_NUMERIC, locale);
return(false);
+ }
va_start(args, query);
if (create_statement(lineno, con, &stmt, query, args) == false)
+ {
+ setlocale(LC_NUMERIC, locale);
return (false);
+ }
va_end(args);
/* are we connected? */
if (con == NULL || con->connection == NULL)
{
+ free_statement(stmt);
ECPGlog("ECPGdo: not connected to %s\n", con->name);
register_error(ECPG_NOT_CONN, "Not connected in line %d.", lineno);
+ setlocale(LC_NUMERIC, locale);
return false;
}
status = ECPGexecute(stmt);
free_statement(stmt);
- /* and reser value so our application is not affected */
+ /* and reset locale value so our application is not affected */
setlocale(LC_NUMERIC, locale);
return (status);
}
@@ -1508,3 +1515,5 @@ ECPGprepared_statement(char *name)
for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next);
return (this) ? this->stmt->command : NULL;
}
+
+#include "dynamic.c"