Back out all ODBC formatting changes, and back out removal of <6.4

protocol. I have left in Tom's SOCK_get_next_byte() fix, and the new
win32.mak file addition.  I have also left in the 'X' connection close
fix.
This commit is contained in:
Bruce Momjian 2001-02-14 05:45:46 +00:00
parent 18b04ae131
commit 594e97b72f
45 changed files with 9580 additions and 11060 deletions

View File

@ -2,7 +2,7 @@
#
# GNUMakefile for psqlodbc (Postgres ODBC driver)
#
# $Header: /cvsroot/pgsql/src/interfaces/odbc/Attic/GNUmakefile,v 1.12 2001/02/10 16:51:40 petere Exp $
# $Header: /cvsroot/pgsql/src/interfaces/odbc/Attic/GNUmakefile,v 1.13 2001/02/14 05:45:38 momjian Exp $
#
#-------------------------------------------------------------------------
@ -24,6 +24,7 @@ OBJS = info.o bind.o columninfo.o connection.o convert.o drvconn.o \
gpps.o tuple.o tuplelist.o dlg_specific.o $(OBJX)
SHLIB_LINK = $(filter -lm, $(LIBS))
all: all-lib
# Shared library stuff
@ -32,7 +33,6 @@ include $(top_srcdir)/src/Makefile.shlib
# Symbols must be resolved to the version in the shared library because
# the driver manager (e.g., iodbc) provides some symbols with the same
# names and we don't want those. (This issue is probably ELF specific.)
LINK.shared += $(shlib_symbolic)
odbc_headers = isql.h isqlext.h iodbc.h

View File

