diff options
author | Michael Meskes <meskes@postgresql.org> | 2000-02-16 16:18:29 +0000 |
---|---|---|
committer | Michael Meskes <meskes@postgresql.org> | 2000-02-16 16:18:29 +0000 |
commit | 35ba9de276150fd3d589509a86ae651924f34cb3 (patch) | |
tree | 8d3c867e2fbb1bd7404036f7e798e9c113fa4859 /src/interfaces/ecpg/lib | |
parent | 988d53e5ea6d87a284e8d3c81829e86b89455fa9 (diff) | |
download | postgresql-35ba9de276150fd3d589509a86ae651924f34cb3.tar.gz postgresql-35ba9de276150fd3d589509a86ae651924f34cb3.zip |
*** empty log message ***
Diffstat (limited to 'src/interfaces/ecpg/lib')
-rw-r--r-- | src/interfaces/ecpg/lib/Makefile.in | 4 | ||||
-rw-r--r-- | src/interfaces/ecpg/lib/dynamic.c | 290 | ||||
-rw-r--r-- | src/interfaces/ecpg/lib/ecpglib.c | 25 |
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" |