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/dynamic.c | |
parent | 988d53e5ea6d87a284e8d3c81829e86b89455fa9 (diff) | |
download | postgresql-35ba9de276150fd3d589509a86ae651924f34cb3.tar.gz postgresql-35ba9de276150fd3d589509a86ae651924f34cb3.zip |
*** empty log message ***
Diffstat (limited to 'src/interfaces/ecpg/lib/dynamic.c')
-rw-r--r-- | src/interfaces/ecpg/lib/dynamic.c | 290 |
1 files changed, 290 insertions, 0 deletions
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; + } +} |