@ -1,14 +1,15 @@
/* Module: bind.c
/* Module: bind.c
*
* Description: This module contains routines related to binding
* columns and parameters.
* Description: This module contains routines related to binding
* columns and parameters.
*
* Classes: BindInfoClass, ParameterInfoClass
* Classes: BindInfoClass, ParameterInfoClass
*
* API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
* SQLParamOptions(NI)
* API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
* SQLParamOptions(NI)
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -33,44 +34,39 @@
#include "sqlext.h"
#endif
/* Bind parameters on a statement handle */
/* Bind parameters on a statement handle */
RETCODE SQL_API
SQLBindParameter(
HSTMT hstmt,
UWORD ipar,
SWORD fParamType,
SWORD fCType,
SWORD fSqlType,
UDWORD cbColDef,
SWORD ibScale,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue)
RETCODE SQL_API SQLBindParameter(
HSTMT hstmt,
UWORD ipar,
SWORD fParamType,
SWORD fCType,
SWORD fSqlType,
UDWORD cbColDef,
SWORD ibScale,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue)
{
StatementClass *stmt = (StatementClass *) hstmt;
static char *func = "SQLBindParameter";
StatementClass *stmt = (StatementClass *) hstmt;
static char *func="SQLBindParameter";
mylog("%s: entering...\n", func);
mylog( "%s: entering...\n", func);
if (!stmt)
{
if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
if (stmt->parameters_allocated < ipar)
{
if(stmt->parameters_allocated < ipar) {
ParameterInfoClass *old_parameters;
int i,
old_parameters_allocated;
int i, old_parameters_allocated;
old_parameters = stmt->parameters;
old_parameters_allocated = stmt->parameters_allocated;
stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass) * (ipar));
if (!stmt->parameters)
{
stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass)*(ipar));
if ( ! stmt->parameters) {
stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Could not allocate memory for statement parameters";
SC_log_error(func, "", stmt);
@ -80,23 +76,18 @@ SQLBindParameter(
stmt->parameters_allocated = ipar;
/* copy the old parameters over */
for (i = 0; i < old_parameters_allocated; i++)
{
for(i = 0; i < old_parameters_allocated; i++) {
/* a structure copy should work */
stmt->parameters[i] = old_parameters[i];
}
/* get rid of the old parameters, if there were any */
if (old_parameters)
if(old_parameters)
free(old_parameters);
/*
* zero out the newly allocated parameters (in case they skipped
* some,
*/
/* zero out the newly allocated parameters (in case they skipped some, */
/* so we don't accidentally try to use them later) */
for (; i < stmt->parameters_allocated; i++)
{
for(; i < stmt->parameters_allocated; i++) {
stmt->parameters[i].buflen = 0;
stmt->parameters[i].buffer = 0;
stmt->parameters[i].used = 0;
@ -112,8 +103,7 @@ SQLBindParameter(
}
}
ipar--; /* use zero based column numbers for the
* below part */
ipar--; /* use zero based column numbers for the below part */
/* store the given info */
stmt->parameters[ipar].buflen = cbValueMax;
@ -125,83 +115,74 @@ SQLBindParameter(
stmt->parameters[ipar].precision = cbColDef;
stmt->parameters[ipar].scale = ibScale;
/*
* If rebinding a parameter that had data-at-exec stuff in it, then
* free that stuff
*/
if (stmt->parameters[ipar].EXEC_used)
{
/* If rebinding a parameter that had data-at-exec stuff in it,
then free that stuff
*/
if (stmt->parameters[ipar].EXEC_used) {
free(stmt->parameters[ipar].EXEC_used);
stmt->parameters[ipar].EXEC_used = NULL;
}
if (stmt->parameters[ipar].EXEC_buffer)
{
if (stmt->parameters[ipar].EXEC_buffer) {
if (stmt->parameters[ipar].SQLType != SQL_LONGVARBINARY)
free(stmt->parameters[ipar].EXEC_buffer);
stmt->parameters[ipar].EXEC_buffer = NULL;
}
/* Data at exec macro only valid for C char/binary data */
/* Data at exec macro only valid for C char/binary data */
if ((fSqlType == SQL_LONGVARBINARY || fSqlType == SQL_LONGVARCHAR) && pcbValue && *pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET)
stmt->parameters[ipar].data_at_exec = TRUE;
else
stmt->parameters[ipar].data_at_exec = FALSE;
mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, stmt->parameters[ipar].data_at_exec);
mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue: -777, stmt->parameters[ipar].data_at_exec);
return SQL_SUCCESS;
}
/* - - - - - - - - - */
/* - - - - - - - - - */
/* Associate a user-supplied buffer with a database column. */
RETCODE SQL_API
SQLBindCol(
HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue)
/* Associate a user-supplied buffer with a database column. */
RETCODE SQL_API SQLBindCol(
HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue)
{
StatementClass *stmt = (StatementClass *) hstmt;
static char *func = "SQLBindCol";
StatementClass *stmt = (StatementClass *) hstmt;
static char *func="SQLBindCol";
mylog("%s: entering...\n", func);
mylog( "%s: entering...\n", func);
mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
if (!stmt)
{
if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
SC_clear_error(stmt);
if (stmt->status == STMT_EXECUTING)
{
if( stmt->status == STMT_EXECUTING) {
stmt->errormsg = "Can't bind columns while statement is still executing.";
stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
/* If the bookmark column is being bound, then just save it */
if (icol == 0)
{
if (rgbValue == NULL)
{
/* If the bookmark column is being bound, then just save it */
if (icol == 0) {
if (rgbValue == NULL) {
stmt->bookmark.buffer = NULL;
stmt->bookmark.used = NULL;
}
else
{
/* Make sure it is the bookmark data type */
if (fCType != SQL_C_BOOKMARK)
{
else {
/* Make sure it is the bookmark data type */
if ( fCType != SQL_C_BOOKMARK) {
stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
SC_log_error(func, "", stmt);
@ -214,42 +195,37 @@ SQLBindCol(
return SQL_SUCCESS;
}
/* allocate enough bindings if not already done */
/* Most likely, execution of a statement would have setup the */
/* necessary bindings. But some apps call BindCol before any */
/* statement is executed. */
if (icol > stmt->bindings_allocated)
/* allocate enough bindings if not already done */
/* Most likely, execution of a statement would have setup the */
/* necessary bindings. But some apps call BindCol before any */
/* statement is executed. */
if ( icol > stmt->bindings_allocated)
extend_bindings(stmt, icol);
/* check to see if the bindings were allocated */
if (!stmt->bindings)
{
/* check to see if the bindings were allocated */
if ( ! stmt->bindings) {
stmt->errormsg = "Could not allocate memory for bindings.";
stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
icol--; /* use zero based col numbers from here
* out */
icol--; /* use zero based col numbers from here out */
/* Reset for SQLGetData */
/* Reset for SQLGetData */
stmt->bindings[icol].data_left = -1;
if (rgbValue == NULL)
{
if (rgbValue == NULL) {
/* we have to unbind the column */
stmt->bindings[icol].buflen = 0;
stmt->bindings[icol].buffer = NULL;
stmt->bindings[icol].used = NULL;
stmt->bindings[icol].used = NULL;
stmt->bindings[icol].returntype = SQL_C_CHAR;
}
else
{
} else {
/* ok, bind that column */
stmt->bindings[icol].buflen = cbValueMax;
stmt->bindings[icol].buffer = rgbValue;
stmt->bindings[icol].used = pcbValue;
stmt->bindings[icol].buflen = cbValueMax;
stmt->bindings[icol].buffer = rgbValue;
stmt->bindings[icol].used = pcbValue;
stmt->bindings[icol].returntype = fCType;
mylog(" bound buffer[%d] = %u\n", icol, stmt->bindings[icol].buffer);
@ -258,37 +234,34 @@ SQLBindCol(
return SQL_SUCCESS;
}
/* - - - - - - - - - */
/* - - - - - - - - - */
/* Returns the description of a parameter marker. */
/* Returns the description of a parameter marker. */
/* This function is listed as not being supported by SQLGetFunctions() because it is */
/* used to describe "parameter markers" (not bound parameters), in which case, */
/* the dbms should return info on the markers. Since Postgres doesn't support that, */
/* it is best to say this function is not supported and let the application assume a */
/* data type (most likely varchar). */
RETCODE SQL_API
SQLDescribeParam(
HSTMT hstmt,
UWORD ipar,
SWORD FAR *pfSqlType,
UDWORD FAR *pcbColDef,
SWORD FAR *pibScale,
SWORD FAR *pfNullable)
RETCODE SQL_API SQLDescribeParam(
HSTMT hstmt,
UWORD ipar,
SWORD FAR *pfSqlType,
UDWORD FAR *pcbColDef,
SWORD FAR *pibScale,
SWORD FAR *pfNullable)
{
StatementClass *stmt = (StatementClass *) hstmt;
static char *func = "SQLDescribeParam";
StatementClass *stmt = (StatementClass *) hstmt;
static char *func = "SQLDescribeParam";
mylog("%s: entering...\n", func);
mylog( "%s: entering...\n", func);
if (!stmt)
{
if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
if ((ipar < 1) || (ipar > stmt->parameters_allocated))
{
if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) {
stmt->errormsg = "Invalid parameter number for SQLDescribeParam.";
stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR;
SC_log_error(func, "", stmt);
@ -297,45 +270,41 @@ SQLDescribeParam(
ipar--;
/*
* This implementation is not very good, since it is supposed to
* describe
*/
/* parameter markers, not bound parameters. */
if (pfSqlType)
/* This implementation is not very good, since it is supposed to describe */
/* parameter markers, not bound parameters. */
if(pfSqlType)
*pfSqlType = stmt->parameters[ipar].SQLType;
if (pcbColDef)
if(pcbColDef)
*pcbColDef = stmt->parameters[ipar].precision;
if (pibScale)
if(pibScale)
*pibScale = stmt->parameters[ipar].scale;
if (pfNullable)
if(pfNullable)
*pfNullable = pgtype_nullable(stmt, stmt->parameters[ipar].paramType);
return SQL_SUCCESS;
}
/* - - - - - - - - - */
/* - - - - - - - - - */
/* Sets multiple values (arrays) for the set of parameter markers. */
/* Sets multiple values (arrays) for the set of parameter markers. */
RETCODE SQL_API
SQLParamOptions(
HSTMT hstmt,
UDWORD crow,
UDWORD FAR *pirow)
RETCODE SQL_API SQLParamOptions(
HSTMT hstmt,
UDWORD crow,
UDWORD FAR *pirow)
{
static char *func = "SQLParamOptions";
static char *func = "SQLParamOptions";
mylog("%s: entering...\n", func);
mylog( "%s: entering...\n", func);
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR;
}
/* - - - - - - - - - */
/* - - - - - - - - - */
/* This function should really talk to the dbms to determine the number of */
/* "parameter markers" (not bound parameters) in the statement. But, since */
@ -344,49 +313,43 @@ SQLParamOptions(
/* like it does for SQLDescribeParam is that some applications don't care and try */
/* to call it anyway. */
/* If the statement does not have parameters, it should just return 0. */
RETCODE SQL_API
SQLNumParams(
HSTMT hstmt,
SWORD FAR *pcpar)
RETCODE SQL_API SQLNumParams(
HSTMT hstmt,
SWORD FAR *pcpar)
{
StatementClass *stmt = (StatementClass *) hstmt;
char in_quote = FALSE;
unsigned int i;
static char *func = "SQLNumParams";
StatementClass *stmt = (StatementClass *) hstmt;
char in_quote = FALSE;
unsigned int i;
static char *func = "SQLNumParams";
mylog("%s: entering...\n", func);
mylog( "%s: entering...\n", func);
if (!stmt)
{
if(!stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
if (pcpar)
*pcpar = 0;
else
{
else {
SC_log_error(func, "pcpar was null", stmt);
return SQL_ERROR;
}
if (!stmt->statement)
{
if(!stmt->statement) {
/* no statement has been allocated */
stmt->errormsg = "SQLNumParams called with no statement ready.";
stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
else
{
for (i = 0; i < strlen(stmt->statement); i++)
{
if (stmt->statement[i] == '?' && !in_quote)
} else {
for(i=0; i < strlen(stmt->statement); i++) {
if(stmt->statement[i] == '?' && !in_quote)
(*pcpar)++;
else
{
else {
if (stmt->statement[i] == '\'')
in_quote = (in_quote ? FALSE : TRUE);
}
@ -397,20 +360,20 @@ SQLNumParams(
}
/********************************************************************
* Bindings Implementation
* Bindings Implementation
*/
BindInfoClass *
create_empty_bindings(int num_columns)
{
BindInfoClass *new_bindings;
int i;
BindInfoClass *new_bindings;
int i;
new_bindings = (BindInfoClass *) malloc(num_columns * sizeof(BindInfoClass));
if (!new_bindings)
new_bindings = (BindInfoClass *)malloc(num_columns * sizeof(BindInfoClass));
if(!new_bindings) {
return 0;
}
for (i = 0; i < num_columns; i++)
{
for(i=0; i < num_columns; i++) {
new_bindings[i].buflen = 0;
new_bindings[i].buffer = NULL;
new_bindings[i].used = NULL;
@ -423,23 +386,21 @@ create_empty_bindings(int num_columns)
void
extend_bindings(StatementClass *stmt, int num_columns)
{
static char *func = "extend_bindings";
BindInfoClass *new_bindings;
int i;
static char *func="extend_bindings";
BindInfoClass *new_bindings;
int i;
mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns);
mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns);
/* if we have too few, allocate room for more, and copy the old */
/* entries into the new structure */
if (stmt->bindings_allocated < num_columns)
{
new_bindings = create_empty_bindings(num_columns);
if (!new_bindings)
{
mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated);
if(stmt->bindings_allocated < num_columns) {
if (stmt->bindings)
{
new_bindings = create_empty_bindings(num_columns);
if ( ! new_bindings) {
mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated);
if (stmt->bindings) {
free(stmt->bindings);
stmt->bindings = NULL;
}
@ -447,9 +408,8 @@ extend_bindings(StatementClass *stmt, int num_columns)
return;
}
if (stmt->bindings)
{
for (i = 0; i < stmt->bindings_allocated; i++)
if(stmt->bindings) {
for(i=0; i<stmt->bindings_allocated; i++)
new_bindings[i] = stmt->bindings[i];
free(stmt->bindings);
@ -457,14 +417,15 @@ extend_bindings(StatementClass *stmt, int num_columns)
stmt->bindings = new_bindings;
stmt->bindings_allocated = num_columns;
}
/* There is no reason to zero out extra bindings if there are */
/* more than needed. If an app has allocated extra bindings, */
/* let it worry about it by unbinding those columns. */
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
/* SQLExecDirect(...) # returns 5 cols */
/* SQLExecDirect(...) # returns 10 cols (now OK) */
}
/* There is no reason to zero out extra bindings if there are */
/* more than needed. If an app has allocated extra bindings, */
/* let it worry about it by unbinding those columns. */
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
/* SQLExecDirect(...) # returns 5 cols */
/* SQLExecDirect(...) # returns 10 cols (now OK) */
mylog("exit extend_bindings\n");
}

View File

@ -1,9 +1,9 @@
/* File: bind.h
/* File: bind.h
*
* Description: See "bind.c"
* Description: See "bind.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -15,40 +15,33 @@
/*
* BindInfoClass -- stores information about a bound column
*/
struct BindInfoClass_
{
Int4 buflen; /* size of buffer */
Int4 data_left; /* amount of data left to read
* (SQLGetData) */
char *buffer; /* pointer to the buffer */
Int4 *used; /* used space in the buffer (for strings
* not counting the '\0') */
Int2 returntype; /* kind of conversion to be applied when
* returning (SQL_C_DEFAULT,
* SQL_C_CHAR...) */
struct BindInfoClass_ {
Int4 buflen; /* size of buffer */
Int4 data_left; /* amount of data left to read (SQLGetData) */
char *buffer; /* pointer to the buffer */
Int4 *used; /* used space in the buffer (for strings not counting the '\0') */
Int2 returntype; /* kind of conversion to be applied when returning (SQL_C_DEFAULT, SQL_C_CHAR...) */
};
/*
* ParameterInfoClass -- stores information about a bound parameter
*/
struct ParameterInfoClass_
{
Int4 buflen;
char *buffer;
Int4 *used;
Int2 paramType;
Int2 CType;
Int2 SQLType;
UInt4 precision;
Int2 scale;
Oid lobj_oid;
Int4 *EXEC_used; /* amount of data OR the oid of the large
* object */
char *EXEC_buffer; /* the data or the FD of the large object */
char data_at_exec;
struct ParameterInfoClass_ {
Int4 buflen;
char *buffer;
Int4 *used;
Int2 paramType;
Int2 CType;
Int2 SQLType;
UInt4 precision;
Int2 scale;
Oid lobj_oid;
Int4 *EXEC_used; /* amount of data OR the oid of the large object */
char *EXEC_buffer; /* the data or the FD of the large object */
char data_at_exec;
};
BindInfoClass *create_empty_bindings(int num_columns);
void extend_bindings(StatementClass *stmt, int num_columns);
void extend_bindings(StatementClass *stmt, int num_columns);
#endif

View File

@ -1,13 +1,14 @@
/* Module: columninfo.c
/* Module: columninfo.c
*
* Description: This module contains routines related to
* reading and storing the field information from a query.
* Description: This module contains routines related to
* reading and storing the field information from a query.
*
* Classes: ColumnInfoClass (Functions prefix: "CI_")
* Classes: ColumnInfoClass (Functions prefix: "CI_")
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -20,12 +21,11 @@
ColumnInfoClass *
CI_Constructor()
{
ColumnInfoClass *rv;
ColumnInfoClass *rv;
rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
if (rv)
{
if (rv) {
rv->num_fields = 0;
rv->name = NULL;
rv->adtid = NULL;
@ -45,21 +45,21 @@ CI_Destructor(ColumnInfoClass *self)
free(self);
}
/* Read in field descriptions.
If self is not null, then also store the information.
/* Read in field descriptions.
If self is not null, then also store the information.
If self is null, then just read, don't store.
*/
char
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
{
Int2 lf;
int new_num_fields;
Oid new_adtid;
Int2 new_adtsize;
Int4 new_atttypmod = -1;
char new_field_name[MAX_MESSAGE_LEN + 1];
SocketClass *sock;
ConnInfo *ci;
Int2 lf;
int new_num_fields;
Oid new_adtid;
Int2 new_adtsize;
Int4 new_atttypmod = -1;
char new_field_name[MAX_MESSAGE_LEN+1];
SocketClass *sock;
ConnInfo *ci;
sock = CC_get_socket(conn);
ci = &conn->connInfo;
@ -69,28 +69,28 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
mylog("num_fields = %d\n", new_num_fields);
if (self)
{ /* according to that allocate memory */
if (self) { /* according to that allocate memory */
CI_set_num_fields(self, new_num_fields);
}
/* now read in the descriptions */
for (lf = 0; lf < new_num_fields; lf++)
{
for(lf = 0; lf < new_num_fields; lf++) {
SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN);
new_adtid = (Oid) SOCK_get_int(sock, 4);
new_adtsize = (Int2) SOCK_get_int(sock, 2);
/* If 6.4 protocol, then read the atttypmod field */
if (PG_VERSION_GE(conn, 6.4))
{
/* If 6.4 protocol, then read the atttypmod field */
if (PG_VERSION_GE(conn, 6.4)) {
mylog("READING ATTTYPMOD\n");
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
/* Subtract the header length */
/* Subtract the header length */
new_atttypmod -= 4;
if (new_atttypmod < 0)
new_atttypmod = -1;
}
mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod);
@ -107,16 +107,15 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
void
CI_free_memory(ColumnInfoClass *self)
{
register Int2 lf;
int num_fields = self->num_fields;
register Int2 lf;
int num_fields = self->num_fields;
for (lf = 0; lf < num_fields; lf++)
{
if (self->name[lf])
free(self->name[lf]);
for (lf = 0; lf < num_fields; lf++) {
if( self->name[lf])
free (self->name[lf]);
}
/* Safe to call even if null */
/* Safe to call even if null */
free(self->name);
free(self->adtid);
free(self->adtsize);
@ -128,30 +127,33 @@ CI_free_memory(ColumnInfoClass *self)
void
CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
{
CI_free_memory(self); /* always safe to call */
CI_free_memory(self); /* always safe to call */
self->num_fields = new_num_fields;
self->name = (char **) malloc(sizeof(char *) * self->num_fields);
self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields);
self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
self->name = (char **) malloc (sizeof(char *) * self->num_fields);
self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields);
self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields);
self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields);
}
void
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
{
/* check bounds */
if ((field_num < 0) || (field_num >= self->num_fields))
if((field_num < 0) || (field_num >= self->num_fields)) {
return;
}
/* store the info */
self->name[field_num] = strdup(new_name);
self->name[field_num] = strdup(new_name);
self->adtid[field_num] = new_adtid;
self->adtsize[field_num] = new_adtsize;
self->atttypmod[field_num] = new_atttypmod;
self->display_size[field_num] = 0;
}

View File

@ -1,9 +1,9 @@
/* File: columninfo.h
/* File: columninfo.h
*
* Description: See "columninfo.c"
* Description: See "columninfo.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -12,14 +12,13 @@
#include "psqlodbc.h"
struct ColumnInfoClass_
{
Int2 num_fields;
char **name; /* list of type names */
Oid *adtid; /* list of type ids */
Int2 *adtsize; /* list type sizes */
Int2 *display_size; /* the display size (longest row) */
Int4 *atttypmod; /* the length of bpchar/varchar */
struct ColumnInfoClass_ {
Int2 num_fields;
char **name; /* list of type names */
Oid *adtid; /* list of type ids */
Int2 *adtsize; /* list type sizes */
Int2 *display_size; /* the display size (longest row) */
Int4 *atttypmod; /* the length of bpchar/varchar */
};
#define CI_get_num_fields(self) (self->num_fields)
@ -30,15 +29,15 @@ struct ColumnInfoClass_
#define CI_get_atttypmod(self, col) (self->atttypmod[col])
ColumnInfoClass *CI_Constructor(void);
void CI_Destructor(ColumnInfoClass *self);
void CI_free_memory(ColumnInfoClass *self);
char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
void CI_Destructor(ColumnInfoClass *self);
void CI_free_memory(ColumnInfoClass *self);
char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
/* functions for setting up the fields from within the program, */
/* without reading from a socket */
void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields);
void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields);
void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/* File: connection.h
/* File: connection.h
*
* Description: See "connection.c"
* Description: See "connection.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -27,14 +27,11 @@
#endif
typedef enum
{
CONN_NOT_CONNECTED, /* Connection has not been established */
CONN_CONNECTED, /* Connection is up and has been
* established */
CONN_DOWN, /* Connection is broken */
CONN_EXECUTING /* the connection is currently executing a
* statement */
typedef enum {
CONN_NOT_CONNECTED, /* Connection has not been established */
CONN_CONNECTED, /* Connection is up and has been established */
CONN_DOWN, /* Connection is broken */
CONN_EXECUTING /* the connection is currently executing a statement */
} CONN_Status;
/* These errors have general sql error state */
@ -53,7 +50,7 @@ typedef enum
#define CONN_INIREAD_ERROR 201
#define CONN_OPENDB_ERROR 202
#define CONN_STMT_ALLOC_ERROR 203
#define CONN_IN_USE 204
#define CONN_IN_USE 204
#define CONN_UNSUPPORTED_OPTION 205
/* Used by SetConnectoption to indicate unsupported options */
#define CONN_INVALID_ARGUMENT_NO 206
@ -93,11 +90,11 @@ typedef enum
#define AUTH_REQ_CRYPT 4
/* Startup Packet sizes */
#define SM_DATABASE 64
#define SM_USER 32
#define SM_OPTIONS 64
#define SM_UNUSED 64
#define SM_TTY 64
#define SM_DATABASE 64
#define SM_USER 32
#define SM_OPTIONS 64
#define SM_UNUSED 64
#define SM_TTY 64
/* Old 6.2 protocol defines */
#define NO_AUTHENTICATION 7
@ -109,44 +106,63 @@ typedef unsigned int ProtocolVersion;
#define PG_PROTOCOL(major, minor) (((major) << 16) | (minor))
#define PG_PROTOCOL_LATEST PG_PROTOCOL(2, 0)
#define PG_PROTOCOL_63 PG_PROTOCOL(1, 0)
#define PG_PROTOCOL_62 PG_PROTOCOL(0, 0)
/* This startup packet is to support latest Postgres protocol */
/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */
typedef struct _StartupPacket
{
ProtocolVersion protoVersion;
char database[SM_DATABASE];
char user[SM_USER];
char options[SM_OPTIONS];
char unused[SM_UNUSED];
char tty[SM_TTY];
ProtocolVersion protoVersion;
char database[SM_DATABASE];
char user[SM_USER];
char options[SM_OPTIONS];
char unused[SM_UNUSED];
char tty[SM_TTY];
} StartupPacket;
/* This startup packet is to support pre-Postgres 6.3 protocol */
typedef struct _StartupPacket6_2
{
unsigned int authtype;
char database[PATH_SIZE];
char user[NAMEDATALEN];
char options[ARGV_SIZE];
char execfile[ARGV_SIZE];
char tty[PATH_SIZE];
} StartupPacket6_2;
/* Structure to hold all the connection attributes for a specific
connection (used for both registry and file, DSN and DRIVER)
*/
typedef struct
{
char dsn[MEDIUM_REGISTRY_LEN];
char desc[MEDIUM_REGISTRY_LEN];
char driver[MEDIUM_REGISTRY_LEN];
char server[MEDIUM_REGISTRY_LEN];
char database[MEDIUM_REGISTRY_LEN];
char username[MEDIUM_REGISTRY_LEN];
char password[MEDIUM_REGISTRY_LEN];
char conn_settings[LARGE_REGISTRY_LEN];
char protocol[SMALL_REGISTRY_LEN];
char port[SMALL_REGISTRY_LEN];
char onlyread[SMALL_REGISTRY_LEN];
char fake_oid_index[SMALL_REGISTRY_LEN];
char show_oid_column[SMALL_REGISTRY_LEN];
char row_versioning[SMALL_REGISTRY_LEN];
char show_system_tables[SMALL_REGISTRY_LEN];
char translation_dll[MEDIUM_REGISTRY_LEN];
char translation_option[SMALL_REGISTRY_LEN];
char focus_password;
typedef struct {
char dsn[MEDIUM_REGISTRY_LEN];
char desc[MEDIUM_REGISTRY_LEN];
char driver[MEDIUM_REGISTRY_LEN];
char server[MEDIUM_REGISTRY_LEN];
char database[MEDIUM_REGISTRY_LEN];
char username[MEDIUM_REGISTRY_LEN];
char password[MEDIUM_REGISTRY_LEN];
char conn_settings[LARGE_REGISTRY_LEN];
char protocol[SMALL_REGISTRY_LEN];
char port[SMALL_REGISTRY_LEN];
char onlyread[SMALL_REGISTRY_LEN];
char fake_oid_index[SMALL_REGISTRY_LEN];
char show_oid_column[SMALL_REGISTRY_LEN];
char row_versioning[SMALL_REGISTRY_LEN];
char show_system_tables[SMALL_REGISTRY_LEN];
char translation_dll[MEDIUM_REGISTRY_LEN];
char translation_option[SMALL_REGISTRY_LEN];
char focus_password;
} ConnInfo;
/* Macro to determine is the connection using 6.2 protocol? */
#define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0)
/* Macro to determine is the connection using 6.3 protocol? */
#define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0)
/*
* Macros to compare the server's version with a specified version
* 1st parameter: pointer to a ConnectionClass object
@ -164,15 +180,15 @@ typedef struct
#define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor))
#define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor))
/*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/
#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
#define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
/*#else
#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
#endif*/
/*
* Simplified macros to compare the server's version with a
* specified version
* Note: Never pass a variable as the second parameter.
* It must be a decimal constant of the form %d.%d .
* It must be a decimal constant of the form %d.%d .
*/
#define PG_VERSION_GT(conn, ver) \
(SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
@ -184,10 +200,9 @@ typedef struct
#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
/* This is used to store cached table information in the connection */
struct col_info
{
QResultClass *result;
char name[MAX_TABLE_LEN + 1];
struct col_info {
QResultClass *result;
char name[MAX_TABLE_LEN+1];
};
/* Translation DLL entry points */
@ -199,95 +214,89 @@ struct col_info
#define HINSTANCE void *
#endif
typedef BOOL (FAR WINAPI * DataSourceToDriverProc) (UDWORD,
SWORD,
PTR,
SDWORD,
PTR,
SDWORD,
SDWORD FAR *,
UCHAR FAR *,
SWORD,
SWORD FAR *);
typedef BOOL (FAR WINAPI *DataSourceToDriverProc) (UDWORD,
SWORD,
PTR,
SDWORD,
PTR,
SDWORD,
SDWORD FAR *,
UCHAR FAR *,
SWORD,
SWORD FAR *);
typedef BOOL (FAR WINAPI * DriverToDataSourceProc) (UDWORD,
SWORD,
PTR,
SDWORD,
PTR,
SDWORD,
SDWORD FAR *,
UCHAR FAR *,
SWORD,
SWORD FAR *);
typedef BOOL (FAR WINAPI *DriverToDataSourceProc) (UDWORD,
SWORD,
PTR,
SDWORD,
PTR,
SDWORD,
SDWORD FAR *,
UCHAR FAR *,
SWORD,
SWORD FAR *);
/******* The Connection handle ************/
struct ConnectionClass_
{
HENV henv; /* environment this connection was created
* on */
struct ConnectionClass_ {
HENV henv; /* environment this connection was created on */
StatementOptions stmtOptions;
char *errormsg;
int errornumber;
CONN_Status status;
ConnInfo connInfo;
StatementClass **stmts;
int num_stmts;
SocketClass *sock;
int lobj_type;
int ntables;
COL_INFO **col_info;
long translation_option;
HINSTANCE translation_handle;
DataSourceToDriverProc DataSourceToDriver;
DriverToDataSourceProc DriverToDataSource;
char transact_status;/* Is a transaction is currently in
* progress */
char errormsg_created; /* has an informative error msg
* been created? */
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL
* we're connected to -
* DJP 25-1-2001 */
float pg_version_number;
Int2 pg_version_major;
Int2 pg_version_minor;
char *errormsg;
int errornumber;
CONN_Status status;
ConnInfo connInfo;
StatementClass **stmts;
int num_stmts;
SocketClass *sock;
int lobj_type;
int ntables;
COL_INFO **col_info;
long translation_option;
HINSTANCE translation_handle;
DataSourceToDriverProc DataSourceToDriver;
DriverToDataSourceProc DriverToDataSource;
char transact_status; /* Is a transaction is currently in progress */
char errormsg_created; /* has an informative error msg been created? */
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */
float pg_version_number;
Int2 pg_version_major;
Int2 pg_version_minor;
};
/* Accessor functions */
#define CC_get_socket(x) (x->sock)
#define CC_get_database(x) (x->connInfo.database)
#define CC_get_server(x) (x->connInfo.server)
#define CC_get_DSN(x) (x->connInfo.dsn)
#define CC_get_username(x) (x->connInfo.username)
#define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1')
#define CC_get_socket(x) (x->sock)
#define CC_get_database(x) (x->connInfo.database)
#define CC_get_server(x) (x->connInfo.server)
#define CC_get_DSN(x) (x->connInfo.dsn)
#define CC_get_username(x) (x->connInfo.username)
#define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1')
/* for CC_DSN_info */
/* for CC_DSN_info */
#define CONN_DONT_OVERWRITE 0
#define CONN_OVERWRITE 1
#define CONN_OVERWRITE 1
/* prototypes */
ConnectionClass *CC_Constructor(void);
char CC_Destructor(ConnectionClass *self);
int CC_cursor_count(ConnectionClass *self);
char CC_cleanup(ConnectionClass *self);
char CC_abort(ConnectionClass *self);
int CC_set_translation(ConnectionClass *self);
char CC_connect(ConnectionClass *self, char do_password);
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
char CC_get_error(ConnectionClass *self, int *number, char **message);
char CC_Destructor(ConnectionClass *self);
int CC_cursor_count(ConnectionClass *self);
char CC_cleanup(ConnectionClass *self);
char CC_abort(ConnectionClass *self);
int CC_set_translation (ConnectionClass *self);
char CC_connect(ConnectionClass *self, char do_password);
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
char CC_get_error(ConnectionClass *self, int *number, char **message);
QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi);
void CC_clear_error(ConnectionClass *self);
char *CC_create_errormsg(ConnectionClass *self);
int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
char CC_send_settings(ConnectionClass *self);
void CC_lookup_lo(ConnectionClass *conn);
void CC_lookup_pg_version(ConnectionClass *conn);
void CC_initialize_pg_version(ConnectionClass *conn);
void CC_log_error(char *func, char *desc, ConnectionClass *self);
void CC_clear_error(ConnectionClass *self);
char *CC_create_errormsg(ConnectionClass *self);
int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
char CC_send_settings(ConnectionClass *self);
void CC_lookup_lo(ConnectionClass *conn);
void CC_lookup_pg_version(ConnectionClass *conn);
void CC_initialize_pg_version(ConnectionClass *conn);
void CC_log_error(char *func, char *desc, ConnectionClass *self);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/* File: convert.h
/* File: convert.h
*
* Description: See "convert.c"
* Description: See "convert.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -13,40 +13,39 @@
#include "psqlodbc.h"
/* copy_and_convert results */
#define COPY_OK 0
#define COPY_UNSUPPORTED_TYPE 1
#define COPY_OK 0
#define COPY_UNSUPPORTED_TYPE 1
#define COPY_UNSUPPORTED_CONVERSION 2
#define COPY_RESULT_TRUNCATED 3
#define COPY_GENERAL_ERROR 4
#define COPY_NO_DATA_FOUND 5
#define COPY_RESULT_TRUNCATED 3
#define COPY_GENERAL_ERROR 4
#define COPY_NO_DATA_FOUND 5
typedef struct
{
int m;
int d;
int y;
int hh;
int mm;
int ss;
typedef struct {
int m;
int d;
int y;
int hh;
int mm;
int ss;
} SIMPLE_TIME;
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
int copy_statement_with_parameters(StatementClass *stmt);
char *convert_escape(char *value);
char *convert_money(char *s);
char parse_datetime(char *buf, SIMPLE_TIME *st);
int convert_linefeeds(char *s, char *dst, size_t max);
char *convert_special_chars(char *si, char *dst, int used);
int copy_statement_with_parameters(StatementClass *stmt);
char *convert_escape(char *value);
char *convert_money(char *s);
char parse_datetime(char *buf, SIMPLE_TIME *st);
int convert_linefeeds(char *s, char *dst, size_t max);
char *convert_special_chars(char *si, char *dst, int used);
int convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax);
int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax);
int convert_to_pgbinary(unsigned char *in, char *out, int len);
void encode(char *in, char *out);
void decode(char *in, char *out);
int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
int convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax);
int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax);
int convert_to_pgbinary(unsigned char *in, char *out, int len);
void encode(char *in, char *out);
void decode(char *in, char *out);
int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
SDWORD cbValueMax, SDWORD *pcbValue);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/* File: dlg_specific.h
/* File: dlg_specific.h
*
* Description: See "dlg_specific.c"
* Description: See "dlg_specific.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -31,50 +31,41 @@
/* INI File Stuff */
#ifndef WIN32
#define ODBC_INI ".odbc.ini"
#ifdef ODBCINSTDIR
#define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini"
#else
#define ODBCINST_INI "/etc/odbcinst.ini"
#warning "location of odbcinst.ini file defaulted to /etc"
#endif
#else /* WIN32 */
#define ODBC_INI "ODBC.INI" /* ODBC initialization file */
#define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */
#endif /* WIN32 */
# define ODBC_INI ".odbc.ini"
# ifdef ODBCINSTDIR
# define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini"
# else
# define ODBCINST_INI "/etc/odbcinst.ini"
# warning "location of odbcinst.ini file defaulted to /etc"
# endif
#else /* WIN32 */
# define ODBC_INI "ODBC.INI" /* ODBC initialization file */
# define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */
#endif /* WIN32 */
#define INI_DSN DBMS_NAME /* Name of default Datasource in
* ini file (not used?) */
#define INI_KDESC "Description" /* Data source description */
#define INI_SERVER "Servername" /* Name of Server running
* the Postgres service */
#define INI_PORT "Port" /* Port on which the Postmaster is
* listening */
#define INI_DATABASE "Database" /* Database Name */
#define INI_USER "Username" /* Default User Name */
#define INI_PASSWORD "Password" /* Default Password */
#define INI_DEBUG "Debug" /* Debug flag */
#define INI_FETCH "Fetch" /* Fetch Max Count */
#define INI_SOCKET "Socket" /* Socket buffer size */
#define INI_READONLY "ReadOnly" /* Database is read only */
#define INI_COMMLOG "CommLog" /* Communication to backend
* logging */
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
#define INI_KSQO "Ksqo" /* Keyset query optimization */
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to
* backend on successful
* connection */
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique
* indexes */
#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown
* result set sizes */
#define INI_DSN DBMS_NAME /* Name of default Datasource in ini file (not used?) */
#define INI_KDESC "Description" /* Data source description */
#define INI_SERVER "Servername" /* Name of Server running the Postgres service */
#define INI_PORT "Port" /* Port on which the Postmaster is listening */
#define INI_DATABASE "Database" /* Database Name */
#define INI_USER "Username" /* Default User Name */
#define INI_PASSWORD "Password" /* Default Password */
#define INI_DEBUG "Debug" /* Debug flag */
#define INI_FETCH "Fetch" /* Fetch Max Count */
#define INI_SOCKET "Socket" /* Socket buffer size */
#define INI_READONLY "ReadOnly" /* Database is read only */
#define INI_COMMLOG "CommLog" /* Communication to backend logging */
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
#define INI_KSQO "Ksqo" /* Keyset query optimization */
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to backend on successful connection */
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */
#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown result set sizes */
#define INI_CANCELASFREESTMT "CancelAsFreeStmt"
#define INI_CANCELASFREESTMT "CancelAsFreeStmt"
#define INI_USEDECLAREFETCH "UseDeclareFetch" /* Use Declare/Fetch
* cursors */
#define INI_USEDECLAREFETCH "UseDeclareFetch" /* Use Declare/Fetch cursors */
/* More ini stuff */
#define INI_TEXTASLONGVARCHAR "TextAsLongVarchar"
@ -91,16 +82,15 @@
#define INI_PARSE "Parse"
#define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes"
#define INI_TRANSLATIONNAME "TranslationName"
#define INI_TRANSLATIONDLL "TranslationDLL"
#define INI_TRANSLATIONOPTION "TranslationOption"
#define INI_TRANSLATIONNAME "TranslationName"
#define INI_TRANSLATIONDLL "TranslationDLL"
#define INI_TRANSLATIONOPTION "TranslationOption"
/* Connection Defaults */
#define DEFAULT_PORT "5432"
#define DEFAULT_READONLY 1
#define DEFAULT_PROTOCOL "6.4" /* the latest protocol is
* the default */
#define DEFAULT_PROTOCOL "6.4" /* the latest protocol is the default */
#define DEFAULT_USEDECLAREFETCH 0
#define DEFAULT_TEXTASLONGVARCHAR 1
#define DEFAULT_UNKNOWNSASLONGVARCHAR 0
@ -124,30 +114,29 @@
#define DEFAULT_EXTRASYSTABLEPREFIXES "dd_;"
/* prototypes */
void getGlobalDefaults(char *section, char *filename, char override);
/* prototypes */
void getGlobalDefaults(char *section, char *filename, char override);
#ifdef WIN32
void SetDlgStuff(HWND hdlg, ConnInfo *ci);
void GetDlgStuff(HWND hdlg, ConnInfo *ci);
void SetDlgStuff(HWND hdlg, ConnInfo *ci);
void GetDlgStuff(HWND hdlg, ConnInfo *ci);
int CALLBACK driver_optionsProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam);
int CALLBACK ds_optionsProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam);
int CALLBACK driver_optionsProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam);
int CALLBACK ds_optionsProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam);
#endif /* WIN32 */
#endif /* WIN32 */
void updateGlobals(void);
void writeDSNinfo(ConnInfo *ci);
void getDSNdefaults(ConnInfo *ci);
void getDSNinfo(ConnInfo *ci, char overwrite);
void makeConnectString(char *connect_string, ConnInfo *ci);
void copyAttributes(ConnInfo *ci, char *attribute, char *value);
void updateGlobals(void);
void writeDSNinfo(ConnInfo *ci);
void getDSNdefaults(ConnInfo *ci);
void getDSNinfo(ConnInfo *ci, char overwrite);
void makeConnectString(char *connect_string, ConnInfo *ci);
void copyAttributes(ConnInfo *ci, char *attribute, char *value);
#endif

View File

@ -1,13 +1,14 @@
/* Module: drvconn.c
/* Module: drvconn.c
*
* Description: This module contains only routines related to
* implementing SQLDriverConnect.
* Description: This module contains only routines related to
* implementing SQLDriverConnect.
*
* Classes: n/a
* Classes: n/a
*
* API functions: SQLDriverConnect
* API functions: SQLDriverConnect
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -52,50 +53,45 @@
#include "dlg_specific.h"
/* prototypes */
void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
#ifdef WIN32
BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
#endif
extern GLOBAL_VALUES globals;
RETCODE SQL_API
SQLDriverConnect(
HDBC hdbc,
HWND hwnd,
UCHAR FAR *szConnStrIn,
SWORD cbConnStrIn,
UCHAR FAR *szConnStrOut,
SWORD cbConnStrOutMax,
SWORD FAR *pcbConnStrOut,
UWORD fDriverCompletion)
RETCODE SQL_API SQLDriverConnect(
HDBC hdbc,
HWND hwnd,
UCHAR FAR *szConnStrIn,
SWORD cbConnStrIn,
UCHAR FAR *szConnStrOut,
SWORD cbConnStrOutMax,
SWORD FAR *pcbConnStrOut,
UWORD fDriverCompletion)
{
static char *func = "SQLDriverConnect";
ConnectionClass *conn = (ConnectionClass *) hdbc;
ConnInfo *ci;
static char *func = "SQLDriverConnect";
ConnectionClass *conn = (ConnectionClass *) hdbc;
ConnInfo *ci;
#ifdef WIN32
RETCODE dialog_result;
RETCODE dialog_result;
#endif
RETCODE result;
char connStrIn[MAX_CONNECT_STRING];
char connStrOut[MAX_CONNECT_STRING];
int retval;
char password_required = FALSE;
int len = 0;
RETCODE result;
char connStrIn[MAX_CONNECT_STRING];
char connStrOut[MAX_CONNECT_STRING];
int retval;
char password_required = FALSE;
int len = 0;
mylog("%s: entering...\n", func);
if (!conn)
{
if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
@ -107,17 +103,17 @@ SQLDriverConnect(
ci = &(conn->connInfo);
/* Parse the connect string and fill in conninfo for this hdbc. */
/* Parse the connect string and fill in conninfo for this hdbc. */
dconn_get_connect_attributes(connStrIn, ci);
/* If the ConnInfo in the hdbc is missing anything, */
/* this function will fill them in from the registry (assuming */
/* of course there is a DSN given -- if not, it does nothing!) */
/* If the ConnInfo in the hdbc is missing anything, */
/* this function will fill them in from the registry (assuming */
/* of course there is a DSN given -- if not, it does nothing!) */
getDSNinfo(ci, CONN_DONT_OVERWRITE);
/* Fill in any default parameters if they are not there. */
/* Fill in any default parameters if they are not there. */
getDSNdefaults(ci);
/* initialize pg_version */
/* initialize pg_version */
CC_initialize_pg_version(conn);
#ifdef WIN32
@ -125,53 +121,51 @@ dialog:
#endif
ci->focus_password = password_required;
switch (fDriverCompletion)
{
switch(fDriverCompletion) {
#ifdef WIN32
case SQL_DRIVER_PROMPT:
case SQL_DRIVER_PROMPT:
dialog_result = dconn_DoDialog(hwnd, ci);
if(dialog_result != SQL_SUCCESS) {
return dialog_result;
}
break;
case SQL_DRIVER_COMPLETE_REQUIRED:
/* Fall through */
case SQL_DRIVER_COMPLETE:
/* Password is not a required parameter. */
if( ci->username[0] == '\0' ||
ci->server[0] == '\0' ||
ci->database[0] == '\0' ||
ci->port[0] == '\0' ||
password_required) {
dialog_result = dconn_DoDialog(hwnd, ci);
if (dialog_result != SQL_SUCCESS)
if(dialog_result != SQL_SUCCESS) {
return dialog_result;
break;
case SQL_DRIVER_COMPLETE_REQUIRED:
/* Fall through */
case SQL_DRIVER_COMPLETE:
/* Password is not a required parameter. */
if (ci->username[0] == '\0' ||
ci->server[0] == '\0' ||
ci->database[0] == '\0' ||
ci->port[0] == '\0' ||
password_required)
{
dialog_result = dconn_DoDialog(hwnd, ci);
if (dialog_result != SQL_SUCCESS)
return dialog_result;
}
break;
}
break;
#else
case SQL_DRIVER_PROMPT:
case SQL_DRIVER_COMPLETE:
case SQL_DRIVER_COMPLETE_REQUIRED:
case SQL_DRIVER_PROMPT:
case SQL_DRIVER_COMPLETE:
case SQL_DRIVER_COMPLETE_REQUIRED:
#endif
case SQL_DRIVER_NOPROMPT:
break;
case SQL_DRIVER_NOPROMPT:
break;
}
/*
* Password is not a required parameter unless authentication asks for
* it. For now, I think it's better to just let the application ask
* over and over until a password is entered (the user can always hit
* Cancel to get out)
*/
if (ci->username[0] == '\0' ||
/* Password is not a required parameter unless authentication asks for it.
For now, I think it's better to just let the application ask over and over until
a password is entered (the user can always hit Cancel to get out)
*/
if( ci->username[0] == '\0' ||
ci->server[0] == '\0' ||
ci->database[0] == '\0' ||
ci->port[0] == '\0')
{
ci->database[0] == '\0' ||
ci->port[0] == '\0') {
/* (password_required && ci->password[0] == '\0')) */
return SQL_NO_DATA_FOUND;
@ -180,16 +174,12 @@ dialog:
/* do the actual connect */
retval = CC_connect(conn, password_required);
if (retval < 0)
{ /* need a password */
if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
{
if (retval < 0) { /* need a password */
if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
return SQL_ERROR; /* need a password but not allowed to
* prompt so error */
return SQL_ERROR; /* need a password but not allowed to prompt so error */
}
else
{
else {
#ifdef WIN32
password_required = TRUE;
goto dialog;
@ -198,44 +188,39 @@ dialog:
#endif
}
}
else if (retval == 0)
{
/* error msg filled in above */
else if (retval == 0) {
/* error msg filled in above */
CC_log_error(func, "Error from CC_Connect", conn);
return SQL_ERROR;
}
/*********************************************/
/* Create the Output Connection String */
/* Create the Output Connection String */
/*********************************************/
result = SQL_SUCCESS;
makeConnectString(connStrOut, ci);
len = strlen(connStrOut);
if (szConnStrOut)
{
if(szConnStrOut) {
/*
* Return the completed string to the caller. The correct method
* is to only construct the connect string if a dialog was put up,
* otherwise, it should just copy the connection input string to
* the output. However, it seems ok to just always construct an
* output string. There are possible bad side effects on working
* applications (Access) by implementing the correct behavior,
* anyway.
*/
/* Return the completed string to the caller. The correct method is to
only construct the connect string if a dialog was put up, otherwise,
it should just copy the connection input string to the output.
However, it seems ok to just always construct an output string. There
are possible bad side effects on working applications (Access) by
implementing the correct behavior, anyway.
*/
strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
if (len >= cbConnStrOutMax)
{
if (len >= cbConnStrOutMax) {
result = SQL_SUCCESS_WITH_INFO;
conn->errornumber = CONN_TRUNCATED;
conn->errormsg = "The buffer was too small for the result.";
}
}
if (pcbConnStrOut)
if(pcbConnStrOut)
*pcbConnStrOut = len;
mylog("szConnStrOut = '%s'\n", szConnStrOut);
@ -247,117 +232,108 @@ dialog:
}
#ifdef WIN32
RETCODE
dconn_DoDialog(HWND hwnd, ConnInfo *ci)
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci)
{
int dialog_result;
int dialog_result;
mylog("dconn_DoDialog: ci = %u\n", ci);
mylog("dconn_DoDialog: ci = %u\n", ci);
if (hwnd)
{
if(hwnd) {
dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
if (!dialog_result || (dialog_result == -1))
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
if(!dialog_result || (dialog_result == -1)) {
return SQL_NO_DATA_FOUND;
else
} else {
return SQL_SUCCESS;
}
}
return SQL_ERROR;
}
BOOL FAR PASCAL
dconn_FDriverConnectProc(
HWND hdlg,
UINT wMsg,
WPARAM wParam,
LPARAM lParam)
BOOL FAR PASCAL dconn_FDriverConnectProc(
HWND hdlg,
UINT wMsg,
WPARAM wParam,
LPARAM lParam)
{
ConnInfo *ci;
ConnInfo *ci;
switch (wMsg)
{
case WM_INITDIALOG:
ci = (ConnInfo *) lParam;
switch (wMsg) {
case WM_INITDIALOG:
ci = (ConnInfo *) lParam;
/* Change the caption for the setup dialog */
SetWindowText(hdlg, "PostgreSQL Connection");
/* Change the caption for the setup dialog */
SetWindowText(hdlg, "PostgreSQL Connection");
SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
/* Hide the DSN and description fields */
ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
/* Hide the DSN and description fields */
ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
SetWindowLong(hdlg, DWL_USER, lParam); /* Save the ConnInfo for
* the "OK" */
SetWindowLong(hdlg, DWL_USER, lParam);/* Save the ConnInfo for the "OK" */
SetDlgStuff(hdlg, ci);
SetDlgStuff(hdlg, ci);
if (ci->database[0] == '\0')
; /* default focus */
else if (ci->server[0] == '\0')
SetFocus(GetDlgItem(hdlg, IDC_SERVER));
else if (ci->port[0] == '\0')
SetFocus(GetDlgItem(hdlg, IDC_PORT));
else if (ci->username[0] == '\0')
SetFocus(GetDlgItem(hdlg, IDC_USER));
else if (ci->focus_password)
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
if (ci->database[0] == '\0')
; /* default focus */
else if (ci->server[0] == '\0')
SetFocus(GetDlgItem(hdlg, IDC_SERVER));
else if (ci->port[0] == '\0')
SetFocus(GetDlgItem(hdlg, IDC_PORT));
else if (ci->username[0] == '\0')
SetFocus(GetDlgItem(hdlg, IDC_USER));
else if (ci->focus_password)
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
GetDlgStuff(hdlg, ci);
case IDCANCEL:
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
return TRUE;
case IDC_DRIVER:
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
case IDC_DATASOURCE:
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
hdlg, ds_optionsProc, (LPARAM) ci);
GetDlgStuff(hdlg, ci);
case IDCANCEL:
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
return TRUE;
case IDC_DRIVER:
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
break;
case IDC_DATASOURCE:
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
hdlg, ds_optionsProc, (LPARAM) ci);
break;
}
break;
}
}
return FALSE;
}
#endif /* WIN32 */
#endif /* WIN32 */
void
dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
{
char *our_connect_string;
char *pair,
*attribute,
*value,
*equals;
char *strtok_arg;
char *our_connect_string;
char *pair, *attribute, *value, *equals;
char *strtok_arg;
memset(ci, 0, sizeof(ConnInfo));
@ -366,31 +342,34 @@ dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
mylog("our_connect_string = '%s'\n", our_connect_string);
while (1)
{
while(1) {
pair = strtok(strtok_arg, ";");
if (strtok_arg)
if(strtok_arg) {
strtok_arg = 0;
if (!pair)
}
if(!pair) {
break;
}
equals = strchr(pair, '=');
if (!equals)
if ( ! equals)
continue;
*equals = '\0';
attribute = pair; /* ex. DSN */
value = equals + 1; /* ex. 'CEO co1' */
attribute = pair; /* ex. DSN */
value = equals + 1; /* ex. 'CEO co1' */
mylog("attribute = '%s', value = '%s'\n", attribute, value);
if (!attribute || !value)
continue;
if( !attribute || !value)
continue;
/* Copy the appropriate value to the conninfo */
/* Copy the appropriate value to the conninfo */
copyAttributes(ci, attribute, value);
}
free(our_connect_string);
}

View File

@ -1,14 +1,15 @@
/* Module: environ.c
/* Module: environ.c
*
* Description: This module contains routines related to
* the environment, such as storing connection handles,
* and returning errors.
* Description: This module contains routines related to
* the environment, such as storing connection handles,
* and returning errors.
*
* Classes: EnvironmentClass (Functions prefix: "EN_")
* Classes: EnvironmentClass (Functions prefix: "EN_")
*
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -22,35 +23,31 @@
ConnectionClass *conns[MAX_CONNECTIONS];
RETCODE SQL_API
SQLAllocEnv(HENV FAR *phenv)
RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv)
{
static char *func = "SQLAllocEnv";
static char *func = "SQLAllocEnv";
mylog("**** in SQLAllocEnv ** \n");
mylog("**** in SQLAllocEnv ** \n");
*phenv = (HENV) EN_Constructor();
if (!*phenv)
{
if ( ! *phenv) {
*phenv = SQL_NULL_HENV;
EN_log_error(func, "Error allocating environment", NULL);
return SQL_ERROR;
}
mylog("** exit SQLAllocEnv: phenv = %u **\n", *phenv);
return SQL_SUCCESS;
}
RETCODE SQL_API
SQLFreeEnv(HENV henv)
RETCODE SQL_API SQLFreeEnv(HENV henv)
{
static char *func = "SQLFreeEnv";
EnvironmentClass *env = (EnvironmentClass *) henv;
static char *func = "SQLFreeEnv";
EnvironmentClass *env = (EnvironmentClass *) henv;
mylog("**** in SQLFreeEnv: env = %u ** \n", env);
mylog("**** in SQLFreeEnv: env = %u ** \n", env);
if (env && EN_Destructor(env))
{
if (env && EN_Destructor(env)) {
mylog(" ok\n");
return SQL_SUCCESS;
}
@ -60,345 +57,321 @@ SQLFreeEnv(HENV henv)
return SQL_ERROR;
}
/* Returns the next SQL error information. */
/* Returns the next SQL error information. */
RETCODE SQL_API
SQLError(
HENV henv,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR *szSqlState,
SDWORD FAR *pfNativeError,
UCHAR FAR *szErrorMsg,
SWORD cbErrorMsgMax,
SWORD FAR *pcbErrorMsg)
RETCODE SQL_API SQLError(
HENV henv,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR *szSqlState,
SDWORD FAR *pfNativeError,
UCHAR FAR *szErrorMsg,
SWORD cbErrorMsgMax,
SWORD FAR *pcbErrorMsg)
{
char *msg;
int status;
char *msg;
int status;
mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u\n", henv, hdbc, hstmt);
if (SQL_NULL_HSTMT != hstmt)
{
/* CC: return an error of a hstmt */
StatementClass *stmt = (StatementClass *) hstmt;
if (SC_get_error(stmt, &status, &msg))
{
if (SQL_NULL_HSTMT != hstmt) {
/* CC: return an error of a hstmt */
StatementClass *stmt = (StatementClass *) hstmt;
if (SC_get_error(stmt, &status, &msg)) {
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL == msg)
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
if (NULL == msg) {
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD)strlen(msg);
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
if (NULL != pfNativeError)
*pfNativeError = status;
if (NULL != szSqlState)
switch (status) {
/* now determine the SQLSTATE to be returned */
case STMT_TRUNCATED:
strcpy(szSqlState, "01004");
/* data truncated */
break;
case STMT_INFO_ONLY:
strcpy(szSqlState, "00000");
/* just information that is returned, no error */
break;
case STMT_BAD_ERROR:
strcpy(szSqlState, "08S01");
/* communication link failure */
break;
case STMT_CREATE_TABLE_ERROR:
strcpy(szSqlState, "S0001");
/* table already exists */
break;
case STMT_STATUS_ERROR:
case STMT_SEQUENCE_ERROR:
strcpy(szSqlState, "S1010");
/* Function sequence error */
break;
case STMT_NO_MEMORY_ERROR:
strcpy(szSqlState, "S1001");
/* memory allocation failure */
break;
case STMT_COLNUM_ERROR:
strcpy(szSqlState, "S1002");
/* invalid column number */
break;
case STMT_NO_STMTSTRING:
strcpy(szSqlState, "S1001");
/* having no stmtstring is also a malloc problem */
break;
case STMT_ERROR_TAKEN_FROM_BACKEND:
strcpy(szSqlState, "S1000");
/* general error */
break;
case STMT_INTERNAL_ERROR:
strcpy(szSqlState, "S1000");
/* general error */
break;
case STMT_ROW_OUT_OF_RANGE:
strcpy(szSqlState, "S1107");
break;
return SQL_NO_DATA_FOUND;
}
if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD) strlen(msg);
case STMT_OPERATION_CANCELLED:
strcpy(szSqlState, "S1008");
break;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
case STMT_NOT_IMPLEMENTED_ERROR:
strcpy(szSqlState, "S1C00"); /* == 'driver not capable' */
break;
case STMT_OPTION_OUT_OF_RANGE_ERROR:
strcpy(szSqlState, "S1092");
break;
case STMT_BAD_PARAMETER_NUMBER_ERROR:
strcpy(szSqlState, "S1093");
break;
case STMT_INVALID_COLUMN_NUMBER_ERROR:
strcpy(szSqlState, "S1002");
break;
case STMT_RESTRICTED_DATA_TYPE_ERROR:
strcpy(szSqlState, "07006");
break;
case STMT_INVALID_CURSOR_STATE_ERROR:
strcpy(szSqlState, "24000");
break;
case STMT_OPTION_VALUE_CHANGED:
strcpy(szSqlState, "01S02");
break;
case STMT_INVALID_CURSOR_NAME:
strcpy(szSqlState, "34000");
break;
case STMT_NO_CURSOR_NAME:
strcpy(szSqlState, "S1015");
break;
case STMT_INVALID_ARGUMENT_NO:
strcpy(szSqlState, "S1009");
/* invalid argument value */
break;
case STMT_INVALID_CURSOR_POSITION:
strcpy(szSqlState, "S1109");
break;
case STMT_VALUE_OUT_OF_RANGE:
strcpy(szSqlState, "22003");
break;
if (NULL != pfNativeError)
*pfNativeError = status;
case STMT_OPERATION_INVALID:
strcpy(szSqlState, "S1011");
break;
if (NULL != szSqlState)
switch (status)
{
/* now determine the SQLSTATE to be returned */
case STMT_TRUNCATED:
strcpy(szSqlState, "01004");
/* data truncated */
break;
case STMT_INFO_ONLY:
strcpy(szSqlState, "00000");
/* just information that is returned, no error */
break;
case STMT_BAD_ERROR:
strcpy(szSqlState, "08S01");
/* communication link failure */
break;
case STMT_CREATE_TABLE_ERROR:
strcpy(szSqlState, "S0001");
/* table already exists */
break;
case STMT_STATUS_ERROR:
case STMT_SEQUENCE_ERROR:
strcpy(szSqlState, "S1010");
/* Function sequence error */
break;
case STMT_NO_MEMORY_ERROR:
strcpy(szSqlState, "S1001");
/* memory allocation failure */
break;
case STMT_COLNUM_ERROR:
strcpy(szSqlState, "S1002");
/* invalid column number */
break;
case STMT_NO_STMTSTRING:
strcpy(szSqlState, "S1001");
/* having no stmtstring is also a malloc problem */
break;
case STMT_ERROR_TAKEN_FROM_BACKEND:
strcpy(szSqlState, "S1000");
/* general error */
break;
case STMT_INTERNAL_ERROR:
strcpy(szSqlState, "S1000");
/* general error */
break;
case STMT_ROW_OUT_OF_RANGE:
strcpy(szSqlState, "S1107");
break;
case STMT_OPERATION_CANCELLED:
strcpy(szSqlState, "S1008");
break;
case STMT_NOT_IMPLEMENTED_ERROR:
strcpy(szSqlState, "S1C00"); /* == 'driver not
* capable' */
break;
case STMT_OPTION_OUT_OF_RANGE_ERROR:
strcpy(szSqlState, "S1092");
break;
case STMT_BAD_PARAMETER_NUMBER_ERROR:
strcpy(szSqlState, "S1093");
break;
case STMT_INVALID_COLUMN_NUMBER_ERROR:
strcpy(szSqlState, "S1002");
break;
case STMT_RESTRICTED_DATA_TYPE_ERROR:
strcpy(szSqlState, "07006");
break;
case STMT_INVALID_CURSOR_STATE_ERROR:
strcpy(szSqlState, "24000");
break;
case STMT_OPTION_VALUE_CHANGED:
strcpy(szSqlState, "01S02");
break;
case STMT_INVALID_CURSOR_NAME:
strcpy(szSqlState, "34000");
break;
case STMT_NO_CURSOR_NAME:
strcpy(szSqlState, "S1015");
break;
case STMT_INVALID_ARGUMENT_NO:
strcpy(szSqlState, "S1009");
/* invalid argument value */
break;
case STMT_INVALID_CURSOR_POSITION:
strcpy(szSqlState, "S1109");
break;
case STMT_VALUE_OUT_OF_RANGE:
strcpy(szSqlState, "22003");
break;
case STMT_OPERATION_INVALID:
strcpy(szSqlState, "S1011");
break;
case STMT_EXEC_ERROR:
default:
strcpy(szSqlState, "S1000");
/* also a general error */
break;
}
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
}
else
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
case STMT_EXEC_ERROR:
default:
strcpy(szSqlState, "S1000");
/* also a general error */
break;
}
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
} else {
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
mylog(" returning NO_DATA_FOUND\n");
return SQL_NO_DATA_FOUND;
}
return SQL_SUCCESS;
}
else if (SQL_NULL_HDBC != hdbc)
{
ConnectionClass *conn = (ConnectionClass *) hdbc;
return SQL_NO_DATA_FOUND;
}
return SQL_SUCCESS;
} else if (SQL_NULL_HDBC != hdbc) {
ConnectionClass *conn = (ConnectionClass *) hdbc;
mylog("calling CC_get_error\n");
if (CC_get_error(conn, &status, &msg))
{
if (CC_get_error(conn, &status, &msg)) {
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL == msg)
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
if (NULL == msg) {
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD)strlen(msg);
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
if (NULL != pfNativeError)
*pfNativeError = status;
if (NULL != szSqlState)
switch(status) {
case STMT_OPTION_VALUE_CHANGED:
case CONN_OPTION_VALUE_CHANGED:
strcpy(szSqlState, "01S02");
break;
case STMT_TRUNCATED:
case CONN_TRUNCATED:
strcpy(szSqlState, "01004");
/* data truncated */
break;
case CONN_INIREAD_ERROR:
strcpy(szSqlState, "IM002");
/* data source not found */
break;
case CONN_OPENDB_ERROR:
strcpy(szSqlState, "08001");
/* unable to connect to data source */
break;
case CONN_INVALID_AUTHENTICATION:
case CONN_AUTH_TYPE_UNSUPPORTED:
strcpy(szSqlState, "28000");
break;
case CONN_STMT_ALLOC_ERROR:
strcpy(szSqlState, "S1001");
/* memory allocation failure */
break;
case CONN_IN_USE:
strcpy(szSqlState, "S1000");
/* general error */
break;
case CONN_UNSUPPORTED_OPTION:
strcpy(szSqlState, "IM001");
/* driver does not support this function */
case CONN_INVALID_ARGUMENT_NO:
strcpy(szSqlState, "S1009");
/* invalid argument value */
break;
case CONN_TRANSACT_IN_PROGRES:
strcpy(szSqlState, "S1010");
/* when the user tries to switch commit mode in a transaction */
/* -> function sequence error */
break;
case CONN_NO_MEMORY_ERROR:
strcpy(szSqlState, "S1001");
break;
case CONN_NOT_IMPLEMENTED_ERROR:
case STMT_NOT_IMPLEMENTED_ERROR:
strcpy(szSqlState, "S1C00");
break;
return SQL_NO_DATA_FOUND;
}
case CONN_VALUE_OUT_OF_RANGE:
case STMT_VALUE_OUT_OF_RANGE:
strcpy(szSqlState, "22003");
break;
if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD) strlen(msg);
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
if (NULL != pfNativeError)
*pfNativeError = status;
if (NULL != szSqlState)
switch (status)
{
case STMT_OPTION_VALUE_CHANGED:
case CONN_OPTION_VALUE_CHANGED:
strcpy(szSqlState, "01S02");
break;
case STMT_TRUNCATED:
case CONN_TRUNCATED:
strcpy(szSqlState, "01004");
/* data truncated */
break;
case CONN_INIREAD_ERROR:
strcpy(szSqlState, "IM002");
/* data source not found */
break;
case CONN_OPENDB_ERROR:
strcpy(szSqlState, "08001");
/* unable to connect to data source */
break;
case CONN_INVALID_AUTHENTICATION:
case CONN_AUTH_TYPE_UNSUPPORTED:
strcpy(szSqlState, "28000");
break;
case CONN_STMT_ALLOC_ERROR:
strcpy(szSqlState, "S1001");
/* memory allocation failure */
break;
case CONN_IN_USE:
strcpy(szSqlState, "S1000");
/* general error */
break;
case CONN_UNSUPPORTED_OPTION:
strcpy(szSqlState, "IM001");
/* driver does not support this function */
case CONN_INVALID_ARGUMENT_NO:
strcpy(szSqlState, "S1009");
/* invalid argument value */
break;
case CONN_TRANSACT_IN_PROGRES:
strcpy(szSqlState, "S1010");
/*
* when the user tries to switch commit mode in a
* transaction
*/
/* -> function sequence error */
break;
case CONN_NO_MEMORY_ERROR:
strcpy(szSqlState, "S1001");
break;
case CONN_NOT_IMPLEMENTED_ERROR:
case STMT_NOT_IMPLEMENTED_ERROR:
strcpy(szSqlState, "S1C00");
break;
case CONN_VALUE_OUT_OF_RANGE:
case STMT_VALUE_OUT_OF_RANGE:
strcpy(szSqlState, "22003");
break;
default:
strcpy(szSqlState, "S1000");
/* general error */
break;
}
}
else
{
default:
strcpy(szSqlState, "S1000");
/* general error */
break;
}
} else {
mylog("CC_Get_error returned nothing.\n");
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
return SQL_SUCCESS;
}
else if (SQL_NULL_HENV != henv)
{
EnvironmentClass *env = (EnvironmentClass *) henv;
if (EN_get_error(env, &status, &msg))
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
return SQL_SUCCESS;
} else if (SQL_NULL_HENV != henv) {
EnvironmentClass *env = (EnvironmentClass *)henv;
if(EN_get_error(env, &status, &msg)) {
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL == msg)
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
if (NULL == msg) {
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
return SQL_NO_DATA_FOUND;
}
if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD) strlen(msg);
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
if (NULL != pfNativeError)
*pfNativeError = status;
if (NULL != pcbErrorMsg)
*pcbErrorMsg = (SWORD)strlen(msg);
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
if (NULL != pfNativeError)
*pfNativeError = status;
if(szSqlState) {
switch(status) {
case ENV_ALLOC_ERROR:
/* memory allocation failure */
strcpy(szSqlState, "S1001");
break;
default:
strcpy(szSqlState, "S1000");
/* general error */
break;
}
}
} else {
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
if (szSqlState)
{
switch (status)
{
case ENV_ALLOC_ERROR:
/* memory allocation failure */
strcpy(szSqlState, "S1001");
break;
default:
strcpy(szSqlState, "S1000");
/* general error */
break;
}
}
}
else
{
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
return SQL_SUCCESS;
}
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
return SQL_SUCCESS;
}
if (NULL != szSqlState)
strcpy(szSqlState, "00000");
if (NULL != pcbErrorMsg)
*pcbErrorMsg = 0;
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
szErrorMsg[0] = '\0';
return SQL_NO_DATA_FOUND;
}
@ -410,27 +383,25 @@ SQLError(
EnvironmentClass
*
EN_Constructor(void)
*EN_Constructor(void)
{
EnvironmentClass *rv;
EnvironmentClass *rv;
rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
if (rv)
{
rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
if( rv) {
rv->errormsg = 0;
rv->errornumber = 0;
}
return rv;
return rv;
}
char
EN_Destructor(EnvironmentClass *self)
{
int lf;
char rv = 1;
int lf;
char rv = 1;
mylog("in EN_Destructor, self=%u\n", self);
@ -438,8 +409,7 @@ EN_Destructor(EnvironmentClass *self)
/* the source--they should not be freed */
/* Free any connections belonging to this environment */
for (lf = 0; lf < MAX_CONNECTIONS; lf++)
{
for (lf = 0; lf < MAX_CONNECTIONS; lf++) {
if (conns[lf] && conns[lf]->henv == self)
rv = rv && CC_Destructor(conns[lf]);
}
@ -451,29 +421,26 @@ EN_Destructor(EnvironmentClass *self)
char
EN_get_error(EnvironmentClass *self, int *number, char **message)
{
if (self && self->errormsg && self->errornumber)
{
if(self && self->errormsg && self->errornumber) {
*message = self->errormsg;
*number = self->errornumber;
self->errormsg = 0;
self->errornumber = 0;
return 1;
}
else
} else {
return 0;
}
}
char
EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
{
int i;
int i;
mylog("EN_add_connection: self = %u, conn = %u\n", self, conn);
mylog("EN_add_connection: self = %u, conn = %u\n", self, conn);
for (i = 0; i < MAX_CONNECTIONS; i++)
{
if (!conns[i])
{
for (i = 0; i < MAX_CONNECTIONS; i++) {
if ( ! conns[i]) {
conn->henv = self;
conns[i] = conn;
@ -489,11 +456,10 @@ EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
char
EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
{
int i;
int i;
for (i = 0; i < MAX_CONNECTIONS; i++)
if (conns[i] == conn && conns[i]->status != CONN_EXECUTING)
{
if (conns[i] == conn && conns[i]->status != CONN_EXECUTING) {
conns[i] = NULL;
return TRUE;
}
@ -504,8 +470,9 @@ EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
void
EN_log_error(char *func, char *desc, EnvironmentClass *self)
{
if (self)
if (self) {
qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
}
else
qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
}

View File

@ -1,9 +1,9 @@
/* File: environ.h
/* File: environ.h
*
* Description: See "environ.c"
* Description: See "environ.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -29,18 +29,17 @@
#define ENV_ALLOC_ERROR 1
/********** Environment Handle *************/
struct EnvironmentClass_
{
char *errormsg;
int errornumber;
struct EnvironmentClass_ {
char *errormsg;
int errornumber;
};
/* Environment prototypes */
EnvironmentClass *EN_Constructor(void);
char EN_Destructor(EnvironmentClass *self);
char EN_get_error(EnvironmentClass *self, int *number, char **message);
char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
char EN_Destructor(EnvironmentClass *self);
char EN_get_error(EnvironmentClass *self, int *number, char **message);
char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
#ifndef WIN32
#if HAVE_CONFIG_H
#include "config.h" /* produced by configure */
#include "config.h" /* produced by configure */
#endif
#include <stdio.h>
@ -38,87 +38,83 @@
DWORD
GetPrivateProfileString(char *theSection, /* section name */
char *theKey, /* search key name */
char *theDefault, /* default value if not
* found */
char *theReturnBuffer, /* return value stored
* here */
size_t theReturnBufferLength, /* byte length of return
* buffer */
char *theIniFileName) /* pathname of ini file to
* search */
GetPrivateProfileString(char *theSection, /* section name */
char *theKey, /* search key name */
char *theDefault, /* default value if not found */
char *theReturnBuffer, /* return value stored here */
size_t theReturnBufferLength, /* byte length of return buffer */
char *theIniFileName) /* pathname of ini file to search */
{
char buf[MAXPGPATH];
char *ptr = 0;
FILE *aFile = 0;
size_t aLength;
char aLine[2048];
char *aValue;
char *aStart;
char *aString;
size_t aLineLength;
size_t aReturnLength = 0;
char buf[MAXPGPATH];
char* ptr = 0;
FILE* aFile = 0;
size_t aLength;
char aLine[2048];
char *aValue;
char *aStart;
char *aString;
size_t aLineLength;
size_t aReturnLength = 0;
BOOL aSectionFound = FALSE;
BOOL aKeyFound = FALSE;
int j = 0;
BOOL aSectionFound = FALSE;
BOOL aKeyFound = FALSE;
int j = 0;
j = strlen(theIniFileName) + 1;
ptr = (char *) getpwuid(getuid()); /* get user info */
ptr = (char*)getpwuid(getuid()); /* get user info */
if (ptr == NULL)
if( ptr == NULL)
{
if (MAXPGPATH - 1 < j)
theIniFileName[MAXPGPATH - 1] = '\0';
if( MAXPGPATH-1 < j )
theIniFileName[MAXPGPATH-1] = '\0';
sprintf(buf, "%s", theIniFileName);
sprintf(buf,"%s",theIniFileName);
}
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
if (ptr == NULL || *ptr == '\0')
ptr = ((struct passwd*)ptr)->pw_dir; /* get user home dir */
if( ptr == NULL || *ptr == '\0' )
ptr = "/home";
/*
* This doesn't make it so we find an ini file but allows normal
* processing to continue further on down. The likelihood is that the
* file won't be found and thus the default value will be returned.
*/
if (MAXPGPATH - 1 < strlen(ptr) + j)
/* This doesn't make it so we find an ini file but allows normal
* processing to continue further on down. The likelihood is that
* the file won't be found and thus the default value will be
* returned.
*/
if( MAXPGPATH-1 < strlen(ptr) + j )
{
if (MAXPGPATH - 1 < strlen(ptr))
ptr[MAXPGPATH - 1] = '\0';
if( MAXPGPATH-1 < strlen(ptr) )
ptr[MAXPGPATH-1] = '\0';
else
theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0';
theIniFileName[MAXPGPATH-1-strlen(ptr)] = '\0';
}
sprintf(buf, "%s/%s", ptr, theIniFileName);
sprintf( buf, "%s/%s",ptr,theIniFileName );
/*
* This code makes it so that a file in the users home dir overrides a
* the "default" file as passed in
*/
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
if (!aFile)
{
sprintf(buf, "%s", theIniFileName);
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
/* This code makes it so that a file in the users home dir
* overrides a the "default" file as passed in
*/
aFile = (FILE*)(buf ? fopen(buf, PG_BINARY_R) : NULL);
if(!aFile) {
sprintf(buf,"%s",theIniFileName);
aFile = (FILE*)(buf ? fopen(buf, PG_BINARY_R) : NULL);
}
aLength = (theDefault == NULL) ? 0 : strlen(theDefault);
if (theReturnBufferLength == 0 || theReturnBuffer == NULL)
if(theReturnBufferLength == 0 || theReturnBuffer == NULL)
{
if (aFile)
if(aFile)
{
fclose(aFile);
}
return 0;
}
if (aFile == NULL)
if(aFile == NULL)
{
/* no ini file specified, return the default */
++aLength; /* room for NULL char */
++aLength; /* room for NULL char */
aLength = theReturnBufferLength < aLength ?
theReturnBufferLength : aLength;
strncpy(theReturnBuffer, theDefault, aLength);
@ -127,77 +123,86 @@ GetPrivateProfileString(char *theSection, /* section name */
}
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
while(fgets(aLine, sizeof(aLine), aFile) != NULL)
{
aLineLength = strlen(aLine);
/* strip final '\n' */
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
aLine[aLineLength - 1] = '\0';
switch (*aLine)
if(aLineLength > 0 && aLine[aLineLength - 1] == '\n')
{
case ' ': /* blank line */
case ';': /* comment line */
aLine[aLineLength - 1] = '\0';
}
switch(*aLine)
{
case ' ': /* blank line */
case ';': /* comment line */
continue;
break;
break;
case '[': /* section marker */
case '[': /* section marker */
if ((aString = strchr(aLine, ']')))
if( (aString = strchr(aLine, ']')) )
{
aStart = aLine + 1;
aString--;
while (isspace((unsigned char) *aStart))
aStart++;
while (isspace((unsigned char) *aString))
aString--;
*(aString + 1) = '\0';
while (isspace((unsigned char) *aStart)) aStart++;
while (isspace((unsigned char) *aString)) aString--;
*(aString+1) = '\0';
/* accept as matched if NULL key or exact match */
if (!theSection || !strcmp(aStart, theSection))
if(!theSection || !strcmp(aStart, theSection))
{
aSectionFound = TRUE;
}
}
break;
break;
default:
/* try to match value keys if in proper section */
if (aSectionFound)
if(aSectionFound)
{
/* try to match requested key */
if ((aString = aValue = strchr(aLine, '=')))
if( (aString = aValue = strchr(aLine, '=')) )
{
*aValue = '\0';
++aValue;
/* strip leading blanks in value field */
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
while(*aValue == ' ' && aValue < aLine + sizeof(aLine))
{
*aValue++ = '\0';
if (aValue >= aLine + sizeof(aLine))
}
if(aValue >= aLine + sizeof(aLine))
{
aValue = "";
}
}
else
{
aValue = "";
}
aStart = aLine;
while (isspace((unsigned char) *aStart))
aStart++;
while (isspace((unsigned char) *aStart)) aStart++;
/* strip trailing blanks from key */
if (aString)
if(aString)
{
while (--aString >= aStart && *aString == ' ')
while(--aString >= aStart && *aString == ' ')
{
*aString = '\0';
}
}
/* see if key is matched */
if (theKey == NULL || !strcmp(theKey, aStart))
if(theKey == NULL || !strcmp(theKey, aStart))
{
/* matched -- first, terminate value part */
@ -208,7 +213,7 @@ GetPrivateProfileString(char *theSection, /* section name */
aString = aValue + aLength - 1;
while (--aString > aValue && *aString == ' ')
while(--aString > aValue && *aString == ' ')
{
*aString = '\0';
--aLength;
@ -216,7 +221,7 @@ GetPrivateProfileString(char *theSection, /* section name */
/* unquote value if quoted */
if (aLength >= 2 && aValue[0] == '"' &&
if(aLength >= 2 && aValue[0] == '"' &&
aValue[aLength - 1] == '"')
{
/* string quoted with double quotes */
@ -229,7 +234,7 @@ GetPrivateProfileString(char *theSection, /* section name */
{
/* single quotes allowed also... */
if (aLength >= 2 && aValue[0] == '\'' &&
if(aLength >= 2 && aValue[0] == '\'' &&
aValue[aLength - 1] == '\'')
{
aValue[aLength - 1] = '\0';
@ -241,23 +246,23 @@ GetPrivateProfileString(char *theSection, /* section name */
/* compute maximum length copyable */
aLineLength = (aLength <
theReturnBufferLength - aReturnLength) ? aLength :
theReturnBufferLength - aReturnLength) ? aLength :
theReturnBufferLength - aReturnLength;
/* do the copy to return buffer */
if (aLineLength)
if(aLineLength)
{
strncpy(&theReturnBuffer[aReturnLength],
aValue, aLineLength);
aValue, aLineLength);
aReturnLength += aLineLength;
if (aReturnLength < theReturnBufferLength)
if(aReturnLength < theReturnBufferLength)
{
theReturnBuffer[aReturnLength] = '\0';
++aReturnLength;
}
}
if (aFile)
if(aFile)
{
fclose(aFile);
aFile = NULL;
@ -267,16 +272,17 @@ GetPrivateProfileString(char *theSection, /* section name */
}
}
break;
break;
}
}
if (aFile)
if(aFile)
{
fclose(aFile);
}
if (!aKeyFound)
{ /* key wasn't found return default */
++aLength; /* room for NULL char */
if(!aKeyFound) { /* key wasn't found return default */
++aLength; /* room for NULL char */
aLength = theReturnBufferLength < aLength ?
theReturnBufferLength : aLength;
strncpy(theReturnBuffer, theDefault, aLength);
@ -287,11 +293,10 @@ GetPrivateProfileString(char *theSection, /* section name */
}
DWORD
WritePrivateProfileString(char *theSection, /* section name */
char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to
* write */
WritePrivateProfileString(char *theSection, /* section name */
char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to write */
{
return 0;
}
@ -302,74 +307,69 @@ WritePrivateProfileString(char *theSection, /* section name */
* I find out different.
*/
DWORD
WritePrivateProfileString(char *theSection, /* section name */
char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to
* write */
WritePrivateProfileString(char *theSection, /* section name */
char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to write */
{
char buf[MAXPGPATH];
char *ptr = 0;
FILE *aFile = 0;
size_t aLength;
char aLine[2048];
char *aValue;
char *aString;
size_t aLineLength;
size_t aReturnLength = 0;
char buf[MAXPGPATH];
char* ptr = 0;
FILE* aFile = 0;
size_t aLength;
char aLine[2048];
char *aValue;
char *aString;
size_t aLineLength;
size_t aReturnLength = 0;
BOOL aSectionFound = FALSE;
BOOL keyFound = FALSE;
int j = 0;
BOOL aSectionFound = FALSE;
BOOL keyFound = FALSE;
int j = 0;
/* If this isn't correct processing we'll change it later */
if (theSection == NULL || theKey == NULL || theBuffer == NULL ||
theIniFileName == NULL)
return 0;
if(theSection == NULL || theKey == NULL || theBuffer == NULL ||
theIniFileName == NULL) return 0;
aLength = strlen(theBuffer);
if (aLength == 0)
return 0;
if(aLength == 0) return 0;
j = strlen(theIniFileName) + 1;
ptr = (char *) getpwuid(getuid()); /* get user info */
ptr = (char*)getpwuid(getuid()); /* get user info */
if (ptr == NULL)
if( ptr == NULL)
{
if (MAXPGPATH - 1 < j)
theIniFileName[MAXPGPATH - 1] = '\0';
if( MAXPGPATH-1 < j )
theIniFileName[MAXPGPATH-1] = '\0';
sprintf(buf, "%s", theIniFileName);
sprintf(buf,"%s",theIniFileName);
}
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
if (ptr == NULL || *ptr == '\0')
ptr = ((struct passwd*)ptr)->pw_dir; /* get user home dir */
if( ptr == NULL || *ptr == '\0' )
ptr = "/home";
/* This doesn't make it so we find an ini file but allows normal */
/* processing to continue further on down. The likelihood is that */
/* processing to continue further on down. The likelihood is that */
/* the file won't be found and thus the default value will be */
/* returned. */
/* */
if (MAXPGPATH - 1 < strlen(ptr) + j)
if( MAXPGPATH-1 < strlen(ptr) + j )
{
if (MAXPGPATH - 1 < strlen(ptr))
ptr[MAXPGPATH - 1] = '\0';
if( MAXPGPATH-1 < strlen(ptr) )
ptr[MAXPGPATH-1] = '\0';
else
theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0';
theIniFileName[MAXPGPATH-1-strlen(ptr)] = '\0';
}
sprintf(buf, "%s/%s", ptr, theIniFileName);
sprintf( buf, "%s/%s",ptr,theIniFileName );
/* This code makes it so that a file in the users home dir */
/* overrides a the "default" file as passed in */
/* overrides a the "default" file as passed in */
/* */
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
if (!aFile)
{
sprintf(buf, "%s", theIniFileName);
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
if (!aFile)
return 0;
aFile = (FILE*)(buf ? fopen(buf, "r+") : NULL);
if(!aFile) {
sprintf(buf,"%s",theIniFileName);
aFile = (FILE*)(buf ? fopen(buf, "r+") : NULL);
if(!aFile) return 0;
}
@ -379,92 +379,104 @@ WritePrivateProfileString(char *theSection, /* section name */
/* exists we have to overwrite it. If it doesn't exist */
/* we just write a new line to the file. */
/* */
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
while(fgets(aLine, sizeof(aLine), aFile) != NULL)
{
aLineLength = strlen(aLine);
/* strip final '\n' */
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
aLine[aLineLength - 1] = '\0';
switch (*aLine)
if(aLineLength > 0 && aLine[aLineLength - 1] == '\n')
{
case ' ': /* blank line */
case ';': /* comment line */
aLine[aLineLength - 1] = '\0';
}
switch(*aLine)
{
case ' ': /* blank line */
case ';': /* comment line */
continue;
break;
break;
case '[': /* section marker */
case '[': /* section marker */
if ((aString = strchr(aLine, ']')))
if( (aString = strchr(aLine, ']')) )
{
*aString = '\0';
/* accept as matched if key exact match */
if (!strcmp(aLine + 1, theSection))
if(!strcmp(aLine + 1, theSection))
{
aSectionFound = TRUE;
}
}
break;
break;
default:
/* try to match value keys if in proper section */
if (aSectionFound)
if(aSectionFound)
{
/* try to match requested key */
if ((aString = aValue = strchr(aLine, '=')))
if( (aString = aValue = strchr(aLine, '=')) )
{
*aValue = '\0';
++aValue;
/* strip leading blanks in value field */
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
while(*aValue == ' ' && aValue < aLine + sizeof(aLine))
{
*aValue++ = '\0';
if (aValue >= aLine + sizeof(aLine))
}
if(aValue >= aLine + sizeof(aLine))
{
aValue = "";
}
}
else
{
aValue = "";
}
/* strip trailing blanks from key */
if (aString)
if(aString)
{
while (--aString >= aLine && *aString == ' ')
while(--aString >= aLine && *aString == ' ')
{
*aString = '\0';
}
}
/* see if key is matched */
if (!strcmp(theKey, aLine))
if(!strcmp(theKey, aLine))
{
keyFound = TRUE;
/* matched -- first, terminate value part */
/* overwrite current value */
fseek(aFile, -aLineLength, SEEK_CUR);
fseek(aFile,-aLineLength,SEEK_CUR);
/* overwrite key and value */
sprintf(aLine, "%s = %s\n", theKey, theBuffer);
fputs(aLine, aFile);
sprintf(aLine,"%s = %s\n",theKey,theBuffer);
fputs(aLine,aFile);
}
}
}
break;
}
break;
}
}
if (!keyFound)
{ /* theKey wasn't in file so */
if (aFile)
if(!keyFound) { /* theKey wasn't in file so */
if(aFile)
{
fclose(aFile);
}
return aReturnLength > 0 ? aReturnLength - 1 : 0;
}
#endif

View File

@ -13,30 +13,25 @@
#endif
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
DWORD GetPrivateProfileString(char *theSection, /* section name */
char *theKey, /* search key name */
char *theDefault, /* default value if not
* found */
char *theReturnBuffer, /* return valuse stored
* here */
size_t theBufferLength, /* byte length of return
* buffer */
char *theIniFileName); /* pathname of ini file
* to search */
DWORD
GetPrivateProfileString(char *theSection, /* section name */
char *theKey, /* search key name */
char *theDefault, /* default value if not found */
char *theReturnBuffer, /* return valuse stored here */
size_t theBufferLength, /* byte length of return buffer */
char *theIniFileName); /* pathname of ini file to search */
DWORD WritePrivateProfileString(char *theSection, /* section name */
char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName); /* pathname of ini file
* to write */
DWORD
WritePrivateProfileString(char *theSection, /* section name */
char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName); /* pathname of ini file to write */
#ifdef __cplusplus
}
#endif
#ifndef WIN32

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +1,66 @@
#ifndef _IODBC_H
#define _IODBC_H
#ifndef _IODBC_H
#define _IODBC_H
#if !defined(WIN32) && !defined(WIN32_SYSTEM)
#define _UNIX_
# if !defined(WIN32) && !defined(WIN32_SYSTEM)
# define _UNIX_
#include <stdlib.h>
#include <sys/types.h>
# include <stdlib.h>
# include <sys/types.h>
#define MEM_ALLOC(size) (malloc((size_t)(size)))
#define MEM_FREE(ptr) {if(ptr) free(ptr);}
# define MEM_ALLOC(size) (malloc((size_t)(size)))
# define MEM_FREE(ptr) {if(ptr) free(ptr);}
#define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
#define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
#define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
#define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
#define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
#define STRLEN(str) ((str)? strlen((char*)(str)):0)
# define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
# define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
# define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
# define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
# define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
# define STRLEN(str) ((str)? strlen((char*)(str)):0)
#define EXPORT
#define CALLBACK
#define FAR
# define EXPORT
# define CALLBACK
# define FAR
typedef signed short SSHOR;
typedef short WORD;
typedef long DWORD;
typedef signed short SSHOR;
typedef short WORD;
typedef long DWORD;
typedef WORD WPARAM;
typedef DWORD LPARAM;
typedef void *HWND;
typedef int BOOL;
typedef WORD WPARAM;
typedef DWORD LPARAM;
typedef void* HWND;
typedef int BOOL;
#endif /* _UNIX_ */
# endif /* _UNIX_ */
#if defined(WIN32) || defined(WIN32_SYSTEM)
# if defined(WIN32) || defined(WIN32_SYSTEM)
#include <windows.h>
#include <windowsx.h>
# include <windows.h>
# include <windowsx.h>
#ifdef _MSVC_
#define MEM_ALLOC(size) (fmalloc((size_t)(size)))
#define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
#define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s)))
#define STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
#define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
#define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
#endif
# ifdef _MSVC_
# define MEM_ALLOC(size) (fmalloc((size_t)(size)))
# define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
# define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s)))
# define STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
# define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
# define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
# endif
#ifdef _BORLAND_
#define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
#define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
#define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s)))
#define STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
#define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
#define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
#endif
# ifdef _BORLAND_
# define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
# define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
# define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s)))
# define STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
# define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
# define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
# endif
#endif /* WIN32 */
# endif /* WIN32 */
#define SYSERR (-1)
# define SYSERR (-1)
#ifndef NULL
#define NULL ((void FAR*)0UL)
#endif
# ifndef NULL
# define NULL ((void FAR*)0UL)
# endif
#endif

View File

@ -2,108 +2,108 @@
* include path to be used to create ODBC compliant applications.
*/
#ifndef _INTRINSIC_SQL_H
#define _INTRINSIC_SQL_H
# define _INTRINSIC_SQL_H
typedef unsigned char UCHAR;
typedef long int SDWORD;
typedef short int SWORD;
typedef unsigned long int UDWORD;
typedef unsigned short int UWORD;
typedef unsigned char UCHAR;
typedef long int SDWORD;
typedef short int SWORD;
typedef unsigned long int UDWORD;
typedef unsigned short int UWORD;
typedef void FAR *PTR;
typedef void FAR* PTR;
typedef void FAR *HENV;
typedef void FAR *HDBC;
typedef void FAR *HSTMT;
typedef void FAR* HENV;
typedef void FAR* HDBC;
typedef void FAR* HSTMT;
typedef signed short RETCODE;
typedef signed short RETCODE;
#ifdef WIN32
#define SQL_API __stdcall
#else
#define SQL_API EXPORT CALLBACK
#endif
# ifdef WIN32
# define SQL_API __stdcall
# else
# define SQL_API EXPORT CALLBACK
# endif
#define ODBCVER 0x0250
# define ODBCVER 0x0250
#define SQL_MAX_MESSAGE_LENGTH 512
#define SQL_MAX_DSN_LENGTH 32
# define SQL_MAX_MESSAGE_LENGTH 512
# define SQL_MAX_DSN_LENGTH 32
/* return code */
#define SQL_INVALID_HANDLE (-2)
#define SQL_ERROR (-1)
#define SQL_SUCCESS 0
#define SQL_SUCCESS_WITH_INFO 1
#define SQL_NO_DATA_FOUND 100
# define SQL_INVALID_HANDLE (-2)
# define SQL_ERROR (-1)
# define SQL_SUCCESS 0
# define SQL_SUCCESS_WITH_INFO 1
# define SQL_NO_DATA_FOUND 100
/* standard SQL datatypes (agree with ANSI type numbering) */
#define SQL_CHAR 1
#define SQL_NUMERIC 2
#define SQL_DECIMAL 3
#define SQL_INTEGER 4
#define SQL_SMALLINT 5
#define SQL_FLOAT 6
#define SQL_REAL 7
#define SQL_DOUBLE 8
#define SQL_VARCHAR 12
# define SQL_CHAR 1
# define SQL_NUMERIC 2
# define SQL_DECIMAL 3
# define SQL_INTEGER 4
# define SQL_SMALLINT 5
# define SQL_FLOAT 6
# define SQL_REAL 7
# define SQL_DOUBLE 8
# define SQL_VARCHAR 12
#define SQL_TYPE_MIN SQL_CHAR
#define SQL_TYPE_NUL 0
#define SQL_TYPE_MAX SQL_VARCHAR
# define SQL_TYPE_MIN SQL_CHAR
# define SQL_TYPE_NULL 0
# define SQL_TYPE_MAX SQL_VARCHAR
/* C to SQL datatype mapping */
#define SQL_C_CHAR SQL_CHAR
#define SQL_C_LONG SQL_INTEGER
#define SQL_C_SHORT SQL_SMALLINT
#define SQL_C_FLOAT SQL_REAL
#define SQL_C_DOUBLE SQL_DOUBLE
#define SQL_C_DEFAULT 99
# define SQL_C_CHAR SQL_CHAR
# define SQL_C_LONG SQL_INTEGER
# define SQL_C_SHORT SQL_SMALLINT
# define SQL_C_FLOAT SQL_REAL
# define SQL_C_DOUBLE SQL_DOUBLE
# define SQL_C_DEFAULT 99
#define SQL_NO_NULLS 0
#define SQL_NULLABLE 1
#define SQL_NULLABLE_UNKNOWN 2
# define SQL_NO_NULLS 0
# define SQL_NULLABLE 1
# define SQL_NULLABLE_UNKNOWN 2
/* some special length values */
#define SQL_NULL_DATA (-1)
#define SQL_DATA_AT_EXEC (-2)
#define SQL_NTS (-3)
# define SQL_NULL_DATA (-1)
# define SQL_DATA_AT_EXEC (-2)
# define SQL_NTS (-3)
/* SQLFreeStmt flag values */
#define SQL_CLOSE 0
#define SQL_DROP 1
#define SQL_UNBIND 2
#define SQL_RESET_PARAMS 3
# define SQL_CLOSE 0
# define SQL_DROP 1
# define SQL_UNBIND 2
# define SQL_RESET_PARAMS 3
/* SQLTransact flag values */
#define SQL_COMMIT 0
#define SQL_ROLLBACK 1
# define SQL_COMMIT 0
# define SQL_ROLLBACK 1
/* SQLColAttributes flag values */
#define SQL_COLUMN_COUNT 0
#define SQL_COLUMN_LABEL 18
#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
#define SQL_COLUMN_DRIVER_START 1000
# define SQL_COLUMN_COUNT 0
# define SQL_COLUMN_LABEL 18
# define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
# define SQL_COLUMN_DRIVER_START 1000
#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
# define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
/* Null handles */
#define SQL_NULL_HENV 0
#define SQL_NULL_HDBC 0
#define SQL_NULL_HSTMT 0
# define SQL_NULL_HENV 0
# define SQL_NULL_HDBC 0
# define SQL_NULL_HSTMT 0
/* All code below has been added to the original isql.h coming from iodbc */
typedef unsigned char BYTE;
typedef unsigned char BYTE;
/* More SQLColAttributes flag values */
#define SQL_COLUMN_NAME 1
#define SQL_COLUMN_TYPE 2
#define SQL_COLUMN_LENGTH 3
#define SQL_COLUMN_NAME 1
#define SQL_COLUMN_TYPE 2
#define SQL_COLUMN_LENGTH 3
#define SQL_COLUMN_PRECISION 4
#define SQL_COLUMN_SCALE 5
#define SQL_COLUMN_SCALE 5
#define SQL_COLUMN_DISPLAY_SIZE 6
#define SQL_COLUMN_NULLABLE 7
#define SQL_COLUMN_UNSIGNED 8
#define SQL_COLUMN_MONEY 9
#define SQL_COLUMN_NULLABLE 7
#define SQL_COLUMN_UNSIGNED 8
#define SQL_COLUMN_MONEY 9
#define SQL_COLUMN_UPDATABLE 10
#define SQL_COLUMN_AUTO_INCREMENT 11
#define SQL_COLUMN_CASE_SENSITIVE 12
@ -114,118 +114,124 @@ typedef unsigned char BYTE;
#define SQL_COLUMN_QUALIFIER_NAME 17
/* SQLColAttributes Searchable flags */
#define SQL_UNSEARCHABLE 0
#define SQL_LIKE_ONLY 1
#define SQL_ALL_EXCEPT_LIKE 2
#define SQL_SEARCHABLE 3
#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE
#define SQL_UNSEARCHABLE 0
#define SQL_LIKE_ONLY 1
#define SQL_ALL_EXCEPT_LIKE 2
#define SQL_SEARCHABLE 3
#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE
/* SQLColAttributes Updateable flags */
#define SQL_ATTR_READONLY 0
#define SQL_ATTR_WRITE 1
#define SQL_ATTR_READONLY 0
#define SQL_ATTR_WRITE 1
#define SQL_ATTR_READWRITE_UNKNOWN 2
/*
* function prototypes previously not contained in isql.h
* function prototypes previously not contained in isql.h
*/
#ifdef __cplusplus
extern "C"
extern "C"
{
#endif
RETCODE SQL_API SQLAllocConnect(HENV henv, HDBC FAR *phdbc);
RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv);
RETCODE SQL_API SQLAllocStmt(HDBC hdbc, HSTMT FAR *phstmt);
RETCODE SQL_API SQLBindCol(HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue);
RETCODE SQL_API SQLAllocConnect (HENV henv,
HDBC FAR * phdbc);
RETCODE SQL_API SQLAllocEnv (HENV FAR * phenv);
RETCODE SQL_API SQLAllocStmt (HDBC hdbc,
HSTMT FAR * phstmt);
RETCODE SQL_API SQLBindCol (HSTMT hstmt,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR * pcbValue);
RETCODE SQL_API SQLCancel(HSTMT hstmt);
RETCODE SQL_API SQLCancel (HSTMT hstmt);
RETCODE SQL_API SQLColAttributes(HSTMT hstmt,
UWORD icol,
UWORD fDescType,
PTR rgbDesc,
SWORD cbDescMax,
SWORD FAR *pcbDesc,
SDWORD FAR *pfDesc);
RETCODE SQL_API SQLColAttributes (HSTMT hstmt,
UWORD icol,
UWORD fDescType,
PTR rgbDesc,
SWORD cbDescMax,
SWORD FAR * pcbDesc,
SDWORD FAR * pfDesc);
RETCODE SQL_API SQLConnect(HDBC hdbc,
UCHAR FAR *szDSN,
SWORD cbDSN,
UCHAR FAR *szUID,
SWORD cbUID,
UCHAR FAR *szAuthStr,
SWORD cbAuthStr);
RETCODE SQL_API SQLConnect (HDBC hdbc,
UCHAR FAR * szDSN,
SWORD cbDSN,
UCHAR FAR * szUID,
SWORD cbUID,
UCHAR FAR * szAuthStr,
SWORD cbAuthStr);
RETCODE SQL_API SQLDescribeCol(HSTMT hstmt,
UWORD icol,
UCHAR FAR *szColName,
SWORD cbColNameMax,
SWORD FAR *pcbColName,
SWORD FAR *pfSqlType,
UDWORD FAR *pcbColDef,
SWORD FAR *pibScale,
SWORD FAR *pfNullable);
RETCODE SQL_API SQLDescribeCol (HSTMT hstmt,
UWORD icol,
UCHAR FAR * szColName,
SWORD cbColNameMax,
SWORD FAR * pcbColName,
SWORD FAR * pfSqlType,
UDWORD FAR * pcbColDef,
SWORD FAR * pibScale,
SWORD FAR * pfNullable);
RETCODE SQL_API SQLDisconnect(HDBC hdbc);
RETCODE SQL_API SQLDisconnect (HDBC hdbc);
RETCODE SQL_API SQLError(HENV henv,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR *szSqlState,
SDWORD FAR *pfNativeError,
UCHAR FAR *szErrorMsg,
SWORD cbErrorMsgMax,
SWORD FAR *pcbErrorMsg);
RETCODE SQL_API SQLError (HENV henv,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR * szSqlState,
SDWORD FAR * pfNativeError,
UCHAR FAR * szErrorMsg,
SWORD cbErrorMsgMax,
SWORD FAR * pcbErrorMsg);
RETCODE SQL_API SQLExecDirect(HSTMT hstmt,
UCHAR FAR *szSqlStr,
SDWORD cbSqlStr);
RETCODE SQL_API SQLExecDirect (HSTMT hstmt,
UCHAR FAR * szSqlStr,
SDWORD cbSqlStr);
RETCODE SQL_API SQLExecute(HSTMT hstmt);
RETCODE SQL_API SQLExecute (HSTMT hstmt);
RETCODE SQL_API SQLFetch(HSTMT hstmt);
RETCODE SQL_API SQLFetch (HSTMT hstmt);
RETCODE SQL_API SQLFreeConnect(HDBC hdbc);
RETCODE SQL_API SQLFreeConnect (HDBC hdbc);
RETCODE SQL_API SQLFreeEnv(HENV henv);
RETCODE SQL_API SQLFreeEnv (HENV henv);
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
UWORD fOption);
RETCODE SQL_API SQLFreeStmt (HSTMT hstmt,
UWORD fOption);
RETCODE SQL_API SQLGetCursorName(HSTMT hstmt,
UCHAR FAR *szCursor,
SWORD cbCursorMax,
SWORD FAR *pcbCursor);
RETCODE SQL_API SQLGetCursorName (HSTMT hstmt,
UCHAR FAR * szCursor,
SWORD cbCursorMax,
SWORD FAR * pcbCursor);
RETCODE SQL_API SQLNumResultCols(HSTMT hstmt, SWORD FAR *pccol);
RETCODE SQL_API SQLNumResultCols (HSTMT hstmt,
SWORD FAR * pccol);
RETCODE SQL_API SQLPrepare(HSTMT hstmt, UCHAR FAR *szSqlStr,
SDWORD cbSqlStr);
RETCODE SQL_API SQLPrepare (HSTMT hstmt,
UCHAR FAR * szSqlStr,
SDWORD cbSqlStr);
RETCODE SQL_API SQLRowCount(HSTMT hstmt, SDWORD FAR *pcrow);
RETCODE SQL_API SQLRowCount (HSTMT hstmt,
SDWORD FAR * pcrow);
RETCODE SQL_API SQLSetCursorName(HSTMT hstmt, UCHAR FAR *szCursor,
SWORD cbCursor);
RETCODE SQL_API SQLSetCursorName (HSTMT hstmt,
UCHAR FAR * szCursor,
SWORD cbCursor);
RETCODE SQL_API SQLTransact(HENV henv, HDBC hdbc,
UWORD fType);
RETCODE SQL_API SQLTransact (HENV henv,
HDBC hdbc,
UWORD fType);
RETCODE SQL_API SQLSetParam(HSTMT hstmt,
UWORD ipar,
SWORD fCType,
SWORD fSqlType,
UDWORD cbColDef,
SWORD ibScale,
PTR rgbValue,
SDWORD FAR *pcbValue);
RETCODE SQL_API SQLSetParam (HSTMT hstmt,
UWORD ipar,
SWORD fCType,
SWORD fSqlType,
UDWORD cbColDef,
SWORD ibScale,
PTR rgbValue,
SDWORD FAR * pcbValue);
#ifdef __cplusplus
}
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
/* Module: lobj.c
/* Module: lobj.c
*
* Description: This module contains routines related to manipulating
* large objects.
* Description: This module contains routines related to manipulating
* large objects.
*
* Classes: none
* Classes: none
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -18,16 +19,15 @@
Oid
lo_creat(ConnectionClass *conn, int mode)
{
LO_ARG argv[1];
int retval,
result_len;
LO_ARG argv[1];
int retval, result_len;
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = mode;
if (!CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1))
return 0; /* invalid oid */
if ( ! CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1))
return 0; /* invalid oid */
else
return retval;
@ -37,9 +37,9 @@ lo_creat(ConnectionClass *conn, int mode)
int
lo_open(ConnectionClass *conn, int lobjId, int mode)
{
int fd;
int result_len;
LO_ARG argv[2];
int fd;
int result_len;
LO_ARG argv[2];
argv[0].isint = 1;
@ -50,7 +50,7 @@ lo_open(ConnectionClass *conn, int lobjId, int mode)
argv[1].len = 4;
argv[1].u.integer = mode;
if (!CC_send_function(conn, LO_OPEN, &fd, &result_len, 1, argv, 2))
if ( ! CC_send_function(conn, LO_OPEN, &fd, &result_len, 1, argv, 2))
return -1;
if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0)
@ -59,31 +59,31 @@ lo_open(ConnectionClass *conn, int lobjId, int mode)
return fd;
}
int
int
lo_close(ConnectionClass *conn, int fd)
{
LO_ARG argv[1];
int retval,
result_len;
LO_ARG argv[1];
int retval, result_len;
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = fd;
if (!CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1))
if ( ! CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1))
return -1;
else
return retval;
}
int
lo_read(ConnectionClass *conn, int fd, char *buf, int len)
{
LO_ARG argv[2];
int result_len;
LO_ARG argv[2];
int result_len;
argv[0].isint = 1;
@ -94,7 +94,7 @@ lo_read(ConnectionClass *conn, int fd, char *buf, int len)
argv[1].len = 4;
argv[1].u.integer = len;
if (!CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2))
if ( ! CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2))
return -1;
else
@ -104,9 +104,8 @@ lo_read(ConnectionClass *conn, int fd, char *buf, int len)
int
lo_write(ConnectionClass *conn, int fd, char *buf, int len)
{
LO_ARG argv[2];
int retval,
result_len;
LO_ARG argv[2];
int retval, result_len;
if (len <= 0)
@ -120,7 +119,7 @@ lo_write(ConnectionClass *conn, int fd, char *buf, int len)
argv[1].len = len;
argv[1].u.ptr = (char *) buf;
if (!CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2))
if ( ! CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2))
return -1;
else
@ -130,9 +129,8 @@ lo_write(ConnectionClass *conn, int fd, char *buf, int len)
int
lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
{
LO_ARG argv[3];
int retval,
result_len;
LO_ARG argv[3];
int retval, result_len;
argv[0].isint = 1;
@ -147,7 +145,7 @@ lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
argv[2].len = 4;
argv[2].u.integer = whence;
if (!CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3))
if ( ! CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3))
return -1;
else
@ -157,37 +155,43 @@ lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
int
lo_tell(ConnectionClass *conn, int fd)
{
LO_ARG argv[1];
int retval,
result_len;
LO_ARG argv[1];
int retval, result_len;
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = fd;
if (!CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1))
if ( ! CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1))
return -1;
else
return retval;
}
int
int
lo_unlink(ConnectionClass *conn, Oid lobjId)
{
LO_ARG argv[1];
int retval,
result_len;
LO_ARG argv[1];
int retval, result_len;
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = lobjId;
if (!CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1))
if ( ! CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1))
return -1;
else
return retval;
}

View File

@ -1,9 +1,9 @@
/* File: lobj.h
/* File: lobj.h
*
* Description: See "lobj.c"
* Description: See "lobj.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -13,15 +13,14 @@
#include "psqlodbc.h"
struct lo_arg
{
int isint;
int len;
struct lo_arg {
int isint;
int len;
union
{
int integer;
char *ptr;
} u;
int integer;
char *ptr;
} u;
};
#define LO_CREAT 957
@ -36,13 +35,14 @@ struct lo_arg
#define INV_WRITE 0x00020000
#define INV_READ 0x00040000
Oid lo_creat(ConnectionClass *conn, int mode);
int lo_open(ConnectionClass *conn, int lobjId, int mode);
int lo_close(ConnectionClass *conn, int fd);
int lo_read(ConnectionClass *conn, int fd, char *buf, int len);
int lo_write(ConnectionClass *conn, int fd, char *buf, int len);
int lo_lseek(ConnectionClass *conn, int fd, int offset, int len);
int lo_tell(ConnectionClass *conn, int fd);
int lo_unlink(ConnectionClass *conn, Oid lobjId);
Oid lo_creat(ConnectionClass *conn, int mode);
int lo_open(ConnectionClass *conn, int lobjId, int mode);
int lo_close(ConnectionClass *conn, int fd);
int lo_read(ConnectionClass *conn, int fd, char *buf, int len);
int lo_write(ConnectionClass *conn, int fd, char *buf, int len);
int lo_lseek(ConnectionClass *conn, int fd, int offset, int len);
int lo_tell(ConnectionClass *conn, int fd);
int lo_unlink(ConnectionClass *conn, Oid lobjId);
#endif

View File

@ -1,13 +1,14 @@
/* Module: misc.c
/* Module: misc.c
*
* Description: This module contains miscellaneous routines
* such as for debugging/logging and string functions.
* Description: This module contains miscellaneous routines
* such as for debugging/logging and string functions.
*
* Classes: n/a
* Classes: n/a
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -24,54 +25,49 @@
#include <sys/types.h>
#include <unistd.h>
#else
#include <process.h> /* Byron: is this where Windows keeps def.
* of getpid ? */
#include <process.h> /* Byron: is this where Windows keeps def. of getpid ? */
#endif
extern GLOBAL_VALUES globals;
void generate_filename(char *, char *, char *);
void generate_filename(char*,char*,char*);
void
generate_filename(char *dirname, char *prefix, char *filename)
generate_filename(char* dirname,char* prefix,char* filename)
{
int pid = 0;
int pid = 0;
#ifndef WIN32
struct passwd *ptr = 0;
ptr = getpwuid(getuid());
#endif
pid = getpid();
if (dirname == 0 || filename == 0)
if(dirname == 0 || filename == 0)
return;
strcpy(filename, dirname);
strcat(filename, DIRSEPARATOR);
if (prefix != 0)
strcat(filename, prefix);
strcpy(filename,dirname);
strcat(filename,DIRSEPARATOR);
if(prefix != 0)
strcat(filename,prefix);
#ifndef WIN32
strcat(filename, ptr->pw_name);
strcat(filename,ptr->pw_name);
#endif
sprintf(filename, "%s%u%s", filename, pid, ".log");
sprintf(filename,"%s%u%s",filename,pid,".log");
return;
}
#ifdef MY_LOG
void
mylog(char *fmt,...)
mylog(char * fmt, ...)
{
va_list args;
char filebuf[80];
FILE *LOGFP = globals.mylogFP;
va_list args;
char filebuf[80];
FILE* LOGFP = globals.mylogFP;
if (globals.debug)
{
if ( globals.debug) {
va_start(args, fmt);
if (!LOGFP)
{
generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
if (! LOGFP) {
generate_filename(MYLOGDIR,MYLOGFILE,filebuf);
LOGFP = fopen(filebuf, PG_BINARY_W);
globals.mylogFP = LOGFP;
setbuf(LOGFP, NULL);
@ -83,26 +79,23 @@ mylog(char *fmt,...)
va_end(args);
}
}
#endif
#ifdef Q_LOG
void
qlog(char *fmt,...)
qlog(char * fmt, ...)
{
va_list args;
char filebuf[80];
FILE *LOGFP = globals.qlogFP;
va_list args;
char filebuf[80];
FILE* LOGFP = globals.qlogFP;
if (globals.commlog)
{
if ( globals.commlog) {
va_start(args, fmt);
if (!LOGFP)
{
generate_filename(QLOGDIR, QLOGFILE, filebuf);
if (! LOGFP) {
generate_filename(QLOGDIR,QLOGFILE,filebuf);
LOGFP = fopen(filebuf, PG_BINARY_W);
globals.qlogFP = LOGFP;
setbuf(LOGFP, NULL);
@ -114,10 +107,9 @@ qlog(char *fmt,...)
va_end(args);
}
}
#endif
/* Undefine these because windows.h will redefine and cause a warning */
/* Undefine these because windows.h will redefine and cause a warning */
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -144,8 +136,7 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
if (dst_len <= 0)
return STRCPY_FAIL;
if (src_len == SQL_NULL_DATA)
{
if (src_len == SQL_NULL_DATA) {
dst[0] = '\0';
return STRCPY_NULL;
}
@ -155,17 +146,14 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
if (src_len <= 0)
return STRCPY_FAIL;
else
{
if (src_len < dst_len)
{
else {
if (src_len < dst_len) {
memcpy(dst, src, src_len);
dst[src_len] = '\0';
}
else
{
memcpy(dst, src, dst_len - 1);
dst[dst_len - 1] = '\0'; /* truncated */
else {
memcpy(dst, src, dst_len-1);
dst[dst_len-1] = '\0'; /* truncated */
return STRCPY_TRUNCATED;
}
}
@ -177,28 +165,28 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
/* the destination string if src has len characters or more. */
/* instead, I want it to copy up to len-1 characters and always */
/* terminate the destination string. */
char *
strncpy_null(char *dst, const char *src, int len)
char *strncpy_null(char *dst, const char *src, int len)
{
int i;
int i;
if (NULL != dst)
{
/* Just in case, check for special lengths */
if (len == SQL_NULL_DATA)
{
if (NULL != dst) {
/* Just in case, check for special lengths */
if (len == SQL_NULL_DATA) {
dst[0] = '\0';
return NULL;
}
else if (len == SQL_NTS)
len = strlen(src) + 1;
for (i = 0; src[i] && i < len - 1; i++)
for(i = 0; src[i] && i < len - 1; i++) {
dst[i] = src[i];
}
if (len > 0)
if(len > 0) {
dst[i] = '\0';
}
}
return dst;
}
@ -209,24 +197,22 @@ strncpy_null(char *dst, const char *src, int len)
char *
make_string(char *s, int len, char *buf)
{
int length;
char *str;
int length;
char *str;
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
{
if(s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) {
length = (len > 0) ? len : strlen(s);
if (buf)
{
strncpy_null(buf, s, length + 1);
if (buf) {
strncpy_null(buf, s, length+1);
return buf;
}
str = malloc(length + 1);
if (!str)
if ( ! str)
return NULL;
strncpy_null(str, s, length + 1);
strncpy_null(str, s, length+1);
return str;
}
@ -240,11 +226,11 @@ make_string(char *s, int len, char *buf)
char *
my_strcat(char *buf, char *fmt, char *s, int len)
{
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
{
int length = (len > 0) ? len : strlen(s);
int pos = strlen(buf);
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) {
int length = (len > 0) ? len : strlen(s);
int pos = strlen(buf);
sprintf(&buf[pos], fmt, length, s);
return buf;
@ -252,26 +238,24 @@ my_strcat(char *buf, char *fmt, char *s, int len)
return NULL;
}
void
remove_newlines(char *string)
void remove_newlines(char *string)
{
unsigned int i;
for (i = 0; i < strlen(string); i++)
{
if ((string[i] == '\n') ||
(string[i] == '\r'))
for(i=0; i < strlen(string); i++) {
if((string[i] == '\n') ||
(string[i] == '\r')) {
string[i] = ' ';
}
}
}
char *
trim(char *s)
{
int i;
int i;
for (i = strlen(s) - 1; i >= 0; i--)
{
for (i = strlen(s) - 1; i >= 0; i--) {
if (s[i] == ' ')
s[i] = '\0';
else

View File

@ -1,9 +1,9 @@
/* File: misc.h
/* File: misc.h
*
* Description: See "misc.c"
* Description: See "misc.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -39,37 +39,35 @@
#ifdef MY_LOG
#define MYLOGFILE "mylog_"
#ifndef WIN32
#define MYLOGDIR "/tmp"
#define MYLOGFILE "mylog_"
#ifndef WIN32
#define MYLOGDIR "/tmp"
#else
#define MYLOGDIR "c:"
#endif
extern void mylog(char * fmt, ...);
#else
#define MYLOGDIR "c:"
#endif
extern void mylog(char *fmt,...);
#else
#ifndef WIN32
#define mylog(args...) /* GNU convention for variable arguments */
#else
#define mylog /* mylog */
#endif
#ifndef WIN32
#define mylog(args...) /* GNU convention for variable arguments */
#else
#define mylog /* mylog */
#endif
#endif
#ifdef Q_LOG
#define QLOGFILE "psqlodbc_"
#ifndef WIN32
#define QLOGDIR "/tmp"
#define QLOGFILE "psqlodbc_"
#ifndef WIN32
#define QLOGDIR "/tmp"
#else
#define QLOGDIR "c:"
#endif
extern void qlog(char * fmt, ...);
#else
#define QLOGDIR "c:"
#endif
extern void qlog(char *fmt,...);
#else
#ifndef WIN32
#define qlog(args...) /* GNU convention for variable arguments */
#else
#define qlog /* qlog */
#endif
#ifndef WIN32
#define qlog(args...) /* GNU convention for variable arguments */
#else
#define qlog /* qlog */
#endif
#endif
#ifndef WIN32
@ -79,21 +77,21 @@ extern void qlog(char *fmt,...);
#endif
#ifdef WIN32
#define PG_BINARY O_BINARY
#define PG_BINARY_R "rb"
#define PG_BINARY_W "wb"
#define PG_BINARY O_BINARY
#define PG_BINARY_R "rb"
#define PG_BINARY_W "wb"
#else
#define PG_BINARY 0
#define PG_BINARY_R "r"
#define PG_BINARY_W "w"
#define PG_BINARY 0
#define PG_BINARY_R "r"
#define PG_BINARY_W "w"
#endif
void remove_newlines(char *string);
char *strncpy_null(char *dst, const char *src, int len);
char *trim(char *string);
char *make_string(char *s, int len, char *buf);
char *my_strcat(char *buf, char *fmt, char *s, int len);
void remove_newlines(char *string);
char *strncpy_null(char *dst, const char *src, int len);
char *trim(char *string);
char *make_string(char *s, int len, char *buf);
char *my_strcat(char *buf, char *fmt, char *s, int len);
/* defines for return value of my_strcpy */
#define STRCPY_SUCCESS 1
@ -101,6 +99,6 @@ char *my_strcat(char *buf, char *fmt, char *s, int len);
#define STRCPY_TRUNCATED -1
#define STRCPY_NULL -2
int my_strcpy(char *dst, int dst_len, char *src, int src_len);
int my_strcpy(char *dst, int dst_len, char *src, int src_len);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/* File: pgtypes.h
/* File: pgtypes.h
*
* Description: See "pgtypes.c"
* Description: See "pgtypes.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -17,81 +17,82 @@
#if 0
#define PG_TYPE_LO ????/* waiting for permanent type */
#define PG_TYPE_LO ???? /* waiting for permanent type */
#endif
#define PG_TYPE_BOOL 16
#define PG_TYPE_BYTEA 17
#define PG_TYPE_CHAR 18
#define PG_TYPE_NAME 19
#define PG_TYPE_INT8 20
#define PG_TYPE_INT2 21
#define PG_TYPE_INT2VECTOR 22
#define PG_TYPE_INT4 23
#define PG_TYPE_REGPROC 24
#define PG_TYPE_TEXT 25
#define PG_TYPE_OID 26
#define PG_TYPE_TID 27
#define PG_TYPE_XID 28
#define PG_TYPE_CID 29
#define PG_TYPE_OIDVECTOR 30
#define PG_TYPE_SET 32
#define PG_TYPE_CHAR2 409
#define PG_TYPE_CHAR4 410
#define PG_TYPE_CHAR8 411
#define PG_TYPE_POINT 600
#define PG_TYPE_LSEG 601
#define PG_TYPE_PATH 602
#define PG_TYPE_BOX 603
#define PG_TYPE_POLYGON 604
#define PG_TYPE_FILENAME 605
#define PG_TYPE_FLOAT4 700
#define PG_TYPE_FLOAT8 701
#define PG_TYPE_ABSTIME 702
#define PG_TYPE_RELTIME 703
#define PG_TYPE_TINTERVAL 704
#define PG_TYPE_UNKNOWN 705
#define PG_TYPE_BOOL 16
#define PG_TYPE_BYTEA 17
#define PG_TYPE_CHAR 18
#define PG_TYPE_NAME 19
#define PG_TYPE_INT8 20
#define PG_TYPE_INT2 21
#define PG_TYPE_INT2VECTOR 22
#define PG_TYPE_INT4 23
#define PG_TYPE_REGPROC 24
#define PG_TYPE_TEXT 25
#define PG_TYPE_OID 26
#define PG_TYPE_TID 27
#define PG_TYPE_XID 28
#define PG_TYPE_CID 29
#define PG_TYPE_OIDVECTOR 30
#define PG_TYPE_SET 32
#define PG_TYPE_CHAR2 409
#define PG_TYPE_CHAR4 410
#define PG_TYPE_CHAR8 411
#define PG_TYPE_POINT 600
#define PG_TYPE_LSEG 601
#define PG_TYPE_PATH 602
#define PG_TYPE_BOX 603
#define PG_TYPE_POLYGON 604
#define PG_TYPE_FILENAME 605
#define PG_TYPE_FLOAT4 700
#define PG_TYPE_FLOAT8 701
#define PG_TYPE_ABSTIME 702
#define PG_TYPE_RELTIME 703
#define PG_TYPE_TINTERVAL 704
#define PG_TYPE_UNKNOWN 705
#define PG_TYPE_MONEY 790
#define PG_TYPE_OIDINT2 810
#define PG_TYPE_OIDINT4 910
#define PG_TYPE_OIDNAME 911
#define PG_TYPE_BPCHAR 1042
#define PG_TYPE_VARCHAR 1043
#define PG_TYPE_DATE 1082
#define PG_TYPE_TIME 1083
#define PG_TYPE_DATETIME 1184
#define PG_TYPE_TIMESTAMP 1296
#define PG_TYPE_NUMERIC 1700
#define PG_TYPE_OIDINT2 810
#define PG_TYPE_OIDINT4 910
#define PG_TYPE_OIDNAME 911
#define PG_TYPE_BPCHAR 1042
#define PG_TYPE_VARCHAR 1043
#define PG_TYPE_DATE 1082
#define PG_TYPE_TIME 1083
#define PG_TYPE_DATETIME 1184
#define PG_TYPE_TIMESTAMP 1296
#define PG_TYPE_NUMERIC 1700
/* extern Int4 pgtypes_defined[]; */
extern Int2 sqlTypes[];
/* Defines for pgtype_precision */
#define PG_STATIC -1
#define PG_STATIC -1
Int4 sqltype_to_pgtype(Int2 fSqlType);
Int4 sqltype_to_pgtype(Int2 fSqlType);
Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type);
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type);
char *pgtype_to_name(StatementClass *stmt, Int4 type);
Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type);
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type);
char *pgtype_to_name(StatementClass *stmt, Int4 type);
/* These functions can use static numbers or result sets(col parameter) */
Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col);
Int2 pgtype_radix(StatementClass *stmt, Int4 type);
Int2 pgtype_nullable(StatementClass *stmt, Int4 type);
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type);
Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type);
Int2 pgtype_money(StatementClass *stmt, Int4 type);
Int2 pgtype_searchable(StatementClass *stmt, Int4 type);
Int2 pgtype_unsigned(StatementClass *stmt, Int4 type);
char *pgtype_literal_prefix(StatementClass *stmt, Int4 type);
char *pgtype_literal_suffix(StatementClass *stmt, Int4 type);
char *pgtype_create_params(StatementClass *stmt, Int4 type);
Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col);
Int2 pgtype_radix(StatementClass *stmt, Int4 type);
Int2 pgtype_nullable(StatementClass *stmt, Int4 type);
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type);
Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type);
Int2 pgtype_money(StatementClass *stmt, Int4 type);
Int2 pgtype_searchable(StatementClass *stmt, Int4 type);
Int2 pgtype_unsigned(StatementClass *stmt, Int4 type);
char *pgtype_literal_prefix(StatementClass *stmt, Int4 type);
char *pgtype_literal_suffix(StatementClass *stmt, Int4 type);
char *pgtype_create_params(StatementClass *stmt, Int4 type);
Int2 sqltype_to_default_ctype(Int2 sqltype);
Int2 sqltype_to_default_ctype(Int2 sqltype);
#endif

View File

@ -1,14 +1,15 @@
/* Module: psqlodbc.c
/* Module: psqlodbc.c
*
* Description: This module contains the main entry point (DllMain) for the library.
* It also contains functions to get and set global variables for the
* driver in the registry.
* Description: This module contains the main entry point (DllMain) for the library.
* It also contains functions to get and set global variables for the
* driver in the registry.
*
* Classes: n/a
* Classes: n/a
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -35,59 +36,57 @@ GLOBAL_VALUES globals;
RETCODE SQL_API SQLDummyOrdinal(void);
#ifdef WIN32
HINSTANCE NEAR s_hModule; /* Saved module handle. */
HINSTANCE NEAR s_hModule; /* Saved module handle. */
/* This is where the Driver Manager attaches to this Driver */
BOOL WINAPI
DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
WORD wVersionRequested;
WSADATA wsaData;
WORD wVersionRequested;
WSADATA wsaData;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
s_hModule = hInst; /* Save for dialog boxes */
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
s_hModule = hInst; /* Save for dialog boxes */
/* Load the WinSock Library */
wVersionRequested = MAKEWORD(1, 1);
/* Load the WinSock Library */
wVersionRequested = MAKEWORD(1, 1);
if (WSAStartup(wVersionRequested, &wsaData))
return FALSE;
if ( WSAStartup(wVersionRequested, &wsaData))
return FALSE;
/* Verify that this is the minimum version of WinSock */
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return FALSE;
}
/* Verify that this is the minimum version of WinSock */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
break;
WSACleanup();
return FALSE;
}
case DLL_THREAD_ATTACH:
break;
getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
break;
WSACleanup();
case DLL_PROCESS_DETACH:
return TRUE;
WSACleanup();
case DLL_THREAD_DETACH:
break;
return TRUE;
default:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return TRUE;
UNREFERENCED_PARAMETER(lpReserved);
return TRUE;
UNREFERENCED_PARAMETER(lpReserved);
}
#else /* not WIN32 */
#else /* not WIN32 */
#ifndef TRUE
#define TRUE (BOOL)1
@ -98,7 +97,7 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
#ifdef __GNUC__
/* This function is called at library initialization time. */
/* This function is called at library initialization time. */
static BOOL
__attribute__((constructor))
@ -108,7 +107,7 @@ init(void)
return TRUE;
}
#else /* not __GNUC__ */
#else /* not __GNUC__ */
/* These two functions do shared library initialziation on UNIX, well at least
* on Linux. I don't know about other systems.
@ -126,9 +125,9 @@ _fini(void)
return TRUE;
}
#endif /* not __GNUC__ */
#endif /* not __GNUC__ */
#endif /* not WIN32 */
#endif /* not WIN32 */
/* This function is used to cause the Driver Manager to
call functions by number rather than name, which is faster.
@ -136,8 +135,8 @@ _fini(void)
Driver Manager do this. Also, the ordinal values of the
functions must match the value of fFunction in SQLGetFunctions()
*/
RETCODE SQL_API
SQLDummyOrdinal(void)
RETCODE SQL_API SQLDummyOrdinal(void)
{
return SQL_SUCCESS;
}

View File

@ -1,12 +1,12 @@
/* File: psqlodbc.h
/* File: psqlodbc.h
*
* Description: This file contains defines and declarations that are related to
* the entire driver.
* Description: This file contains defines and declarations that are related to
* the entire driver.
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
* $Id: psqlodbc.h,v 1.36 2001/02/11 13:53:42 momjian Exp $
* $Id: psqlodbc.h,v 1.37 2001/02/14 05:45:46 momjian Exp $
*/
#ifndef __PSQLODBC_H__
@ -16,7 +16,7 @@
#include "config.h"
#endif
#include <stdio.h> /* for FILE* pointers: see GLOBAL_VALUES */
#include <stdio.h> /* for FILE* pointers: see GLOBAL_VALUES */
#ifndef WIN32
#define Int4 long int
@ -25,7 +25,6 @@
#define UInt2 unsigned short
typedef float SFLOAT;
typedef double SDOUBLE;
#else
#define Int4 int
#define UInt4 unsigned int
@ -36,13 +35,13 @@ typedef double SDOUBLE;
typedef UInt4 Oid;
/* Driver stuff */
#define ODBCVER 0x0250
#define DRIVER_ODBC_VER "02.50"
#define ODBCVER 0x0250
#define DRIVER_ODBC_VER "02.50"
#define DRIVERNAME "PostgreSQL ODBC"
#define DBMS_NAME "PostgreSQL"
#define DRIVERNAME "PostgreSQL ODBC"
#define DBMS_NAME "PostgreSQL"
#define POSTGRESDRIVERVERSION "07.01.0003"
#define POSTGRESDRIVERVERSION "07.01.0002"
#ifdef WIN32
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
@ -52,53 +51,48 @@ typedef UInt4 Oid;
/* Limits */
#ifdef WIN32
#define BLCKSZ 4096
#define BLCKSZ 4096
#endif
#define MAX_MESSAGE_LEN 65536 /* This puts a limit on query size
* but I don't */
/* see an easy way round this - DJP 24-1-2001 */
#define MAX_CONNECT_STRING 4096
#define ERROR_MSG_LENGTH 4096
#define FETCH_MAX 100 /* default number of rows to cache
* for declare/fetch */
#define TUPLE_MALLOC_INC 100
#define SOCK_BUFFER_SIZE 4096 /* default socket buffer size */
#define MAX_CONNECTIONS 128 /* conns per environment
* (arbitrary) */
#define MAX_FIELDS 512
#define BYTELEN 8
#define VARHDRSZ sizeof(Int4)
#define MAX_MESSAGE_LEN 65536 /* This puts a limit on query size but I don't */
/* see an easy way round this - DJP 24-1-2001 */
#define MAX_CONNECT_STRING 4096
#define ERROR_MSG_LENGTH 4096
#define FETCH_MAX 100 /* default number of rows to cache for declare/fetch */
#define TUPLE_MALLOC_INC 100
#define SOCK_BUFFER_SIZE 4096 /* default socket buffer size */
#define MAX_CONNECTIONS 128 /* conns per environment (arbitrary) */
#define MAX_FIELDS 512
#define BYTELEN 8
#define VARHDRSZ sizeof(Int4)
#define MAX_TABLE_LEN 32
#define MAX_COLUMN_LEN 32
#define MAX_CURSOR_LEN 32
#define MAX_TABLE_LEN 32
#define MAX_COLUMN_LEN 32
#define MAX_CURSOR_LEN 32
/* Registry length limits */
#define LARGE_REGISTRY_LEN 4096 /* used for special cases */
#define MEDIUM_REGISTRY_LEN 256 /* normal size for
* user,database,etc. */
#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */
#define LARGE_REGISTRY_LEN 4096 /* used for special cases */
#define MEDIUM_REGISTRY_LEN 256 /* normal size for user,database,etc. */
#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */
/* These prefixes denote system tables */
#define POSTGRES_SYS_PREFIX "pg_"
#define KEYS_TABLE "dd_fkey"
#define POSTGRES_SYS_PREFIX "pg_"
#define KEYS_TABLE "dd_fkey"
/* Info limits */
#define MAX_INFO_STRING 128
#define MAX_KEYPARTS 20
#define MAX_KEYLEN 512 /* max key of the form
* "date+outlet+invoice" */
#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the
* Tuple Toaster */
#define MAX_STATEMENT_LEN 0 /* Unlimited statement size with
* 7.0 */
#define MAX_INFO_STRING 128
#define MAX_KEYPARTS 20
#define MAX_KEYLEN 512 /* max key of the form "date+outlet+invoice" */
#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the Tuple Toaster */
#define MAX_STATEMENT_LEN 0 /* Unlimited statement size with 7.0 */
/* Previously, numerous query strings were defined of length MAX_STATEMENT_LEN */
/* Now that's 0, lets use this instead. DJP 24-1-2001 */
#define STD_STATEMENT_LEN MAX_MESSAGE_LEN
#define STD_STATEMENT_LEN MAX_MESSAGE_LEN
#define PG62 "6.2" /* "Protocol" key setting to force Postgres 6.2 */
#define PG63 "6.3" /* "Protocol" key setting to force postgres 6.3 */
#define PG64 "6.4"
typedef struct ConnectionClass_ ConnectionClass;
@ -118,73 +112,60 @@ typedef struct lo_arg LO_ARG;
typedef struct GlobalValues_
{
int fetch_max;
int socket_buffersize;
int unknown_sizes;
int max_varchar_size;
int max_longvarchar_size;
char debug;
char commlog;
char disable_optimizer;
char ksqo;
char unique_index;
char onlyread; /* readonly is reserved on Digital C++
* compiler */
char use_declarefetch;
char text_as_longvarchar;
char unknowns_as_longvarchar;
char bools_as_char;
char lie;
char parse;
char cancel_as_freestmt;
char extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
char conn_settings[LARGE_REGISTRY_LEN];
int fetch_max;
int socket_buffersize;
int unknown_sizes;
int max_varchar_size;
int max_longvarchar_size;
char debug;
char commlog;
char disable_optimizer;
char ksqo;
char unique_index;
char onlyread; /* readonly is reserved on Digital C++ compiler */
char use_declarefetch;
char text_as_longvarchar;
char unknowns_as_longvarchar;
char bools_as_char;
char lie;
char parse;
char cancel_as_freestmt;
char extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
char conn_settings[LARGE_REGISTRY_LEN];
char protocol[SMALL_REGISTRY_LEN];
/*
* Protocol is not used anymore, but kept in case it is useful in the
* future. bjm 2001-02-10
*/
char protocol[SMALL_REGISTRY_LEN];
FILE *mylogFP;
FILE *qlogFP;
FILE* mylogFP;
FILE* qlogFP;
} GLOBAL_VALUES;
typedef struct StatementOptions_
{
int maxRows;
int maxLength;
int rowset_size;
int keyset_size;
int cursor_type;
int scroll_concurrency;
int retrieve_data;
int bind_size; /* size of each structure if using Row
* Binding */
int use_bookmarks;
typedef struct StatementOptions_ {
int maxRows;
int maxLength;
int rowset_size;
int keyset_size;
int cursor_type;
int scroll_concurrency;
int retrieve_data;
int bind_size; /* size of each structure if using Row Binding */
int use_bookmarks;
} StatementOptions;
/* Used to pass extra query info to send_query */
typedef struct QueryInfo_
{
int row_size;
QResultClass *result_in;
char *cursor;
typedef struct QueryInfo_ {
int row_size;
QResultClass *result_in;
char *cursor;
} QueryInfo;
#define PG_TYPE_LO -999 /* hack until permanent
* type available */
#define PG_TYPE_LO_NAME "lo"
#define OID_ATTNUM -2 /* the attnum in pg_index of the
* oid */
#define PG_TYPE_LO -999 /* hack until permanent type available */
#define PG_TYPE_LO_NAME "lo"
#define OID_ATTNUM -2 /* the attnum in pg_index of the oid */
/* sizes */
#define TEXT_FIELD_SIZE 8190 /* size of text fields
* (not including null
* term) */
#define NAME_FIELD_SIZE 32 /* size of name fields */
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not
* including null term) */
#define TEXT_FIELD_SIZE 8190 /* size of text fields (not including null term) */
#define NAME_FIELD_SIZE 32 /* size of name fields */
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not including null term) */
#define PG_NUMERIC_MAX_PRECISION 1000
#define PG_NUMERIC_MAX_SCALE 1000

View File

@ -133,7 +133,7 @@ BEGIN
PUSHBUTTON "Defaults",IDDEFAULTS,185,205,50,15
END
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 125
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 161
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced Options (DataSource)"
FONT 8, "MS Sans Serif"
@ -144,16 +144,23 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,130,10,85,10
CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,25,25,85,10
GROUPBOX "OID Options",IDC_STATIC,39,41,180,25
GROUPBOX "Protocol",IDC_STATIC,15,40,180,25
CONTROL "6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,25,
50,35,10
CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
75,50,26,10
CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
130,50,26,10
GROUPBOX "OID Options",IDC_STATIC,15,70,180,25
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,62,51,59,10
WS_GROUP | WS_TABSTOP,25,81,59,10
CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,151,51,51,10
RTEXT "Connect &Settings:",IDC_STATIC,11,73,35,25
EDITTEXT DS_CONNSETTINGS,49,73,200,20,ES_MULTILINE |
WS_GROUP | WS_TABSTOP,115,81,51,10
RTEXT "Connect &Settings:",IDC_STATIC,10,105,35,25
EDITTEXT DS_CONNSETTINGS,50,105,200,20,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,71,103,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,145,103,50,14
DEFPUSHBUTTON "OK",IDOK,71,135,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,146,135,50,14
END
@ -184,7 +191,7 @@ BEGIN
RIGHTMARGIN, 260
VERTGUIDE, 55
TOPMARGIN, 7
BOTTOMMARGIN, 118
BOTTOMMARGIN, 154
END
END
#endif // APSTUDIO_INVOKED
@ -197,8 +204,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 7,1,0,3
PRODUCTVERSION 7,1,0,3
FILEVERSION 7,1,0,2
PRODUCTVERSION 7,1,0,2
FILEFLAGSMASK 0x3L
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -216,14 +223,14 @@ BEGIN
VALUE "Comments", "PostgreSQL ODBC driver\0"
VALUE "CompanyName", "Insight Distribution Systems\0"
VALUE "FileDescription", "PostgreSQL Driver\0"
VALUE "FileVersion", " 07.01.0003\0"
VALUE "FileVersion", " 07.01.0002\0"
VALUE "InternalName", "psqlodbc\0"
VALUE "LegalCopyright", "\0"
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
VALUE "OriginalFilename", "psqlodbc.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
VALUE "ProductVersion", " 07.01.0003\0"
VALUE "ProductVersion", " 07.01.0002\0"
VALUE "SpecialBuild", "\0"
END
END

View File

@ -1,19 +1,20 @@
/* Module: qresult.c
/* Module: qresult.c
*
* Description: This module contains functions related to
* managing result information (i.e, fetching rows from the backend,
* managing the tuple cache, etc.) and retrieving it.
* Depending on the situation, a QResultClass will hold either data
* from the backend or a manually built result (see "qresult.h" to
* see which functions/macros are for manual or backend results.
* For manually built results, the QResultClass simply points to
* TupleList and ColumnInfo structures, which actually hold the data.
* Description: This module contains functions related to
* managing result information (i.e, fetching rows from the backend,
* managing the tuple cache, etc.) and retrieving it.
* Depending on the situation, a QResultClass will hold either data
* from the backend or a manually built result (see "qresult.h" to
* see which functions/macros are for manual or backend results.
* For manually built results, the QResultClass simply points to
* TupleList and ColumnInfo structures, which actually hold the data.
*
* Classes: QResultClass (Functions prefix: "QR_")
* Classes: QResultClass (Functions prefix: "QR_")
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -31,23 +32,23 @@
extern GLOBAL_VALUES globals;
/* Used for building a Manual Result only */
/* Used for building a Manual Result only */
/* All info functions call this function to create the manual result set. */
void
void
QR_set_num_fields(QResultClass *self, int new_num_fields)
{
mylog("in QR_set_num_fields\n");
CI_set_num_fields(self->fields, new_num_fields);
if (self->manual_tuples)
TL_Destructor(self->manual_tuples);
CI_set_num_fields(self->fields, new_num_fields);
if(self->manual_tuples)
TL_Destructor(self->manual_tuples);
self->manual_tuples = TL_Constructor(new_num_fields);
self->manual_tuples = TL_Constructor(new_num_fields);
mylog("exit QR_set_num_fields\n");
}
void
void
QR_set_position(QResultClass *self, int pos)
{
self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields);
@ -59,7 +60,7 @@ QR_set_cache_size(QResultClass *self, int cache_size)
self->cache_size = cache_size;
}
void
void
QR_set_rowset_size(QResultClass *self, int rowset_size)
{
self->rowset_size = rowset_size;
@ -72,29 +73,27 @@ QR_inc_base(QResultClass *self, int base_inc)
}
/************************************/
/* CLASS QResult */
/* CLASS QResult */
/************************************/
QResultClass *
QR_Constructor(void)
{
QResultClass *rv;
QResultClass *rv;
mylog("in QR_Constructor\n");
rv = (QResultClass *) malloc(sizeof(QResultClass));
if (rv != NULL)
{
if (rv != NULL) {
rv->status = PGRES_EMPTY_QUERY;
/* construct the column info */
if (!(rv->fields = CI_Constructor()))
{
if ( ! (rv->fields = CI_Constructor())) {
free(rv);
return NULL;
}
rv->manual_tuples = NULL;
rv->backend_tuples = NULL;
rv->manual_tuples = NULL;
rv->backend_tuples = NULL;
rv->message = NULL;
rv->command = NULL;
rv->notice = NULL;
@ -110,6 +109,7 @@ QR_Constructor(void)
rv->cache_size = globals.fetch_max;
rv->rowset_size = 1;
}
mylog("exit QR_Constructor\n");
@ -125,32 +125,33 @@ QR_Destructor(QResultClass *self)
if (self->manual_tuples)
TL_Destructor(self->manual_tuples);
/* If conn is defined, then we may have used "backend_tuples", */
/* so in case we need to, free it up. Also, close the cursor. */
/* If conn is defined, then we may have used "backend_tuples", */
/* so in case we need to, free it up. Also, close the cursor. */
if (self->conn && self->conn->sock && CC_is_in_trans(self->conn))
QR_close(self); /* close the cursor if there is one */
QR_free_memory(self); /* safe to call anyway */
QR_free_memory(self); /* safe to call anyway */
/* Should have been freed in the close() but just in case... */
/* Should have been freed in the close() but just in case... */
if (self->cursor)
free(self->cursor);
/* Free up column info */
/* Free up column info */
if (self->fields)
CI_Destructor(self->fields);
/* Free command info (this is from strdup()) */
/* Free command info (this is from strdup()) */
if (self->command)
free(self->command);
/* Free notice info (this is from strdup()) */
/* Free notice info (this is from strdup()) */
if (self->notice)
free(self->notice);
free(self);
mylog("QResult: exit DESTRUCTOR\n");
}
void
@ -162,7 +163,7 @@ QR_set_command(QResultClass *self, char *msg)
self->command = msg ? strdup(msg) : NULL;
}
void
void
QR_set_notice(QResultClass *self, char *msg)
{
if (self->notice)
@ -171,31 +172,27 @@ QR_set_notice(QResultClass *self, char *msg)
self->notice = msg ? strdup(msg) : NULL;
}
void
void
QR_free_memory(QResultClass *self)
{
register int lf,
row;
register TupleField *tuple = self->backend_tuples;
int fcount = self->fcount;
int num_fields = self->num_fields;
register int lf, row;
register TupleField *tuple = self->backend_tuples;
int fcount = self->fcount;
int num_fields = self->num_fields;
mylog("QResult: free memory in, fcount=%d\n", fcount);
if (self->backend_tuples)
{
for (row = 0; row < fcount; row++)
{
if ( self->backend_tuples) {
for (row = 0; row < fcount; row++) {
mylog("row = %d, num_fields = %d\n", row, num_fields);
for (lf = 0; lf < num_fields; lf++)
{
if (tuple[lf].value != NULL)
{
for (lf=0; lf < num_fields; lf++) {
if (tuple[lf].value != NULL) {
mylog("free [lf=%d] %u\n", lf, tuple[lf].value);
free(tuple[lf].value);
}
}
tuple += num_fields;/* next row */
tuple += num_fields; /* next row */
}
free(self->backend_tuples);
@ -211,42 +208,37 @@ QR_free_memory(QResultClass *self)
char
QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
{
int tuple_size;
int tuple_size;
/* If called from send_query the first time (conn != NULL), */
/* then set the inTuples state, */
/* and read the tuples. If conn is NULL, */
/* it implies that we are being called from next_tuple(), */
/* like to get more rows so don't call next_tuple again! */
if (conn != NULL)
{
/* If called from send_query the first time (conn != NULL), */
/* then set the inTuples state, */
/* and read the tuples. If conn is NULL, */
/* it implies that we are being called from next_tuple(), */
/* like to get more rows so don't call next_tuple again! */
if (conn != NULL) {
self->conn = conn;
mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor == NULL) ? "" : cursor, self->cursor);
mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor==NULL)?"":cursor, self->cursor);
if (self->cursor)
free(self->cursor);
if (globals.use_declarefetch)
{
if (!cursor || cursor[0] == '\0')
{
if ( globals.use_declarefetch) {
if (! cursor || cursor[0] == '\0') {
self->status = PGRES_INTERNAL_ERROR;
QR_set_message(self, "Internal Error -- no cursor for fetch");
return FALSE;
}
self->cursor = strdup(cursor);
}
/* Read the field attributes. */
/* $$$$ Should do some error control HERE! $$$$ */
if (CI_read_fields(self->fields, self->conn))
{
/* Read the field attributes. */
/* $$$$ Should do some error control HERE! $$$$ */
if ( CI_read_fields(self->fields, self->conn)) {
self->status = PGRES_FIELDS_OK;
self->num_fields = CI_get_num_fields(self->fields);
}
else
{
else {
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Error reading field information");
return FALSE;
@ -254,7 +246,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields);
if (globals.use_declarefetch)
if (globals.use_declarefetch)
tuple_size = self->cache_size;
else
tuple_size = TUPLE_MALLOC_INC;
@ -262,9 +254,8 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
/* allocate memory for the tuple cache */
mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);
if (!self->backend_tuples)
{
self->status = PGRES_FATAL_ERROR;
if ( ! self->backend_tuples) {
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Could not get memory for tuple cache.");
return FALSE;
}
@ -272,20 +263,19 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
self->inTuples = TRUE;
/* Force a read to occur in next_tuple */
self->fcount = tuple_size + 1;
self->fetch_count = tuple_size + 1;
/* Force a read to occur in next_tuple */
self->fcount = tuple_size+1;
self->fetch_count = tuple_size+1;
self->base = 0;
return QR_next_tuple(self);
}
else
{
/* Always have to read the field attributes. */
/* But we dont have to reallocate memory for them! */
else {
if (!CI_read_fields(NULL, self->conn))
{
/* Always have to read the field attributes. */
/* But we dont have to reallocate memory for them! */
if ( ! CI_read_fields(NULL, self->conn)) {
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Error reading field information");
return FALSE;
@ -299,11 +289,10 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
int
QR_close(QResultClass *self)
{
QResultClass *res;
QResultClass *res;
if (globals.use_declarefetch && self->conn && self->cursor)
{
char buf[64];
if (globals.use_declarefetch && self->conn && self->cursor) {
char buf[64];
sprintf(buf, "close %s", self->cursor);
mylog("QResult: closing cursor: '%s'\n", buf);
@ -316,29 +305,27 @@ QR_close(QResultClass *self)
free(self->cursor);
self->cursor = NULL;
if (res == NULL)
{
if (res == NULL) {
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Error closing cursor.");
return FALSE;
}
/* End the transaction if there are no cursors left on this conn */
if (CC_cursor_count(self->conn) == 0)
{
/* End the transaction if there are no cursors left on this conn */
if (CC_cursor_count(self->conn) == 0) {
mylog("QResult: END transaction on conn=%u\n", self->conn);
res = CC_send_query(self->conn, "END", NULL);
CC_set_no_trans(self->conn);
if (res == NULL)
{
if (res == NULL) {
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Error ending transaction.");
return FALSE;
}
}
}
return TRUE;
@ -348,64 +335,54 @@ QR_close(QResultClass *self)
int
QR_next_tuple(QResultClass *self)
{
int id;
QResultClass *res;
SocketClass *sock;
int id;
QResultClass *res;
SocketClass *sock;
/* Speed up access */
int fetch_count = self->fetch_count;
int fcount = self->fcount;
int fetch_size,
offset = 0;
int end_tuple = self->rowset_size + self->base;
char corrected = FALSE;
TupleField *the_tuples = self->backend_tuples;
static char msgbuffer[MAX_MESSAGE_LEN + 1];
char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups
* this string so dont
* need static */
char fetch[128];
QueryInfo qi;
int fetch_count = self->fetch_count;
int fcount = self->fcount;
int fetch_size, offset= 0;
int end_tuple = self->rowset_size + self->base;
char corrected = FALSE;
TupleField *the_tuples = self->backend_tuples;
static char msgbuffer[MAX_MESSAGE_LEN+1];
char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont need static */
char fetch[128];
QueryInfo qi;
if (fetch_count < fcount)
{ /* return a row from cache */
if (fetch_count < fcount) { /* return a row from cache */
mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, fcount);
self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
self->fetch_count++;
return TRUE;
}
else if (self->fcount < self->cache_size)
{ /* last row from cache */
/* We are done because we didn't even get CACHE_SIZE tuples */
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
self->tupleField = NULL;
self->status = PGRES_END_TUPLES;
return -1; /* end of tuples */
else if (self->fcount < self->cache_size) { /* last row from cache */
/* We are done because we didn't even get CACHE_SIZE tuples */
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
self->tupleField = NULL;
self->status = PGRES_END_TUPLES;
return -1; /* end of tuples */
}
else
{
/*
* See if we need to fetch another group of rows. We may be being
* called from send_query(), and if so, don't send another fetch,
* just fall through and read the tuples.
*/
else {
/* See if we need to fetch another group of rows.
We may be being called from send_query(), and
if so, don't send another fetch, just fall through
and read the tuples.
*/
self->tupleField = NULL;
if (!self->inTuples)
{
if (!globals.use_declarefetch)
{
if ( ! self->inTuples) {
if ( ! globals.use_declarefetch) {
mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count);
self->tupleField = NULL;
self->status = PGRES_END_TUPLES;
return -1; /* end of tuples */
return -1; /* end of tuples */
}
if (self->base == fcount)
{ /* not a correction */
if (self->base == fcount) { /* not a correction */
/* Determine the optimum cache size. */
/* Determine the optimum cache size. */
if (globals.fetch_max % self->rowset_size == 0)
fetch_size = globals.fetch_max;
else if (self->rowset_size < globals.fetch_max)
@ -414,10 +391,9 @@ QR_next_tuple(QResultClass *self)
fetch_size = self->rowset_size;
self->cache_size = fetch_size;
self->fetch_count = 1;
}
else
{ /* need to correct */
self->fetch_count = 1;
}
else { /* need to correct */
corrected = TRUE;
@ -427,13 +403,13 @@ QR_next_tuple(QResultClass *self)
offset = self->fetch_count;
self->fetch_count++;
}
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
if (!self->backend_tuples)
{
self->status = PGRES_FATAL_ERROR;
if ( ! self->backend_tuples) {
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Out of memory while reading tuples.");
return FALSE;
}
@ -441,34 +417,29 @@ QR_next_tuple(QResultClass *self)
mylog("next_tuple: sending actual fetch (%d) query '%s'\n", fetch_size, fetch);
/* don't read ahead for the next tuple (self) ! */
/* don't read ahead for the next tuple (self) ! */
qi.row_size = self->cache_size;
qi.result_in = self;
qi.cursor = NULL;
res = CC_send_query(self->conn, fetch, &qi);
if (res == NULL)
{
if (res == NULL) {
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Error fetching next group.");
return FALSE;
}
self->inTuples = TRUE;
}
else
{
else {
mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->fcount, self->fetch_count);
/*
* This is a pre-fetch (fetching rows right after query but
* before any real SQLFetch() calls. This is done so the
* field attributes are available.
*/
/* This is a pre-fetch (fetching rows right after query
but before any real SQLFetch() calls. This is done
so the field attributes are available.
*/
self->fetch_count = 0;
}
}
if (!corrected)
{
if ( ! corrected) {
self->base = 0;
self->fcount = 0;
}
@ -477,96 +448,88 @@ QR_next_tuple(QResultClass *self)
sock = CC_get_socket(self->conn);
self->tupleField = NULL;
for (;;)
{
for ( ; ;) {
id = SOCK_get_char(sock);
switch (id)
{
case 'T': /* Tuples within tuples cannot be handled */
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Tuples within tuples cannot be handled");
return FALSE;
case 'B': /* Tuples in binary format */
case 'D': /* Tuples in ASCII format */
switch (id) {
case 'T': /* Tuples within tuples cannot be handled */
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Tuples within tuples cannot be handled");
return FALSE;
case 'B': /* Tuples in binary format */
case 'D': /* Tuples in ASCII format */
if (!globals.use_declarefetch && self->fcount > 0 && !(self->fcount % TUPLE_MALLOC_INC))
{
size_t old_size = self->fcount * self->num_fields * sizeof(TupleField);
if ( ! globals.use_declarefetch && self->fcount > 0 && ! (self->fcount % TUPLE_MALLOC_INC)) {
size_t old_size = self->fcount * self->num_fields * sizeof(TupleField);
mylog("REALLOC: old_size = %d\n", old_size);
mylog("REALLOC: old_size = %d\n", old_size);
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC));
if (!self->backend_tuples)
{
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Out of memory while reading tuples.");
return FALSE;
}
}
if (!QR_read_tuple(self, (char) (id == 0)))
{
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Error reading the tuple");
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC));
if ( ! self->backend_tuples) {
self->status = PGRES_FATAL_ERROR;
QR_set_message(self, "Out of memory while reading tuples.");
return FALSE;
}
}
self->fcount++;
break; /* continue reading */
case 'C': /* End of tuple list */
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
QR_set_command(self, cmdbuffer);
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
self->inTuples = FALSE;
if (self->fcount > 0)
{
qlog(" [ fetched %d rows ]\n", self->fcount);
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
/* set to first row */
self->tupleField = self->backend_tuples + (offset * self->num_fields);
return TRUE;
}
else
{ /* We are surely done here (we read 0
* tuples) */
qlog(" [ fetched 0 rows ]\n");
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
return -1; /* end of tuples */
}
case 'E': /* Error */
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
QR_set_message(self, msgbuffer);
self->status = PGRES_FATAL_ERROR;
if (!strncmp(msgbuffer, "FATAL", 5))
CC_set_no_trans(self->conn);
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
if ( ! QR_read_tuple(self, (char) (id == 0))) {
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Error reading the tuple");
return FALSE;
}
self->fcount++;
break; /* continue reading */
case 'N': /* Notice */
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
QR_set_message(self, msgbuffer);
self->status = PGRES_NONFATAL_ERROR;
qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
continue;
default: /* this should only happen if the backend
* dumped core */
mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
QR_set_message(self, "Unexpected result from backend. It probably crashed");
self->status = PGRES_FATAL_ERROR;
case 'C': /* End of tuple list */
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
QR_set_command(self, cmdbuffer);
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
self->inTuples = FALSE;
if (self->fcount > 0) {
qlog(" [ fetched %d rows ]\n", self->fcount);
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
/* set to first row */
self->tupleField = self->backend_tuples + (offset * self->num_fields);
return TRUE;
}
else { /* We are surely done here (we read 0 tuples) */
qlog(" [ fetched 0 rows ]\n");
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
return -1; /* end of tuples */
}
case 'E': /* Error */
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
QR_set_message(self, msgbuffer);
self->status = PGRES_FATAL_ERROR;
if ( ! strncmp(msgbuffer, "FATAL", 5))
CC_set_no_trans(self->conn);
return FALSE;
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
return FALSE;
case 'N': /* Notice */
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
QR_set_message(self, msgbuffer);
self->status = PGRES_NONFATAL_ERROR;
qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
continue;
default: /* this should only happen if the backend dumped core */
mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
QR_set_message(self, "Unexpected result from backend. It probably crashed");
self->status = PGRES_FATAL_ERROR;
CC_set_no_trans(self->conn);
return FALSE;
}
}
return TRUE;
@ -575,18 +538,17 @@ QR_next_tuple(QResultClass *self)
char
QR_read_tuple(QResultClass *self, char binary)
{
Int2 field_lf;
TupleField *this_tuplefield;
char bmp,
bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
Int2 bitmaplen; /* len of the bitmap in bytes */
Int2 bitmap_pos;
Int2 bitcnt;
Int4 len;
char *buffer;
int num_fields = self->num_fields; /* speed up access */
SocketClass *sock = CC_get_socket(self->conn);
ColumnInfoClass *flds;
Int2 field_lf;
TupleField *this_tuplefield;
char bmp, bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
Int2 bitmaplen; /* len of the bitmap in bytes */
Int2 bitmap_pos;
Int2 bitcnt;
Int4 len;
char *buffer;
int num_fields = self->num_fields; /* speed up access */
SocketClass *sock = CC_get_socket(self->conn);
ColumnInfoClass *flds;
/* set the current row to read the fields into */
@ -597,36 +559,31 @@ QR_read_tuple(QResultClass *self, char binary)
bitmaplen++;
/*
* At first the server sends a bitmap that indicates which database
* fields are null
*/
At first the server sends a bitmap that indicates which
database fields are null
*/
SOCK_get_n_char(sock, bitmap, bitmaplen);
bitmap_pos = 0;
bitcnt = 0;
bmp = bitmap[bitmap_pos];
for (field_lf = 0; field_lf < num_fields; field_lf++)
{
for(field_lf = 0; field_lf < num_fields; field_lf++) {
/* Check if the current field is NULL */
if (!(bmp & 0200))
{
if(!(bmp & 0200)) {
/* YES, it is NULL ! */
this_tuplefield[field_lf].len = 0;
this_tuplefield[field_lf].value = 0;
}
else
{
} else {
/*
* NO, the field is not null. so get at first the length of
* the field (four bytes)
*/
NO, the field is not null. so get at first the
length of the field (four bytes)
*/
len = SOCK_get_int(sock, VARHDRSZ);
if (!binary)
len -= VARHDRSZ;
buffer = (char *) malloc(len + 1);
buffer = (char *)malloc(len+1);
SOCK_get_n_char(sock, buffer, len);
buffer[len] = '\0';
@ -635,31 +592,27 @@ QR_read_tuple(QResultClass *self, char binary)
this_tuplefield[field_lf].len = len;
this_tuplefield[field_lf].value = buffer;
/*
* This can be used to set the longest length of the column
* for any row in the tuple cache. It would not be accurate
* for varchar and text fields to use this since a tuple cache
* is only 100 rows. Bpchar can be handled since the strlen of
* all rows is fixed, assuming there are not 100 nulls in a
* row!
*/
/* This can be used to set the longest length of the column for any
row in the tuple cache. It would not be accurate for varchar and
text fields to use this since a tuple cache is only 100 rows.
Bpchar can be handled since the strlen of all rows is fixed,
assuming there are not 100 nulls in a row!
*/
flds = self->fields;
if (flds->display_size[field_lf] < len)
flds->display_size[field_lf] = len;
}
/*
* Now adjust for the next bit to be scanned in the next loop.
*/
Now adjust for the next bit to be scanned in the
next loop.
*/
bitcnt++;
if (BYTELEN == bitcnt)
{
if (BYTELEN == bitcnt) {
bitmap_pos++;
bmp = bitmap[bitmap_pos];
bitcnt = 0;
}
else
} else
bmp <<= 1;
}
self->currTuple++;

View File

@ -1,9 +1,9 @@
/* File: qresult.h
/* File: qresult.h
*
* Description: See "qresult.c"
* Description: See "qresult.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -17,75 +17,68 @@
#include "psqlodbc.h"
#include "tuple.h"
enum QueryResultCode_
{
PGRES_EMPTY_QUERY = 0,
PGRES_COMMAND_OK, /* a query command that doesn't return */
/* anything was executed properly by the backend */
PGRES_TUPLES_OK, /* a query command that returns tuples */
/* was executed properly by the backend, PGresult */
/* contains the resulttuples */
PGRES_COPY_OUT,
PGRES_COPY_IN,
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from
* the backend */
PGRES_NONFATAL_ERROR,
PGRES_FATAL_ERROR,
PGRES_FIELDS_OK, /* field information from a query was
* successful */
PGRES_END_TUPLES,
PGRES_INTERNAL_ERROR
enum QueryResultCode_ {
PGRES_EMPTY_QUERY = 0,
PGRES_COMMAND_OK, /* a query command that doesn't return */
/* anything was executed properly by the backend */
PGRES_TUPLES_OK, /* a query command that returns tuples */
/* was executed properly by the backend, PGresult */
/* contains the resulttuples */
PGRES_COPY_OUT,
PGRES_COPY_IN,
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the backend */
PGRES_NONFATAL_ERROR,
PGRES_FATAL_ERROR,
PGRES_FIELDS_OK, /* field information from a query was successful */
PGRES_END_TUPLES,
PGRES_INTERNAL_ERROR
};
typedef enum QueryResultCode_ QueryResultCode;
struct QResultClass_
{
ColumnInfoClass *fields; /* the Column information */
TupleListClass *manual_tuples; /* manual result tuple list */
ConnectionClass *conn; /* the connection this result is using
* (backend) */
struct QResultClass_ {
ColumnInfoClass *fields; /* the Column information */
TupleListClass *manual_tuples; /* manual result tuple list */
ConnectionClass *conn; /* the connection this result is using (backend) */
/* Stuff for declare/fetch tuples */
int fetch_count; /* logical rows read so far */
int fcount; /* actual rows read in the fetch */
int currTuple;
int base;
/* Stuff for declare/fetch tuples */
int fetch_count; /* logical rows read so far */
int fcount; /* actual rows read in the fetch */
int currTuple;
int base;
int num_fields; /* number of fields in the result */
int cache_size;
int rowset_size;
int num_fields; /* number of fields in the result */
int cache_size;
int rowset_size;
QueryResultCode status;
QueryResultCode status;
char *message;
char *cursor; /* The name of the cursor for select
* statements */
char *command;
char *notice;
char *message;
char *cursor; /* The name of the cursor for select statements */
char *command;
char *notice;
TupleField *backend_tuples; /* data from the backend (the tuple cache) */
TupleField *tupleField; /* current backend tuple being retrieved */
TupleField *backend_tuples; /* data from the backend (the tuple cache) */
TupleField *tupleField; /* current backend tuple being retrieved */
char inTuples; /* is a fetch of rows from the backend in
* progress? */
char inTuples; /* is a fetch of rows from the backend in progress? */
};
#define QR_get_fields(self) (self->fields)
/* These functions are for retrieving data from the qresult */
#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
#define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value)
#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
#define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value)
#define QR_get_value_backend_row(self, tupleno, fieldno) ((self->backend_tuples + (tupleno * self->num_fields))[fieldno].value)
/* These functions are used by both manual and backend results */
#define QR_NumResultCols(self) (CI_get_num_fields(self->fields))
#define QR_get_fieldname(self, fieldno_) (CI_get_fieldname(self->fields, fieldno_))
#define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_))
#define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_))
#define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_))
#define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_))
#define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_))
#define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_))
#define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_))
#define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_))
/* These functions are used only for manual result sets */
#define QR_get_num_tuples(self) (self->manual_tuples ? TL_get_num_tuples(self->manual_tuples) : self->fcount)
@ -106,20 +99,20 @@ struct QResultClass_
/* Core Functions */
QResultClass *QR_Constructor(void);
void QR_Destructor(QResultClass *self);
char QR_read_tuple(QResultClass *self, char binary);
int QR_next_tuple(QResultClass *self);
int QR_close(QResultClass *self);
char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor);
void QR_free_memory(QResultClass *self);
void QR_set_command(QResultClass *self, char *msg);
void QR_set_notice(QResultClass *self, char *msg);
void QR_Destructor(QResultClass *self);
char QR_read_tuple(QResultClass *self, char binary);
int QR_next_tuple(QResultClass *self);
int QR_close(QResultClass *self);
char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor);
void QR_free_memory(QResultClass *self);
void QR_set_command(QResultClass *self, char *msg);
void QR_set_notice(QResultClass *self, char *msg);
void QR_set_num_fields(QResultClass *self, int new_num_fields); /* manual result only */
void QR_inc_base(QResultClass *self, int base_inc);
void QR_set_cache_size(QResultClass *self, int cache_size);
void QR_set_rowset_size(QResultClass *self, int rowset_size);
void QR_set_position(QResultClass *self, int pos);
void QR_set_num_fields(QResultClass *self, int new_num_fields); /* manual result only */
void QR_inc_base(QResultClass *self, int base_inc);
void QR_set_cache_size(QResultClass *self, int cache_size);
void QR_set_rowset_size(QResultClass *self, int rowset_size);
void QR_set_position(QResultClass *self, int pos);
#endif

View File

@ -1,60 +1,62 @@
/* {{NO_DEPENDENCIES}} */
/* Microsoft Developer Studio generated include file. */
/* Used by psqlodbc.rc */
/* */
#define IDS_BADDSN 1
#define IDS_MSGTITLE 2
#define DLG_OPTIONS_DRV 102
#define DLG_OPTIONS_DS 103
#define IDC_DSNAME 400
#define IDC_DSNAMETEXT 401
#define IDC_DESC 404
#define IDC_SERVER 407
#define IDC_DATABASE 408
#define DLG_CONFIG 1001
#define IDC_PORT 1002
#define IDC_USER 1006
#define IDC_PASSWORD 1009
#define DS_READONLY 1011
#define DS_SHOWOIDCOLUMN 1012
#define DS_FAKEOIDINDEX 1013
#define DRV_COMMLOG 1014
#define IDC_DATASOURCE 1018
#define DRV_OPTIMIZER 1019
#define DS_CONNSETTINGS 1020
#define IDC_DRIVER 1021
#define DRV_CONNSETTINGS 1031
#define DRV_UNIQUEINDEX 1032
#define DRV_UNKNOWN_MAX 1035
#define DRV_UNKNOWN_DONTKNOW 1036
#define DRV_READONLY 1037
#define IDC_DESCTEXT 1039
#define DRV_MSG_LABEL 1040
#define DRV_UNKNOWN_LONGEST 1041
#define DRV_TEXT_LONGVARCHAR 1043
#define DRV_UNKNOWNS_LONGVARCHAR 1044
#define DRV_CACHE_SIZE 1045
#define DRV_VARCHAR_SIZE 1046
#define DRV_LONGVARCHAR_SIZE 1047
#define IDDEFAULTS 1048
#define DRV_USEDECLAREFETCH 1049
#define DRV_BOOLS_CHAR 1050
#define DS_SHOWSYSTEMTABLES 1051
#define DRV_EXTRASYSTABLEPREFIXES 1051
#define DS_ROWVERSIONING 1052
#define DRV_PARSE 1052
#define DRV_CANCELASFREESTMT 1053
#define IDC_OPTIONS 1054
#define DRV_KSQO 1055
#define DS_PG64 1057
/* Microsoft Developer Studio generated include file. */
/* Used by psqlodbc.rc */
#define IDS_BADDSN 1
#define IDS_MSGTITLE 2
#define DLG_OPTIONS_DRV 102
#define DLG_OPTIONS_DS 103
#define IDC_DSNAME 400
#define IDC_DSNAMETEXT 401
#define IDC_DESC 404
#define IDC_SERVER 407
#define IDC_DATABASE 408
#define DLG_CONFIG 1001
#define IDC_PORT 1002
#define IDC_USER 1006
#define IDC_PASSWORD 1009
#define DS_READONLY 1011
#define DS_SHOWOIDCOLUMN 1012
#define DS_FAKEOIDINDEX 1013
#define DRV_COMMLOG 1014
#define DS_PG62 1016
#define IDC_DATASOURCE 1018
#define DRV_OPTIMIZER 1019
#define DS_CONNSETTINGS 1020
#define IDC_DRIVER 1021
#define DRV_CONNSETTINGS 1031
#define DRV_UNIQUEINDEX 1032
#define DRV_UNKNOWN_MAX 1035
#define DRV_UNKNOWN_DONTKNOW 1036
#define DRV_READONLY 1037
#define IDC_DESCTEXT 1039
#define DRV_MSG_LABEL 1040
#define DRV_UNKNOWN_LONGEST 1041
#define DRV_TEXT_LONGVARCHAR 1043
#define DRV_UNKNOWNS_LONGVARCHAR 1044
#define DRV_CACHE_SIZE 1045
#define DRV_VARCHAR_SIZE 1046
#define DRV_LONGVARCHAR_SIZE 1047
#define IDDEFAULTS 1048
#define DRV_USEDECLAREFETCH 1049
#define DRV_BOOLS_CHAR 1050
#define DS_SHOWSYSTEMTABLES 1051
#define DRV_EXTRASYSTABLEPREFIXES 1051
#define DS_ROWVERSIONING 1052
#define DRV_PARSE 1052
#define DRV_CANCELASFREESTMT 1053
#define IDC_OPTIONS 1054
#define DRV_KSQO 1055
#define DS_PG64 1057
#define DS_PG63 1058
/* Next default values for new objects */
/* Next default values for new objects */
/* */
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1060
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1060
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,15 @@
/* Module: setup.c
/* Module: setup.c
*
* Description: This module contains the setup functions for
* adding/modifying a Data Source in the ODBC.INI portion
* of the registry.
* Description: This module contains the setup functions for
* adding/modifying a Data Source in the ODBC.INI portion
* of the registry.
*
* Classes: n/a
* Classes: n/a
*
* API functions: ConfigDSN
* API functions: ConfigDSN
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*************************************************************************************/
@ -25,311 +26,288 @@
#define INTFUNC __stdcall
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
extern GLOBAL_VALUES globals;
/* Constants --------------------------------------------------------------- */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#ifdef WIN32
#define MAXPGPATH (255+1)
#define MAXPGPATH (255+1)
#endif
#define MAXKEYLEN (15+1) /* Max keyword length */
#define MAXDESC (255+1) /* Max description length */
#define MAXDSNAME (32+1) /* Max data source name length */
#define MAXKEYLEN (15+1) /* Max keyword length */
#define MAXDESC (255+1) /* Max description length */
#define MAXDSNAME (32+1) /* Max data source name length */
/* Globals ----------------------------------------------------------------- */
/* NOTE: All these are used by the dialog procedures */
typedef struct tagSETUPDLG
{
HWND hwndParent; /* Parent window handle */
LPCSTR lpszDrvr; /* Driver description */
ConnInfo ci;
char szDSN[MAXDSNAME]; /* Original data source name */
BOOL fNewDSN; /* New data source flag */
BOOL fDefault; /* Default data source flag */
} SETUPDLG, FAR *LPSETUPDLG;
typedef struct tagSETUPDLG {
HWND hwndParent; /* Parent window handle */
LPCSTR lpszDrvr; /* Driver description */
ConnInfo ci;
char szDSN[MAXDSNAME]; /* Original data source name */
BOOL fNewDSN; /* New data source flag */
BOOL fDefault; /* Default data source flag */
} SETUPDLG, FAR *LPSETUPDLG;
/* Prototypes -------------------------------------------------------------- */
void INTFUNC CenterDialog(HWND hdlg);
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
void INTFUNC ParseAttributes (LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
/* ConfigDSN ---------------------------------------------------------------
Description: ODBC Setup entry point
This entry point is called by the ODBC Installer
(see file header for more details)
Input : hwnd ----------- Parent window handle
fRequest ------- Request type (i.e., add, config, or remove)
lpszDriver ----- Driver name
lpszAttributes - data source attribute string
Output : TRUE success, FALSE otherwise
Description: ODBC Setup entry point
This entry point is called by the ODBC Installer
(see file header for more details)
Input : hwnd ----------- Parent window handle
fRequest ------- Request type (i.e., add, config, or remove)
lpszDriver ----- Driver name
lpszAttributes - data source attribute string
Output : TRUE success, FALSE otherwise
--------------------------------------------------------------------------*/
BOOL CALLBACK
ConfigDSN(HWND hwnd,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszAttributes)
BOOL CALLBACK ConfigDSN (HWND hwnd,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszAttributes)
{
BOOL fSuccess; /* Success/fail flag */
GLOBALHANDLE hglbAttr;
LPSETUPDLG lpsetupdlg;
BOOL fSuccess; /* Success/fail flag */
GLOBALHANDLE hglbAttr;
LPSETUPDLG lpsetupdlg;
/* Allocate attribute array */
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
if (!hglbAttr)
return FALSE;
lpsetupdlg = (LPSETUPDLG) GlobalLock(hglbAttr);
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
if (!hglbAttr)
return FALSE;
lpsetupdlg = (LPSETUPDLG)GlobalLock(hglbAttr);
/* Parse attribute string */
if (lpszAttributes)
ParseAttributes(lpszAttributes, lpsetupdlg);
/* Parse attribute string */
if (lpszAttributes)
ParseAttributes(lpszAttributes, lpsetupdlg);
/* Save original data source name */
if (lpsetupdlg->ci.dsn[0])
lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn);
else
lpsetupdlg->szDSN[0] = '\0';
/* Save original data source name */
if (lpsetupdlg->ci.dsn[0])
lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn);
else
lpsetupdlg->szDSN[0] = '\0';
/* Remove data source */
if (ODBC_REMOVE_DSN == fRequest)
{
/* Remove data source */
if (ODBC_REMOVE_DSN == fRequest) {
/* Fail if no data source name was supplied */
if (!lpsetupdlg->ci.dsn[0])
fSuccess = FALSE;
if (!lpsetupdlg->ci.dsn[0])
fSuccess = FALSE;
/* Otherwise remove data source from ODBC.INI */
else
fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
}
/* Otherwise remove data source from ODBC.INI */
else
fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
}
/* Add or Configure data source */
else
{
/* Add or Configure data source */
else {
/* Save passed variables for global access (e.g., dialog access) */
lpsetupdlg->hwndParent = hwnd;
lpsetupdlg->lpszDrvr = lpszDriver;
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
lpsetupdlg->hwndParent = hwnd;
lpsetupdlg->lpszDrvr = lpszDriver;
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
/*
* Display the appropriate dialog (if parent window handle
* supplied)
*/
if (hwnd)
{
/* Display dialog(s) */
fSuccess = (IDOK == DialogBoxParam(s_hModule,
MAKEINTRESOURCE(DLG_CONFIG),
hwnd,
ConfigDlgProc,
(LONG) (LPSTR) lpsetupdlg));
}
/* Display the appropriate dialog (if parent window handle supplied) */
if (hwnd) {
/* Display dialog(s) */
fSuccess = (IDOK == DialogBoxParam(s_hModule,
MAKEINTRESOURCE(DLG_CONFIG),
hwnd,
ConfigDlgProc,
(LONG)(LPSTR)lpsetupdlg));
}
else if (lpsetupdlg->ci.dsn[0])
fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
else
fSuccess = FALSE;
}
else if (lpsetupdlg->ci.dsn[0])
fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
else
fSuccess = FALSE;
}
GlobalUnlock(hglbAttr);
GlobalFree(hglbAttr);
GlobalUnlock(hglbAttr);
GlobalFree(hglbAttr);
return fSuccess;
return fSuccess;
}
/* CenterDialog ------------------------------------------------------------
Description: Center the dialog over the frame window
Input : hdlg -- Dialog window handle
Output : None
Description: Center the dialog over the frame window
Input : hdlg -- Dialog window handle
Output : None
--------------------------------------------------------------------------*/
void INTFUNC
CenterDialog(HWND hdlg)
void INTFUNC CenterDialog(HWND hdlg)
{
HWND hwndFrame;
RECT rcDlg,
rcScr,
rcFrame;
int cx,
cy;
HWND hwndFrame;
RECT rcDlg, rcScr, rcFrame;
int cx, cy;
hwndFrame = GetParent(hdlg);
hwndFrame = GetParent(hdlg);
GetWindowRect(hdlg, &rcDlg);
cx = rcDlg.right - rcDlg.left;
cy = rcDlg.bottom - rcDlg.top;
GetWindowRect(hdlg, &rcDlg);
cx = rcDlg.right - rcDlg.left;
cy = rcDlg.bottom - rcDlg.top;
GetClientRect(hwndFrame, &rcFrame);
ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.left));
ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.right));
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
rcDlg.bottom = rcDlg.top + cy;
rcDlg.right = rcDlg.left + cx;
GetClientRect(hwndFrame, &rcFrame);
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.left));
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.right));
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
rcDlg.bottom = rcDlg.top + cy;
rcDlg.right = rcDlg.left + cx;
GetWindowRect(GetDesktopWindow(), &rcScr);
if (rcDlg.bottom > rcScr.bottom)
{
rcDlg.bottom = rcScr.bottom;
rcDlg.top = rcDlg.bottom - cy;
}
if (rcDlg.right > rcScr.right)
{
rcDlg.right = rcScr.right;
rcDlg.left = rcDlg.right - cx;
}
GetWindowRect(GetDesktopWindow(), &rcScr);
if (rcDlg.bottom > rcScr.bottom)
{
rcDlg.bottom = rcScr.bottom;
rcDlg.top = rcDlg.bottom - cy;
}
if (rcDlg.right > rcScr.right)
{
rcDlg.right = rcScr.right;
rcDlg.left = rcDlg.right - cx;
}
if (rcDlg.left < 0)
rcDlg.left = 0;
if (rcDlg.top < 0)
rcDlg.top = 0;
if (rcDlg.left < 0) rcDlg.left = 0;
if (rcDlg.top < 0) rcDlg.top = 0;
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
return;
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
return;
}
/* ConfigDlgProc -----------------------------------------------------------
Description: Manage add data source name dialog
Input : hdlg --- Dialog window handle
wMsg --- Message
wParam - Message parameter
lParam - Message parameter
Output : TRUE if message processed, FALSE otherwise
Description: Manage add data source name dialog
Input : hdlg --- Dialog window handle
wMsg --- Message
wParam - Message parameter
lParam - Message parameter
Output : TRUE if message processed, FALSE otherwise
--------------------------------------------------------------------------*/
int CALLBACK
ConfigDlgProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam)
int CALLBACK ConfigDlgProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (wMsg)
switch (wMsg) {
/* Initialize the dialog */
case WM_INITDIALOG:
{
/* Initialize the dialog */
case WM_INITDIALOG:
LPSETUPDLG lpsetupdlg = (LPSETUPDLG) lParam;
ConnInfo *ci = &lpsetupdlg->ci;
/* Hide the driver connect message */
ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
SetWindowLong(hdlg, DWL_USER, lParam);
CenterDialog(hdlg); /* Center dialog */
/* NOTE: Values supplied in the attribute string will always */
/* override settings in ODBC.INI */
/* Get the rest of the common attributes */
getDSNinfo(ci, CONN_DONT_OVERWRITE);
/* Fill in any defaults */
getDSNdefaults(ci);
/* Initialize dialog fields */
SetDlgStuff(hdlg, ci);
if (lpsetupdlg->fDefault) {
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
}
else
SendDlgItemMessage(hdlg, IDC_DSNAME,
EM_LIMITTEXT, (WPARAM)(MAXDSNAME-1), 0L);
SendDlgItemMessage(hdlg, IDC_DESC,
EM_LIMITTEXT, (WPARAM)(MAXDESC-1), 0L);
return TRUE; /* Focus was not set */
}
/* Process buttons */
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
/* Ensure the OK button is enabled only when a data source name */
/* is entered */
case IDC_DSNAME:
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
{
LPSETUPDLG lpsetupdlg = (LPSETUPDLG) lParam;
ConnInfo *ci = &lpsetupdlg->ci;
char szItem[MAXDSNAME]; /* Edit control text */
/* Hide the driver connect message */
ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
/* Enable/disable the OK button */
EnableWindow(GetDlgItem(hdlg, IDOK),
GetDlgItemText(hdlg, IDC_DSNAME,
szItem, sizeof(szItem)));
SetWindowLong(hdlg, DWL_USER, lParam);
CenterDialog(hdlg); /* Center dialog */
/*
* NOTE: Values supplied in the attribute string will
* always
*/
/* override settings in ODBC.INI */
/* Get the rest of the common attributes */
getDSNinfo(ci, CONN_DONT_OVERWRITE);
/* Fill in any defaults */
getDSNdefaults(ci);
/* Initialize dialog fields */
SetDlgStuff(hdlg, ci);
if (lpsetupdlg->fDefault)
{
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
}
else
SendDlgItemMessage(hdlg, IDC_DSNAME,
EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
SendDlgItemMessage(hdlg, IDC_DESC,
EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
return TRUE; /* Focus was not set */
return TRUE;
}
/* Process buttons */
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
/*
* Ensure the OK button is enabled only when a data
* source name
*/
/* is entered */
case IDC_DSNAME:
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
{
char szItem[MAXDSNAME]; /* Edit control text */
/* Enable/disable the OK button */
EnableWindow(GetDlgItem(hdlg, IDOK),
GetDlgItemText(hdlg, IDC_DSNAME,
szItem, sizeof(szItem)));
return TRUE;
}
break;
/* Accept results */
case IDOK:
{
LPSETUPDLG lpsetupdlg;
lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
/* Retrieve dialog values */
if (!lpsetupdlg->fDefault)
GetDlgItemText(hdlg, IDC_DSNAME,
lpsetupdlg->ci.dsn,
sizeof(lpsetupdlg->ci.dsn));
/* Get Dialog Values */
GetDlgStuff(hdlg, &lpsetupdlg->ci);
/* Update ODBC.INI */
SetDSNAttributes(hdlg, lpsetupdlg);
}
/* Return to caller */
case IDCANCEL:
EndDialog(hdlg, wParam);
return TRUE;
case IDC_DRIVER:
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
return TRUE;
case IDC_DATASOURCE:
{
LPSETUPDLG lpsetupdlg;
lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
return TRUE;
}
}
break;
/* Accept results */
case IDOK:
{
LPSETUPDLG lpsetupdlg;
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
/* Retrieve dialog values */
if (!lpsetupdlg->fDefault)
GetDlgItemText(hdlg, IDC_DSNAME,
lpsetupdlg->ci.dsn,
sizeof(lpsetupdlg->ci.dsn));
/* Get Dialog Values */
GetDlgStuff(hdlg, &lpsetupdlg->ci);
/* Update ODBC.INI */
SetDSNAttributes(hdlg, lpsetupdlg);
}
/* Return to caller */
case IDCANCEL:
EndDialog(hdlg, wParam);
return TRUE;
case IDC_DRIVER:
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
return TRUE;
case IDC_DATASOURCE:
{
LPSETUPDLG lpsetupdlg;
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
return TRUE;
}
}
break;
}
/* Message not processed */
@ -338,97 +316,97 @@ ConfigDlgProc(HWND hdlg,
/* ParseAttributes ---------------------------------------------------------
Description: Parse attribute string moving values into the aAttr array
Input : lpszAttributes - Pointer to attribute string
Output : None (global aAttr normally updated)
Description: Parse attribute string moving values into the aAttr array
Input : lpszAttributes - Pointer to attribute string
Output : None (global aAttr normally updated)
--------------------------------------------------------------------------*/
void INTFUNC
ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
{
LPCSTR lpsz;
LPCSTR lpszStart;
char aszKey[MAXKEYLEN];
int cbKey;
char value[MAXPGPATH];
LPCSTR lpsz;
LPCSTR lpszStart;
char aszKey[MAXKEYLEN];
int cbKey;
char value[MAXPGPATH];
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
for (lpsz = lpszAttributes; *lpsz; lpsz++)
{ /* Extract key name (e.g., DSN), it must
* be terminated by an equals */
lpszStart = lpsz;
for (;; lpsz++)
{
if (!*lpsz)
return; /* No key was found */
else if (*lpsz == '=')
break; /* Valid key found */
}
/* Determine the key's index in the key table (-1 if not found) */
cbKey = lpsz - lpszStart;
if (cbKey < sizeof(aszKey))
{
_fmemcpy(aszKey, lpszStart, cbKey);
aszKey[cbKey] = '\0';
}
for (lpsz=lpszAttributes; *lpsz; lpsz++)
{ /* Extract key name (e.g., DSN), it must be terminated by an equals */
lpszStart = lpsz;
for (;; lpsz++)
{
if (!*lpsz)
return; /* No key was found */
else if (*lpsz == '=')
break; /* Valid key found */
}
/* Determine the key's index in the key table (-1 if not found) */
cbKey = lpsz - lpszStart;
if (cbKey < sizeof(aszKey))
{
/* Locate end of key value */
lpszStart = ++lpsz;
for (; *lpsz; lpsz++);
_fmemcpy(aszKey, lpszStart, cbKey);
aszKey[cbKey] = '\0';
}
/* Locate end of key value */
lpszStart = ++lpsz;
for (; *lpsz; lpsz++);
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
_fmemcpy(value, lpszStart, MIN(lpsz - lpszStart + 1, MAXPGPATH));
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
_fmemcpy(value, lpszStart, MIN(lpsz-lpszStart+1, MAXPGPATH));
mylog("aszKey='%s', value='%s'\n", aszKey, value);
mylog("aszKey='%s', value='%s'\n", aszKey, value);
/* Copy the appropriate value to the conninfo */
copyAttributes(&lpsetupdlg->ci, aszKey, value);
}
return;
/* Copy the appropriate value to the conninfo */
copyAttributes(&lpsetupdlg->ci, aszKey, value);
}
return;
}
/* SetDSNAttributes --------------------------------------------------------
Description: Write data source attributes to ODBC.INI
Input : hwnd - Parent window handle (plus globals)
Output : TRUE if successful, FALSE otherwise
Description: Write data source attributes to ODBC.INI
Input : hwnd - Parent window handle (plus globals)
Output : TRUE if successful, FALSE otherwise
--------------------------------------------------------------------------*/
BOOL INTFUNC
SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
BOOL INTFUNC SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
{
LPCSTR lpszDSN; /* Pointer to data source name */
LPCSTR lpszDSN; /* Pointer to data source name */
lpszDSN = lpsetupdlg->ci.dsn;
lpszDSN = lpsetupdlg->ci.dsn;
/* Validate arguments */
if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn)
return FALSE;
/* Validate arguments */
if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn)
return FALSE;
/* Write the data source name */
if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr))
{
if (hwndParent)
{
char szBuf[MAXPGPATH];
char szMsg[MAXPGPATH];
/* Write the data source name */
if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr))
{
if (hwndParent)
{
char szBuf[MAXPGPATH];
char szMsg[MAXPGPATH];
LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf));
wsprintf(szMsg, szBuf, lpszDSN);
LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf));
MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK);
}
return FALSE;
}
LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf));
wsprintf(szMsg, szBuf, lpszDSN);
LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf));
MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK);
}
return FALSE;
}
/* Update ODBC.INI */
writeDSNinfo(&lpsetupdlg->ci);
/* Update ODBC.INI */
writeDSNinfo(&lpsetupdlg->ci);
/* If the data source name has changed, remove the old name */
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
return TRUE;
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
{
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
}
return TRUE;
}

View File

@ -1,13 +1,14 @@
/* Module: socket.c
/* Module: socket.c
*
* Description: This module contains functions for low level socket
* operations (connecting/reading/writing to the backend)
* Description: This module contains functions for low level socket
* operations (connecting/reading/writing to the backend)
*
* Classes: SocketClass (Functions prefix: "SOCK_")
* Classes: SocketClass (Functions prefix: "SOCK_")
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -19,7 +20,7 @@
#ifndef WIN32
#include <stdlib.h>
#include <string.h> /* for memset */
#include <string.h> /* for memset */
#endif
extern GLOBAL_VALUES globals;
@ -38,45 +39,44 @@ extern GLOBAL_VALUES globals;
void
SOCK_clear_error(SocketClass *self)
{
self->errornumber = 0;
self->errormsg = NULL;
self->errornumber = 0;
self->errormsg = NULL;
}
SocketClass *
SocketClass *
SOCK_Constructor()
{
SocketClass *rv;
SocketClass *rv;
rv = (SocketClass *) malloc(sizeof(SocketClass));
rv = (SocketClass *) malloc(sizeof(SocketClass));
if (rv != NULL)
{
rv->socket = (SOCKETFD) - 1;
if (rv != NULL) {
rv->socket = (SOCKETFD) -1;
rv->buffer_filled_in = 0;
rv->buffer_filled_out = 0;
rv->buffer_read_in = 0;
rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize);
if (!rv->buffer_in)
if ( ! rv->buffer_in)
return NULL;
rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize);
if (!rv->buffer_out)
if ( ! rv->buffer_out)
return NULL;
rv->errormsg = NULL;
rv->errornumber = 0;
rv->errormsg = NULL;
rv->errornumber = 0;
rv->reverse = FALSE;
}
return rv;
}
return rv;
}
void
SOCK_Destructor(SocketClass *self)
{
if (self->socket != -1)
{
if (self->socket != -1) {
SOCK_put_char(self, 'X');
SOCK_flush_output(self);
closesocket(self->socket);
@ -89,34 +89,32 @@ SOCK_Destructor(SocketClass *self)
free(self->buffer_out);
free(self);
}
char
char
SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
{
struct hostent *host;
struct sockaddr_in sadr;
unsigned long iaddr;
struct hostent *host;
struct sockaddr_in sadr;
unsigned long iaddr;
if (self->socket != -1)
{
if (self->socket != -1) {
self->errornumber = SOCKET_ALREADY_CONNECTED;
self->errormsg = "Socket is already connected";
return 0;
}
memset((char *) &sadr, 0, sizeof(sadr));
memset((char *)&sadr, 0, sizeof(sadr));
/*
* If it is a valid IP address, use it. Otherwise use hostname lookup.
*/
/* If it is a valid IP address, use it.
Otherwise use hostname lookup.
*/
iaddr = inet_addr(hostname);
if (iaddr == INADDR_NONE)
{
if (iaddr == INADDR_NONE) {
host = gethostbyname(hostname);
if (host == NULL)
{
if (host == NULL) {
self->errornumber = SOCKET_HOST_NOT_FOUND;
self->errormsg = "Could not resolve hostname.";
return 0;
@ -124,187 +122,177 @@ SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
memcpy(&(sadr.sin_addr), host->h_addr, host->h_length);
}
else
memcpy(&(sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr));
memcpy(&(sadr.sin_addr), (struct in_addr *) &iaddr, sizeof(iaddr));
sadr.sin_family = AF_INET;
sadr.sin_port = htons(port);
self->socket = socket(AF_INET, SOCK_STREAM, 0);
if (self->socket == -1)
{
if (self->socket == -1) {
self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET;
self->errormsg = "Could not create Socket.";
return 0;
}
if (connect(self->socket, (struct sockaddr *) & (sadr),
sizeof(sadr)) < 0)
{
if ( connect(self->socket, (struct sockaddr *)&(sadr),
sizeof(sadr)) < 0) {
self->errornumber = SOCKET_COULD_NOT_CONNECT;
self->errormsg = "Could not connect to remote socket.";
closesocket(self->socket);
self->socket = (SOCKETFD) - 1;
self->socket = (SOCKETFD) -1;
return 0;
}
return 1;
}
void
void
SOCK_get_n_char(SocketClass *self, char *buffer, int len)
{
int lf;
int lf;
if (!buffer)
{
if ( ! buffer) {
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
self->errormsg = "get_n_char was called with NULL-Pointer";
return;
}
for (lf = 0; lf < len; lf++)
for(lf=0; lf < len; lf++)
buffer[lf] = SOCK_get_next_byte(self);
}
void
void
SOCK_put_n_char(SocketClass *self, char *buffer, int len)
{
int lf;
int lf;
if (!buffer)
{
if ( ! buffer) {
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
self->errormsg = "put_n_char was called with NULL-Pointer";
return;
}
for (lf = 0; lf < len; lf++)
SOCK_put_next_byte(self, (unsigned char) buffer[lf]);
for(lf=0; lf < len; lf++)
SOCK_put_next_byte(self, (unsigned char)buffer[lf]);
}
/* bufsize must include room for the null terminator
will read at most bufsize-1 characters + null.
/* bufsize must include room for the null terminator
will read at most bufsize-1 characters + null.
*/
void
void
SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
{
register int lf = 0;
register int lf = 0;
for (lf = 0; lf < bufsize; lf++)
if (!(buffer[lf] = SOCK_get_next_byte(self)))
if ( ! (buffer[lf] = SOCK_get_next_byte(self)))
return;
buffer[bufsize - 1] = '\0';
buffer[bufsize-1] = '\0';
}
void
void
SOCK_put_string(SocketClass *self, char *string)
{
register int lf;
int len;
register int lf;
int len;
len = strlen(string) + 1;
len = strlen(string)+1;
for (lf = 0; lf < len; lf++)
SOCK_put_next_byte(self, (unsigned char) string[lf]);
for(lf = 0; lf < len; lf++)
SOCK_put_next_byte(self, (unsigned char)string[lf]);
}
int
int
SOCK_get_int(SocketClass *self, short len)
{
char buf[4];
char buf[4];
switch (len)
{
case 2:
SOCK_get_n_char(self, buf, len);
if (self->reverse)
return *((unsigned short *) buf);
else
return ntohs(*((unsigned short *) buf));
switch (len) {
case 2:
SOCK_get_n_char(self, buf, len);
if (self->reverse)
return *((unsigned short *) buf);
else
return ntohs( *((unsigned short *) buf) );
case 4:
SOCK_get_n_char(self, buf, len);
if (self->reverse)
return *((unsigned int *) buf);
else
return ntohl(*((unsigned int *) buf));
case 4:
SOCK_get_n_char(self, buf, len);
if (self->reverse)
return *((unsigned int *) buf);
else
return ntohl( *((unsigned int *) buf) );
default:
self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
self->errormsg = "Cannot read ints of that length";
return 0;
default:
self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
self->errormsg = "Cannot read ints of that length";
return 0;
}
}
void
void
SOCK_put_int(SocketClass *self, int value, short len)
{
unsigned int rv;
unsigned int rv;
switch (len)
{
case 2:
rv = self->reverse ? value : htons((unsigned short) value);
SOCK_put_n_char(self, (char *) &rv, 2);
return;
switch (len) {
case 2:
rv = self->reverse ? value : htons( (unsigned short) value);
SOCK_put_n_char(self, (char *) &rv, 2);
return;
case 4:
rv = self->reverse ? value : htonl((unsigned int) value);
SOCK_put_n_char(self, (char *) &rv, 4);
return;
case 4:
rv = self->reverse ? value : htonl( (unsigned int) value);
SOCK_put_n_char(self, (char *) &rv, 4);
return;
default:
self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH;
self->errormsg = "Cannot write ints of that length";
return;
}
default:
self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH;
self->errormsg = "Cannot write ints of that length";
return;
}
}
void
void
SOCK_flush_output(SocketClass *self)
{
int written;
int written;
written = send(self->socket, (char *) self->buffer_out, self->buffer_filled_out, 0);
if (written != self->buffer_filled_out)
{
written = send(self->socket, (char *)self->buffer_out, self->buffer_filled_out, 0);
if (written != self->buffer_filled_out) {
self->errornumber = SOCKET_WRITE_ERROR;
self->errormsg = "Could not flush socket buffer.";
}
self->buffer_filled_out = 0;
}
unsigned char
unsigned char
SOCK_get_next_byte(SocketClass *self)
{
if (self->buffer_read_in >= self->buffer_filled_in)
{
/* there are no more bytes left in the buffer, so */
/* reload the buffer */
if (self->buffer_read_in >= self->buffer_filled_in) {
/* there are no more bytes left in the buffer so */
/* reload the buffer */
self->buffer_read_in = 0;
self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in,
globals.socket_buffersize, 0);
self->buffer_filled_in = recv(self->socket, (char *)self->buffer_in, globals.socket_buffersize, 0);
mylog("read %d, global_socket_buffersize=%d\n",
self->buffer_filled_in, globals.socket_buffersize);
mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, globals.socket_buffersize);
if (self->buffer_filled_in < 0)
{
if (self->buffer_filled_in < 0) {
self->errornumber = SOCKET_READ_ERROR;
self->errormsg = "Error while reading from the socket.";
self->buffer_filled_in = 0;
return 0;
}
if (self->buffer_filled_in == 0)
{
if (self->buffer_filled_in == 0) {
self->errornumber = SOCKET_CLOSED;
self->errormsg = "Socket has been closed.";
self->buffer_filled_in = 0;
@ -314,19 +302,17 @@ SOCK_get_next_byte(SocketClass *self)
return self->buffer_in[self->buffer_read_in++];
}
void
void
SOCK_put_next_byte(SocketClass *self, unsigned char next_byte)
{
int bytes_sent;
int bytes_sent;
self->buffer_out[self->buffer_filled_out++] = next_byte;
if (self->buffer_filled_out == globals.socket_buffersize)
{
if (self->buffer_filled_out == globals.socket_buffersize) {
/* buffer is full, so write it out */
bytes_sent = send(self->socket, (char *) self->buffer_out, globals.socket_buffersize, 0);
if (bytes_sent != globals.socket_buffersize)
{
bytes_sent = send(self->socket, (char *)self->buffer_out, globals.socket_buffersize, 0);
if (bytes_sent != globals.socket_buffersize) {
self->errornumber = SOCKET_WRITE_ERROR;
self->errormsg = "Error while writing to the socket.";
}

View File

@ -1,9 +1,9 @@
/* File: socket.h
/* File: socket.h
*
* Description: See "socket.c"
* Description: See "socket.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -25,11 +25,10 @@
#define closesocket(xxx) close(xxx)
#define SOCKETFD int
#ifndef INADDR_NONE
#ifndef INADDR_NONE
#ifndef _IN_ADDR_T
#define _IN_ADDR_T
typedef unsigned int in_addr_t;
typedef unsigned int in_addr_t;
#endif
#define INADDR_NONE ((in_addr_t)-1)
#endif
@ -41,34 +40,32 @@ typedef unsigned int in_addr_t;
#include "psqlodbc.h"
#define SOCKET_ALREADY_CONNECTED 1
#define SOCKET_HOST_NOT_FOUND 2
#define SOCKET_COULD_NOT_CREATE_SOCKET 3
#define SOCKET_COULD_NOT_CONNECT 4
#define SOCKET_READ_ERROR 5
#define SOCKET_WRITE_ERROR 6
#define SOCKET_NULLPOINTER_PARAMETER 7
#define SOCKET_PUT_INT_WRONG_LENGTH 8
#define SOCKET_GET_INT_WRONG_LENGTH 9
#define SOCKET_CLOSED 10
#define SOCKET_ALREADY_CONNECTED 1
#define SOCKET_HOST_NOT_FOUND 2
#define SOCKET_COULD_NOT_CREATE_SOCKET 3
#define SOCKET_COULD_NOT_CONNECT 4
#define SOCKET_READ_ERROR 5
#define SOCKET_WRITE_ERROR 6
#define SOCKET_NULLPOINTER_PARAMETER 7
#define SOCKET_PUT_INT_WRONG_LENGTH 8
#define SOCKET_GET_INT_WRONG_LENGTH 9
#define SOCKET_CLOSED 10
struct SocketClass_
{
struct SocketClass_ {
int buffer_filled_in;
int buffer_filled_out;
int buffer_read_in;
int buffer_filled_in;
int buffer_filled_out;
int buffer_read_in;
unsigned char *buffer_in;
unsigned char *buffer_out;
SOCKETFD socket;
SOCKETFD socket;
char *errormsg;
int errornumber;
char *errormsg;
int errornumber;
char reverse; /* used to handle Postgres 6.2 protocol
* (reverse byte order) */
char reverse; /* used to handle Postgres 6.2 protocol (reverse byte order) */
};
@ -83,17 +80,17 @@ struct SocketClass_
/* Socket prototypes */
SocketClass *SOCK_Constructor(void);
void SOCK_Destructor(SocketClass *self);
char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
void SOCK_get_n_char(SocketClass *self, char *buffer, int len);
void SOCK_put_n_char(SocketClass *self, char *buffer, int len);
void SOCK_get_string(SocketClass *self, char *buffer, int bufsize);
void SOCK_put_string(SocketClass *self, char *string);
int SOCK_get_int(SocketClass *self, short len);
void SOCK_put_int(SocketClass *self, int value, short len);
void SOCK_flush_output(SocketClass *self);
void SOCK_Destructor(SocketClass *self);
char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
void SOCK_get_n_char(SocketClass *self, char *buffer, int len);
void SOCK_put_n_char(SocketClass *self, char *buffer, int len);
void SOCK_get_string(SocketClass *self, char *buffer, int bufsize);
void SOCK_put_string(SocketClass *self, char *string);
int SOCK_get_int(SocketClass *self, short len);
void SOCK_put_int(SocketClass *self, int value, short len);
void SOCK_flush_output(SocketClass *self);
unsigned char SOCK_get_next_byte(SocketClass *self);
void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte);
void SOCK_clear_error(SocketClass *self);
void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte);
void SOCK_clear_error(SocketClass *self);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/* File: statement.h
/* File: statement.h
*
* Description: See "statement.c"
* Description: See "statement.c"
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -33,59 +33,51 @@
#define TRUE (BOOL)1
#endif
typedef enum
{
STMT_ALLOCATED, /* The statement handle is allocated, but
* not used so far */
STMT_READY, /* the statement is waiting to be executed */
STMT_PREMATURE, /* ODBC states that it is legal to call
* e.g. SQLDescribeCol before a call to
* SQLExecute, but after SQLPrepare. To
* get all the necessary information in
* such a case, we simply execute the
* query _before_ the actual call to
* SQLExecute, so that statement is
* considered to be "premature". */
STMT_FINISHED, /* statement execution has finished */
STMT_EXECUTING /* statement execution is still going on */
typedef enum {
STMT_ALLOCATED, /* The statement handle is allocated, but not used so far */
STMT_READY, /* the statement is waiting to be executed */
STMT_PREMATURE, /* ODBC states that it is legal to call e.g. SQLDescribeCol before
a call to SQLExecute, but after SQLPrepare. To get all the necessary
information in such a case, we simply execute the query _before_ the
actual call to SQLExecute, so that statement is considered to be "premature".
*/
STMT_FINISHED, /* statement execution has finished */
STMT_EXECUTING /* statement execution is still going on */
} STMT_Status;
#define STMT_TRUNCATED (-2)
#define STMT_INFO_ONLY (-1) /* not an error message, just a
* notification to be returned by SQLError */
#define STMT_OK 0 /* will be interpreted as "no error
* pending" */
#define STMT_EXEC_ERROR 1
#define STMT_STATUS_ERROR 2
#define STMT_SEQUENCE_ERROR 3
#define STMT_NO_MEMORY_ERROR 4
#define STMT_COLNUM_ERROR 5
#define STMT_NO_STMTSTRING 6
#define STMT_ERROR_TAKEN_FROM_BACKEND 7
#define STMT_INTERNAL_ERROR 8
#define STMT_STILL_EXECUTING 9
#define STMT_NOT_IMPLEMENTED_ERROR 10
#define STMT_BAD_PARAMETER_NUMBER_ERROR 11
#define STMT_OPTION_OUT_OF_RANGE_ERROR 12
#define STMT_INVALID_COLUMN_NUMBER_ERROR 13
#define STMT_RESTRICTED_DATA_TYPE_ERROR 14
#define STMT_INVALID_CURSOR_STATE_ERROR 15
#define STMT_OPTION_VALUE_CHANGED 16
#define STMT_CREATE_TABLE_ERROR 17
#define STMT_NO_CURSOR_NAME 18
#define STMT_INVALID_CURSOR_NAME 19
#define STMT_INVALID_ARGUMENT_NO 20
#define STMT_ROW_OUT_OF_RANGE 21
#define STMT_OPERATION_CANCELLED 22
#define STMT_INVALID_CURSOR_POSITION 23
#define STMT_VALUE_OUT_OF_RANGE 24
#define STMT_OPERATION_INVALID 25
#define STMT_PROGRAM_TYPE_OUT_OF_RANGE 26
#define STMT_BAD_ERROR 27
#define STMT_TRUNCATED -2
#define STMT_INFO_ONLY -1 /* not an error message, just a notification to be returned by SQLError */
#define STMT_OK 0 /* will be interpreted as "no error pending" */
#define STMT_EXEC_ERROR 1
#define STMT_STATUS_ERROR 2
#define STMT_SEQUENCE_ERROR 3
#define STMT_NO_MEMORY_ERROR 4
#define STMT_COLNUM_ERROR 5
#define STMT_NO_STMTSTRING 6
#define STMT_ERROR_TAKEN_FROM_BACKEND 7
#define STMT_INTERNAL_ERROR 8
#define STMT_STILL_EXECUTING 9
#define STMT_NOT_IMPLEMENTED_ERROR 10
#define STMT_BAD_PARAMETER_NUMBER_ERROR 11
#define STMT_OPTION_OUT_OF_RANGE_ERROR 12
#define STMT_INVALID_COLUMN_NUMBER_ERROR 13
#define STMT_RESTRICTED_DATA_TYPE_ERROR 14
#define STMT_INVALID_CURSOR_STATE_ERROR 15
#define STMT_OPTION_VALUE_CHANGED 16
#define STMT_CREATE_TABLE_ERROR 17
#define STMT_NO_CURSOR_NAME 18
#define STMT_INVALID_CURSOR_NAME 19
#define STMT_INVALID_ARGUMENT_NO 20
#define STMT_ROW_OUT_OF_RANGE 21
#define STMT_OPERATION_CANCELLED 22
#define STMT_INVALID_CURSOR_POSITION 23
#define STMT_VALUE_OUT_OF_RANGE 24
#define STMT_OPERATION_INVALID 25
#define STMT_PROGRAM_TYPE_OUT_OF_RANGE 26
#define STMT_BAD_ERROR 27
/* statement types */
enum
{
enum {
STMT_TYPE_UNKNOWN = -2,
STMT_TYPE_OTHER = -1,
STMT_TYPE_SELECT = 0,
@ -103,8 +95,7 @@ enum
/* Parsing status */
enum
{
enum {
STMT_PARSE_NONE = 0,
STMT_PARSE_COMPLETE,
STMT_PARSE_INCOMPLETE,
@ -112,110 +103,92 @@ enum
};
/* Result style */
enum
{
enum {
STMT_FETCH_NONE = 0,
STMT_FETCH_NORMAL,
STMT_FETCH_EXTENDED,
};
typedef struct
{
COL_INFO *col_info; /* cached SQLColumns info for this table */
char name[MAX_TABLE_LEN + 1];
char alias[MAX_TABLE_LEN + 1];
typedef struct {
COL_INFO *col_info; /* cached SQLColumns info for this table */
char name[MAX_TABLE_LEN+1];
char alias[MAX_TABLE_LEN+1];
} TABLE_INFO;
typedef struct
{
TABLE_INFO *ti; /* resolve to explicit table names */
int precision;
int display_size;
int length;
int type;
char nullable;
char func;
char expr;
char quote;
char dquote;
char numeric;
char dot[MAX_TABLE_LEN + 1];
char name[MAX_COLUMN_LEN + 1];
char alias[MAX_COLUMN_LEN + 1];
typedef struct {
TABLE_INFO *ti; /* resolve to explicit table names */
int precision;
int display_size;
int length;
int type;
char nullable;
char func;
char expr;
char quote;
char dquote;
char numeric;
char dot[MAX_TABLE_LEN+1];
char name[MAX_COLUMN_LEN+1];
char alias[MAX_COLUMN_LEN+1];
} FIELD_INFO;
/******** Statement Handle ***********/
struct StatementClass_
{
ConnectionClass *hdbc; /* pointer to ConnectionClass this
* statement belongs to */
QResultClass *result; /* result of the current statement */
HSTMT FAR *phstmt;
struct StatementClass_ {
ConnectionClass *hdbc; /* pointer to ConnectionClass this statement belongs to */
QResultClass *result; /* result of the current statement */
HSTMT FAR *phstmt;
StatementOptions options;
STMT_Status status;
char *errormsg;
int errornumber;
STMT_Status status;
char *errormsg;
int errornumber;
/* information on bindings */
BindInfoClass *bindings; /* array to store the binding information */
/* information on bindings */
BindInfoClass *bindings; /* array to store the binding information */
BindInfoClass bookmark;
int bindings_allocated;
int bindings_allocated;
/* information on statement parameters */
int parameters_allocated;
ParameterInfoClass *parameters;
/* information on statement parameters */
int parameters_allocated;
ParameterInfoClass *parameters;
Int4 currTuple; /* current absolute row number (GetData,
* SetPos, SQLFetch) */
int save_rowset_size; /* saved rowset size in case of
* change/FETCH_NEXT */
int rowset_start; /* start of rowset (an absolute row
* number) */
int bind_row; /* current offset for Multiple row/column
* binding */
int last_fetch_count; /* number of rows retrieved in
* last fetch/extended fetch */
int current_col; /* current column for GetData -- used to
* handle multiple calls */
int lobj_fd; /* fd of the current large object */
Int4 currTuple; /* current absolute row number (GetData, SetPos, SQLFetch) */
int save_rowset_size; /* saved rowset size in case of change/FETCH_NEXT */
int rowset_start; /* start of rowset (an absolute row number) */
int bind_row; /* current offset for Multiple row/column binding */
int last_fetch_count; /* number of rows retrieved in last fetch/extended fetch */
int current_col; /* current column for GetData -- used to handle multiple calls */
int lobj_fd; /* fd of the current large object */
char *statement; /* if non--null pointer to the SQL
* statement that has been executed */
char *statement; /* if non--null pointer to the SQL statement that has been executed */
TABLE_INFO **ti;
FIELD_INFO **fi;
TABLE_INFO **ti;
FIELD_INFO **fi;
int nfld;
int ntab;
int parse_status;
int parse_status;
int statement_type; /* According to the defines above */
int data_at_exec; /* Number of params needing SQLPutData */
int current_exec_param; /* The current parameter for
* SQLPutData */
int statement_type; /* According to the defines above */
int data_at_exec; /* Number of params needing SQLPutData */
int current_exec_param; /* The current parameter for SQLPutData */
char put_data; /* Has SQLPutData been called yet? */
char put_data; /* Has SQLPutData been called yet? */
char errormsg_created; /* has an informative error msg
* been created? */
char manual_result; /* Is the statement result manually built? */
char prepare; /* is this statement a prepared statement
* or direct */
char errormsg_created; /* has an informative error msg been created? */
char manual_result; /* Is the statement result manually built? */
char prepare; /* is this statement a prepared statement or direct */
char internal; /* Is this statement being called
* internally? */
char internal; /* Is this statement being called internally? */
char cursor_name[MAX_CURSOR_LEN + 1];
char cursor_name[MAX_CURSOR_LEN+1];
char stmt_with_params[STD_STATEMENT_LEN]; /* statement after
* parameter
* substitution */
char stmt_with_params[STD_STATEMENT_LEN]; /* statement after parameter substitution */
};
#define SC_get_conn(a) (a->hdbc)
#define SC_get_conn(a) (a->hdbc)
#define SC_get_Result(a) (a->result);
/* options for SC_free_params() */
@ -224,21 +197,21 @@ struct StatementClass_
/* Statement prototypes */
StatementClass *SC_Constructor(void);
void InitializeStatementOptions(StatementOptions *opt);
char SC_Destructor(StatementClass *self);
int statement_type(char *statement);
char parse_statement(StatementClass *stmt);
void SC_pre_execute(StatementClass *self);
char SC_unbind_cols(StatementClass *self);
char SC_recycle_statement(StatementClass *self);
void InitializeStatementOptions(StatementOptions *opt);
char SC_Destructor(StatementClass *self);
int statement_type(char *statement);
char parse_statement(StatementClass *stmt);
void SC_pre_execute(StatementClass *self);
char SC_unbind_cols(StatementClass *self);
char SC_recycle_statement(StatementClass *self);
void SC_clear_error(StatementClass *self);
char SC_get_error(StatementClass *self, int *number, char **message);
char *SC_create_errormsg(StatementClass *self);
RETCODE SC_execute(StatementClass *self);
RETCODE SC_fetch(StatementClass *self);
void SC_free_params(StatementClass *self, char option);
void SC_log_error(char *func, char *desc, StatementClass *self);
void SC_clear_error(StatementClass *self);
char SC_get_error(StatementClass *self, int *number, char **message);
char *SC_create_errormsg(StatementClass *self);
RETCODE SC_execute(StatementClass *self);
RETCODE SC_fetch(StatementClass *self);
void SC_free_params(StatementClass *self, char option);
void SC_log_error(char *func, char *desc, StatementClass *self);
unsigned long SC_get_bookmark(StatementClass *self);

View File

@ -1,16 +1,17 @@
/* Module: tuple.c
/* Module: tuple.c
*
* Description: This module contains functions for setting the data for individual
* fields (TupleField structure) of a manual result set.
* Description: This module contains functions for setting the data for individual
* fields (TupleField structure) of a manual result set.
*
* Important Note: These functions are ONLY used in building manual result sets for
* info functions (SQLTables, SQLColumns, etc.)
* Important Note: These functions are ONLY used in building manual result sets for
* info functions (SQLTables, SQLColumns, etc.)
*
* Classes: n/a
* Classes: n/a
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -18,43 +19,39 @@
#include <string.h>
#include <stdlib.h>
void
set_tuplefield_null(TupleField *tuple_field)
void set_tuplefield_null(TupleField *tuple_field)
{
tuple_field->len = 0;
tuple_field->value = NULL; /* strdup(""); */
tuple_field->value = NULL; /* strdup(""); */
}
void
set_tuplefield_string(TupleField *tuple_field, char *string)
void set_tuplefield_string(TupleField *tuple_field, char *string)
{
tuple_field->len = strlen(string);
tuple_field->value = malloc(strlen(string) + 1);
tuple_field->value = malloc(strlen(string)+1);
strcpy(tuple_field->value, string);
}
void
set_tuplefield_int2(TupleField *tuple_field, Int2 value)
void set_tuplefield_int2(TupleField *tuple_field, Int2 value)
{
char buffer[10];
char buffer[10];
sprintf(buffer, "%d", value);
sprintf(buffer,"%d", value);
tuple_field->len = strlen(buffer) + 1;
tuple_field->len = strlen(buffer)+1;
/* +1 ... is this correct (better be on the save side-...) */
tuple_field->value = strdup(buffer);
}
void
set_tuplefield_int4(TupleField *tuple_field, Int4 value)
void set_tuplefield_int4(TupleField *tuple_field, Int4 value)
{
char buffer[15];
char buffer[15];
sprintf(buffer, "%ld", value);
sprintf(buffer,"%ld", value);
tuple_field->len = strlen(buffer) + 1;
tuple_field->len = strlen(buffer)+1;
/* +1 ... is this correct (better be on the save side-...) */
tuple_field->value = strdup(buffer);
}

View File

@ -1,13 +1,13 @@
/* File: tuple.h
/* File: tuple.h
*
* Description: See "tuple.c"
* Description: See "tuple.c"
*
* Important NOTE: The TupleField structure is used both to hold backend data and
* manual result set data. The "set_" functions and the TupleNode
* structure are only used for manual result sets by info routines.
* Important NOTE: The TupleField structure is used both to hold backend data and
* manual result set data. The "set_" functions and the TupleNode
* structure are only used for manual result sets by info routines.
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -17,18 +17,15 @@
#include "psqlodbc.h"
/* Used by backend data AND manual result sets */
struct TupleField_
{
Int4 len; /* length of the current Tuple */
void *value; /* an array representing the value */
struct TupleField_ {
Int4 len; /* length of the current Tuple */
void *value; /* an array representing the value */
};
/* Used ONLY for manual result sets */
struct TupleNode_
{
struct TupleNode_ *prev,
*next;
TupleField tuple[1];
struct TupleNode_ {
struct TupleNode_ *prev, *next;
TupleField tuple[1];
};
/* These macros are wrappers for the corresponding set_tuplefield functions
@ -39,9 +36,9 @@ struct TupleNode_
#define set_nullfield_int2(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int2(FLD, (VAL)) : set_tuplefield_null(FLD))
#define set_nullfield_int4(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int4(FLD, (VAL)) : set_tuplefield_null(FLD))
void set_tuplefield_null(TupleField *tuple_field);
void set_tuplefield_string(TupleField *tuple_field, char *string);
void set_tuplefield_int2(TupleField *tuple_field, Int2 value);
void set_tuplefield_int4(TupleField *tuple_field, Int4 value);
void set_tuplefield_null(TupleField *tuple_field);
void set_tuplefield_string(TupleField *tuple_field, char *string);
void set_tuplefield_int2(TupleField *tuple_field, Int2 value);
void set_tuplefield_int4(TupleField *tuple_field, Int4 value);
#endif

View File

@ -1,13 +1,14 @@
/* Module: tuplelist.c
/* Module: tuplelist.c
*
* Description: This module contains functions for creating a manual result set
* (the TupleList) and retrieving data from it for a specific row/column.
* Description: This module contains functions for creating a manual result set
* (the TupleList) and retrieving data from it for a specific row/column.
*
* Classes: TupleListClass (Functions prefix: "TL_")
* Classes: TupleListClass (Functions prefix: "TL_")
*
* API functions: none
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -18,19 +19,19 @@
TupleListClass *
TL_Constructor(UInt4 fieldcnt)
{
TupleListClass *rv;
TupleListClass *rv;
mylog("in TL_Constructor\n");
rv = (TupleListClass *) malloc(sizeof(TupleListClass));
if (rv)
{
rv->num_fields = fieldcnt;
rv->num_tuples = 0;
rv->list_start = NULL;
rv->list_end = NULL;
rv->lastref = NULL;
rv->last_indexed = -1;
if (rv) {
rv->num_fields = fieldcnt;
rv->num_tuples = 0;
rv->list_start = NULL;
rv->list_end = NULL;
rv->lastref = NULL;
rv->last_indexed = -1;
}
mylog("exit TL_Constructor\n");
@ -41,38 +42,35 @@ TL_Constructor(UInt4 fieldcnt)
void
TL_Destructor(TupleListClass *self)
{
int lf;
TupleNode *node,
*tp;
int lf;
TupleNode *node, *tp;
mylog("TupleList: in DESTRUCTOR\n");
node = self->list_start;
while (node != NULL)
{
for (lf = 0; lf < self->num_fields; lf++)
if (node->tuple[lf].value != NULL)
free(node->tuple[lf].value);
tp = node->next;
free(node);
node = tp;
}
node = self->list_start;
while(node != NULL) {
for (lf=0; lf < self->num_fields; lf++)
if (node->tuple[lf].value != NULL) {
free(node->tuple[lf].value);
}
tp = node->next;
free(node);
node = tp;
}
free(self);
mylog("TupleList: exit DESTRUCTOR\n");
}
void *
TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
{
Int4 lf;
Int4 delta,
from_end;
char end_is_closer,
start_is_closer;
TupleNode *rv;
Int4 lf;
Int4 delta, from_end;
char end_is_closer, start_is_closer;
TupleNode *rv;
if (self->last_indexed == -1)
/* we have an empty tuple list */
@ -87,88 +85,67 @@ TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
/* illegel field number range */
return NULL;
/*
* check if we are accessing the same tuple that was used in the last
* fetch (e.g: for fetching all the fields one after another. Do this
* to speed things up
*/
/* check if we are accessing the same tuple that was used in
the last fetch (e.g: for fetching all the fields one after
another. Do this to speed things up
*/
if (tupleno == self->last_indexed)
return self->lastref->tuple[fieldno].value;
/* now for the tricky part... */
/* now for the tricky part... */
/*
* Since random access is quite inefficient for linked lists we use
* the lastref pointer that points to the last element referenced by a
* get_fieldval() call in conjunction with the its index number that
* is stored in last_indexed. (So we use some locality of reference
* principle to speed things up)
*/
/*
Since random access is quite inefficient for linked lists we use
the lastref pointer that points to the last element referenced
by a get_fieldval() call in conjunction with the its index number
that is stored in last_indexed. (So we use some locality of
reference principle to speed things up)
*/
delta = tupleno - self->last_indexed;
/* if delta is positive, we have to go forward */
/*
* now check if we are closer to the start or the end of the list than
* to our last_indexed pointer
*/
/* now check if we are closer to the start or the end of the list
than to our last_indexed pointer
*/
from_end = (self->num_tuples - 1) - tupleno;
start_is_closer = labs(delta) > tupleno;
/*
* true if we are closer to the start of the list than to the
* last_indexed pointer
*/
/* true if we are closer to the start of the list than to the
last_indexed pointer
*/
end_is_closer = labs(delta) > from_end;
/* true if we are closer at the end of the list */
if (end_is_closer)
{
if (end_is_closer) {
/* scanning from the end is the shortest way. so we do that... */
rv = self->list_end;
for (lf = 0; lf < from_end; lf++)
for (lf=0; lf < from_end; lf++)
rv = rv->prev;
}
else if (start_is_closer)
{
/*
* the shortest way is to start the search from the head of the
* list
*/
} else if (start_is_closer) {
/* the shortest way is to start the search from the head of the list */
rv = self->list_start;
for (lf = 0; lf < tupleno; lf++)
for (lf=0; lf < tupleno; lf++)
rv = rv->next;
}
else
{
} else {
/* the closest way is starting from our lastref - pointer */
rv = self->lastref;
/*
* at first determine whether we have to search forward or
* backwards
*/
if (delta < 0)
{
/* at first determine whether we have to search forward or backwards */
if (delta < 0) {
/* we have to search backwards */
for (lf = 0; lf < (-1) * delta; lf++)
for(lf=0; lf < (-1)*delta; lf++)
rv = rv->prev;
}
else
{
} else {
/* ok, we have to search forward... */
for (lf = 0; lf < delta; lf++)
rv = rv->next;
for (lf=0; lf < delta; lf++)
rv = rv->next;
}
}
/*
* now we have got our return pointer, so update the lastref and the
* last_indexed values
*/
/* now we have got our return pointer, so update the lastref
and the last_indexed values
*/
self->lastref = rv;
self->last_indexed = tupleno;
@ -180,30 +157,23 @@ TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
char
TL_add_tuple(TupleListClass *self, TupleNode *new_field)
{
/*
* we append the tuple at the end of the doubly linked list of the
* tuples we have already read in
*/
/* we append the tuple at the end of the doubly linked list
of the tuples we have already read in
*/
new_field->prev = NULL;
new_field->next = NULL;
if (self->list_start == NULL)
{
if (self->list_start == NULL) {
/* the list is empty, we have to add the first tuple */
self->list_start = new_field;
self->list_end = new_field;
self->lastref = new_field;
self->last_indexed = 0;
}
else
{
/*
* there is already an element in the list, so add the new one at
* the end of the list
*/
} else {
/* there is already an element in the list, so add the new
one at the end of the list
*/
self->list_end->next = new_field;
new_field->prev = self->list_end;
self->list_end = new_field;
@ -213,3 +183,5 @@ TL_add_tuple(TupleListClass *self, TupleNode *new_field)
/* this method of building a list cannot fail, so we return 1 */
return 1;
}

View File

@ -1,12 +1,12 @@
/* File: tuplelist.h
/* File: tuplelist.h
*
* Description: See "tuplelist.c"
* Description: See "tuplelist.c"
*
* Important Note: This structure and its functions are ONLY used in building manual result
* sets for info functions (SQLTables, SQLColumns, etc.)
* Important Note: This structure and its functions are ONLY used in building manual result
* sets for info functions (SQLTables, SQLColumns, etc.)
*
* Comments: See "notice.txt" for copyright and license information.
* Comments: See "notice.txt" for copyright and license information.
*
*/
@ -15,22 +15,19 @@
#include "psqlodbc.h"
struct TupleListClass_
{
Int4 num_fields;
Int4 num_tuples;
TupleNode *list_start,
*list_end,
*lastref;
Int4 last_indexed;
struct TupleListClass_ {
Int4 num_fields;
Int4 num_tuples;
TupleNode *list_start, *list_end, *lastref;
Int4 last_indexed;
};
#define TL_get_num_tuples(x) (x->num_tuples)
/* Create a TupleList. Each tuple consits of fieldcnt columns */
TupleListClass *TL_Constructor(UInt4 fieldcnt);
void TL_Destructor(TupleListClass *self);
void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno);
char TL_add_tuple(TupleListClass *self, TupleNode *new_field);
void TL_Destructor(TupleListClass *self);
void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno);
char TL_add_tuple(TupleListClass *self, TupleNode *new_field);
#endif