mirror of
https://github.com/postgres/postgres.git
synced 2025-05-12 16:21:30 +03:00
Run pgindent over ODBC source. We couldn't do this years ago because we
weren't the master source. We are now, and it really needs it.
This commit is contained in:
parent
505a828a66
commit
755a87332a
@ -35,7 +35,8 @@
|
|||||||
|
|
||||||
/* Bind parameters on a statement handle */
|
/* Bind parameters on a statement handle */
|
||||||
|
|
||||||
RETCODE SQL_API SQLBindParameter(
|
RETCODE SQL_API
|
||||||
|
SQLBindParameter(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UWORD ipar,
|
UWORD ipar,
|
||||||
SWORD fParamType,
|
SWORD fParamType,
|
||||||
@ -45,27 +46,31 @@ RETCODE SQL_API SQLBindParameter(
|
|||||||
SWORD ibScale,
|
SWORD ibScale,
|
||||||
PTR rgbValue,
|
PTR rgbValue,
|
||||||
SDWORD cbValueMax,
|
SDWORD cbValueMax,
|
||||||
SDWORD FAR *pcbValue)
|
SDWORD FAR * pcbValue)
|
||||||
{
|
{
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
static char *func="SQLBindParameter";
|
static char *func = "SQLBindParameter";
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stmt->parameters_allocated < ipar) {
|
if (stmt->parameters_allocated < ipar)
|
||||||
|
{
|
||||||
ParameterInfoClass *old_parameters;
|
ParameterInfoClass *old_parameters;
|
||||||
int i, old_parameters_allocated;
|
int i,
|
||||||
|
old_parameters_allocated;
|
||||||
|
|
||||||
old_parameters = stmt->parameters;
|
old_parameters = stmt->parameters;
|
||||||
old_parameters_allocated = stmt->parameters_allocated;
|
old_parameters_allocated = stmt->parameters_allocated;
|
||||||
|
|
||||||
stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass)*(ipar));
|
stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass) * (ipar));
|
||||||
if ( ! stmt->parameters) {
|
if (!stmt->parameters)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "Could not allocate memory for statement parameters";
|
stmt->errormsg = "Could not allocate memory for statement parameters";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -75,18 +80,23 @@ static char *func="SQLBindParameter";
|
|||||||
stmt->parameters_allocated = ipar;
|
stmt->parameters_allocated = ipar;
|
||||||
|
|
||||||
/* copy the old parameters over */
|
/* 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 */
|
/* a structure copy should work */
|
||||||
stmt->parameters[i] = old_parameters[i];
|
stmt->parameters[i] = old_parameters[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get rid of the old parameters, if there were any */
|
/* get rid of the old parameters, if there were any */
|
||||||
if(old_parameters)
|
if (old_parameters)
|
||||||
free(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) */
|
/* 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].buflen = 0;
|
||||||
stmt->parameters[i].buffer = 0;
|
stmt->parameters[i].buffer = 0;
|
||||||
stmt->parameters[i].used = 0;
|
stmt->parameters[i].used = 0;
|
||||||
@ -102,7 +112,8 @@ static char *func="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 */
|
/* store the given info */
|
||||||
stmt->parameters[ipar].buflen = cbValueMax;
|
stmt->parameters[ipar].buflen = cbValueMax;
|
||||||
@ -114,15 +125,18 @@ static char *func="SQLBindParameter";
|
|||||||
stmt->parameters[ipar].precision = cbColDef;
|
stmt->parameters[ipar].precision = cbColDef;
|
||||||
stmt->parameters[ipar].scale = ibScale;
|
stmt->parameters[ipar].scale = ibScale;
|
||||||
|
|
||||||
/* If rebinding a parameter that had data-at-exec stuff in it,
|
/*
|
||||||
then free that stuff
|
* If rebinding a parameter that had data-at-exec stuff in it, then
|
||||||
|
* free that stuff
|
||||||
*/
|
*/
|
||||||
if (stmt->parameters[ipar].EXEC_used) {
|
if (stmt->parameters[ipar].EXEC_used)
|
||||||
|
{
|
||||||
free(stmt->parameters[ipar].EXEC_used);
|
free(stmt->parameters[ipar].EXEC_used);
|
||||||
stmt->parameters[ipar].EXEC_used = NULL;
|
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)
|
if (stmt->parameters[ipar].SQLType != SQL_LONGVARBINARY)
|
||||||
free(stmt->parameters[ipar].EXEC_buffer);
|
free(stmt->parameters[ipar].EXEC_buffer);
|
||||||
stmt->parameters[ipar].EXEC_buffer = NULL;
|
stmt->parameters[ipar].EXEC_buffer = NULL;
|
||||||
@ -134,7 +148,7 @@ static char *func="SQLBindParameter";
|
|||||||
else
|
else
|
||||||
stmt->parameters[ipar].data_at_exec = FALSE;
|
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;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -142,22 +156,24 @@ static char *func="SQLBindParameter";
|
|||||||
/* - - - - - - - - - */
|
/* - - - - - - - - - */
|
||||||
|
|
||||||
/* Associate a user-supplied buffer with a database column. */
|
/* Associate a user-supplied buffer with a database column. */
|
||||||
RETCODE SQL_API SQLBindCol(
|
RETCODE SQL_API
|
||||||
|
SQLBindCol(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UWORD icol,
|
UWORD icol,
|
||||||
SWORD fCType,
|
SWORD fCType,
|
||||||
PTR rgbValue,
|
PTR rgbValue,
|
||||||
SDWORD cbValueMax,
|
SDWORD cbValueMax,
|
||||||
SDWORD FAR *pcbValue)
|
SDWORD FAR * pcbValue)
|
||||||
{
|
{
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
static char *func="SQLBindCol";
|
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);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
@ -165,7 +181,8 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
|||||||
|
|
||||||
SC_clear_error(stmt);
|
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->errormsg = "Can't bind columns while statement is still executing.";
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -173,15 +190,19 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If the bookmark column is being bound, then just save it */
|
/* If the bookmark column is being bound, then just save it */
|
||||||
if (icol == 0) {
|
if (icol == 0)
|
||||||
|
{
|
||||||
|
|
||||||
if (rgbValue == NULL) {
|
if (rgbValue == NULL)
|
||||||
|
{
|
||||||
stmt->bookmark.buffer = NULL;
|
stmt->bookmark.buffer = NULL;
|
||||||
stmt->bookmark.used = NULL;
|
stmt->bookmark.used = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* Make sure it is the bookmark data type */
|
/* Make sure it is the bookmark data type */
|
||||||
if ( fCType != SQL_C_BOOKMARK) {
|
if (fCType != SQL_C_BOOKMARK)
|
||||||
|
{
|
||||||
stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
|
stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
|
||||||
stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
|
stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -198,29 +219,34 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
|||||||
/* Most likely, execution of a statement would have setup the */
|
/* Most likely, execution of a statement would have setup the */
|
||||||
/* necessary bindings. But some apps call BindCol before any */
|
/* necessary bindings. But some apps call BindCol before any */
|
||||||
/* statement is executed. */
|
/* statement is executed. */
|
||||||
if ( icol > stmt->bindings_allocated)
|
if (icol > stmt->bindings_allocated)
|
||||||
extend_bindings(stmt, icol);
|
extend_bindings(stmt, icol);
|
||||||
|
|
||||||
/* check to see if the bindings were allocated */
|
/* check to see if the bindings were allocated */
|
||||||
if ( ! stmt->bindings) {
|
if (!stmt->bindings)
|
||||||
|
{
|
||||||
stmt->errormsg = "Could not allocate memory for bindings.";
|
stmt->errormsg = "Could not allocate memory for bindings.";
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR;
|
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;
|
stmt->bindings[icol].data_left = -1;
|
||||||
|
|
||||||
if (rgbValue == NULL) {
|
if (rgbValue == NULL)
|
||||||
|
{
|
||||||
/* we have to unbind the column */
|
/* we have to unbind the column */
|
||||||
stmt->bindings[icol].buflen = 0;
|
stmt->bindings[icol].buflen = 0;
|
||||||
stmt->bindings[icol].buffer = NULL;
|
stmt->bindings[icol].buffer = NULL;
|
||||||
stmt->bindings[icol].used = NULL;
|
stmt->bindings[icol].used = NULL;
|
||||||
stmt->bindings[icol].returntype = SQL_C_CHAR;
|
stmt->bindings[icol].returntype = SQL_C_CHAR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* ok, bind that column */
|
/* ok, bind that column */
|
||||||
stmt->bindings[icol].buflen = cbValueMax;
|
stmt->bindings[icol].buflen = cbValueMax;
|
||||||
stmt->bindings[icol].buffer = rgbValue;
|
stmt->bindings[icol].buffer = rgbValue;
|
||||||
@ -242,25 +268,28 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
|||||||
/* it is best to say this function is not supported and let the application assume a */
|
/* it is best to say this function is not supported and let the application assume a */
|
||||||
/* data type (most likely varchar). */
|
/* data type (most likely varchar). */
|
||||||
|
|
||||||
RETCODE SQL_API SQLDescribeParam(
|
RETCODE SQL_API
|
||||||
|
SQLDescribeParam(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UWORD ipar,
|
UWORD ipar,
|
||||||
SWORD FAR *pfSqlType,
|
SWORD FAR * pfSqlType,
|
||||||
UDWORD FAR *pcbColDef,
|
UDWORD FAR * pcbColDef,
|
||||||
SWORD FAR *pibScale,
|
SWORD FAR * pibScale,
|
||||||
SWORD FAR *pfNullable)
|
SWORD FAR * pfNullable)
|
||||||
{
|
{
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
static char *func = "SQLDescribeParam";
|
static char *func = "SQLDescribeParam";
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
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->errormsg = "Invalid parameter number for SQLDescribeParam.";
|
||||||
stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR;
|
stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -269,18 +298,21 @@ static char *func = "SQLDescribeParam";
|
|||||||
|
|
||||||
ipar--;
|
ipar--;
|
||||||
|
|
||||||
/* This implementation is not very good, since it is supposed to describe */
|
/*
|
||||||
|
* This implementation is not very good, since it is supposed to
|
||||||
|
* describe
|
||||||
|
*/
|
||||||
/* parameter markers, not bound parameters. */
|
/* parameter markers, not bound parameters. */
|
||||||
if(pfSqlType)
|
if (pfSqlType)
|
||||||
*pfSqlType = stmt->parameters[ipar].SQLType;
|
*pfSqlType = stmt->parameters[ipar].SQLType;
|
||||||
|
|
||||||
if(pcbColDef)
|
if (pcbColDef)
|
||||||
*pcbColDef = stmt->parameters[ipar].precision;
|
*pcbColDef = stmt->parameters[ipar].precision;
|
||||||
|
|
||||||
if(pibScale)
|
if (pibScale)
|
||||||
*pibScale = stmt->parameters[ipar].scale;
|
*pibScale = stmt->parameters[ipar].scale;
|
||||||
|
|
||||||
if(pfNullable)
|
if (pfNullable)
|
||||||
*pfNullable = pgtype_nullable(stmt, stmt->parameters[ipar].paramType);
|
*pfNullable = pgtype_nullable(stmt, stmt->parameters[ipar].paramType);
|
||||||
|
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
@ -290,14 +322,15 @@ static char *func = "SQLDescribeParam";
|
|||||||
|
|
||||||
/* Sets multiple values (arrays) for the set of parameter markers. */
|
/* Sets multiple values (arrays) for the set of parameter markers. */
|
||||||
|
|
||||||
RETCODE SQL_API SQLParamOptions(
|
RETCODE SQL_API
|
||||||
|
SQLParamOptions(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UDWORD crow,
|
UDWORD crow,
|
||||||
UDWORD FAR *pirow)
|
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);
|
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
@ -312,43 +345,51 @@ static char *func = "SQLParamOptions";
|
|||||||
/* like it does for SQLDescribeParam is that some applications don't care and try */
|
/* like it does for SQLDescribeParam is that some applications don't care and try */
|
||||||
/* to call it anyway. */
|
/* to call it anyway. */
|
||||||
/* If the statement does not have parameters, it should just return 0. */
|
/* If the statement does not have parameters, it should just return 0. */
|
||||||
RETCODE SQL_API SQLNumParams(
|
RETCODE SQL_API
|
||||||
|
SQLNumParams(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
SWORD FAR *pcpar)
|
SWORD FAR * pcpar)
|
||||||
{
|
{
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
char in_quote = FALSE;
|
char in_quote = FALSE;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
static char *func = "SQLNumParams";
|
static char *func = "SQLNumParams";
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if(!stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcpar)
|
if (pcpar)
|
||||||
*pcpar = 0;
|
*pcpar = 0;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
SC_log_error(func, "pcpar was null", stmt);
|
SC_log_error(func, "pcpar was null", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!stmt->statement) {
|
if (!stmt->statement)
|
||||||
|
{
|
||||||
/* no statement has been allocated */
|
/* no statement has been allocated */
|
||||||
stmt->errormsg = "SQLNumParams called with no statement ready.";
|
stmt->errormsg = "SQLNumParams called with no statement ready.";
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
for(i=0; i < strlen(stmt->statement); i++) {
|
for (i = 0; i < strlen(stmt->statement); i++)
|
||||||
|
{
|
||||||
|
|
||||||
if(stmt->statement[i] == '?' && !in_quote)
|
if (stmt->statement[i] == '?' && !in_quote)
|
||||||
(*pcpar)++;
|
(*pcpar)++;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
if (stmt->statement[i] == '\'')
|
if (stmt->statement[i] == '\'')
|
||||||
in_quote = (in_quote ? FALSE : TRUE);
|
in_quote = (in_quote ? FALSE : TRUE);
|
||||||
}
|
}
|
||||||
@ -364,15 +405,15 @@ static char *func = "SQLNumParams";
|
|||||||
BindInfoClass *
|
BindInfoClass *
|
||||||
create_empty_bindings(int num_columns)
|
create_empty_bindings(int num_columns)
|
||||||
{
|
{
|
||||||
BindInfoClass *new_bindings;
|
BindInfoClass *new_bindings;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
new_bindings = (BindInfoClass *)malloc(num_columns * sizeof(BindInfoClass));
|
new_bindings = (BindInfoClass *) malloc(num_columns * sizeof(BindInfoClass));
|
||||||
if(!new_bindings) {
|
if (!new_bindings)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i < num_columns; i++) {
|
for (i = 0; i < num_columns; i++)
|
||||||
|
{
|
||||||
new_bindings[i].buflen = 0;
|
new_bindings[i].buflen = 0;
|
||||||
new_bindings[i].buffer = NULL;
|
new_bindings[i].buffer = NULL;
|
||||||
new_bindings[i].used = NULL;
|
new_bindings[i].used = NULL;
|
||||||
@ -383,23 +424,26 @@ int i;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
extend_bindings(StatementClass *stmt, int num_columns)
|
extend_bindings(StatementClass * stmt, int num_columns)
|
||||||
{
|
{
|
||||||
static char *func="extend_bindings";
|
static char *func = "extend_bindings";
|
||||||
BindInfoClass *new_bindings;
|
BindInfoClass *new_bindings;
|
||||||
int i;
|
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 */
|
/* if we have too few, allocate room for more, and copy the old */
|
||||||
/* entries into the new structure */
|
/* entries into the new structure */
|
||||||
if(stmt->bindings_allocated < num_columns) {
|
if (stmt->bindings_allocated < num_columns)
|
||||||
|
{
|
||||||
|
|
||||||
new_bindings = create_empty_bindings(num_columns);
|
new_bindings = create_empty_bindings(num_columns);
|
||||||
if ( ! new_bindings) {
|
if (!new_bindings)
|
||||||
|
{
|
||||||
mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated);
|
mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated);
|
||||||
|
|
||||||
if (stmt->bindings) {
|
if (stmt->bindings)
|
||||||
|
{
|
||||||
free(stmt->bindings);
|
free(stmt->bindings);
|
||||||
stmt->bindings = NULL;
|
stmt->bindings = NULL;
|
||||||
}
|
}
|
||||||
@ -407,8 +451,9 @@ mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stmt->bindings) {
|
if (stmt->bindings)
|
||||||
for(i=0; i<stmt->bindings_allocated; i++)
|
{
|
||||||
|
for (i = 0; i < stmt->bindings_allocated; i++)
|
||||||
new_bindings[i] = stmt->bindings[i];
|
new_bindings[i] = stmt->bindings[i];
|
||||||
|
|
||||||
free(stmt->bindings);
|
free(stmt->bindings);
|
||||||
|
@ -15,18 +15,24 @@
|
|||||||
/*
|
/*
|
||||||
* BindInfoClass -- stores information about a bound column
|
* BindInfoClass -- stores information about a bound column
|
||||||
*/
|
*/
|
||||||
struct BindInfoClass_ {
|
struct BindInfoClass_
|
||||||
|
{
|
||||||
Int4 buflen; /* size of buffer */
|
Int4 buflen; /* size of buffer */
|
||||||
Int4 data_left; /* amount of data left to read (SQLGetData) */
|
Int4 data_left; /* amount of data left to read
|
||||||
|
* (SQLGetData) */
|
||||||
char *buffer; /* pointer to the buffer */
|
char *buffer; /* pointer to the buffer */
|
||||||
Int4 *used; /* used space in the buffer (for strings not counting the '\0') */
|
Int4 *used; /* used space in the buffer (for strings
|
||||||
Int2 returntype; /* kind of conversion to be applied when returning (SQL_C_DEFAULT, SQL_C_CHAR...) */
|
* 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
|
* ParameterInfoClass -- stores information about a bound parameter
|
||||||
*/
|
*/
|
||||||
struct ParameterInfoClass_ {
|
struct ParameterInfoClass_
|
||||||
|
{
|
||||||
Int4 buflen;
|
Int4 buflen;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
Int4 *used;
|
Int4 *used;
|
||||||
@ -36,12 +42,13 @@ struct ParameterInfoClass_ {
|
|||||||
UInt4 precision;
|
UInt4 precision;
|
||||||
Int2 scale;
|
Int2 scale;
|
||||||
Oid lobj_oid;
|
Oid lobj_oid;
|
||||||
Int4 *EXEC_used; /* amount of data OR the oid of the large object */
|
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 *EXEC_buffer; /* the data or the FD of the large object */
|
||||||
char data_at_exec;
|
char data_at_exec;
|
||||||
};
|
};
|
||||||
|
|
||||||
BindInfoClass *create_empty_bindings(int num_columns);
|
BindInfoClass *create_empty_bindings(int num_columns);
|
||||||
void extend_bindings(StatementClass *stmt, int num_columns);
|
void extend_bindings(StatementClass * stmt, int num_columns);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,11 +20,12 @@
|
|||||||
ColumnInfoClass *
|
ColumnInfoClass *
|
||||||
CI_Constructor()
|
CI_Constructor()
|
||||||
{
|
{
|
||||||
ColumnInfoClass *rv;
|
ColumnInfoClass *rv;
|
||||||
|
|
||||||
rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
|
rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
|
||||||
|
|
||||||
if (rv) {
|
if (rv)
|
||||||
|
{
|
||||||
rv->num_fields = 0;
|
rv->num_fields = 0;
|
||||||
rv->name = NULL;
|
rv->name = NULL;
|
||||||
rv->adtid = NULL;
|
rv->adtid = NULL;
|
||||||
@ -37,7 +38,7 @@ ColumnInfoClass *rv;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CI_Destructor(ColumnInfoClass *self)
|
CI_Destructor(ColumnInfoClass * self)
|
||||||
{
|
{
|
||||||
CI_free_memory(self);
|
CI_free_memory(self);
|
||||||
|
|
||||||
@ -49,16 +50,16 @@ CI_Destructor(ColumnInfoClass *self)
|
|||||||
If self is null, then just read, don't store.
|
If self is null, then just read, don't store.
|
||||||
*/
|
*/
|
||||||
char
|
char
|
||||||
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
|
CI_read_fields(ColumnInfoClass * self, ConnectionClass * conn)
|
||||||
{
|
{
|
||||||
Int2 lf;
|
Int2 lf;
|
||||||
int new_num_fields;
|
int new_num_fields;
|
||||||
Oid new_adtid;
|
Oid new_adtid;
|
||||||
Int2 new_adtsize;
|
Int2 new_adtsize;
|
||||||
Int4 new_atttypmod = -1;
|
Int4 new_atttypmod = -1;
|
||||||
char new_field_name[MAX_MESSAGE_LEN+1];
|
char new_field_name[MAX_MESSAGE_LEN + 1];
|
||||||
SocketClass *sock;
|
SocketClass *sock;
|
||||||
ConnInfo *ci;
|
ConnInfo *ci;
|
||||||
|
|
||||||
sock = CC_get_socket(conn);
|
sock = CC_get_socket(conn);
|
||||||
ci = &conn->connInfo;
|
ci = &conn->connInfo;
|
||||||
@ -68,19 +69,22 @@ ConnInfo *ci;
|
|||||||
|
|
||||||
mylog("num_fields = %d\n", new_num_fields);
|
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);
|
CI_set_num_fields(self, new_num_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now read in the descriptions */
|
/* 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);
|
SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN);
|
||||||
new_adtid = (Oid) SOCK_get_int(sock, 4);
|
new_adtid = (Oid) SOCK_get_int(sock, 4);
|
||||||
new_adtsize = (Int2) SOCK_get_int(sock, 2);
|
new_adtsize = (Int2) SOCK_get_int(sock, 2);
|
||||||
|
|
||||||
/* If 6.4 protocol, then read the atttypmod field */
|
/* If 6.4 protocol, then read the atttypmod field */
|
||||||
if (PG_VERSION_GE(conn, 6.4)) {
|
if (PG_VERSION_GE(conn, 6.4))
|
||||||
|
{
|
||||||
|
|
||||||
mylog("READING ATTTYPMOD\n");
|
mylog("READING ATTTYPMOD\n");
|
||||||
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
|
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
|
||||||
@ -104,14 +108,15 @@ ConnInfo *ci;
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CI_free_memory(ColumnInfoClass *self)
|
CI_free_memory(ColumnInfoClass * self)
|
||||||
{
|
{
|
||||||
register Int2 lf;
|
register Int2 lf;
|
||||||
int num_fields = self->num_fields;
|
int num_fields = self->num_fields;
|
||||||
|
|
||||||
for (lf = 0; lf < num_fields; lf++) {
|
for (lf = 0; lf < num_fields; lf++)
|
||||||
if( self->name[lf])
|
{
|
||||||
free (self->name[lf]);
|
if (self->name[lf])
|
||||||
|
free(self->name[lf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Safe to call even if null */
|
/* Safe to call even if null */
|
||||||
@ -124,28 +129,27 @@ int num_fields = self->num_fields;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
|
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->num_fields = new_num_fields;
|
||||||
|
|
||||||
self->name = (char **) malloc (sizeof(char *) * self->num_fields);
|
self->name = (char **) malloc(sizeof(char *) * self->num_fields);
|
||||||
self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields);
|
self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields);
|
||||||
self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields);
|
self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
|
||||||
self->display_size = (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);
|
self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
CI_set_field_info(ColumnInfoClass * self, int field_num, char *new_name,
|
||||||
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
|
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* check bounds */
|
/* check bounds */
|
||||||
if((field_num < 0) || (field_num >= self->num_fields)) {
|
if ((field_num < 0) || (field_num >= self->num_fields))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* store the info */
|
/* store the info */
|
||||||
self->name[field_num] = strdup(new_name);
|
self->name[field_num] = strdup(new_name);
|
||||||
@ -155,4 +159,3 @@ CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
|||||||
|
|
||||||
self->display_size[field_num] = 0;
|
self->display_size[field_num] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
#include "psqlodbc.h"
|
#include "psqlodbc.h"
|
||||||
|
|
||||||
struct ColumnInfoClass_ {
|
struct ColumnInfoClass_
|
||||||
|
{
|
||||||
Int2 num_fields;
|
Int2 num_fields;
|
||||||
char **name; /* list of type names */
|
char **name; /* list of type names */
|
||||||
Oid *adtid; /* list of type ids */
|
Oid *adtid; /* list of type ids */
|
||||||
@ -29,14 +30,14 @@ struct ColumnInfoClass_ {
|
|||||||
#define CI_get_atttypmod(self, col) (self->atttypmod[col])
|
#define CI_get_atttypmod(self, col) (self->atttypmod[col])
|
||||||
|
|
||||||
ColumnInfoClass *CI_Constructor(void);
|
ColumnInfoClass *CI_Constructor(void);
|
||||||
void CI_Destructor(ColumnInfoClass *self);
|
void CI_Destructor(ColumnInfoClass * self);
|
||||||
void CI_free_memory(ColumnInfoClass *self);
|
void CI_free_memory(ColumnInfoClass * self);
|
||||||
char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
|
char CI_read_fields(ColumnInfoClass * self, ConnectionClass * conn);
|
||||||
|
|
||||||
/* functions for setting up the fields from within the program, */
|
/* functions for setting up the fields from within the program, */
|
||||||
/* without reading from a socket */
|
/* without reading from a socket */
|
||||||
void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields);
|
void CI_set_num_fields(ColumnInfoClass * self, int new_num_fields);
|
||||||
void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
|
void CI_set_field_info(ColumnInfoClass * self, int field_num, char *new_name,
|
||||||
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
|
Oid new_adtid, Int2 new_adtsize, Int4 atttypmod);
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,11 +27,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
CONN_NOT_CONNECTED, /* Connection has not been established */
|
CONN_NOT_CONNECTED, /* Connection has not been established */
|
||||||
CONN_CONNECTED, /* Connection is up and has been established */
|
CONN_CONNECTED, /* Connection is up and has been
|
||||||
|
* established */
|
||||||
CONN_DOWN, /* Connection is broken */
|
CONN_DOWN, /* Connection is broken */
|
||||||
CONN_EXECUTING /* the connection is currently executing a statement */
|
CONN_EXECUTING /* the connection is currently executing a
|
||||||
|
* statement */
|
||||||
} CONN_Status;
|
} CONN_Status;
|
||||||
|
|
||||||
/* These errors have general sql error state */
|
/* These errors have general sql error state */
|
||||||
@ -122,7 +125,8 @@ typedef struct _StartupPacket
|
|||||||
/* Structure to hold all the connection attributes for a specific
|
/* Structure to hold all the connection attributes for a specific
|
||||||
connection (used for both registry and file, DSN and DRIVER)
|
connection (used for both registry and file, DSN and DRIVER)
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
char dsn[MEDIUM_REGISTRY_LEN];
|
char dsn[MEDIUM_REGISTRY_LEN];
|
||||||
char desc[MEDIUM_REGISTRY_LEN];
|
char desc[MEDIUM_REGISTRY_LEN];
|
||||||
char driver[MEDIUM_REGISTRY_LEN];
|
char driver[MEDIUM_REGISTRY_LEN];
|
||||||
@ -180,9 +184,10 @@ typedef struct {
|
|||||||
#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
|
#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
|
||||||
|
|
||||||
/* This is used to store cached table information in the connection */
|
/* This is used to store cached table information in the connection */
|
||||||
struct col_info {
|
struct col_info
|
||||||
|
{
|
||||||
QResultClass *result;
|
QResultClass *result;
|
||||||
char name[MAX_TABLE_LEN+1];
|
char name[MAX_TABLE_LEN + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Translation DLL entry points */
|
/* Translation DLL entry points */
|
||||||
@ -194,7 +199,7 @@ struct col_info {
|
|||||||
#define HINSTANCE void *
|
#define HINSTANCE void *
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef BOOL (FAR WINAPI *DataSourceToDriverProc) (UDWORD,
|
typedef BOOL(FAR WINAPI * DataSourceToDriverProc) (UDWORD,
|
||||||
SWORD,
|
SWORD,
|
||||||
PTR,
|
PTR,
|
||||||
SDWORD,
|
SDWORD,
|
||||||
@ -205,7 +210,7 @@ typedef BOOL (FAR WINAPI *DataSourceToDriverProc) (UDWORD,
|
|||||||
SWORD,
|
SWORD,
|
||||||
SWORD FAR *);
|
SWORD FAR *);
|
||||||
|
|
||||||
typedef BOOL (FAR WINAPI *DriverToDataSourceProc) (UDWORD,
|
typedef BOOL(FAR WINAPI * DriverToDataSourceProc) (UDWORD,
|
||||||
SWORD,
|
SWORD,
|
||||||
PTR,
|
PTR,
|
||||||
SDWORD,
|
SDWORD,
|
||||||
@ -217,8 +222,10 @@ typedef BOOL (FAR WINAPI *DriverToDataSourceProc) (UDWORD,
|
|||||||
SWORD FAR *);
|
SWORD FAR *);
|
||||||
|
|
||||||
/******* The Connection handle ************/
|
/******* The Connection handle ************/
|
||||||
struct ConnectionClass_ {
|
struct ConnectionClass_
|
||||||
HENV henv; /* environment this connection was created on */
|
{
|
||||||
|
HENV henv; /* environment this connection was created
|
||||||
|
* on */
|
||||||
StatementOptions stmtOptions;
|
StatementOptions stmtOptions;
|
||||||
char *errormsg;
|
char *errormsg;
|
||||||
int errornumber;
|
int errornumber;
|
||||||
@ -234,9 +241,13 @@ struct ConnectionClass_ {
|
|||||||
HINSTANCE translation_handle;
|
HINSTANCE translation_handle;
|
||||||
DataSourceToDriverProc DataSourceToDriver;
|
DataSourceToDriverProc DataSourceToDriver;
|
||||||
DriverToDataSourceProc DriverToDataSource;
|
DriverToDataSourceProc DriverToDataSource;
|
||||||
char transact_status; /* Is a transaction is currently in progress */
|
char transact_status;/* Is a transaction is currently in
|
||||||
char errormsg_created; /* has an informative error msg been created? */
|
* progress */
|
||||||
char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */
|
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;
|
float pg_version_number;
|
||||||
Int2 pg_version_major;
|
Int2 pg_version_major;
|
||||||
Int2 pg_version_minor;
|
Int2 pg_version_minor;
|
||||||
@ -259,24 +270,24 @@ struct ConnectionClass_ {
|
|||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
ConnectionClass *CC_Constructor(void);
|
ConnectionClass *CC_Constructor(void);
|
||||||
char CC_Destructor(ConnectionClass *self);
|
char CC_Destructor(ConnectionClass * self);
|
||||||
int CC_cursor_count(ConnectionClass *self);
|
int CC_cursor_count(ConnectionClass * self);
|
||||||
char CC_cleanup(ConnectionClass *self);
|
char CC_cleanup(ConnectionClass * self);
|
||||||
char CC_abort(ConnectionClass *self);
|
char CC_abort(ConnectionClass * self);
|
||||||
int CC_set_translation (ConnectionClass *self);
|
int CC_set_translation(ConnectionClass * self);
|
||||||
char CC_connect(ConnectionClass *self, char do_password);
|
char CC_connect(ConnectionClass * self, char do_password);
|
||||||
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
|
char CC_add_statement(ConnectionClass * self, StatementClass * stmt);
|
||||||
char CC_remove_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_get_error(ConnectionClass * self, int *number, char **message);
|
||||||
QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi);
|
QResultClass *CC_send_query(ConnectionClass * self, char *query, QueryInfo * qi);
|
||||||
void CC_clear_error(ConnectionClass *self);
|
void CC_clear_error(ConnectionClass * self);
|
||||||
char *CC_create_errormsg(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);
|
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);
|
char CC_send_settings(ConnectionClass * self);
|
||||||
void CC_lookup_lo(ConnectionClass *conn);
|
void CC_lookup_lo(ConnectionClass * conn);
|
||||||
void CC_lookup_pg_version(ConnectionClass *conn);
|
void CC_lookup_pg_version(ConnectionClass * conn);
|
||||||
void CC_initialize_pg_version(ConnectionClass *conn);
|
void CC_initialize_pg_version(ConnectionClass * conn);
|
||||||
void CC_log_error(char *func, char *desc, ConnectionClass *self);
|
void CC_log_error(char *func, char *desc, ConnectionClass * self);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,8 @@
|
|||||||
#define COPY_GENERAL_ERROR 4
|
#define COPY_GENERAL_ERROR 4
|
||||||
#define COPY_NO_DATA_FOUND 5
|
#define COPY_NO_DATA_FOUND 5
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
int m;
|
int m;
|
||||||
int d;
|
int d;
|
||||||
int y;
|
int y;
|
||||||
@ -29,14 +30,14 @@ typedef struct {
|
|||||||
int ss;
|
int ss;
|
||||||
} SIMPLE_TIME;
|
} SIMPLE_TIME;
|
||||||
|
|
||||||
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
|
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,
|
int copy_and_convert_field(StatementClass * stmt, Int4 field_type, void *value, Int2 fCType,
|
||||||
PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
|
PTR rgbValue, SDWORD cbValueMax, SDWORD * pcbValue);
|
||||||
|
|
||||||
int copy_statement_with_parameters(StatementClass *stmt);
|
int copy_statement_with_parameters(StatementClass * stmt);
|
||||||
char *convert_escape(char *value);
|
char *convert_escape(char *value);
|
||||||
char *convert_money(char *s);
|
char *convert_money(char *s);
|
||||||
char parse_datetime(char *buf, SIMPLE_TIME *st);
|
char parse_datetime(char *buf, SIMPLE_TIME * st);
|
||||||
int convert_linefeeds(char *s, char *dst, size_t max);
|
int convert_linefeeds(char *s, char *dst, size_t max);
|
||||||
char *convert_special_chars(char *si, char *dst, int used);
|
char *convert_special_chars(char *si, char *dst, int used);
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbV
|
|||||||
int convert_to_pgbinary(unsigned char *in, char *out, int len);
|
int convert_to_pgbinary(unsigned char *in, char *out, int len);
|
||||||
void encode(char *in, char *out);
|
void encode(char *in, char *out);
|
||||||
void decode(char *in, char *out);
|
void decode(char *in, char *out);
|
||||||
int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
|
int convert_lo(StatementClass * stmt, void *value, Int2 fCType, PTR rgbValue,
|
||||||
SDWORD cbValueMax, SDWORD *pcbValue);
|
SDWORD cbValueMax, SDWORD * pcbValue);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
# include <string.h>
|
#include <string.h>
|
||||||
# include "gpps.h"
|
#include "gpps.h"
|
||||||
# define SQLGetPrivateProfileString(a,b,c,d,e,f) GetPrivateProfileString(a,b,c,d,e,f)
|
#define SQLGetPrivateProfileString(a,b,c,d,e,f) GetPrivateProfileString(a,b,c,d,e,f)
|
||||||
# define SQLWritePrivateProfileString(a,b,c,d) WritePrivateProfileString(a,b,c,d)
|
#define SQLWritePrivateProfileString(a,b,c,d) WritePrivateProfileString(a,b,c,d)
|
||||||
# ifndef HAVE_STRICMP
|
#ifndef HAVE_STRICMP
|
||||||
# define stricmp(s1,s2) strcasecmp(s1,s2)
|
#define stricmp(s1,s2) strcasecmp(s1,s2)
|
||||||
# define strnicmp(s1,s2,n) strncasecmp(s1,s2,n)
|
#define strnicmp(s1,s2,n) strncasecmp(s1,s2,n)
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "dlg_specific.h"
|
#include "dlg_specific.h"
|
||||||
@ -47,10 +47,15 @@ extern GLOBAL_VALUES globals;
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
void
|
void
|
||||||
SetDlgStuff(HWND hdlg, ConnInfo *ci)
|
SetDlgStuff(HWND hdlg, ConnInfo * ci)
|
||||||
{
|
{
|
||||||
/* If driver attribute NOT present, then set the datasource name and description */
|
|
||||||
if (ci->driver[0] == '\0') {
|
/*
|
||||||
|
* If driver attribute NOT present, then set the datasource name and
|
||||||
|
* description
|
||||||
|
*/
|
||||||
|
if (ci->driver[0] == '\0')
|
||||||
|
{
|
||||||
SetDlgItemText(hdlg, IDC_DSNAME, ci->dsn);
|
SetDlgItemText(hdlg, IDC_DSNAME, ci->dsn);
|
||||||
SetDlgItemText(hdlg, IDC_DESC, ci->desc);
|
SetDlgItemText(hdlg, IDC_DESC, ci->desc);
|
||||||
}
|
}
|
||||||
@ -63,7 +68,7 @@ SetDlgStuff(HWND hdlg, ConnInfo *ci)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GetDlgStuff(HWND hdlg, ConnInfo *ci)
|
GetDlgStuff(HWND hdlg, ConnInfo * ci)
|
||||||
{
|
{
|
||||||
GetDlgItemText(hdlg, IDC_DESC, ci->desc, sizeof(ci->desc));
|
GetDlgItemText(hdlg, IDC_DESC, ci->desc, sizeof(ci->desc));
|
||||||
|
|
||||||
@ -76,12 +81,14 @@ GetDlgStuff(HWND hdlg, ConnInfo *ci)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int CALLBACK driver_optionsProc(HWND hdlg,
|
int CALLBACK
|
||||||
|
driver_optionsProc(HWND hdlg,
|
||||||
WORD wMsg,
|
WORD wMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch (wMsg) {
|
switch (wMsg)
|
||||||
|
{
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
|
|
||||||
CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog);
|
CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog);
|
||||||
@ -92,7 +99,8 @@ int CALLBACK driver_optionsProc(HWND hdlg,
|
|||||||
CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, globals.use_declarefetch);
|
CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, globals.use_declarefetch);
|
||||||
|
|
||||||
/* Unknown (Default) Data Type sizes */
|
/* Unknown (Default) Data Type sizes */
|
||||||
switch(globals.unknown_sizes) {
|
switch (globals.unknown_sizes)
|
||||||
|
{
|
||||||
case UNKNOWNS_AS_DONTKNOW:
|
case UNKNOWNS_AS_DONTKNOW:
|
||||||
CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
|
CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
|
||||||
break;
|
break;
|
||||||
@ -125,7 +133,8 @@ int CALLBACK driver_optionsProc(HWND hdlg,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
{
|
||||||
case IDOK:
|
case IDOK:
|
||||||
|
|
||||||
globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
|
globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
|
||||||
@ -155,7 +164,8 @@ int CALLBACK driver_optionsProc(HWND hdlg,
|
|||||||
|
|
||||||
globals.fetch_max = GetDlgItemInt(hdlg, DRV_CACHE_SIZE, NULL, FALSE);
|
globals.fetch_max = GetDlgItemInt(hdlg, DRV_CACHE_SIZE, NULL, FALSE);
|
||||||
globals.max_varchar_size = GetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, NULL, FALSE);
|
globals.max_varchar_size = GetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, NULL, FALSE);
|
||||||
globals.max_longvarchar_size= GetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, NULL, TRUE); /* allows for SQL_NO_TOTAL */
|
globals.max_longvarchar_size = GetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, NULL, TRUE); /* allows for
|
||||||
|
* SQL_NO_TOTAL */
|
||||||
|
|
||||||
GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes, sizeof(globals.extra_systable_prefixes));
|
GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes, sizeof(globals.extra_systable_prefixes));
|
||||||
|
|
||||||
@ -185,7 +195,8 @@ int CALLBACK driver_optionsProc(HWND hdlg,
|
|||||||
CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 0);
|
CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 0);
|
||||||
CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 0);
|
CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 0);
|
||||||
CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 0);
|
CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 0);
|
||||||
switch(DEFAULT_UNKNOWNSIZES) {
|
switch (DEFAULT_UNKNOWNSIZES)
|
||||||
|
{
|
||||||
case UNKNOWNS_AS_DONTKNOW:
|
case UNKNOWNS_AS_DONTKNOW:
|
||||||
CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
|
CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
|
||||||
break;
|
break;
|
||||||
@ -218,15 +229,17 @@ int CALLBACK driver_optionsProc(HWND hdlg,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CALLBACK ds_optionsProc(HWND hdlg,
|
int CALLBACK
|
||||||
|
ds_optionsProc(HWND hdlg,
|
||||||
WORD wMsg,
|
WORD wMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
ConnInfo *ci;
|
ConnInfo *ci;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
switch (wMsg) {
|
switch (wMsg)
|
||||||
|
{
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
ci = (ConnInfo *) lParam;
|
ci = (ConnInfo *) lParam;
|
||||||
SetWindowLong(hdlg, DWL_USER, lParam); /* save for OK */
|
SetWindowLong(hdlg, DWL_USER, lParam); /* save for OK */
|
||||||
@ -234,7 +247,8 @@ char buf[128];
|
|||||||
/* Change window caption */
|
/* Change window caption */
|
||||||
if (ci->driver[0])
|
if (ci->driver[0])
|
||||||
SetWindowText(hdlg, "Advanced Options (Connection)");
|
SetWindowText(hdlg, "Advanced Options (Connection)");
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
sprintf(buf, "Advanced Options (%s)", ci->dsn);
|
sprintf(buf, "Advanced Options (%s)", ci->dsn);
|
||||||
SetWindowText(hdlg, buf);
|
SetWindowText(hdlg, buf);
|
||||||
}
|
}
|
||||||
@ -260,7 +274,8 @@ char buf[128];
|
|||||||
|
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
{
|
||||||
case DS_SHOWOIDCOLUMN:
|
case DS_SHOWOIDCOLUMN:
|
||||||
mylog("WM_COMMAND: DS_SHOWOIDCOLUMN\n");
|
mylog("WM_COMMAND: DS_SHOWOIDCOLUMN\n");
|
||||||
EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
|
EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
|
||||||
@ -269,7 +284,7 @@ char buf[128];
|
|||||||
|
|
||||||
case IDOK:
|
case IDOK:
|
||||||
|
|
||||||
ci = (ConnInfo *)GetWindowLong(hdlg, DWL_USER);
|
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
||||||
mylog("IDOK: got ci = %u\n", ci);
|
mylog("IDOK: got ci = %u\n", ci);
|
||||||
|
|
||||||
/* Readonly */
|
/* Readonly */
|
||||||
@ -282,7 +297,7 @@ char buf[128];
|
|||||||
|
|
||||||
sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING));
|
sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING));
|
||||||
|
|
||||||
/* OID Options*/
|
/* OID Options */
|
||||||
sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX));
|
sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX));
|
||||||
sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
|
sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
|
||||||
|
|
||||||
@ -304,10 +319,10 @@ char buf[128];
|
|||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
void
|
void
|
||||||
makeConnectString(char *connect_string, ConnInfo *ci)
|
makeConnectString(char *connect_string, ConnInfo * ci)
|
||||||
{
|
{
|
||||||
char got_dsn = (ci->dsn[0] != '\0');
|
char got_dsn = (ci->dsn[0] != '\0');
|
||||||
char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
||||||
|
|
||||||
/* fundamental info */
|
/* fundamental info */
|
||||||
sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s",
|
sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s",
|
||||||
@ -334,28 +349,28 @@ char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copyAttributes(ConnInfo *ci, char *attribute, char *value)
|
copyAttributes(ConnInfo * ci, char *attribute, char *value)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(stricmp(attribute, "DSN") == 0)
|
if (stricmp(attribute, "DSN") == 0)
|
||||||
strcpy(ci->dsn, value);
|
strcpy(ci->dsn, value);
|
||||||
|
|
||||||
else if(stricmp(attribute, "driver") == 0)
|
else if (stricmp(attribute, "driver") == 0)
|
||||||
strcpy(ci->driver, value);
|
strcpy(ci->driver, value);
|
||||||
|
|
||||||
else if(stricmp(attribute, INI_DATABASE) == 0)
|
else if (stricmp(attribute, INI_DATABASE) == 0)
|
||||||
strcpy(ci->database, value);
|
strcpy(ci->database, value);
|
||||||
|
|
||||||
else if(stricmp(attribute, INI_SERVER) == 0 || stricmp(attribute, "server") == 0)
|
else if (stricmp(attribute, INI_SERVER) == 0 || stricmp(attribute, "server") == 0)
|
||||||
strcpy(ci->server, value);
|
strcpy(ci->server, value);
|
||||||
|
|
||||||
else if(stricmp(attribute, INI_USER) == 0 || stricmp(attribute, "uid") == 0)
|
else if (stricmp(attribute, INI_USER) == 0 || stricmp(attribute, "uid") == 0)
|
||||||
strcpy(ci->username, value);
|
strcpy(ci->username, value);
|
||||||
|
|
||||||
else if(stricmp(attribute, INI_PASSWORD) == 0 || stricmp(attribute, "pwd") == 0)
|
else if (stricmp(attribute, INI_PASSWORD) == 0 || stricmp(attribute, "pwd") == 0)
|
||||||
strcpy(ci->password, value);
|
strcpy(ci->password, value);
|
||||||
|
|
||||||
else if(stricmp(attribute, INI_PORT) == 0)
|
else if (stricmp(attribute, INI_PORT) == 0)
|
||||||
strcpy(ci->port, value);
|
strcpy(ci->port, value);
|
||||||
|
|
||||||
else if (stricmp(attribute, INI_READONLY) == 0)
|
else if (stricmp(attribute, INI_READONLY) == 0)
|
||||||
@ -376,17 +391,18 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
|
|||||||
else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0)
|
else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0)
|
||||||
strcpy(ci->show_system_tables, value);
|
strcpy(ci->show_system_tables, value);
|
||||||
|
|
||||||
else if (stricmp(attribute, INI_CONNSETTINGS) == 0) {
|
else if (stricmp(attribute, INI_CONNSETTINGS) == 0)
|
||||||
|
{
|
||||||
decode(value, ci->conn_settings);
|
decode(value, ci->conn_settings);
|
||||||
/* strcpy(ci->conn_settings, value); */
|
/* strcpy(ci->conn_settings, value); */
|
||||||
}
|
}
|
||||||
|
|
||||||
mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')\n", ci->dsn, ci->server,ci->database,ci->username,ci->password,ci->port,ci->onlyread,ci->protocol,ci->conn_settings);
|
mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
getDSNdefaults(ConnInfo *ci)
|
getDSNdefaults(ConnInfo * ci)
|
||||||
{
|
{
|
||||||
if (ci->port[0] == '\0')
|
if (ci->port[0] == '\0')
|
||||||
strcpy(ci->port, DEFAULT_PORT);
|
strcpy(ci->port, DEFAULT_PORT);
|
||||||
@ -412,70 +428,73 @@ getDSNdefaults(ConnInfo *ci)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
getDSNinfo(ConnInfo *ci, char overwrite)
|
getDSNinfo(ConnInfo * ci, char overwrite)
|
||||||
{
|
{
|
||||||
char *DSN = ci->dsn;
|
char *DSN = ci->dsn;
|
||||||
char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
||||||
|
|
||||||
/* If a driver keyword was present, then dont use a DSN and return. */
|
/* If a driver keyword was present, then dont use a DSN and return. */
|
||||||
/* If DSN is null and no driver, then use the default datasource. */
|
/* If DSN is null and no driver, then use the default datasource. */
|
||||||
if ( DSN[0] == '\0') {
|
if (DSN[0] == '\0')
|
||||||
if ( ci->driver[0] != '\0')
|
{
|
||||||
|
if (ci->driver[0] != '\0')
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
strcpy(DSN, INI_DSN);
|
strcpy(DSN, INI_DSN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* brute-force chop off trailing blanks... */
|
/* brute-force chop off trailing blanks... */
|
||||||
while (*(DSN+strlen(DSN)-1) == ' ') *(DSN+strlen(DSN)-1) = '\0';
|
while (*(DSN + strlen(DSN) - 1) == ' ')
|
||||||
|
*(DSN + strlen(DSN) - 1) = '\0';
|
||||||
|
|
||||||
/* Proceed with getting info for the given DSN. */
|
/* Proceed with getting info for the given DSN. */
|
||||||
|
|
||||||
if ( ci->desc[0] == '\0' || overwrite)
|
if (ci->desc[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_KDESC, "", ci->desc, sizeof(ci->desc), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_KDESC, "", ci->desc, sizeof(ci->desc), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->server[0] == '\0' || overwrite)
|
if (ci->server[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_SERVER, "", ci->server, sizeof(ci->server), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_SERVER, "", ci->server, sizeof(ci->server), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->database[0] == '\0' || overwrite)
|
if (ci->database[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_DATABASE, "", ci->database, sizeof(ci->database), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_DATABASE, "", ci->database, sizeof(ci->database), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->username[0] == '\0' || overwrite)
|
if (ci->username[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_USER, "", ci->username, sizeof(ci->username), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_USER, "", ci->username, sizeof(ci->username), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->password[0] == '\0' || overwrite)
|
if (ci->password[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_PASSWORD, "", ci->password, sizeof(ci->password), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_PASSWORD, "", ci->password, sizeof(ci->password), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->port[0] == '\0' || overwrite)
|
if (ci->port[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_PORT, "", ci->port, sizeof(ci->port), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_PORT, "", ci->port, sizeof(ci->port), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->onlyread[0] == '\0' || overwrite)
|
if (ci->onlyread[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_READONLY, "", ci->onlyread, sizeof(ci->onlyread), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_READONLY, "", ci->onlyread, sizeof(ci->onlyread), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->show_oid_column[0] == '\0' || overwrite)
|
if (ci->show_oid_column[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_SHOWOIDCOLUMN, "", ci->show_oid_column, sizeof(ci->show_oid_column), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_SHOWOIDCOLUMN, "", ci->show_oid_column, sizeof(ci->show_oid_column), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->fake_oid_index[0] == '\0' || overwrite)
|
if (ci->fake_oid_index[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->row_versioning[0] == '\0' || overwrite)
|
if (ci->row_versioning[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->show_system_tables[0] == '\0' || overwrite)
|
if (ci->show_system_tables[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->protocol[0] == '\0' || overwrite)
|
if (ci->protocol[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_PROTOCOL, "", ci->protocol, sizeof(ci->protocol), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_PROTOCOL, "", ci->protocol, sizeof(ci->protocol), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->conn_settings[0] == '\0' || overwrite) {
|
if (ci->conn_settings[0] == '\0' || overwrite)
|
||||||
|
{
|
||||||
SQLGetPrivateProfileString(DSN, INI_CONNSETTINGS, "", encoded_conn_settings, sizeof(encoded_conn_settings), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_CONNSETTINGS, "", encoded_conn_settings, sizeof(encoded_conn_settings), ODBC_INI);
|
||||||
decode(encoded_conn_settings, ci->conn_settings);
|
decode(encoded_conn_settings, ci->conn_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ci->translation_dll[0] == '\0' || overwrite)
|
if (ci->translation_dll[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_TRANSLATIONDLL, "", ci->translation_dll, sizeof(ci->translation_dll), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_TRANSLATIONDLL, "", ci->translation_dll, sizeof(ci->translation_dll), ODBC_INI);
|
||||||
|
|
||||||
if ( ci->translation_option[0] == '\0' || overwrite)
|
if (ci->translation_option[0] == '\0' || overwrite)
|
||||||
SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI);
|
SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI);
|
||||||
|
|
||||||
|
|
||||||
@ -507,10 +526,10 @@ char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
|||||||
|
|
||||||
/* This is for datasource based options only */
|
/* This is for datasource based options only */
|
||||||
void
|
void
|
||||||
writeDSNinfo(ConnInfo *ci)
|
writeDSNinfo(ConnInfo * ci)
|
||||||
{
|
{
|
||||||
char *DSN = ci->dsn;
|
char *DSN = ci->dsn;
|
||||||
char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
||||||
|
|
||||||
encode(ci->conn_settings, encoded_conn_settings);
|
encode(ci->conn_settings, encoded_conn_settings);
|
||||||
|
|
||||||
@ -584,107 +603,109 @@ char encoded_conn_settings[LARGE_REGISTRY_LEN];
|
|||||||
/* This function reads the ODBCINST.INI portion of
|
/* This function reads the ODBCINST.INI portion of
|
||||||
the registry and gets any driver defaults.
|
the registry and gets any driver defaults.
|
||||||
*/
|
*/
|
||||||
void getGlobalDefaults(char *section, char *filename, char override)
|
void
|
||||||
|
getGlobalDefaults(char *section, char *filename, char override)
|
||||||
{
|
{
|
||||||
char temp[256];
|
char temp[256];
|
||||||
|
|
||||||
|
|
||||||
/* Fetch Count is stored in driver section */
|
/* Fetch Count is stored in driver section */
|
||||||
SQLGetPrivateProfileString(section, INI_FETCH, "",
|
SQLGetPrivateProfileString(section, INI_FETCH, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] ) {
|
if (temp[0])
|
||||||
|
{
|
||||||
globals.fetch_max = atoi(temp);
|
globals.fetch_max = atoi(temp);
|
||||||
/* sanity check if using cursors */
|
/* sanity check if using cursors */
|
||||||
if (globals.fetch_max <= 0)
|
if (globals.fetch_max <= 0)
|
||||||
globals.fetch_max = FETCH_MAX;
|
globals.fetch_max = FETCH_MAX;
|
||||||
}
|
}
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.fetch_max = FETCH_MAX;
|
globals.fetch_max = FETCH_MAX;
|
||||||
|
|
||||||
|
|
||||||
/* Socket Buffersize is stored in driver section */
|
/* Socket Buffersize is stored in driver section */
|
||||||
SQLGetPrivateProfileString(section, INI_SOCKET, "",
|
SQLGetPrivateProfileString(section, INI_SOCKET, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.socket_buffersize = atoi(temp);
|
globals.socket_buffersize = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.socket_buffersize = SOCK_BUFFER_SIZE;
|
globals.socket_buffersize = SOCK_BUFFER_SIZE;
|
||||||
|
|
||||||
|
|
||||||
/* Debug is stored in the driver section */
|
/* Debug is stored in the driver section */
|
||||||
SQLGetPrivateProfileString(section, INI_DEBUG, "",
|
SQLGetPrivateProfileString(section, INI_DEBUG, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.debug = atoi(temp);
|
globals.debug = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.debug = DEFAULT_DEBUG;
|
globals.debug = DEFAULT_DEBUG;
|
||||||
|
|
||||||
|
|
||||||
/* CommLog is stored in the driver section */
|
/* CommLog is stored in the driver section */
|
||||||
SQLGetPrivateProfileString(section, INI_COMMLOG, "",
|
SQLGetPrivateProfileString(section, INI_COMMLOG, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.commlog = atoi(temp);
|
globals.commlog = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.commlog = DEFAULT_COMMLOG;
|
globals.commlog = DEFAULT_COMMLOG;
|
||||||
|
|
||||||
|
|
||||||
/* Optimizer is stored in the driver section only */
|
/* Optimizer is stored in the driver section only */
|
||||||
SQLGetPrivateProfileString(section, INI_OPTIMIZER, "",
|
SQLGetPrivateProfileString(section, INI_OPTIMIZER, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.disable_optimizer = atoi(temp);
|
globals.disable_optimizer = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.disable_optimizer = DEFAULT_OPTIMIZER;
|
globals.disable_optimizer = DEFAULT_OPTIMIZER;
|
||||||
|
|
||||||
/* KSQO is stored in the driver section only */
|
/* KSQO is stored in the driver section only */
|
||||||
SQLGetPrivateProfileString(section, INI_KSQO, "",
|
SQLGetPrivateProfileString(section, INI_KSQO, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.ksqo = atoi(temp);
|
globals.ksqo = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.ksqo = DEFAULT_KSQO;
|
globals.ksqo = DEFAULT_KSQO;
|
||||||
|
|
||||||
/* Recognize Unique Index is stored in the driver section only */
|
/* Recognize Unique Index is stored in the driver section only */
|
||||||
SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "",
|
SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.unique_index = atoi(temp);
|
globals.unique_index = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.unique_index = DEFAULT_UNIQUEINDEX;
|
globals.unique_index = DEFAULT_UNIQUEINDEX;
|
||||||
|
|
||||||
|
|
||||||
/* Unknown Sizes is stored in the driver section only */
|
/* Unknown Sizes is stored in the driver section only */
|
||||||
SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, "",
|
SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.unknown_sizes = atoi(temp);
|
globals.unknown_sizes = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.unknown_sizes = DEFAULT_UNKNOWNSIZES;
|
globals.unknown_sizes = DEFAULT_UNKNOWNSIZES;
|
||||||
|
|
||||||
|
|
||||||
/* Lie about supported functions? */
|
/* Lie about supported functions? */
|
||||||
SQLGetPrivateProfileString(section, INI_LIE, "",
|
SQLGetPrivateProfileString(section, INI_LIE, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.lie = atoi(temp);
|
globals.lie = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.lie = DEFAULT_LIE;
|
globals.lie = DEFAULT_LIE;
|
||||||
|
|
||||||
/* Parse statements */
|
/* Parse statements */
|
||||||
SQLGetPrivateProfileString(section, INI_PARSE, "",
|
SQLGetPrivateProfileString(section, INI_PARSE, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.parse = atoi(temp);
|
globals.parse = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.parse = DEFAULT_PARSE;
|
globals.parse = DEFAULT_PARSE;
|
||||||
|
|
||||||
/* SQLCancel calls SQLFreeStmt in Driver Manager */
|
/* SQLCancel calls SQLFreeStmt in Driver Manager */
|
||||||
SQLGetPrivateProfileString(section, INI_CANCELASFREESTMT, "",
|
SQLGetPrivateProfileString(section, INI_CANCELASFREESTMT, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.cancel_as_freestmt = atoi(temp);
|
globals.cancel_as_freestmt = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
|
globals.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
|
||||||
|
|
||||||
|
|
||||||
@ -692,86 +713,95 @@ char temp[256];
|
|||||||
/* UseDeclareFetch is stored in the driver section only */
|
/* UseDeclareFetch is stored in the driver section only */
|
||||||
SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "",
|
SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.use_declarefetch = atoi(temp);
|
globals.use_declarefetch = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.use_declarefetch = DEFAULT_USEDECLAREFETCH;
|
globals.use_declarefetch = DEFAULT_USEDECLAREFETCH;
|
||||||
|
|
||||||
|
|
||||||
/* Max Varchar Size */
|
/* Max Varchar Size */
|
||||||
SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "",
|
SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.max_varchar_size = atoi(temp);
|
globals.max_varchar_size = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.max_varchar_size = MAX_VARCHAR_SIZE;
|
globals.max_varchar_size = MAX_VARCHAR_SIZE;
|
||||||
|
|
||||||
/* Max TextField Size */
|
/* Max TextField Size */
|
||||||
SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, "",
|
SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.max_longvarchar_size = atoi(temp);
|
globals.max_longvarchar_size = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.max_longvarchar_size = TEXT_FIELD_SIZE;
|
globals.max_longvarchar_size = TEXT_FIELD_SIZE;
|
||||||
|
|
||||||
/* Text As LongVarchar */
|
/* Text As LongVarchar */
|
||||||
SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, "",
|
SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.text_as_longvarchar = atoi(temp);
|
globals.text_as_longvarchar = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
|
globals.text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
|
||||||
|
|
||||||
/* Unknowns As LongVarchar */
|
/* Unknowns As LongVarchar */
|
||||||
SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, "",
|
SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.unknowns_as_longvarchar = atoi(temp);
|
globals.unknowns_as_longvarchar = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
|
globals.unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
|
||||||
|
|
||||||
/* Bools As Char */
|
/* Bools As Char */
|
||||||
SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, "",
|
SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.bools_as_char = atoi(temp);
|
globals.bools_as_char = atoi(temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
globals.bools_as_char = DEFAULT_BOOLSASCHAR;
|
globals.bools_as_char = DEFAULT_BOOLSASCHAR;
|
||||||
|
|
||||||
/* Extra Systable prefixes */
|
/* Extra Systable prefixes */
|
||||||
/* Use @@@ to distinguish between blank extra prefixes and no key entry */
|
|
||||||
|
/*
|
||||||
|
* Use @@@ to distinguish between blank extra prefixes and no key
|
||||||
|
* entry
|
||||||
|
*/
|
||||||
SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, "@@@",
|
SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, "@@@",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( strcmp(temp, "@@@" ))
|
if (strcmp(temp, "@@@"))
|
||||||
strcpy(globals.extra_systable_prefixes, temp);
|
strcpy(globals.extra_systable_prefixes, temp);
|
||||||
else if ( ! override)
|
else if (!override)
|
||||||
strcpy(globals.extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES);
|
strcpy(globals.extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES);
|
||||||
|
|
||||||
mylog("globals.extra_systable_prefixes = '%s'\n", globals.extra_systable_prefixes);
|
mylog("globals.extra_systable_prefixes = '%s'\n", globals.extra_systable_prefixes);
|
||||||
|
|
||||||
|
|
||||||
/* Dont allow override of an override! */
|
/* Dont allow override of an override! */
|
||||||
if ( ! override) {
|
if (!override)
|
||||||
|
{
|
||||||
|
|
||||||
/* ConnSettings is stored in the driver section and per datasource for override */
|
/*
|
||||||
|
* ConnSettings is stored in the driver section and per datasource
|
||||||
|
* for override
|
||||||
|
*/
|
||||||
SQLGetPrivateProfileString(section, INI_CONNSETTINGS, "",
|
SQLGetPrivateProfileString(section, INI_CONNSETTINGS, "",
|
||||||
globals.conn_settings, sizeof(globals.conn_settings), filename);
|
globals.conn_settings, sizeof(globals.conn_settings), filename);
|
||||||
|
|
||||||
/* Default state for future DSN's Readonly attribute */
|
/* Default state for future DSN's Readonly attribute */
|
||||||
SQLGetPrivateProfileString(section, INI_READONLY, "",
|
SQLGetPrivateProfileString(section, INI_READONLY, "",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( temp[0] )
|
if (temp[0])
|
||||||
globals.onlyread = atoi(temp);
|
globals.onlyread = atoi(temp);
|
||||||
else
|
else
|
||||||
globals.onlyread = DEFAULT_READONLY;
|
globals.onlyread = DEFAULT_READONLY;
|
||||||
|
|
||||||
/* Default state for future DSN's protocol attribute
|
/*
|
||||||
This isn't a real driver option YET. This is more
|
* Default state for future DSN's protocol attribute This isn't a
|
||||||
intended for customization from the install.
|
* real driver option YET. This is more intended for
|
||||||
|
* customization from the install.
|
||||||
*/
|
*/
|
||||||
SQLGetPrivateProfileString(section, INI_PROTOCOL, "@@@",
|
SQLGetPrivateProfileString(section, INI_PROTOCOL, "@@@",
|
||||||
temp, sizeof(temp), filename);
|
temp, sizeof(temp), filename);
|
||||||
if ( strcmp(temp, "@@@" ))
|
if (strcmp(temp, "@@@"))
|
||||||
strcpy(globals.protocol, temp);
|
strcpy(globals.protocol, temp);
|
||||||
else
|
else
|
||||||
strcpy(globals.protocol, DEFAULT_PROTOCOL);
|
strcpy(globals.protocol, DEFAULT_PROTOCOL);
|
||||||
@ -783,9 +813,10 @@ char temp[256];
|
|||||||
/* This function writes any global parameters (that can be manipulated)
|
/* This function writes any global parameters (that can be manipulated)
|
||||||
to the ODBCINST.INI portion of the registry
|
to the ODBCINST.INI portion of the registry
|
||||||
*/
|
*/
|
||||||
void updateGlobals(void)
|
void
|
||||||
|
updateGlobals(void)
|
||||||
{
|
{
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
|
|
||||||
sprintf(tmp, "%d", globals.fetch_max);
|
sprintf(tmp, "%d", globals.fetch_max);
|
||||||
SQLWritePrivateProfileString(DBMS_NAME,
|
SQLWritePrivateProfileString(DBMS_NAME,
|
||||||
|
@ -31,23 +31,26 @@
|
|||||||
|
|
||||||
/* INI File Stuff */
|
/* INI File Stuff */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
# define ODBC_INI ".odbc.ini"
|
#define ODBC_INI ".odbc.ini"
|
||||||
# ifdef ODBCINSTDIR
|
#ifdef ODBCINSTDIR
|
||||||
# define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini"
|
#define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini"
|
||||||
# else
|
#else
|
||||||
# define ODBCINST_INI "/etc/odbcinst.ini"
|
#define ODBCINST_INI "/etc/odbcinst.ini"
|
||||||
# warning "location of odbcinst.ini file defaulted to /etc"
|
#warning "location of odbcinst.ini file defaulted to /etc"
|
||||||
# endif
|
#endif
|
||||||
#else /* WIN32 */
|
#else /* WIN32 */
|
||||||
# define ODBC_INI "ODBC.INI" /* ODBC initialization file */
|
#define ODBC_INI "ODBC.INI" /* ODBC initialization file */
|
||||||
# define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */
|
#define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
|
||||||
#define INI_DSN DBMS_NAME /* Name of default Datasource in ini file (not used?) */
|
#define INI_DSN DBMS_NAME /* Name of default Datasource in
|
||||||
|
* ini file (not used?) */
|
||||||
#define INI_KDESC "Description" /* Data source description */
|
#define INI_KDESC "Description" /* Data source description */
|
||||||
#define INI_SERVER "Servername" /* Name of Server running the Postgres service */
|
#define INI_SERVER "Servername" /* Name of Server running the
|
||||||
#define INI_PORT "Port" /* Port on which the Postmaster is listening */
|
* Postgres service */
|
||||||
|
#define INI_PORT "Port"/* Port on which the Postmaster is
|
||||||
|
* listening */
|
||||||
#define INI_DATABASE "Database" /* Database Name */
|
#define INI_DATABASE "Database" /* Database Name */
|
||||||
#define INI_USER "Username" /* Default User Name */
|
#define INI_USER "Username" /* Default User Name */
|
||||||
#define INI_PASSWORD "Password" /* Default Password */
|
#define INI_PASSWORD "Password" /* Default Password */
|
||||||
@ -55,17 +58,22 @@
|
|||||||
#define INI_FETCH "Fetch" /* Fetch Max Count */
|
#define INI_FETCH "Fetch" /* Fetch Max Count */
|
||||||
#define INI_SOCKET "Socket" /* Socket buffer size */
|
#define INI_SOCKET "Socket" /* Socket buffer size */
|
||||||
#define INI_READONLY "ReadOnly" /* Database is read only */
|
#define INI_READONLY "ReadOnly" /* Database is read only */
|
||||||
#define INI_COMMLOG "CommLog" /* Communication to backend logging */
|
#define INI_COMMLOG "CommLog" /* Communication to backend
|
||||||
|
* logging */
|
||||||
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
|
#define INI_PROTOCOL "Protocol" /* What protocol (6.2) */
|
||||||
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
|
#define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */
|
||||||
#define INI_KSQO "Ksqo" /* Keyset query optimization */
|
#define INI_KSQO "Ksqo"/* Keyset query optimization */
|
||||||
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to backend on successful connection */
|
#define INI_CONNSETTINGS "ConnSettings" /* Anything to send to
|
||||||
|
* backend on successful
|
||||||
|
* connection */
|
||||||
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */
|
#define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */
|
||||||
#define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown result set sizes */
|
#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 */
|
/* More ini stuff */
|
||||||
#define INI_TEXTASLONGVARCHAR "TextAsLongVarchar"
|
#define INI_TEXTASLONGVARCHAR "TextAsLongVarchar"
|
||||||
@ -90,7 +98,8 @@
|
|||||||
/* Connection Defaults */
|
/* Connection Defaults */
|
||||||
#define DEFAULT_PORT "5432"
|
#define DEFAULT_PORT "5432"
|
||||||
#define DEFAULT_READONLY 1
|
#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_USEDECLAREFETCH 0
|
||||||
#define DEFAULT_TEXTASLONGVARCHAR 1
|
#define DEFAULT_TEXTASLONGVARCHAR 1
|
||||||
#define DEFAULT_UNKNOWNSASLONGVARCHAR 0
|
#define DEFAULT_UNKNOWNSASLONGVARCHAR 0
|
||||||
@ -118,8 +127,8 @@
|
|||||||
void getGlobalDefaults(char *section, char *filename, char override);
|
void getGlobalDefaults(char *section, char *filename, char override);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
void SetDlgStuff(HWND hdlg, ConnInfo *ci);
|
void SetDlgStuff(HWND hdlg, ConnInfo * ci);
|
||||||
void GetDlgStuff(HWND hdlg, ConnInfo *ci);
|
void GetDlgStuff(HWND hdlg, ConnInfo * ci);
|
||||||
|
|
||||||
int CALLBACK driver_optionsProc(HWND hdlg,
|
int CALLBACK driver_optionsProc(HWND hdlg,
|
||||||
WORD wMsg,
|
WORD wMsg,
|
||||||
@ -129,14 +138,15 @@ int CALLBACK ds_optionsProc(HWND hdlg,
|
|||||||
WORD wMsg,
|
WORD wMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam);
|
LPARAM lParam);
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
void updateGlobals(void);
|
void updateGlobals(void);
|
||||||
void writeDSNinfo(ConnInfo *ci);
|
void writeDSNinfo(ConnInfo * ci);
|
||||||
void getDSNdefaults(ConnInfo *ci);
|
void getDSNdefaults(ConnInfo * ci);
|
||||||
void getDSNinfo(ConnInfo *ci, char overwrite);
|
void getDSNinfo(ConnInfo * ci, char overwrite);
|
||||||
void makeConnectString(char *connect_string, ConnInfo *ci);
|
void makeConnectString(char *connect_string, ConnInfo * ci);
|
||||||
void copyAttributes(ConnInfo *ci, char *attribute, char *value);
|
void copyAttributes(ConnInfo * ci, char *attribute, char *value);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,45 +52,50 @@
|
|||||||
#include "dlg_specific.h"
|
#include "dlg_specific.h"
|
||||||
|
|
||||||
/* prototypes */
|
/* 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
|
#ifdef WIN32
|
||||||
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);
|
||||||
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
|
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo * ci);
|
||||||
|
|
||||||
|
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
|
||||||
|
|
||||||
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern GLOBAL_VALUES globals;
|
extern GLOBAL_VALUES globals;
|
||||||
|
|
||||||
|
|
||||||
RETCODE SQL_API SQLDriverConnect(
|
RETCODE SQL_API
|
||||||
|
SQLDriverConnect(
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
HWND hwnd,
|
HWND hwnd,
|
||||||
UCHAR FAR *szConnStrIn,
|
UCHAR FAR * szConnStrIn,
|
||||||
SWORD cbConnStrIn,
|
SWORD cbConnStrIn,
|
||||||
UCHAR FAR *szConnStrOut,
|
UCHAR FAR * szConnStrOut,
|
||||||
SWORD cbConnStrOutMax,
|
SWORD cbConnStrOutMax,
|
||||||
SWORD FAR *pcbConnStrOut,
|
SWORD FAR * pcbConnStrOut,
|
||||||
UWORD fDriverCompletion)
|
UWORD fDriverCompletion)
|
||||||
{
|
{
|
||||||
static char *func = "SQLDriverConnect";
|
static char *func = "SQLDriverConnect";
|
||||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||||
ConnInfo *ci;
|
ConnInfo *ci;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
RETCODE dialog_result;
|
RETCODE dialog_result;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
RETCODE result;
|
RETCODE result;
|
||||||
char connStrIn[MAX_CONNECT_STRING];
|
char connStrIn[MAX_CONNECT_STRING];
|
||||||
char connStrOut[MAX_CONNECT_STRING];
|
char connStrOut[MAX_CONNECT_STRING];
|
||||||
int retval;
|
int retval;
|
||||||
char password_required = FALSE;
|
char password_required = FALSE;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! conn) {
|
if (!conn)
|
||||||
|
{
|
||||||
CC_log_error(func, "", NULL);
|
CC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
@ -120,13 +125,13 @@ dialog:
|
|||||||
#endif
|
#endif
|
||||||
ci->focus_password = password_required;
|
ci->focus_password = password_required;
|
||||||
|
|
||||||
switch(fDriverCompletion) {
|
switch (fDriverCompletion)
|
||||||
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
case SQL_DRIVER_PROMPT:
|
case SQL_DRIVER_PROMPT:
|
||||||
dialog_result = dconn_DoDialog(hwnd, ci);
|
dialog_result = dconn_DoDialog(hwnd, ci);
|
||||||
if(dialog_result != SQL_SUCCESS) {
|
if (dialog_result != SQL_SUCCESS)
|
||||||
return dialog_result;
|
return dialog_result;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_DRIVER_COMPLETE_REQUIRED:
|
case SQL_DRIVER_COMPLETE_REQUIRED:
|
||||||
@ -136,17 +141,17 @@ dialog:
|
|||||||
case SQL_DRIVER_COMPLETE:
|
case SQL_DRIVER_COMPLETE:
|
||||||
|
|
||||||
/* Password is not a required parameter. */
|
/* Password is not a required parameter. */
|
||||||
if( ci->username[0] == '\0' ||
|
if (ci->username[0] == '\0' ||
|
||||||
ci->server[0] == '\0' ||
|
ci->server[0] == '\0' ||
|
||||||
ci->database[0] == '\0' ||
|
ci->database[0] == '\0' ||
|
||||||
ci->port[0] == '\0' ||
|
ci->port[0] == '\0' ||
|
||||||
password_required) {
|
password_required)
|
||||||
|
{
|
||||||
|
|
||||||
dialog_result = dconn_DoDialog(hwnd, ci);
|
dialog_result = dconn_DoDialog(hwnd, ci);
|
||||||
if(dialog_result != SQL_SUCCESS) {
|
if (dialog_result != SQL_SUCCESS)
|
||||||
return dialog_result;
|
return dialog_result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
case SQL_DRIVER_PROMPT:
|
case SQL_DRIVER_PROMPT:
|
||||||
@ -157,14 +162,17 @@ dialog:
|
|||||||
break;
|
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
|
* Password is not a required parameter unless authentication asks for
|
||||||
a password is entered (the user can always hit Cancel to get out)
|
* 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' ||
|
if (ci->username[0] == '\0' ||
|
||||||
ci->server[0] == '\0' ||
|
ci->server[0] == '\0' ||
|
||||||
ci->database[0] == '\0' ||
|
ci->database[0] == '\0' ||
|
||||||
ci->port[0] == '\0') {
|
ci->port[0] == '\0')
|
||||||
|
{
|
||||||
/* (password_required && ci->password[0] == '\0')) */
|
/* (password_required && ci->password[0] == '\0')) */
|
||||||
|
|
||||||
return SQL_NO_DATA_FOUND;
|
return SQL_NO_DATA_FOUND;
|
||||||
@ -173,12 +181,16 @@ dialog:
|
|||||||
|
|
||||||
/* do the actual connect */
|
/* do the actual connect */
|
||||||
retval = CC_connect(conn, password_required);
|
retval = CC_connect(conn, password_required);
|
||||||
if (retval < 0) { /* need a password */
|
if (retval < 0)
|
||||||
if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
|
{ /* need a password */
|
||||||
|
if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
|
||||||
|
{
|
||||||
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
|
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
|
#ifdef WIN32
|
||||||
password_required = TRUE;
|
password_required = TRUE;
|
||||||
goto dialog;
|
goto dialog;
|
||||||
@ -187,7 +199,8 @@ dialog:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (retval == 0) {
|
else if (retval == 0)
|
||||||
|
{
|
||||||
/* error msg filled in above */
|
/* error msg filled in above */
|
||||||
CC_log_error(func, "Error from CC_Connect", conn);
|
CC_log_error(func, "Error from CC_Connect", conn);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
@ -201,25 +214,29 @@ dialog:
|
|||||||
makeConnectString(connStrOut, ci);
|
makeConnectString(connStrOut, ci);
|
||||||
len = strlen(connStrOut);
|
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,
|
* Return the completed string to the caller. The correct method
|
||||||
it should just copy the connection input string to the output.
|
* is to only construct the connect string if a dialog was put up,
|
||||||
However, it seems ok to just always construct an output string. There
|
* otherwise, it should just copy the connection input string to
|
||||||
are possible bad side effects on working applications (Access) by
|
* the output. However, it seems ok to just always construct an
|
||||||
implementing the correct behavior, anyway.
|
* output string. There are possible bad side effects on working
|
||||||
|
* applications (Access) by implementing the correct behavior,
|
||||||
|
* anyway.
|
||||||
*/
|
*/
|
||||||
strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
|
strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
|
||||||
|
|
||||||
if (len >= cbConnStrOutMax) {
|
if (len >= cbConnStrOutMax)
|
||||||
|
{
|
||||||
result = SQL_SUCCESS_WITH_INFO;
|
result = SQL_SUCCESS_WITH_INFO;
|
||||||
conn->errornumber = CONN_TRUNCATED;
|
conn->errornumber = CONN_TRUNCATED;
|
||||||
conn->errormsg = "The buffer was too small for the result.";
|
conn->errormsg = "The buffer was too small for the result.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcbConnStrOut)
|
if (pcbConnStrOut)
|
||||||
*pcbConnStrOut = len;
|
*pcbConnStrOut = len;
|
||||||
|
|
||||||
mylog("szConnStrOut = '%s'\n", szConnStrOut);
|
mylog("szConnStrOut = '%s'\n", szConnStrOut);
|
||||||
@ -231,35 +248,38 @@ dialog:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#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),
|
dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
|
||||||
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
|
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
|
||||||
if(!dialog_result || (dialog_result == -1)) {
|
if (!dialog_result || (dialog_result == -1))
|
||||||
return SQL_NO_DATA_FOUND;
|
return SQL_NO_DATA_FOUND;
|
||||||
} else {
|
else
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL FAR PASCAL dconn_FDriverConnectProc(
|
BOOL FAR PASCAL
|
||||||
|
dconn_FDriverConnectProc(
|
||||||
HWND hdlg,
|
HWND hdlg,
|
||||||
UINT wMsg,
|
UINT wMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
ConnInfo *ci;
|
ConnInfo *ci;
|
||||||
|
|
||||||
switch (wMsg) {
|
switch (wMsg)
|
||||||
|
{
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
ci = (ConnInfo *) lParam;
|
ci = (ConnInfo *) lParam;
|
||||||
|
|
||||||
@ -274,7 +294,8 @@ ConnInfo *ci;
|
|||||||
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
|
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
|
||||||
ShowWindow(GetDlgItem(hdlg, IDC_DESC), 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);
|
||||||
|
|
||||||
@ -293,7 +314,8 @@ ConnInfo *ci;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
{
|
||||||
case IDOK:
|
case IDOK:
|
||||||
|
|
||||||
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
|
||||||
@ -328,11 +350,15 @@ ConnInfo *ci;
|
|||||||
|
|
||||||
#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 *our_connect_string;
|
||||||
char *pair, *attribute, *value, *equals;
|
char *pair,
|
||||||
char *strtok_arg;
|
*attribute,
|
||||||
|
*value,
|
||||||
|
*equals;
|
||||||
|
char *strtok_arg;
|
||||||
|
|
||||||
memset(ci, 0, sizeof(ConnInfo));
|
memset(ci, 0, sizeof(ConnInfo));
|
||||||
|
|
||||||
@ -341,17 +367,16 @@ char *strtok_arg;
|
|||||||
|
|
||||||
mylog("our_connect_string = '%s'\n", our_connect_string);
|
mylog("our_connect_string = '%s'\n", our_connect_string);
|
||||||
|
|
||||||
while(1) {
|
while (1)
|
||||||
|
{
|
||||||
pair = strtok(strtok_arg, ";");
|
pair = strtok(strtok_arg, ";");
|
||||||
if(strtok_arg) {
|
if (strtok_arg)
|
||||||
strtok_arg = 0;
|
strtok_arg = 0;
|
||||||
}
|
if (!pair)
|
||||||
if(!pair) {
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
equals = strchr(pair, '=');
|
equals = strchr(pair, '=');
|
||||||
if ( ! equals)
|
if (!equals)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*equals = '\0';
|
*equals = '\0';
|
||||||
@ -360,7 +385,7 @@ char *strtok_arg;
|
|||||||
|
|
||||||
mylog("attribute = '%s', value = '%s'\n", attribute, value);
|
mylog("attribute = '%s', value = '%s'\n", attribute, value);
|
||||||
|
|
||||||
if( !attribute || !value)
|
if (!attribute || !value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Copy the appropriate value to the conninfo */
|
/* Copy the appropriate value to the conninfo */
|
||||||
@ -371,4 +396,3 @@ char *strtok_arg;
|
|||||||
|
|
||||||
free(our_connect_string);
|
free(our_connect_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,16 @@
|
|||||||
ConnectionClass *conns[MAX_CONNECTIONS];
|
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();
|
*phenv = (HENV) EN_Constructor();
|
||||||
if ( ! *phenv) {
|
if (!*phenv)
|
||||||
|
{
|
||||||
*phenv = SQL_NULL_HENV;
|
*phenv = SQL_NULL_HENV;
|
||||||
EN_log_error(func, "Error allocating environment", NULL);
|
EN_log_error(func, "Error allocating environment", NULL);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
@ -39,14 +41,16 @@ mylog("**** in SQLAllocEnv ** \n");
|
|||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETCODE SQL_API SQLFreeEnv(HENV henv)
|
RETCODE SQL_API
|
||||||
|
SQLFreeEnv(HENV henv)
|
||||||
{
|
{
|
||||||
static char *func = "SQLFreeEnv";
|
static char *func = "SQLFreeEnv";
|
||||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
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");
|
mylog(" ok\n");
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -58,28 +62,32 @@ mylog("**** in SQLFreeEnv: env = %u ** \n", env);
|
|||||||
|
|
||||||
/* Returns the next SQL error information. */
|
/* Returns the next SQL error information. */
|
||||||
|
|
||||||
RETCODE SQL_API SQLError(
|
RETCODE SQL_API
|
||||||
|
SQLError(
|
||||||
HENV henv,
|
HENV henv,
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UCHAR FAR *szSqlState,
|
UCHAR FAR * szSqlState,
|
||||||
SDWORD FAR *pfNativeError,
|
SDWORD FAR * pfNativeError,
|
||||||
UCHAR FAR *szErrorMsg,
|
UCHAR FAR * szErrorMsg,
|
||||||
SWORD cbErrorMsgMax,
|
SWORD cbErrorMsgMax,
|
||||||
SWORD FAR *pcbErrorMsg)
|
SWORD FAR * pcbErrorMsg)
|
||||||
{
|
{
|
||||||
char *msg;
|
char *msg;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u\n", henv, hdbc, hstmt);
|
mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u\n", henv, hdbc, hstmt);
|
||||||
|
|
||||||
if (SQL_NULL_HSTMT != hstmt) {
|
if (SQL_NULL_HSTMT != hstmt)
|
||||||
|
{
|
||||||
/* CC: return an error of a hstmt */
|
/* CC: return an error of a hstmt */
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
|
|
||||||
if (SC_get_error(stmt, &status, &msg)) {
|
if (SC_get_error(stmt, &status, &msg))
|
||||||
|
{
|
||||||
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
|
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||||
if (NULL == msg) {
|
if (NULL == msg)
|
||||||
|
{
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
strcpy(szSqlState, "00000");
|
strcpy(szSqlState, "00000");
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
@ -90,7 +98,7 @@ int status;
|
|||||||
return SQL_NO_DATA_FOUND;
|
return SQL_NO_DATA_FOUND;
|
||||||
}
|
}
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
*pcbErrorMsg = (SWORD)strlen(msg);
|
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||||
|
|
||||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||||
@ -100,7 +108,8 @@ int status;
|
|||||||
|
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
|
|
||||||
switch (status) {
|
switch (status)
|
||||||
|
{
|
||||||
/* now determine the SQLSTATE to be returned */
|
/* now determine the SQLSTATE to be returned */
|
||||||
case STMT_TRUNCATED:
|
case STMT_TRUNCATED:
|
||||||
strcpy(szSqlState, "01004");
|
strcpy(szSqlState, "01004");
|
||||||
@ -152,7 +161,8 @@ int status;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||||
strcpy(szSqlState, "S1C00"); /* == 'driver not capable' */
|
strcpy(szSqlState, "S1C00"); /* == 'driver not
|
||||||
|
* capable' */
|
||||||
break;
|
break;
|
||||||
case STMT_OPTION_OUT_OF_RANGE_ERROR:
|
case STMT_OPTION_OUT_OF_RANGE_ERROR:
|
||||||
strcpy(szSqlState, "S1092");
|
strcpy(szSqlState, "S1092");
|
||||||
@ -203,7 +213,9 @@ int status;
|
|||||||
|
|
||||||
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
|
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
strcpy(szSqlState, "00000");
|
strcpy(szSqlState, "00000");
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
@ -216,13 +228,17 @@ int status;
|
|||||||
}
|
}
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
|
|
||||||
} else if (SQL_NULL_HDBC != hdbc) {
|
}
|
||||||
|
else if (SQL_NULL_HDBC != hdbc)
|
||||||
|
{
|
||||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||||
|
|
||||||
mylog("calling CC_get_error\n");
|
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);
|
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||||
if (NULL == msg) {
|
if (NULL == msg)
|
||||||
|
{
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
strcpy(szSqlState, "00000");
|
strcpy(szSqlState, "00000");
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
@ -234,14 +250,15 @@ int status;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
*pcbErrorMsg = (SWORD)strlen(msg);
|
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||||
if (NULL != pfNativeError)
|
if (NULL != pfNativeError)
|
||||||
*pfNativeError = status;
|
*pfNativeError = status;
|
||||||
|
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
switch(status) {
|
switch (status)
|
||||||
|
{
|
||||||
case STMT_OPTION_VALUE_CHANGED:
|
case STMT_OPTION_VALUE_CHANGED:
|
||||||
case CONN_OPTION_VALUE_CHANGED:
|
case CONN_OPTION_VALUE_CHANGED:
|
||||||
strcpy(szSqlState, "01S02");
|
strcpy(szSqlState, "01S02");
|
||||||
@ -280,7 +297,11 @@ int status;
|
|||||||
break;
|
break;
|
||||||
case CONN_TRANSACT_IN_PROGRES:
|
case CONN_TRANSACT_IN_PROGRES:
|
||||||
strcpy(szSqlState, "S1010");
|
strcpy(szSqlState, "S1010");
|
||||||
/* when the user tries to switch commit mode in a transaction */
|
|
||||||
|
/*
|
||||||
|
* when the user tries to switch commit mode in a
|
||||||
|
* transaction
|
||||||
|
*/
|
||||||
/* -> function sequence error */
|
/* -> function sequence error */
|
||||||
break;
|
break;
|
||||||
case CONN_NO_MEMORY_ERROR:
|
case CONN_NO_MEMORY_ERROR:
|
||||||
@ -302,7 +323,9 @@ int status;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mylog("CC_Get_error returned nothing.\n");
|
mylog("CC_Get_error returned nothing.\n");
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
strcpy(szSqlState, "00000");
|
strcpy(szSqlState, "00000");
|
||||||
@ -315,11 +338,16 @@ int status;
|
|||||||
}
|
}
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
|
|
||||||
} else if (SQL_NULL_HENV != henv) {
|
}
|
||||||
EnvironmentClass *env = (EnvironmentClass *)henv;
|
else if (SQL_NULL_HENV != henv)
|
||||||
if(EN_get_error(env, &status, &msg)) {
|
{
|
||||||
|
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||||
|
|
||||||
|
if (EN_get_error(env, &status, &msg))
|
||||||
|
{
|
||||||
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
|
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||||
if (NULL == msg) {
|
if (NULL == msg)
|
||||||
|
{
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
strcpy(szSqlState, "00000");
|
strcpy(szSqlState, "00000");
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
@ -331,14 +359,16 @@ int status;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
*pcbErrorMsg = (SWORD)strlen(msg);
|
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||||
if (NULL != pfNativeError)
|
if (NULL != pfNativeError)
|
||||||
*pfNativeError = status;
|
*pfNativeError = status;
|
||||||
|
|
||||||
if(szSqlState) {
|
if (szSqlState)
|
||||||
switch(status) {
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
case ENV_ALLOC_ERROR:
|
case ENV_ALLOC_ERROR:
|
||||||
/* memory allocation failure */
|
/* memory allocation failure */
|
||||||
strcpy(szSqlState, "S1001");
|
strcpy(szSqlState, "S1001");
|
||||||
@ -349,7 +379,9 @@ int status;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (NULL != szSqlState)
|
if (NULL != szSqlState)
|
||||||
strcpy(szSqlState, "00000");
|
strcpy(szSqlState, "00000");
|
||||||
if (NULL != pcbErrorMsg)
|
if (NULL != pcbErrorMsg)
|
||||||
@ -382,12 +414,13 @@ int status;
|
|||||||
|
|
||||||
|
|
||||||
EnvironmentClass
|
EnvironmentClass
|
||||||
*EN_Constructor(void)
|
* EN_Constructor(void)
|
||||||
{
|
{
|
||||||
EnvironmentClass *rv;
|
EnvironmentClass *rv;
|
||||||
|
|
||||||
rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
|
rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
|
||||||
if( rv) {
|
if (rv)
|
||||||
|
{
|
||||||
rv->errormsg = 0;
|
rv->errormsg = 0;
|
||||||
rv->errornumber = 0;
|
rv->errornumber = 0;
|
||||||
}
|
}
|
||||||
@ -397,10 +430,10 @@ EnvironmentClass *rv;
|
|||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
EN_Destructor(EnvironmentClass *self)
|
EN_Destructor(EnvironmentClass * self)
|
||||||
{
|
{
|
||||||
int lf;
|
int lf;
|
||||||
char rv = 1;
|
char rv = 1;
|
||||||
|
|
||||||
mylog("in EN_Destructor, self=%u\n", self);
|
mylog("in EN_Destructor, self=%u\n", self);
|
||||||
|
|
||||||
@ -408,7 +441,8 @@ char rv = 1;
|
|||||||
/* the source--they should not be freed */
|
/* the source--they should not be freed */
|
||||||
|
|
||||||
/* Free any connections belonging to this environment */
|
/* 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)
|
if (conns[lf] && conns[lf]->henv == self)
|
||||||
rv = rv && CC_Destructor(conns[lf]);
|
rv = rv && CC_Destructor(conns[lf]);
|
||||||
}
|
}
|
||||||
@ -418,28 +452,31 @@ char rv = 1;
|
|||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
EN_get_error(EnvironmentClass *self, int *number, char **message)
|
EN_get_error(EnvironmentClass * self, int *number, char **message)
|
||||||
{
|
{
|
||||||
if(self && self->errormsg && self->errornumber) {
|
if (self && self->errormsg && self->errornumber)
|
||||||
|
{
|
||||||
*message = self->errormsg;
|
*message = self->errormsg;
|
||||||
*number = self->errornumber;
|
*number = self->errornumber;
|
||||||
self->errormsg = 0;
|
self->errormsg = 0;
|
||||||
self->errornumber = 0;
|
self->errornumber = 0;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
|
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++) {
|
for (i = 0; i < MAX_CONNECTIONS; i++)
|
||||||
if ( ! conns[i]) {
|
{
|
||||||
|
if (!conns[i])
|
||||||
|
{
|
||||||
conn->henv = self;
|
conn->henv = self;
|
||||||
conns[i] = conn;
|
conns[i] = conn;
|
||||||
|
|
||||||
@ -453,12 +490,13 @@ mylog("EN_add_connection: self = %u, conn = %u\n", self, conn);
|
|||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
|
EN_remove_connection(EnvironmentClass * self, ConnectionClass * conn)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_CONNECTIONS; 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;
|
conns[i] = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -467,11 +505,10 @@ int i;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EN_log_error(char *func, char *desc, EnvironmentClass *self)
|
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);
|
qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||||
}
|
}
|
||||||
|
@ -29,17 +29,18 @@
|
|||||||
#define ENV_ALLOC_ERROR 1
|
#define ENV_ALLOC_ERROR 1
|
||||||
|
|
||||||
/********** Environment Handle *************/
|
/********** Environment Handle *************/
|
||||||
struct EnvironmentClass_ {
|
struct EnvironmentClass_
|
||||||
|
{
|
||||||
char *errormsg;
|
char *errormsg;
|
||||||
int errornumber;
|
int errornumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Environment prototypes */
|
/* Environment prototypes */
|
||||||
EnvironmentClass *EN_Constructor(void);
|
EnvironmentClass *EN_Constructor(void);
|
||||||
char EN_Destructor(EnvironmentClass *self);
|
char EN_Destructor(EnvironmentClass * self);
|
||||||
char EN_get_error(EnvironmentClass *self, int *number, char **message);
|
char EN_get_error(EnvironmentClass * self, int *number, char **message);
|
||||||
char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
|
char EN_add_connection(EnvironmentClass * self, ConnectionClass * conn);
|
||||||
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
|
char EN_remove_connection(EnvironmentClass * self, ConnectionClass * conn);
|
||||||
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
|
void EN_log_error(char *func, char *desc, EnvironmentClass * self);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,33 +39,40 @@ extern GLOBAL_VALUES globals;
|
|||||||
|
|
||||||
|
|
||||||
/* Perform a Prepare on the SQL statement */
|
/* Perform a Prepare on the SQL statement */
|
||||||
RETCODE SQL_API SQLPrepare(HSTMT hstmt,
|
RETCODE SQL_API
|
||||||
UCHAR FAR *szSqlStr,
|
SQLPrepare(HSTMT hstmt,
|
||||||
|
UCHAR FAR * szSqlStr,
|
||||||
SDWORD cbSqlStr)
|
SDWORD cbSqlStr)
|
||||||
{
|
{
|
||||||
static char *func = "SQLPrepare";
|
static char *func = "SQLPrepare";
|
||||||
StatementClass *self = (StatementClass *) hstmt;
|
StatementClass *self = (StatementClass *) hstmt;
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! self) {
|
if (!self)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* According to the ODBC specs it is valid to call SQLPrepare mulitple times.
|
/*
|
||||||
In that case, the bound SQL statement is replaced by the new one
|
* According to the ODBC specs it is valid to call SQLPrepare mulitple
|
||||||
|
* times. In that case, the bound SQL statement is replaced by the new
|
||||||
|
* one
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch(self->status) {
|
switch (self->status)
|
||||||
|
{
|
||||||
case STMT_PREMATURE:
|
case STMT_PREMATURE:
|
||||||
mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n");
|
mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n");
|
||||||
SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */
|
SC_recycle_statement(self); /* recycle the statement, but do
|
||||||
|
* not remove parameter bindings */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STMT_FINISHED:
|
case STMT_FINISHED:
|
||||||
mylog("**** SQLPrepare: STMT_FINISHED, recycle\n");
|
mylog("**** SQLPrepare: STMT_FINISHED, recycle\n");
|
||||||
SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */
|
SC_recycle_statement(self); /* recycle the statement, but do
|
||||||
|
* not remove parameter bindings */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STMT_ALLOCATED:
|
case STMT_ALLOCATED:
|
||||||
@ -97,7 +104,8 @@ StatementClass *self = (StatementClass *) hstmt;
|
|||||||
free(self->statement);
|
free(self->statement);
|
||||||
|
|
||||||
self->statement = make_string(szSqlStr, cbSqlStr, NULL);
|
self->statement = make_string(szSqlStr, cbSqlStr, NULL);
|
||||||
if ( ! self->statement) {
|
if (!self->statement)
|
||||||
|
{
|
||||||
self->errornumber = STMT_NO_MEMORY_ERROR;
|
self->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
self->errormsg = "No memory available to store statement";
|
self->errormsg = "No memory available to store statement";
|
||||||
SC_log_error(func, "", self);
|
SC_log_error(func, "", self);
|
||||||
@ -108,7 +116,8 @@ StatementClass *self = (StatementClass *) hstmt;
|
|||||||
self->statement_type = statement_type(self->statement);
|
self->statement_type = statement_type(self->statement);
|
||||||
|
|
||||||
/* Check if connection is onlyread (only selects are allowed) */
|
/* Check if connection is onlyread (only selects are allowed) */
|
||||||
if ( CC_is_onlyread(self->hdbc) && STMT_UPDATE(self)) {
|
if (CC_is_onlyread(self->hdbc) && STMT_UPDATE(self))
|
||||||
|
{
|
||||||
self->errornumber = STMT_EXEC_ERROR;
|
self->errornumber = STMT_EXEC_ERROR;
|
||||||
self->errormsg = "Connection is readonly, only select statements are allowed.";
|
self->errormsg = "Connection is readonly, only select statements are allowed.";
|
||||||
SC_log_error(func, "", self);
|
SC_log_error(func, "", self);
|
||||||
@ -124,18 +133,20 @@ StatementClass *self = (StatementClass *) hstmt;
|
|||||||
|
|
||||||
/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */
|
/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */
|
||||||
|
|
||||||
RETCODE SQL_API SQLExecDirect(
|
RETCODE SQL_API
|
||||||
|
SQLExecDirect(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UCHAR FAR *szSqlStr,
|
UCHAR FAR * szSqlStr,
|
||||||
SDWORD cbSqlStr)
|
SDWORD cbSqlStr)
|
||||||
{
|
{
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
RETCODE result;
|
RETCODE result;
|
||||||
static char *func = "SQLExecDirect";
|
static char *func = "SQLExecDirect";
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
@ -146,7 +157,8 @@ static char *func = "SQLExecDirect";
|
|||||||
/* keep a copy of the un-parametrized statement, in case */
|
/* keep a copy of the un-parametrized statement, in case */
|
||||||
/* they try to execute this statement again */
|
/* they try to execute this statement again */
|
||||||
stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);
|
stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);
|
||||||
if ( ! stmt->statement) {
|
if (!stmt->statement)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "No memory available to store statement";
|
stmt->errormsg = "No memory available to store statement";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -160,13 +172,14 @@ static char *func = "SQLExecDirect";
|
|||||||
/* If an SQLPrepare was performed prior to this, but was left in */
|
/* If an SQLPrepare was performed prior to this, but was left in */
|
||||||
/* the premature state because an error occurred prior to SQLExecute */
|
/* the premature state because an error occurred prior to SQLExecute */
|
||||||
/* then set the statement to finished so it can be recycled. */
|
/* then set the statement to finished so it can be recycled. */
|
||||||
if ( stmt->status == STMT_PREMATURE )
|
if (stmt->status == STMT_PREMATURE)
|
||||||
stmt->status = STMT_FINISHED;
|
stmt->status = STMT_FINISHED;
|
||||||
|
|
||||||
stmt->statement_type = statement_type(stmt->statement);
|
stmt->statement_type = statement_type(stmt->statement);
|
||||||
|
|
||||||
/* Check if connection is onlyread (only selects are allowed) */
|
/* Check if connection is onlyread (only selects are allowed) */
|
||||||
if ( CC_is_onlyread(stmt->hdbc) && STMT_UPDATE(stmt)) {
|
if (CC_is_onlyread(stmt->hdbc) && STMT_UPDATE(stmt))
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
stmt->errormsg = "Connection is readonly, only select statements are allowed.";
|
stmt->errormsg = "Connection is readonly, only select statements are allowed.";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -182,34 +195,41 @@ static char *func = "SQLExecDirect";
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Execute a prepared SQL statement */
|
/* Execute a prepared SQL statement */
|
||||||
RETCODE SQL_API SQLExecute(
|
RETCODE SQL_API
|
||||||
|
SQLExecute(
|
||||||
HSTMT hstmt)
|
HSTMT hstmt)
|
||||||
{
|
{
|
||||||
static char *func="SQLExecute";
|
static char *func = "SQLExecute";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
ConnectionClass *conn;
|
ConnectionClass *conn;
|
||||||
int i, retval;
|
int i,
|
||||||
|
retval;
|
||||||
|
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func);
|
mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the statement is premature, it means we already executed
|
/*
|
||||||
it from an SQLPrepare/SQLDescribeCol type of scenario. So
|
* If the statement is premature, it means we already executed it from
|
||||||
just return success.
|
* an SQLPrepare/SQLDescribeCol type of scenario. So just return
|
||||||
|
* success.
|
||||||
*/
|
*/
|
||||||
if ( stmt->prepare && stmt->status == STMT_PREMATURE) {
|
if (stmt->prepare && stmt->status == STMT_PREMATURE)
|
||||||
|
{
|
||||||
stmt->status = STMT_FINISHED;
|
stmt->status = STMT_FINISHED;
|
||||||
if (stmt->errormsg == NULL) {
|
if (stmt->errormsg == NULL)
|
||||||
|
{
|
||||||
mylog("%s: premature statement but return SQL_SUCCESS\n", func);
|
mylog("%s: premature statement but return SQL_SUCCESS\n", func);
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
mylog("%s: premature statement so return SQL_ERROR\n", func);
|
mylog("%s: premature statement so return SQL_ERROR\n", func);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
@ -221,7 +241,8 @@ int i, retval;
|
|||||||
SC_clear_error(stmt);
|
SC_clear_error(stmt);
|
||||||
|
|
||||||
conn = SC_get_conn(stmt);
|
conn = SC_get_conn(stmt);
|
||||||
if (conn->status == CONN_EXECUTING) {
|
if (conn->status == CONN_EXECUTING)
|
||||||
|
{
|
||||||
stmt->errormsg = "Connection is already in use.";
|
stmt->errormsg = "Connection is already in use.";
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -229,7 +250,8 @@ int i, retval;
|
|||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! stmt->statement) {
|
if (!stmt->statement)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_STMTSTRING;
|
stmt->errornumber = STMT_NO_STMTSTRING;
|
||||||
stmt->errormsg = "This handle does not have a SQL statement stored in it";
|
stmt->errormsg = "This handle does not have a SQL statement stored in it";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -237,18 +259,21 @@ int i, retval;
|
|||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If SQLExecute is being called again, recycle the statement.
|
/*
|
||||||
Note this should have been done by the application in a call
|
* If SQLExecute is being called again, recycle the statement. Note
|
||||||
to SQLFreeStmt(SQL_CLOSE) or SQLCancel.
|
* this should have been done by the application in a call to
|
||||||
|
* SQLFreeStmt(SQL_CLOSE) or SQLCancel.
|
||||||
*/
|
*/
|
||||||
if (stmt->status == STMT_FINISHED) {
|
if (stmt->status == STMT_FINISHED)
|
||||||
|
{
|
||||||
mylog("%s: recycling statement (should have been done by app)...\n", func);
|
mylog("%s: recycling statement (should have been done by app)...\n", func);
|
||||||
SC_recycle_statement(stmt);
|
SC_recycle_statement(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the statement is in the correct state */
|
/* Check if the statement is in the correct state */
|
||||||
if ((stmt->prepare && stmt->status != STMT_READY) ||
|
if ((stmt->prepare && stmt->status != STMT_READY) ||
|
||||||
(stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) {
|
(stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY))
|
||||||
|
{
|
||||||
|
|
||||||
stmt->errornumber = STMT_STATUS_ERROR;
|
stmt->errornumber = STMT_STATUS_ERROR;
|
||||||
stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
|
stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
|
||||||
@ -258,13 +283,16 @@ int i, retval;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The bound parameters could have possibly changed since the last execute
|
/*
|
||||||
of this statement? Therefore check for params and re-copy.
|
* The bound parameters could have possibly changed since the last
|
||||||
|
* execute of this statement? Therefore check for params and re-copy.
|
||||||
*/
|
*/
|
||||||
stmt->data_at_exec = -1;
|
stmt->data_at_exec = -1;
|
||||||
for (i = 0; i < stmt->parameters_allocated; i++) {
|
for (i = 0; i < stmt->parameters_allocated; i++)
|
||||||
|
{
|
||||||
/* Check for data at execution parameters */
|
/* Check for data at execution parameters */
|
||||||
if ( stmt->parameters[i].data_at_exec == TRUE) {
|
if (stmt->parameters[i].data_at_exec == TRUE)
|
||||||
|
{
|
||||||
if (stmt->data_at_exec < 0)
|
if (stmt->data_at_exec < 0)
|
||||||
stmt->data_at_exec = 1;
|
stmt->data_at_exec = 1;
|
||||||
else
|
else
|
||||||
@ -272,7 +300,11 @@ int i, retval;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If there are some data at execution parameters, return need data */
|
/* If there are some data at execution parameters, return need data */
|
||||||
/* SQLParamData and SQLPutData will be used to send params and execute the statement. */
|
|
||||||
|
/*
|
||||||
|
* SQLParamData and SQLPutData will be used to send params and execute
|
||||||
|
* the statement.
|
||||||
|
*/
|
||||||
if (stmt->data_at_exec > 0)
|
if (stmt->data_at_exec > 0)
|
||||||
return SQL_NEED_DATA;
|
return SQL_NEED_DATA;
|
||||||
|
|
||||||
@ -281,7 +313,7 @@ int i, retval;
|
|||||||
|
|
||||||
/* Create the statement with parameters substituted. */
|
/* Create the statement with parameters substituted. */
|
||||||
retval = copy_statement_with_parameters(stmt);
|
retval = copy_statement_with_parameters(stmt);
|
||||||
if( retval != SQL_SUCCESS)
|
if (retval != SQL_SUCCESS)
|
||||||
/* error msg passed from above */
|
/* error msg passed from above */
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
@ -296,34 +328,40 @@ int i, retval;
|
|||||||
|
|
||||||
|
|
||||||
/* - - - - - - - - - */
|
/* - - - - - - - - - */
|
||||||
RETCODE SQL_API SQLTransact(
|
RETCODE SQL_API
|
||||||
|
SQLTransact(
|
||||||
HENV henv,
|
HENV henv,
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
UWORD fType)
|
UWORD fType)
|
||||||
{
|
{
|
||||||
static char *func = "SQLTransact";
|
static char *func = "SQLTransact";
|
||||||
extern ConnectionClass *conns[];
|
extern ConnectionClass *conns[];
|
||||||
ConnectionClass *conn;
|
ConnectionClass *conn;
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
char ok, *stmt_string;
|
char ok,
|
||||||
int lf;
|
*stmt_string;
|
||||||
|
int lf;
|
||||||
|
|
||||||
mylog("entering %s: hdbc=%u, henv=%u\n", func, hdbc, henv);
|
mylog("entering %s: hdbc=%u, henv=%u\n", func, hdbc, henv);
|
||||||
|
|
||||||
if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) {
|
if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV)
|
||||||
|
{
|
||||||
CC_log_error(func, "", NULL);
|
CC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If hdbc is null and henv is valid,
|
/*
|
||||||
it means transact all connections on that henv.
|
* If hdbc is null and henv is valid, it means transact all
|
||||||
|
* connections on that henv.
|
||||||
*/
|
*/
|
||||||
if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) {
|
if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV)
|
||||||
for (lf=0; lf <MAX_CONNECTIONS; lf++) {
|
{
|
||||||
|
for (lf = 0; lf < MAX_CONNECTIONS; lf++)
|
||||||
|
{
|
||||||
conn = conns[lf];
|
conn = conns[lf];
|
||||||
|
|
||||||
if (conn && conn->henv == henv)
|
if (conn && conn->henv == henv)
|
||||||
if ( SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS)
|
if (SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS)
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -332,28 +370,35 @@ int lf;
|
|||||||
|
|
||||||
conn = (ConnectionClass *) hdbc;
|
conn = (ConnectionClass *) hdbc;
|
||||||
|
|
||||||
if (fType == SQL_COMMIT) {
|
if (fType == SQL_COMMIT)
|
||||||
|
{
|
||||||
stmt_string = "COMMIT";
|
stmt_string = "COMMIT";
|
||||||
|
|
||||||
} else if (fType == SQL_ROLLBACK) {
|
}
|
||||||
|
else if (fType == SQL_ROLLBACK)
|
||||||
|
{
|
||||||
stmt_string = "ROLLBACK";
|
stmt_string = "ROLLBACK";
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
conn->errornumber = CONN_INVALID_ARGUMENT_NO;
|
conn->errornumber = CONN_INVALID_ARGUMENT_NO;
|
||||||
conn->errormsg ="SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter";
|
conn->errormsg = "SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter";
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If manual commit and in transaction, then proceed. */
|
/* If manual commit and in transaction, then proceed. */
|
||||||
if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) {
|
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
|
||||||
|
{
|
||||||
|
|
||||||
mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string);
|
mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string);
|
||||||
|
|
||||||
res = CC_send_query(conn, stmt_string, NULL);
|
res = CC_send_query(conn, stmt_string, NULL);
|
||||||
CC_set_no_trans(conn);
|
CC_set_no_trans(conn);
|
||||||
|
|
||||||
if ( ! res) {
|
if (!res)
|
||||||
|
{
|
||||||
/* error msg will be in the connection */
|
/* error msg will be in the connection */
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
@ -362,7 +407,8 @@ int lf;
|
|||||||
ok = QR_command_successful(res);
|
ok = QR_command_successful(res);
|
||||||
QR_Destructor(res);
|
QR_Destructor(res);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
|
{
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
@ -372,48 +418,57 @@ int lf;
|
|||||||
|
|
||||||
/* - - - - - - - - - */
|
/* - - - - - - - - - */
|
||||||
|
|
||||||
RETCODE SQL_API SQLCancel(
|
RETCODE SQL_API
|
||||||
|
SQLCancel(
|
||||||
HSTMT hstmt) /* Statement to cancel. */
|
HSTMT hstmt) /* Statement to cancel. */
|
||||||
{
|
{
|
||||||
static char *func="SQLCancel";
|
static char *func = "SQLCancel";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
RETCODE result;
|
RETCODE result;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
HMODULE hmodule;
|
HMODULE hmodule;
|
||||||
FARPROC addr;
|
FARPROC addr;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
/* Check if this can handle canceling in the middle of a SQLPutData? */
|
/* Check if this can handle canceling in the middle of a SQLPutData? */
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in the middle of SQLParamData/SQLPutData so cancel like a close. */
|
/*
|
||||||
if (stmt->data_at_exec < 0) {
|
* Not in the middle of SQLParamData/SQLPutData so cancel like a
|
||||||
|
* close.
|
||||||
|
*/
|
||||||
|
if (stmt->data_at_exec < 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
/* MAJOR HACK for Windows to reset the driver manager's cursor state:
|
/*
|
||||||
Because of what seems like a bug in the Odbc driver manager,
|
* MAJOR HACK for Windows to reset the driver manager's cursor
|
||||||
SQLCancel does not act like a SQLFreeStmt(CLOSE), as many
|
* state: Because of what seems like a bug in the Odbc driver
|
||||||
applications depend on this behavior. So, this
|
* manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as
|
||||||
brute force method calls the driver manager's function on
|
* many applications depend on this behavior. So, this brute
|
||||||
behalf of the application.
|
* force method calls the driver manager's function on behalf of
|
||||||
|
* the application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (globals.cancel_as_freestmt) {
|
if (globals.cancel_as_freestmt)
|
||||||
|
{
|
||||||
hmodule = GetModuleHandle("ODBC32");
|
hmodule = GetModuleHandle("ODBC32");
|
||||||
addr = GetProcAddress(hmodule, "SQLFreeStmt");
|
addr = GetProcAddress(hmodule, "SQLFreeStmt");
|
||||||
result = addr( (char *) (stmt->phstmt) - 96, SQL_CLOSE);
|
result = addr((char *) (stmt->phstmt) - 96, SQL_CLOSE);
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = SQLFreeStmt( hstmt, SQL_CLOSE);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
result = SQLFreeStmt(hstmt, SQL_CLOSE);
|
||||||
#else
|
#else
|
||||||
result = SQLFreeStmt( hstmt, SQL_CLOSE);
|
result = SQLFreeStmt(hstmt, SQL_CLOSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mylog("SQLCancel: SQLFreeStmt returned %d\n", result);
|
mylog("SQLCancel: SQLFreeStmt returned %d\n", result);
|
||||||
@ -423,7 +478,11 @@ FARPROC addr;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* In the middle of SQLParamData/SQLPutData, so cancel that. */
|
/* In the middle of SQLParamData/SQLPutData, so cancel that. */
|
||||||
/* Note, any previous data-at-exec buffers will be freed in the recycle */
|
|
||||||
|
/*
|
||||||
|
* Note, any previous data-at-exec buffers will be freed in the
|
||||||
|
* recycle
|
||||||
|
*/
|
||||||
/* if they call SQLExecDirect or SQLExecute again. */
|
/* if they call SQLExecDirect or SQLExecute again. */
|
||||||
|
|
||||||
stmt->data_at_exec = -1;
|
stmt->data_at_exec = -1;
|
||||||
@ -439,24 +498,26 @@ FARPROC addr;
|
|||||||
/* Returns the SQL string as modified by the driver. */
|
/* Returns the SQL string as modified by the driver. */
|
||||||
/* Currently, just copy the input string without modification */
|
/* Currently, just copy the input string without modification */
|
||||||
/* observing buffer limits and truncation. */
|
/* observing buffer limits and truncation. */
|
||||||
RETCODE SQL_API SQLNativeSql(
|
RETCODE SQL_API
|
||||||
|
SQLNativeSql(
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
UCHAR FAR *szSqlStrIn,
|
UCHAR FAR * szSqlStrIn,
|
||||||
SDWORD cbSqlStrIn,
|
SDWORD cbSqlStrIn,
|
||||||
UCHAR FAR *szSqlStr,
|
UCHAR FAR * szSqlStr,
|
||||||
SDWORD cbSqlStrMax,
|
SDWORD cbSqlStrMax,
|
||||||
SDWORD FAR *pcbSqlStr)
|
SDWORD FAR * pcbSqlStr)
|
||||||
{
|
{
|
||||||
static char *func="SQLNativeSql";
|
static char *func = "SQLNativeSql";
|
||||||
int len = 0;
|
int len = 0;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||||
RETCODE result;
|
RETCODE result;
|
||||||
|
|
||||||
mylog( "%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn);
|
mylog("%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn);
|
||||||
|
|
||||||
ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL);
|
ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL);
|
||||||
if ( ! ptr) {
|
if (!ptr)
|
||||||
|
{
|
||||||
conn->errornumber = CONN_NO_MEMORY_ERROR;
|
conn->errornumber = CONN_NO_MEMORY_ERROR;
|
||||||
conn->errormsg = "No memory available to store native sql string";
|
conn->errormsg = "No memory available to store native sql string";
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
@ -466,10 +527,12 @@ RETCODE result;
|
|||||||
result = SQL_SUCCESS;
|
result = SQL_SUCCESS;
|
||||||
len = strlen(ptr);
|
len = strlen(ptr);
|
||||||
|
|
||||||
if (szSqlStr) {
|
if (szSqlStr)
|
||||||
|
{
|
||||||
strncpy_null(szSqlStr, ptr, cbSqlStrMax);
|
strncpy_null(szSqlStr, ptr, cbSqlStrMax);
|
||||||
|
|
||||||
if (len >= cbSqlStrMax) {
|
if (len >= cbSqlStrMax)
|
||||||
|
{
|
||||||
result = SQL_SUCCESS_WITH_INFO;
|
result = SQL_SUCCESS_WITH_INFO;
|
||||||
conn->errornumber = STMT_TRUNCATED;
|
conn->errornumber = STMT_TRUNCATED;
|
||||||
conn->errormsg = "The buffer was too small for the result.";
|
conn->errormsg = "The buffer was too small for the result.";
|
||||||
@ -489,31 +552,36 @@ RETCODE result;
|
|||||||
/* Supplies parameter data at execution time. Used in conjuction with */
|
/* Supplies parameter data at execution time. Used in conjuction with */
|
||||||
/* SQLPutData. */
|
/* SQLPutData. */
|
||||||
|
|
||||||
RETCODE SQL_API SQLParamData(
|
RETCODE SQL_API
|
||||||
|
SQLParamData(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
PTR FAR *prgbValue)
|
PTR FAR * prgbValue)
|
||||||
{
|
{
|
||||||
static char *func = "SQLParamData";
|
static char *func = "SQLParamData";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
int i, retval;
|
int i,
|
||||||
|
retval;
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, stmt->parameters_allocated);
|
mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, stmt->parameters_allocated);
|
||||||
|
|
||||||
if (stmt->data_at_exec < 0) {
|
if (stmt->data_at_exec < 0)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
stmt->errormsg = "No execution-time parameters for this statement";
|
stmt->errormsg = "No execution-time parameters for this statement";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt->data_at_exec > stmt->parameters_allocated) {
|
if (stmt->data_at_exec > stmt->parameters_allocated)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
stmt->errormsg = "Too many execution-time parameters were present";
|
stmt->errormsg = "Too many execution-time parameters were present";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -521,16 +589,19 @@ int i, retval;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* close the large object */
|
/* close the large object */
|
||||||
if ( stmt->lobj_fd >= 0) {
|
if (stmt->lobj_fd >= 0)
|
||||||
|
{
|
||||||
lo_close(stmt->hdbc, stmt->lobj_fd);
|
lo_close(stmt->hdbc, stmt->lobj_fd);
|
||||||
|
|
||||||
/* commit transaction if needed */
|
/* commit transaction if needed */
|
||||||
if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) {
|
if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
|
||||||
|
{
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
char ok;
|
char ok;
|
||||||
|
|
||||||
res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
|
res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
|
||||||
if (!res) {
|
if (!res)
|
||||||
|
{
|
||||||
stmt->errormsg = "Could not commit (in-line) a transaction";
|
stmt->errormsg = "Could not commit (in-line) a transaction";
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -538,7 +609,8 @@ int i, retval;
|
|||||||
}
|
}
|
||||||
ok = QR_command_successful(res);
|
ok = QR_command_successful(res);
|
||||||
QR_Destructor(res);
|
QR_Destructor(res);
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
|
{
|
||||||
stmt->errormsg = "Could not commit (in-line) a transaction";
|
stmt->errormsg = "Could not commit (in-line) a transaction";
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -553,7 +625,8 @@ int i, retval;
|
|||||||
|
|
||||||
|
|
||||||
/* Done, now copy the params and then execute the statement */
|
/* Done, now copy the params and then execute the statement */
|
||||||
if (stmt->data_at_exec == 0) {
|
if (stmt->data_at_exec == 0)
|
||||||
|
{
|
||||||
retval = copy_statement_with_parameters(stmt);
|
retval = copy_statement_with_parameters(stmt);
|
||||||
if (retval != SQL_SUCCESS)
|
if (retval != SQL_SUCCESS)
|
||||||
return retval;
|
return retval;
|
||||||
@ -563,14 +636,17 @@ int i, retval;
|
|||||||
return SC_execute(stmt);
|
return SC_execute(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set beginning param; if first time SQLParamData is called , start at 0.
|
/*
|
||||||
Otherwise, start at the last parameter + 1.
|
* Set beginning param; if first time SQLParamData is called , start
|
||||||
|
* at 0. Otherwise, start at the last parameter + 1.
|
||||||
*/
|
*/
|
||||||
i = stmt->current_exec_param >= 0 ? stmt->current_exec_param+1 : 0;
|
i = stmt->current_exec_param >= 0 ? stmt->current_exec_param + 1 : 0;
|
||||||
|
|
||||||
/* At least 1 data at execution parameter, so Fill in the token value */
|
/* At least 1 data at execution parameter, so Fill in the token value */
|
||||||
for ( ; i < stmt->parameters_allocated; i++) {
|
for (; i < stmt->parameters_allocated; i++)
|
||||||
if (stmt->parameters[i].data_at_exec == TRUE) {
|
{
|
||||||
|
if (stmt->parameters[i].data_at_exec == TRUE)
|
||||||
|
{
|
||||||
stmt->data_at_exec--;
|
stmt->data_at_exec--;
|
||||||
stmt->current_exec_param = i;
|
stmt->current_exec_param = i;
|
||||||
stmt->put_data = FALSE;
|
stmt->put_data = FALSE;
|
||||||
@ -587,26 +663,30 @@ int i, retval;
|
|||||||
/* Supplies parameter data at execution time. Used in conjunction with */
|
/* Supplies parameter data at execution time. Used in conjunction with */
|
||||||
/* SQLParamData. */
|
/* SQLParamData. */
|
||||||
|
|
||||||
RETCODE SQL_API SQLPutData(
|
RETCODE SQL_API
|
||||||
|
SQLPutData(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
PTR rgbValue,
|
PTR rgbValue,
|
||||||
SDWORD cbValue)
|
SDWORD cbValue)
|
||||||
{
|
{
|
||||||
static char *func = "SQLPutData";
|
static char *func = "SQLPutData";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
int old_pos, retval;
|
int old_pos,
|
||||||
ParameterInfoClass *current_param;
|
retval;
|
||||||
char *buffer;
|
ParameterInfoClass *current_param;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
mylog( "%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (stmt->current_exec_param < 0) {
|
if (stmt->current_exec_param < 0)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
stmt->errormsg = "Previous call was not SQLPutData or SQLParamData";
|
stmt->errormsg = "Previous call was not SQLPutData or SQLParamData";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -615,14 +695,16 @@ char *buffer;
|
|||||||
|
|
||||||
current_param = &(stmt->parameters[stmt->current_exec_param]);
|
current_param = &(stmt->parameters[stmt->current_exec_param]);
|
||||||
|
|
||||||
if ( ! stmt->put_data) { /* first call */
|
if (!stmt->put_data)
|
||||||
|
{ /* first call */
|
||||||
|
|
||||||
mylog("SQLPutData: (1) cbValue = %d\n", cbValue);
|
mylog("SQLPutData: (1) cbValue = %d\n", cbValue);
|
||||||
|
|
||||||
stmt->put_data = TRUE;
|
stmt->put_data = TRUE;
|
||||||
|
|
||||||
current_param->EXEC_used = (SDWORD *) malloc(sizeof(SDWORD));
|
current_param->EXEC_used = (SDWORD *) malloc(sizeof(SDWORD));
|
||||||
if ( ! current_param->EXEC_used) {
|
if (!current_param->EXEC_used)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "Out of memory in SQLPutData (1)";
|
stmt->errormsg = "Out of memory in SQLPutData (1)";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -636,15 +718,18 @@ char *buffer;
|
|||||||
|
|
||||||
|
|
||||||
/* Handle Long Var Binary with Large Objects */
|
/* Handle Long Var Binary with Large Objects */
|
||||||
if ( current_param->SQLType == SQL_LONGVARBINARY) {
|
if (current_param->SQLType == SQL_LONGVARBINARY)
|
||||||
|
{
|
||||||
|
|
||||||
/* begin transaction if needed */
|
/* begin transaction if needed */
|
||||||
if(!CC_is_in_trans(stmt->hdbc)) {
|
if (!CC_is_in_trans(stmt->hdbc))
|
||||||
|
{
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
char ok;
|
char ok;
|
||||||
|
|
||||||
res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
|
res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
|
||||||
if (!res) {
|
if (!res)
|
||||||
|
{
|
||||||
stmt->errormsg = "Could not begin (in-line) a transaction";
|
stmt->errormsg = "Could not begin (in-line) a transaction";
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -652,7 +737,8 @@ char *buffer;
|
|||||||
}
|
}
|
||||||
ok = QR_command_successful(res);
|
ok = QR_command_successful(res);
|
||||||
QR_Destructor(res);
|
QR_Destructor(res);
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
|
{
|
||||||
stmt->errormsg = "Could not begin (in-line) a transaction";
|
stmt->errormsg = "Could not begin (in-line) a transaction";
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -664,7 +750,8 @@ char *buffer;
|
|||||||
|
|
||||||
/* store the oid */
|
/* store the oid */
|
||||||
current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE);
|
current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE);
|
||||||
if (current_param->lobj_oid == 0) {
|
if (current_param->lobj_oid == 0)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
stmt->errormsg = "Couldnt create large object.";
|
stmt->errormsg = "Couldnt create large object.";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -677,7 +764,8 @@ char *buffer;
|
|||||||
|
|
||||||
/* store the fd */
|
/* store the fd */
|
||||||
stmt->lobj_fd = lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE);
|
stmt->lobj_fd = lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE);
|
||||||
if ( stmt->lobj_fd < 0) {
|
if (stmt->lobj_fd < 0)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_EXEC_ERROR;
|
stmt->errornumber = STMT_EXEC_ERROR;
|
||||||
stmt->errormsg = "Couldnt open large object for writing.";
|
stmt->errormsg = "Couldnt open large object for writing.";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -688,20 +776,26 @@ char *buffer;
|
|||||||
mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval);
|
mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval);
|
||||||
|
|
||||||
}
|
}
|
||||||
else { /* for handling text fields and small binaries */
|
else
|
||||||
|
{ /* for handling text fields and small
|
||||||
|
* binaries */
|
||||||
|
|
||||||
if (cbValue == SQL_NTS) {
|
if (cbValue == SQL_NTS)
|
||||||
|
{
|
||||||
current_param->EXEC_buffer = strdup(rgbValue);
|
current_param->EXEC_buffer = strdup(rgbValue);
|
||||||
if ( ! current_param->EXEC_buffer) {
|
if (!current_param->EXEC_buffer)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "Out of memory in SQLPutData (2)";
|
stmt->errormsg = "Out of memory in SQLPutData (2)";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
current_param->EXEC_buffer = malloc(cbValue + 1);
|
current_param->EXEC_buffer = malloc(cbValue + 1);
|
||||||
if ( ! current_param->EXEC_buffer) {
|
if (!current_param->EXEC_buffer)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "Out of memory in SQLPutData (2)";
|
stmt->errormsg = "Out of memory in SQLPutData (2)";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -713,11 +807,13 @@ char *buffer;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else { /* calling SQLPutData more than once */
|
else
|
||||||
|
{ /* calling SQLPutData more than once */
|
||||||
|
|
||||||
mylog("SQLPutData: (>1) cbValue = %d\n", cbValue);
|
mylog("SQLPutData: (>1) cbValue = %d\n", cbValue);
|
||||||
|
|
||||||
if (current_param->SQLType == SQL_LONGVARBINARY) {
|
if (current_param->SQLType == SQL_LONGVARBINARY)
|
||||||
|
{
|
||||||
|
|
||||||
/* the large object fd is in EXEC_buffer */
|
/* the large object fd is in EXEC_buffer */
|
||||||
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
|
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
|
||||||
@ -725,13 +821,17 @@ char *buffer;
|
|||||||
|
|
||||||
*current_param->EXEC_used += cbValue;
|
*current_param->EXEC_used += cbValue;
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
buffer = current_param->EXEC_buffer;
|
buffer = current_param->EXEC_buffer;
|
||||||
|
|
||||||
if (cbValue == SQL_NTS) {
|
if (cbValue == SQL_NTS)
|
||||||
|
{
|
||||||
buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1);
|
buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1);
|
||||||
if ( ! buffer) {
|
if (!buffer)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "Out of memory in SQLPutData (3)";
|
stmt->errormsg = "Out of memory in SQLPutData (3)";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -747,7 +847,8 @@ char *buffer;
|
|||||||
current_param->EXEC_buffer = buffer;
|
current_param->EXEC_buffer = buffer;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (cbValue > 0) {
|
else if (cbValue > 0)
|
||||||
|
{
|
||||||
|
|
||||||
old_pos = *current_param->EXEC_used;
|
old_pos = *current_param->EXEC_used;
|
||||||
|
|
||||||
@ -757,7 +858,8 @@ char *buffer;
|
|||||||
|
|
||||||
/* dont lose the old pointer in case out of memory */
|
/* dont lose the old pointer in case out of memory */
|
||||||
buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1);
|
buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1);
|
||||||
if ( ! buffer) {
|
if (!buffer)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->errormsg = "Out of memory in SQLPutData (3)";
|
stmt->errormsg = "Out of memory in SQLPutData (3)";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -771,7 +873,8 @@ char *buffer;
|
|||||||
current_param->EXEC_buffer = buffer;
|
current_param->EXEC_buffer = buffer;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
SC_log_error(func, "bad cbValue", stmt);
|
SC_log_error(func, "bad cbValue", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -40,14 +40,18 @@
|
|||||||
DWORD
|
DWORD
|
||||||
GetPrivateProfileString(char *theSection, /* section name */
|
GetPrivateProfileString(char *theSection, /* section name */
|
||||||
char *theKey, /* search key name */
|
char *theKey, /* search key name */
|
||||||
char *theDefault, /* default value if not found */
|
char *theDefault, /* default value if not
|
||||||
char *theReturnBuffer, /* return value stored here */
|
* found */
|
||||||
size_t theReturnBufferLength, /* byte length of return buffer */
|
char *theReturnBuffer, /* return value stored
|
||||||
char *theIniFileName) /* pathname of ini file to search */
|
* here */
|
||||||
|
size_t theReturnBufferLength, /* byte length of return
|
||||||
|
* buffer */
|
||||||
|
char *theIniFileName) /* pathname of ini file to
|
||||||
|
* search */
|
||||||
{
|
{
|
||||||
char buf[MAXPGPATH];
|
char buf[MAXPGPATH];
|
||||||
char* ptr = 0;
|
char *ptr = 0;
|
||||||
FILE* aFile = 0;
|
FILE *aFile = 0;
|
||||||
size_t aLength;
|
size_t aLength;
|
||||||
char aLine[2048];
|
char aLine[2048];
|
||||||
char *aValue;
|
char *aValue;
|
||||||
@ -61,56 +65,56 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
j = strlen(theIniFileName) + 1;
|
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 )
|
if (MAXPGPATH - 1 < j)
|
||||||
theIniFileName[MAXPGPATH-1] = '\0';
|
theIniFileName[MAXPGPATH - 1] = '\0';
|
||||||
|
|
||||||
sprintf(buf,"%s",theIniFileName);
|
sprintf(buf, "%s", theIniFileName);
|
||||||
}
|
}
|
||||||
ptr = ((struct passwd*)ptr)->pw_dir; /* get user home dir */
|
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
|
||||||
if( ptr == NULL || *ptr == '\0' )
|
if (ptr == NULL || *ptr == '\0')
|
||||||
ptr = "/home";
|
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
|
* This doesn't make it so we find an ini file but allows normal
|
||||||
* the file won't be found and thus the default value will be
|
* processing to continue further on down. The likelihood is that the
|
||||||
* returned.
|
* 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) )
|
if (MAXPGPATH - 1 < strlen(ptr))
|
||||||
ptr[MAXPGPATH-1] = '\0';
|
ptr[MAXPGPATH - 1] = '\0';
|
||||||
else
|
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
|
* 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);
|
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
|
||||||
if(!aFile) {
|
if (!aFile)
|
||||||
sprintf(buf,"%s",theIniFileName);
|
{
|
||||||
aFile = (FILE*)(buf ? fopen(buf, PG_BINARY_R) : NULL);
|
sprintf(buf, "%s", theIniFileName);
|
||||||
|
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aLength = (theDefault == NULL) ? 0 : strlen(theDefault);
|
aLength = (theDefault == NULL) ? 0 : strlen(theDefault);
|
||||||
|
|
||||||
if(theReturnBufferLength == 0 || theReturnBuffer == NULL)
|
if (theReturnBufferLength == 0 || theReturnBuffer == NULL)
|
||||||
{
|
|
||||||
if(aFile)
|
|
||||||
{
|
{
|
||||||
|
if (aFile)
|
||||||
fclose(aFile);
|
fclose(aFile);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(aFile == NULL)
|
if (aFile == NULL)
|
||||||
{
|
{
|
||||||
/* no ini file specified, return the default */
|
/* no ini file specified, return the default */
|
||||||
|
|
||||||
@ -123,15 +127,13 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while(fgets(aLine, sizeof(aLine), aFile) != NULL)
|
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
|
||||||
{
|
{
|
||||||
aLineLength = strlen(aLine);
|
aLineLength = strlen(aLine);
|
||||||
/* strip final '\n' */
|
/* strip final '\n' */
|
||||||
if(aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
||||||
{
|
|
||||||
aLine[aLineLength - 1] = '\0';
|
aLine[aLineLength - 1] = '\0';
|
||||||
}
|
switch (*aLine)
|
||||||
switch(*aLine)
|
|
||||||
{
|
{
|
||||||
case ' ': /* blank line */
|
case ' ': /* blank line */
|
||||||
case ';': /* comment line */
|
case ';': /* comment line */
|
||||||
@ -140,21 +142,21 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
case '[': /* section marker */
|
case '[': /* section marker */
|
||||||
|
|
||||||
if( (aString = strchr(aLine, ']')) )
|
if ((aString = strchr(aLine, ']')))
|
||||||
{
|
{
|
||||||
aStart = aLine + 1;
|
aStart = aLine + 1;
|
||||||
aString--;
|
aString--;
|
||||||
while (isspace((unsigned char) *aStart)) aStart++;
|
while (isspace((unsigned char) *aStart))
|
||||||
while (isspace((unsigned char) *aString)) aString--;
|
aStart++;
|
||||||
*(aString+1) = '\0';
|
while (isspace((unsigned char) *aString))
|
||||||
|
aString--;
|
||||||
|
*(aString + 1) = '\0';
|
||||||
|
|
||||||
/* accept as matched if NULL key or exact match */
|
/* accept as matched if NULL key or exact match */
|
||||||
|
|
||||||
if(!theSection || !strcmp(aStart, theSection))
|
if (!theSection || !strcmp(aStart, theSection))
|
||||||
{
|
|
||||||
aSectionFound = TRUE;
|
aSectionFound = TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -162,47 +164,40 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
/* try to match value keys if in proper section */
|
/* try to match value keys if in proper section */
|
||||||
|
|
||||||
if(aSectionFound)
|
if (aSectionFound)
|
||||||
{
|
{
|
||||||
/* try to match requested key */
|
/* try to match requested key */
|
||||||
|
|
||||||
if( (aString = aValue = strchr(aLine, '=')) )
|
if ((aString = aValue = strchr(aLine, '=')))
|
||||||
{
|
{
|
||||||
*aValue = '\0';
|
*aValue = '\0';
|
||||||
++aValue;
|
++aValue;
|
||||||
|
|
||||||
/* strip leading blanks in value field */
|
/* strip leading blanks in value field */
|
||||||
|
|
||||||
while(*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
||||||
{
|
|
||||||
*aValue++ = '\0';
|
*aValue++ = '\0';
|
||||||
}
|
if (aValue >= aLine + sizeof(aLine))
|
||||||
if(aValue >= aLine + sizeof(aLine))
|
|
||||||
{
|
|
||||||
aValue = "";
|
aValue = "";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
aValue = "";
|
aValue = "";
|
||||||
}
|
|
||||||
|
|
||||||
aStart = aLine;
|
aStart = aLine;
|
||||||
while (isspace((unsigned char) *aStart)) aStart++;
|
while (isspace((unsigned char) *aStart))
|
||||||
|
aStart++;
|
||||||
|
|
||||||
/* strip trailing blanks from key */
|
/* strip trailing blanks from key */
|
||||||
|
|
||||||
if(aString)
|
if (aString)
|
||||||
{
|
|
||||||
while(--aString >= aStart && *aString == ' ')
|
|
||||||
{
|
{
|
||||||
|
while (--aString >= aStart && *aString == ' ')
|
||||||
*aString = '\0';
|
*aString = '\0';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* see if key is matched */
|
/* see if key is matched */
|
||||||
|
|
||||||
if(theKey == NULL || !strcmp(theKey, aStart))
|
if (theKey == NULL || !strcmp(theKey, aStart))
|
||||||
{
|
{
|
||||||
/* matched -- first, terminate value part */
|
/* matched -- first, terminate value part */
|
||||||
|
|
||||||
@ -213,7 +208,7 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
aString = aValue + aLength - 1;
|
aString = aValue + aLength - 1;
|
||||||
|
|
||||||
while(--aString > aValue && *aString == ' ')
|
while (--aString > aValue && *aString == ' ')
|
||||||
{
|
{
|
||||||
*aString = '\0';
|
*aString = '\0';
|
||||||
--aLength;
|
--aLength;
|
||||||
@ -221,7 +216,7 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
/* unquote value if quoted */
|
/* unquote value if quoted */
|
||||||
|
|
||||||
if(aLength >= 2 && aValue[0] == '"' &&
|
if (aLength >= 2 && aValue[0] == '"' &&
|
||||||
aValue[aLength - 1] == '"')
|
aValue[aLength - 1] == '"')
|
||||||
{
|
{
|
||||||
/* string quoted with double quotes */
|
/* string quoted with double quotes */
|
||||||
@ -234,7 +229,7 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
{
|
{
|
||||||
/* single quotes allowed also... */
|
/* single quotes allowed also... */
|
||||||
|
|
||||||
if(aLength >= 2 && aValue[0] == '\'' &&
|
if (aLength >= 2 && aValue[0] == '\'' &&
|
||||||
aValue[aLength - 1] == '\'')
|
aValue[aLength - 1] == '\'')
|
||||||
{
|
{
|
||||||
aValue[aLength - 1] = '\0';
|
aValue[aLength - 1] = '\0';
|
||||||
@ -251,18 +246,18 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
/* do the copy to return buffer */
|
/* do the copy to return buffer */
|
||||||
|
|
||||||
if(aLineLength)
|
if (aLineLength)
|
||||||
{
|
{
|
||||||
strncpy(&theReturnBuffer[aReturnLength],
|
strncpy(&theReturnBuffer[aReturnLength],
|
||||||
aValue, aLineLength);
|
aValue, aLineLength);
|
||||||
aReturnLength += aLineLength;
|
aReturnLength += aLineLength;
|
||||||
if(aReturnLength < theReturnBufferLength)
|
if (aReturnLength < theReturnBufferLength)
|
||||||
{
|
{
|
||||||
theReturnBuffer[aReturnLength] = '\0';
|
theReturnBuffer[aReturnLength] = '\0';
|
||||||
++aReturnLength;
|
++aReturnLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(aFile)
|
if (aFile)
|
||||||
{
|
{
|
||||||
fclose(aFile);
|
fclose(aFile);
|
||||||
aFile = NULL;
|
aFile = NULL;
|
||||||
@ -276,12 +271,11 @@ GetPrivateProfileString(char *theSection, /* section name */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(aFile)
|
if (aFile)
|
||||||
{
|
|
||||||
fclose(aFile);
|
fclose(aFile);
|
||||||
}
|
|
||||||
|
|
||||||
if(!aKeyFound) { /* key wasn't found return default */
|
if (!aKeyFound)
|
||||||
|
{ /* key wasn't found return default */
|
||||||
++aLength; /* room for NULL char */
|
++aLength; /* room for NULL char */
|
||||||
aLength = theReturnBufferLength < aLength ?
|
aLength = theReturnBufferLength < aLength ?
|
||||||
theReturnBufferLength : aLength;
|
theReturnBufferLength : aLength;
|
||||||
@ -296,7 +290,8 @@ DWORD
|
|||||||
WritePrivateProfileString(char *theSection, /* section name */
|
WritePrivateProfileString(char *theSection, /* section name */
|
||||||
char *theKey, /* write key name */
|
char *theKey, /* write key name */
|
||||||
char *theBuffer, /* input buffer */
|
char *theBuffer, /* input buffer */
|
||||||
char *theIniFileName) /* pathname of ini file to write */
|
char *theIniFileName) /* pathname of ini file to
|
||||||
|
* write */
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -310,11 +305,12 @@ DWORD
|
|||||||
WritePrivateProfileString(char *theSection, /* section name */
|
WritePrivateProfileString(char *theSection, /* section name */
|
||||||
char *theKey, /* write key name */
|
char *theKey, /* write key name */
|
||||||
char *theBuffer, /* input buffer */
|
char *theBuffer, /* input buffer */
|
||||||
char *theIniFileName) /* pathname of ini file to write */
|
char *theIniFileName) /* pathname of ini file to
|
||||||
|
* write */
|
||||||
{
|
{
|
||||||
char buf[MAXPGPATH];
|
char buf[MAXPGPATH];
|
||||||
char* ptr = 0;
|
char *ptr = 0;
|
||||||
FILE* aFile = 0;
|
FILE *aFile = 0;
|
||||||
size_t aLength;
|
size_t aLength;
|
||||||
char aLine[2048];
|
char aLine[2048];
|
||||||
char *aValue;
|
char *aValue;
|
||||||
@ -327,24 +323,26 @@ WritePrivateProfileString(char *theSection, /* section name */
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
/* If this isn't correct processing we'll change it later */
|
/* If this isn't correct processing we'll change it later */
|
||||||
if(theSection == NULL || theKey == NULL || theBuffer == NULL ||
|
if (theSection == NULL || theKey == NULL || theBuffer == NULL ||
|
||||||
theIniFileName == NULL) return 0;
|
theIniFileName == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
aLength = strlen(theBuffer);
|
aLength = strlen(theBuffer);
|
||||||
if(aLength == 0) return 0;
|
if (aLength == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
j = strlen(theIniFileName) + 1;
|
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 )
|
if (MAXPGPATH - 1 < j)
|
||||||
theIniFileName[MAXPGPATH-1] = '\0';
|
theIniFileName[MAXPGPATH - 1] = '\0';
|
||||||
|
|
||||||
sprintf(buf,"%s",theIniFileName);
|
sprintf(buf, "%s", theIniFileName);
|
||||||
}
|
}
|
||||||
ptr = ((struct passwd*)ptr)->pw_dir; /* get user home dir */
|
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
|
||||||
if( ptr == NULL || *ptr == '\0' )
|
if (ptr == NULL || *ptr == '\0')
|
||||||
ptr = "/home";
|
ptr = "/home";
|
||||||
|
|
||||||
/* This doesn't make it so we find an ini file but allows normal */
|
/* This doesn't make it so we find an ini file but allows normal */
|
||||||
@ -352,24 +350,26 @@ WritePrivateProfileString(char *theSection, /* section name */
|
|||||||
/* the file won't be found and thus the default value will be */
|
/* the file won't be found and thus the default value will be */
|
||||||
/* returned. */
|
/* returned. */
|
||||||
/* */
|
/* */
|
||||||
if( MAXPGPATH-1 < strlen(ptr) + j )
|
if (MAXPGPATH - 1 < strlen(ptr) + j)
|
||||||
{
|
{
|
||||||
if( MAXPGPATH-1 < strlen(ptr) )
|
if (MAXPGPATH - 1 < strlen(ptr))
|
||||||
ptr[MAXPGPATH-1] = '\0';
|
ptr[MAXPGPATH - 1] = '\0';
|
||||||
else
|
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 */
|
/* 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);
|
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
|
||||||
if(!aFile) {
|
if (!aFile)
|
||||||
sprintf(buf,"%s",theIniFileName);
|
{
|
||||||
aFile = (FILE*)(buf ? fopen(buf, "r+") : NULL);
|
sprintf(buf, "%s", theIniFileName);
|
||||||
if(!aFile) return 0;
|
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
|
||||||
|
if (!aFile)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -379,15 +379,13 @@ WritePrivateProfileString(char *theSection, /* section name */
|
|||||||
/* exists we have to overwrite it. If it doesn't exist */
|
/* exists we have to overwrite it. If it doesn't exist */
|
||||||
/* we just write a new line to the file. */
|
/* 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);
|
aLineLength = strlen(aLine);
|
||||||
/* strip final '\n' */
|
/* strip final '\n' */
|
||||||
if(aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
|
||||||
{
|
|
||||||
aLine[aLineLength - 1] = '\0';
|
aLine[aLineLength - 1] = '\0';
|
||||||
}
|
switch (*aLine)
|
||||||
switch(*aLine)
|
|
||||||
{
|
{
|
||||||
case ' ': /* blank line */
|
case ' ': /* blank line */
|
||||||
case ';': /* comment line */
|
case ';': /* comment line */
|
||||||
@ -396,17 +394,15 @@ WritePrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
case '[': /* section marker */
|
case '[': /* section marker */
|
||||||
|
|
||||||
if( (aString = strchr(aLine, ']')) )
|
if ((aString = strchr(aLine, ']')))
|
||||||
{
|
{
|
||||||
*aString = '\0';
|
*aString = '\0';
|
||||||
|
|
||||||
/* accept as matched if key exact match */
|
/* accept as matched if key exact match */
|
||||||
|
|
||||||
if(!strcmp(aLine + 1, theSection))
|
if (!strcmp(aLine + 1, theSection))
|
||||||
{
|
|
||||||
aSectionFound = TRUE;
|
aSectionFound = TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -414,69 +410,61 @@ WritePrivateProfileString(char *theSection, /* section name */
|
|||||||
|
|
||||||
/* try to match value keys if in proper section */
|
/* try to match value keys if in proper section */
|
||||||
|
|
||||||
if(aSectionFound)
|
if (aSectionFound)
|
||||||
{
|
{
|
||||||
/* try to match requested key */
|
/* try to match requested key */
|
||||||
|
|
||||||
if( (aString = aValue = strchr(aLine, '=')) )
|
if ((aString = aValue = strchr(aLine, '=')))
|
||||||
{
|
{
|
||||||
*aValue = '\0';
|
*aValue = '\0';
|
||||||
++aValue;
|
++aValue;
|
||||||
|
|
||||||
/* strip leading blanks in value field */
|
/* strip leading blanks in value field */
|
||||||
|
|
||||||
while(*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
|
||||||
{
|
|
||||||
*aValue++ = '\0';
|
*aValue++ = '\0';
|
||||||
}
|
if (aValue >= aLine + sizeof(aLine))
|
||||||
if(aValue >= aLine + sizeof(aLine))
|
|
||||||
{
|
|
||||||
aValue = "";
|
aValue = "";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
aValue = "";
|
aValue = "";
|
||||||
}
|
|
||||||
|
|
||||||
/* strip trailing blanks from key */
|
/* strip trailing blanks from key */
|
||||||
|
|
||||||
if(aString)
|
if (aString)
|
||||||
{
|
|
||||||
while(--aString >= aLine && *aString == ' ')
|
|
||||||
{
|
{
|
||||||
|
while (--aString >= aLine && *aString == ' ')
|
||||||
*aString = '\0';
|
*aString = '\0';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* see if key is matched */
|
/* see if key is matched */
|
||||||
|
|
||||||
if(!strcmp(theKey, aLine))
|
if (!strcmp(theKey, aLine))
|
||||||
{
|
{
|
||||||
keyFound = TRUE;
|
keyFound = TRUE;
|
||||||
/* matched -- first, terminate value part */
|
/* matched -- first, terminate value part */
|
||||||
|
|
||||||
/* overwrite current value */
|
/* overwrite current value */
|
||||||
fseek(aFile,-aLineLength,SEEK_CUR);
|
fseek(aFile, -aLineLength, SEEK_CUR);
|
||||||
/* overwrite key and value */
|
/* overwrite key and value */
|
||||||
sprintf(aLine,"%s = %s\n",theKey,theBuffer);
|
sprintf(aLine, "%s = %s\n", theKey, theBuffer);
|
||||||
fputs(aLine,aFile);
|
fputs(aLine, aFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!keyFound) { /* theKey wasn't in file so */
|
if (!keyFound)
|
||||||
if(aFile)
|
{ /* theKey wasn't in file so */
|
||||||
{
|
if (aFile)
|
||||||
fclose(aFile);
|
fclose(aFile);
|
||||||
}
|
|
||||||
|
|
||||||
return aReturnLength > 0 ? aReturnLength - 1 : 0;
|
return aReturnLength > 0 ? aReturnLength - 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,25 +13,32 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
GetPrivateProfileString(char *theSection, /* section name */
|
GetPrivateProfileString(char *theSection, /* section name */
|
||||||
char *theKey, /* search key name */
|
char *theKey, /* search key name */
|
||||||
char *theDefault, /* default value if not found */
|
char *theDefault, /* default value if not
|
||||||
char *theReturnBuffer, /* return valuse stored here */
|
* found */
|
||||||
size_t theBufferLength, /* byte length of return buffer */
|
char *theReturnBuffer, /* return valuse stored
|
||||||
char *theIniFileName); /* pathname of ini file to search */
|
* here */
|
||||||
|
size_t theBufferLength, /* byte length of return
|
||||||
|
* buffer */
|
||||||
|
char *theIniFileName); /* pathname of ini file
|
||||||
|
* to search */
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
WritePrivateProfileString(char *theSection, /* section name */
|
WritePrivateProfileString(char *theSection, /* section name */
|
||||||
char *theKey, /* write key name */
|
char *theKey, /* write key name */
|
||||||
char *theBuffer, /* input buffer */
|
char *theBuffer, /* input buffer */
|
||||||
char *theIniFileName); /* pathname of ini file to write */
|
char *theIniFileName); /* pathname of ini file
|
||||||
|
* to write */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,66 +1,66 @@
|
|||||||
#ifndef _IODBC_H
|
#ifndef _IODBC_H
|
||||||
#define _IODBC_H
|
#define _IODBC_H
|
||||||
|
|
||||||
# if !defined(WIN32) && !defined(WIN32_SYSTEM)
|
#if !defined(WIN32) && !defined(WIN32_SYSTEM)
|
||||||
# define _UNIX_
|
#define _UNIX_
|
||||||
|
|
||||||
# include <stdlib.h>
|
#include <stdlib.h>
|
||||||
# include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
# define MEM_ALLOC(size) (malloc((size_t)(size)))
|
#define MEM_ALLOC(size) (malloc((size_t)(size)))
|
||||||
# define MEM_FREE(ptr) {if(ptr) free(ptr);}
|
#define MEM_FREE(ptr) {if(ptr) free(ptr);}
|
||||||
|
|
||||||
# define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
|
#define STRCPY(t, s) (strcpy((char*)(t), (char*)(s)))
|
||||||
# define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
|
#define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n)))
|
||||||
# define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
|
#define STRCAT(t, s) (strcat((char*)(t), (char*)(s)))
|
||||||
# define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
|
#define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n)))
|
||||||
# define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
|
#define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0)
|
||||||
# define STRLEN(str) ((str)? strlen((char*)(str)):0)
|
#define STRLEN(str) ((str)? strlen((char*)(str)):0)
|
||||||
|
|
||||||
# define EXPORT
|
#define EXPORT
|
||||||
# define CALLBACK
|
#define CALLBACK
|
||||||
# define FAR
|
#define FAR
|
||||||
|
|
||||||
typedef signed short SSHOR;
|
typedef signed short SSHOR;
|
||||||
typedef short WORD;
|
typedef short WORD;
|
||||||
typedef long DWORD;
|
typedef long DWORD;
|
||||||
|
|
||||||
typedef WORD WPARAM;
|
typedef WORD WPARAM;
|
||||||
typedef DWORD LPARAM;
|
typedef DWORD LPARAM;
|
||||||
typedef void* HWND;
|
typedef void *HWND;
|
||||||
typedef int BOOL;
|
typedef int BOOL;
|
||||||
|
|
||||||
# endif /* _UNIX_ */
|
#endif /* _UNIX_ */
|
||||||
|
|
||||||
# if defined(WIN32) || defined(WIN32_SYSTEM)
|
#if defined(WIN32) || defined(WIN32_SYSTEM)
|
||||||
|
|
||||||
# include <windows.h>
|
#include <windows.h>
|
||||||
# include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
|
||||||
# ifdef _MSVC_
|
#ifdef _MSVC_
|
||||||
# define MEM_ALLOC(size) (fmalloc((size_t)(size)))
|
#define MEM_ALLOC(size) (fmalloc((size_t)(size)))
|
||||||
# define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
|
#define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0))
|
||||||
# define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s)))
|
#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 STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
|
||||||
# define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
|
#define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0)
|
||||||
# define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
#define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# ifdef _BORLAND_
|
#ifdef _BORLAND_
|
||||||
# define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
|
#define MEM_ALLOC(size) (farmalloc((unsigned long)(size))
|
||||||
# define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
|
#define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0)
|
||||||
# define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s)))
|
#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 STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n)))
|
||||||
# define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
|
#define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0)
|
||||||
# define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
#define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0)
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
# define SYSERR (-1)
|
#define SYSERR (-1)
|
||||||
|
|
||||||
# ifndef NULL
|
#ifndef NULL
|
||||||
# define NULL ((void FAR*)0UL)
|
#define NULL ((void FAR*)0UL)
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* include path to be used to create ODBC compliant applications.
|
* include path to be used to create ODBC compliant applications.
|
||||||
*/
|
*/
|
||||||
#ifndef _INTRINSIC_SQL_H
|
#ifndef _INTRINSIC_SQL_H
|
||||||
# define _INTRINSIC_SQL_H
|
#define _INTRINSIC_SQL_H
|
||||||
|
|
||||||
typedef unsigned char UCHAR;
|
typedef unsigned char UCHAR;
|
||||||
typedef long int SDWORD;
|
typedef long int SDWORD;
|
||||||
@ -10,86 +10,86 @@ typedef short int SWORD;
|
|||||||
typedef unsigned long int UDWORD;
|
typedef unsigned long int UDWORD;
|
||||||
typedef unsigned short int UWORD;
|
typedef unsigned short int UWORD;
|
||||||
|
|
||||||
typedef void FAR* PTR;
|
typedef void FAR *PTR;
|
||||||
|
|
||||||
typedef void FAR* HENV;
|
typedef void FAR *HENV;
|
||||||
typedef void FAR* HDBC;
|
typedef void FAR *HDBC;
|
||||||
typedef void FAR* HSTMT;
|
typedef void FAR *HSTMT;
|
||||||
|
|
||||||
typedef signed short RETCODE;
|
typedef signed short RETCODE;
|
||||||
|
|
||||||
# ifdef WIN32
|
#ifdef WIN32
|
||||||
# define SQL_API __stdcall
|
#define SQL_API __stdcall
|
||||||
# else
|
#else
|
||||||
# define SQL_API EXPORT CALLBACK
|
#define SQL_API EXPORT CALLBACK
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# define ODBCVER 0x0250
|
#define ODBCVER 0x0250
|
||||||
|
|
||||||
# define SQL_MAX_MESSAGE_LENGTH 512
|
#define SQL_MAX_MESSAGE_LENGTH 512
|
||||||
# define SQL_MAX_DSN_LENGTH 32
|
#define SQL_MAX_DSN_LENGTH 32
|
||||||
|
|
||||||
/* return code */
|
/* return code */
|
||||||
# define SQL_INVALID_HANDLE (-2)
|
#define SQL_INVALID_HANDLE (-2)
|
||||||
# define SQL_ERROR (-1)
|
#define SQL_ERROR (-1)
|
||||||
# define SQL_SUCCESS 0
|
#define SQL_SUCCESS 0
|
||||||
# define SQL_SUCCESS_WITH_INFO 1
|
#define SQL_SUCCESS_WITH_INFO 1
|
||||||
# define SQL_NO_DATA_FOUND 100
|
#define SQL_NO_DATA_FOUND 100
|
||||||
|
|
||||||
/* standard SQL datatypes (agree with ANSI type numbering) */
|
/* standard SQL datatypes (agree with ANSI type numbering) */
|
||||||
# define SQL_CHAR 1
|
#define SQL_CHAR 1
|
||||||
# define SQL_NUMERIC 2
|
#define SQL_NUMERIC 2
|
||||||
# define SQL_DECIMAL 3
|
#define SQL_DECIMAL 3
|
||||||
# define SQL_INTEGER 4
|
#define SQL_INTEGER 4
|
||||||
# define SQL_SMALLINT 5
|
#define SQL_SMALLINT 5
|
||||||
# define SQL_FLOAT 6
|
#define SQL_FLOAT 6
|
||||||
# define SQL_REAL 7
|
#define SQL_REAL 7
|
||||||
# define SQL_DOUBLE 8
|
#define SQL_DOUBLE 8
|
||||||
# define SQL_VARCHAR 12
|
#define SQL_VARCHAR 12
|
||||||
|
|
||||||
# define SQL_TYPE_MIN SQL_CHAR
|
#define SQL_TYPE_MIN SQL_CHAR
|
||||||
# define SQL_TYPE_NULL 0
|
#define SQL_TYPE_NULL 0
|
||||||
# define SQL_TYPE_MAX SQL_VARCHAR
|
#define SQL_TYPE_MAX SQL_VARCHAR
|
||||||
|
|
||||||
/* C to SQL datatype mapping */
|
/* C to SQL datatype mapping */
|
||||||
# define SQL_C_CHAR SQL_CHAR
|
#define SQL_C_CHAR SQL_CHAR
|
||||||
# define SQL_C_LONG SQL_INTEGER
|
#define SQL_C_LONG SQL_INTEGER
|
||||||
# define SQL_C_SHORT SQL_SMALLINT
|
#define SQL_C_SHORT SQL_SMALLINT
|
||||||
# define SQL_C_FLOAT SQL_REAL
|
#define SQL_C_FLOAT SQL_REAL
|
||||||
# define SQL_C_DOUBLE SQL_DOUBLE
|
#define SQL_C_DOUBLE SQL_DOUBLE
|
||||||
# define SQL_C_DEFAULT 99
|
#define SQL_C_DEFAULT 99
|
||||||
|
|
||||||
# define SQL_NO_NULLS 0
|
#define SQL_NO_NULLS 0
|
||||||
# define SQL_NULLABLE 1
|
#define SQL_NULLABLE 1
|
||||||
# define SQL_NULLABLE_UNKNOWN 2
|
#define SQL_NULLABLE_UNKNOWN 2
|
||||||
|
|
||||||
/* some special length values */
|
/* some special length values */
|
||||||
# define SQL_NULL_DATA (-1)
|
#define SQL_NULL_DATA (-1)
|
||||||
# define SQL_DATA_AT_EXEC (-2)
|
#define SQL_DATA_AT_EXEC (-2)
|
||||||
# define SQL_NTS (-3)
|
#define SQL_NTS (-3)
|
||||||
|
|
||||||
/* SQLFreeStmt flag values */
|
/* SQLFreeStmt flag values */
|
||||||
# define SQL_CLOSE 0
|
#define SQL_CLOSE 0
|
||||||
# define SQL_DROP 1
|
#define SQL_DROP 1
|
||||||
# define SQL_UNBIND 2
|
#define SQL_UNBIND 2
|
||||||
# define SQL_RESET_PARAMS 3
|
#define SQL_RESET_PARAMS 3
|
||||||
|
|
||||||
/* SQLTransact flag values */
|
/* SQLTransact flag values */
|
||||||
# define SQL_COMMIT 0
|
#define SQL_COMMIT 0
|
||||||
# define SQL_ROLLBACK 1
|
#define SQL_ROLLBACK 1
|
||||||
|
|
||||||
/* SQLColAttributes flag values */
|
/* SQLColAttributes flag values */
|
||||||
# define SQL_COLUMN_COUNT 0
|
#define SQL_COLUMN_COUNT 0
|
||||||
# define SQL_COLUMN_LABEL 18
|
#define SQL_COLUMN_LABEL 18
|
||||||
# define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
|
#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
|
||||||
# define SQL_COLUMN_DRIVER_START 1000
|
#define SQL_COLUMN_DRIVER_START 1000
|
||||||
|
|
||||||
# define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
|
#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
|
||||||
|
|
||||||
/* Null handles */
|
/* Null handles */
|
||||||
# define SQL_NULL_HENV 0
|
#define SQL_NULL_HENV 0
|
||||||
# define SQL_NULL_HDBC 0
|
#define SQL_NULL_HDBC 0
|
||||||
# define SQL_NULL_HSTMT 0
|
#define SQL_NULL_HSTMT 0
|
||||||
|
|
||||||
/* All code below has been added to the original isql.h coming from iodbc */
|
/* All code below has been added to the original isql.h coming from iodbc */
|
||||||
typedef unsigned char BYTE;
|
typedef unsigned char BYTE;
|
||||||
@ -133,21 +133,21 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RETCODE SQL_API SQLAllocConnect (HENV henv,
|
RETCODE SQL_API SQLAllocConnect(HENV henv,
|
||||||
HDBC FAR * phdbc);
|
HDBC FAR * phdbc);
|
||||||
RETCODE SQL_API SQLAllocEnv (HENV FAR * phenv);
|
RETCODE SQL_API SQLAllocEnv(HENV FAR * phenv);
|
||||||
RETCODE SQL_API SQLAllocStmt (HDBC hdbc,
|
RETCODE SQL_API SQLAllocStmt(HDBC hdbc,
|
||||||
HSTMT FAR * phstmt);
|
HSTMT FAR * phstmt);
|
||||||
RETCODE SQL_API SQLBindCol (HSTMT hstmt,
|
RETCODE SQL_API SQLBindCol(HSTMT hstmt,
|
||||||
UWORD icol,
|
UWORD icol,
|
||||||
SWORD fCType,
|
SWORD fCType,
|
||||||
PTR rgbValue,
|
PTR rgbValue,
|
||||||
SDWORD cbValueMax,
|
SDWORD cbValueMax,
|
||||||
SDWORD FAR * pcbValue);
|
SDWORD FAR * pcbValue);
|
||||||
|
|
||||||
RETCODE SQL_API SQLCancel (HSTMT hstmt);
|
RETCODE SQL_API SQLCancel(HSTMT hstmt);
|
||||||
|
|
||||||
RETCODE SQL_API SQLColAttributes (HSTMT hstmt,
|
RETCODE SQL_API SQLColAttributes(HSTMT hstmt,
|
||||||
UWORD icol,
|
UWORD icol,
|
||||||
UWORD fDescType,
|
UWORD fDescType,
|
||||||
PTR rgbDesc,
|
PTR rgbDesc,
|
||||||
@ -155,7 +155,7 @@ RETCODE SQL_API SQLColAttributes (HSTMT hstmt,
|
|||||||
SWORD FAR * pcbDesc,
|
SWORD FAR * pcbDesc,
|
||||||
SDWORD FAR * pfDesc);
|
SDWORD FAR * pfDesc);
|
||||||
|
|
||||||
RETCODE SQL_API SQLConnect (HDBC hdbc,
|
RETCODE SQL_API SQLConnect(HDBC hdbc,
|
||||||
UCHAR FAR * szDSN,
|
UCHAR FAR * szDSN,
|
||||||
SWORD cbDSN,
|
SWORD cbDSN,
|
||||||
UCHAR FAR * szUID,
|
UCHAR FAR * szUID,
|
||||||
@ -163,7 +163,7 @@ RETCODE SQL_API SQLConnect (HDBC hdbc,
|
|||||||
UCHAR FAR * szAuthStr,
|
UCHAR FAR * szAuthStr,
|
||||||
SWORD cbAuthStr);
|
SWORD cbAuthStr);
|
||||||
|
|
||||||
RETCODE SQL_API SQLDescribeCol (HSTMT hstmt,
|
RETCODE SQL_API SQLDescribeCol(HSTMT hstmt,
|
||||||
UWORD icol,
|
UWORD icol,
|
||||||
UCHAR FAR * szColName,
|
UCHAR FAR * szColName,
|
||||||
SWORD cbColNameMax,
|
SWORD cbColNameMax,
|
||||||
@ -173,9 +173,9 @@ RETCODE SQL_API SQLDescribeCol (HSTMT hstmt,
|
|||||||
SWORD FAR * pibScale,
|
SWORD FAR * pibScale,
|
||||||
SWORD FAR * pfNullable);
|
SWORD FAR * pfNullable);
|
||||||
|
|
||||||
RETCODE SQL_API SQLDisconnect (HDBC hdbc);
|
RETCODE SQL_API SQLDisconnect(HDBC hdbc);
|
||||||
|
|
||||||
RETCODE SQL_API SQLError (HENV henv,
|
RETCODE SQL_API SQLError(HENV henv,
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UCHAR FAR * szSqlState,
|
UCHAR FAR * szSqlState,
|
||||||
@ -184,45 +184,45 @@ RETCODE SQL_API SQLError (HENV henv,
|
|||||||
SWORD cbErrorMsgMax,
|
SWORD cbErrorMsgMax,
|
||||||
SWORD FAR * pcbErrorMsg);
|
SWORD FAR * pcbErrorMsg);
|
||||||
|
|
||||||
RETCODE SQL_API SQLExecDirect (HSTMT hstmt,
|
RETCODE SQL_API SQLExecDirect(HSTMT hstmt,
|
||||||
UCHAR FAR * szSqlStr,
|
UCHAR FAR * szSqlStr,
|
||||||
SDWORD cbSqlStr);
|
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,
|
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
|
||||||
UWORD fOption);
|
UWORD fOption);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetCursorName (HSTMT hstmt,
|
RETCODE SQL_API SQLGetCursorName(HSTMT hstmt,
|
||||||
UCHAR FAR * szCursor,
|
UCHAR FAR * szCursor,
|
||||||
SWORD cbCursorMax,
|
SWORD cbCursorMax,
|
||||||
SWORD FAR * pcbCursor);
|
SWORD FAR * pcbCursor);
|
||||||
|
|
||||||
RETCODE SQL_API SQLNumResultCols (HSTMT hstmt,
|
RETCODE SQL_API SQLNumResultCols(HSTMT hstmt,
|
||||||
SWORD FAR * pccol);
|
SWORD FAR * pccol);
|
||||||
|
|
||||||
RETCODE SQL_API SQLPrepare (HSTMT hstmt,
|
RETCODE SQL_API SQLPrepare(HSTMT hstmt,
|
||||||
UCHAR FAR * szSqlStr,
|
UCHAR FAR * szSqlStr,
|
||||||
SDWORD cbSqlStr);
|
SDWORD cbSqlStr);
|
||||||
|
|
||||||
RETCODE SQL_API SQLRowCount (HSTMT hstmt,
|
RETCODE SQL_API SQLRowCount(HSTMT hstmt,
|
||||||
SDWORD FAR * pcrow);
|
SDWORD FAR * pcrow);
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetCursorName (HSTMT hstmt,
|
RETCODE SQL_API SQLSetCursorName(HSTMT hstmt,
|
||||||
UCHAR FAR * szCursor,
|
UCHAR FAR * szCursor,
|
||||||
SWORD cbCursor);
|
SWORD cbCursor);
|
||||||
|
|
||||||
RETCODE SQL_API SQLTransact (HENV henv,
|
RETCODE SQL_API SQLTransact(HENV henv,
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
UWORD fType);
|
UWORD fType);
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetParam (HSTMT hstmt,
|
RETCODE SQL_API SQLSetParam(HSTMT hstmt,
|
||||||
UWORD ipar,
|
UWORD ipar,
|
||||||
SWORD fCType,
|
SWORD fCType,
|
||||||
SWORD fSqlType,
|
SWORD fSqlType,
|
||||||
@ -233,5 +233,6 @@ RETCODE SQL_API SQLSetParam (HSTMT hstmt,
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,212 +3,212 @@
|
|||||||
* to be a drop in replacement for isqlext.h from iodbc.
|
* to be a drop in replacement for isqlext.h from iodbc.
|
||||||
*/
|
*/
|
||||||
#ifndef _INTRINSIC_SQLEXT_H
|
#ifndef _INTRINSIC_SQLEXT_H
|
||||||
# define _INTRINSIC_SQLEXT_H
|
#define _INTRINSIC_SQLEXT_H
|
||||||
|
|
||||||
# include "isql.h"
|
#include "isql.h"
|
||||||
|
|
||||||
# define SQL_STILL_EXECUTING 2
|
#define SQL_STILL_EXECUTING 2
|
||||||
# define SQL_NEED_DATA 99
|
#define SQL_NEED_DATA 99
|
||||||
|
|
||||||
/* extend SQL datatypes */
|
/* extend SQL datatypes */
|
||||||
# define SQL_DATE 9
|
#define SQL_DATE 9
|
||||||
# define SQL_TIME 10
|
#define SQL_TIME 10
|
||||||
# define SQL_TIMESTAMP 11
|
#define SQL_TIMESTAMP 11
|
||||||
# define SQL_LONGVARCHAR (-1)
|
#define SQL_LONGVARCHAR (-1)
|
||||||
# define SQL_BINARY (-2)
|
#define SQL_BINARY (-2)
|
||||||
# define SQL_VARBINARY (-3)
|
#define SQL_VARBINARY (-3)
|
||||||
# define SQL_LONGVARBINARY (-4)
|
#define SQL_LONGVARBINARY (-4)
|
||||||
# define SQL_BIGINT (-5)
|
#define SQL_BIGINT (-5)
|
||||||
# define SQL_TINYINT (-6)
|
#define SQL_TINYINT (-6)
|
||||||
# define SQL_BIT (-7) /* conflict with SQL3 ??? */
|
#define SQL_BIT (-7) /* conflict with SQL3 ??? */
|
||||||
# define SQL_TYPE_DRIVER_START (-80)
|
#define SQL_TYPE_DRIVER_START (-80)
|
||||||
|
|
||||||
/* C to SQL datatype mapping */
|
/* C to SQL datatype mapping */
|
||||||
# define SQL_C_DATE SQL_DATE
|
#define SQL_C_DATE SQL_DATE
|
||||||
# define SQL_C_TIME SQL_TIME
|
#define SQL_C_TIME SQL_TIME
|
||||||
# define SQL_C_TIMESTAMP SQL_TIMESTAMP
|
#define SQL_C_TIMESTAMP SQL_TIMESTAMP
|
||||||
# define SQL_C_BINARY SQL_BINARY
|
#define SQL_C_BINARY SQL_BINARY
|
||||||
# define SQL_C_BIT SQL_BIT
|
#define SQL_C_BIT SQL_BIT
|
||||||
# define SQL_C_TINYINT SQL_TINYINT
|
#define SQL_C_TINYINT SQL_TINYINT
|
||||||
|
|
||||||
# define SQL_SIGNED_OFFSET (-20)
|
#define SQL_SIGNED_OFFSET (-20)
|
||||||
# define SQL_UNSIGNED_OFFSET (-22)
|
#define SQL_UNSIGNED_OFFSET (-22)
|
||||||
|
|
||||||
# define SQL_C_SLONG (SQL_C_LONG + SQL_SIGNED_OFFSET)
|
#define SQL_C_SLONG (SQL_C_LONG + SQL_SIGNED_OFFSET)
|
||||||
# define SQL_C_SSHORT (SQL_C_SHORT + SQL_SIGNED_OFFSET)
|
#define SQL_C_SSHORT (SQL_C_SHORT + SQL_SIGNED_OFFSET)
|
||||||
# define SQL_C_STINYINT (SQL_TINYINT + SQL_SIGNED_OFFSET)
|
#define SQL_C_STINYINT (SQL_TINYINT + SQL_SIGNED_OFFSET)
|
||||||
# define SQL_C_ULONG (SQL_C_LONG + SQL_UNSIGNED_OFFSET)
|
#define SQL_C_ULONG (SQL_C_LONG + SQL_UNSIGNED_OFFSET)
|
||||||
# define SQL_C_USHORT (SQL_C_SHORT + SQL_UNSIGNED_OFFSET)
|
#define SQL_C_USHORT (SQL_C_SHORT + SQL_UNSIGNED_OFFSET)
|
||||||
# define SQL_C_UTINYINT (SQL_TINYINT + SQL_UNSIGNED_OFFSET)
|
#define SQL_C_UTINYINT (SQL_TINYINT + SQL_UNSIGNED_OFFSET)
|
||||||
# define SQL_C_BOOKMARK SQL_C_ULONG
|
#define SQL_C_BOOKMARK SQL_C_ULONG
|
||||||
|
|
||||||
# if defined(SQL_TYPE_MIN)
|
#if defined(SQL_TYPE_MIN)
|
||||||
# undef SQL_TYPE_MIN
|
#undef SQL_TYPE_MIN
|
||||||
# define SQL_TYPE_MIN SQL_BIT
|
#define SQL_TYPE_MIN SQL_BIT
|
||||||
/* Note:If SQL_BIT uses SQL3 value (i.e. 14) then,
|
/* Note:If SQL_BIT uses SQL3 value (i.e. 14) then,
|
||||||
* SQL_TYPE_MIN need to be defined as SQL_TINYINT
|
* SQL_TYPE_MIN need to be defined as SQL_TINYINT
|
||||||
* (i.e. -6).
|
* (i.e. -6).
|
||||||
*/
|
*/
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# define SQL_ALL_TYPES 0
|
#define SQL_ALL_TYPES 0
|
||||||
|
|
||||||
/* SQLDriverConnect flag values */
|
/* SQLDriverConnect flag values */
|
||||||
# define SQL_DRIVER_NOPROMPT 0
|
#define SQL_DRIVER_NOPROMPT 0
|
||||||
# define SQL_DRIVER_COMPLETE 1
|
#define SQL_DRIVER_COMPLETE 1
|
||||||
# define SQL_DRIVER_PROMPT 2
|
#define SQL_DRIVER_PROMPT 2
|
||||||
# define SQL_DRIVER_COMPLETE_REQUIRED 3
|
#define SQL_DRIVER_COMPLETE_REQUIRED 3
|
||||||
|
|
||||||
/* SQLSetParam extensions */
|
/* SQLSetParam extensions */
|
||||||
# define SQL_DEFAULT_PARAM (-5)
|
#define SQL_DEFAULT_PARAM (-5)
|
||||||
# define SQL_IGNORE (-6)
|
#define SQL_IGNORE (-6)
|
||||||
|
|
||||||
/* function number for SQLGetFunctions and _iodbcdm_getproc */
|
/* function number for SQLGetFunctions and _iodbcdm_getproc */
|
||||||
# define SQL_API_SQLALLOCCONNECT 1
|
#define SQL_API_SQLALLOCCONNECT 1
|
||||||
# define SQL_API_SQLALLOCENV 2
|
#define SQL_API_SQLALLOCENV 2
|
||||||
# define SQL_API_SQLALLOCSTMT 3
|
#define SQL_API_SQLALLOCSTMT 3
|
||||||
# define SQL_API_SQLBINDCOL 4
|
#define SQL_API_SQLBINDCOL 4
|
||||||
# define SQL_API_SQLCANCEL 5
|
#define SQL_API_SQLCANCEL 5
|
||||||
# define SQL_API_SQLCOLATTRIBUTES 6
|
#define SQL_API_SQLCOLATTRIBUTES 6
|
||||||
# define SQL_API_SQLCONNECT 7
|
#define SQL_API_SQLCONNECT 7
|
||||||
# define SQL_API_SQLDESCRIBECOL 8
|
#define SQL_API_SQLDESCRIBECOL 8
|
||||||
# define SQL_API_SQLDISCONNECT 9
|
#define SQL_API_SQLDISCONNECT 9
|
||||||
# define SQL_API_SQLERROR 10
|
#define SQL_API_SQLERROR 10
|
||||||
# define SQL_API_SQLEXECDIRECT 11
|
#define SQL_API_SQLEXECDIRECT 11
|
||||||
# define SQL_API_SQLEXECUTE 12
|
#define SQL_API_SQLEXECUTE 12
|
||||||
# define SQL_API_SQLFETCH 13
|
#define SQL_API_SQLFETCH 13
|
||||||
# define SQL_API_SQLFREECONNECT 14
|
#define SQL_API_SQLFREECONNECT 14
|
||||||
# define SQL_API_SQLFREEENV 15
|
#define SQL_API_SQLFREEENV 15
|
||||||
# define SQL_API_SQLFREESTMT 16
|
#define SQL_API_SQLFREESTMT 16
|
||||||
# define SQL_API_SQLGETCURSORNAME 17
|
#define SQL_API_SQLGETCURSORNAME 17
|
||||||
# define SQL_API_SQLNUMRESULTCOLS 18
|
#define SQL_API_SQLNUMRESULTCOLS 18
|
||||||
# define SQL_API_SQLPREPARE 19
|
#define SQL_API_SQLPREPARE 19
|
||||||
# define SQL_API_SQLROWCOUNT 20
|
#define SQL_API_SQLROWCOUNT 20
|
||||||
# define SQL_API_SQLSETCURSORNAME 21
|
#define SQL_API_SQLSETCURSORNAME 21
|
||||||
# define SQL_API_SQLSETPARAM 22
|
#define SQL_API_SQLSETPARAM 22
|
||||||
# define SQL_API_SQLTRANSACT 23
|
#define SQL_API_SQLTRANSACT 23
|
||||||
|
|
||||||
# define SQL_NUM_FUNCTIONS 23
|
#define SQL_NUM_FUNCTIONS 23
|
||||||
|
|
||||||
# define SQL_EXT_API_START 40
|
#define SQL_EXT_API_START 40
|
||||||
|
|
||||||
# define SQL_API_SQLCOLUMNS 40
|
#define SQL_API_SQLCOLUMNS 40
|
||||||
|
|
||||||
# define SQL_API_SQLDRIVERCONNECT 41
|
#define SQL_API_SQLDRIVERCONNECT 41
|
||||||
# define SQL_API_SQLGETCONNECTOPTION 42
|
#define SQL_API_SQLGETCONNECTOPTION 42
|
||||||
# define SQL_API_SQLGETDATA 43
|
#define SQL_API_SQLGETDATA 43
|
||||||
# define SQL_API_SQLGETFUNCTIONS 44
|
#define SQL_API_SQLGETFUNCTIONS 44
|
||||||
# define SQL_API_SQLGETINFO 45
|
#define SQL_API_SQLGETINFO 45
|
||||||
# define SQL_API_SQLGETSTMTOPTION 46
|
#define SQL_API_SQLGETSTMTOPTION 46
|
||||||
# define SQL_API_SQLGETTYPEINFO 47
|
#define SQL_API_SQLGETTYPEINFO 47
|
||||||
# define SQL_API_SQLPARAMDATA 48
|
#define SQL_API_SQLPARAMDATA 48
|
||||||
# define SQL_API_SQLPUTDATA 49
|
#define SQL_API_SQLPUTDATA 49
|
||||||
# define SQL_API_SQLSETCONNECTOPTION 50
|
#define SQL_API_SQLSETCONNECTOPTION 50
|
||||||
# define SQL_API_SQLSETSTMTOPTION 51
|
#define SQL_API_SQLSETSTMTOPTION 51
|
||||||
# define SQL_API_SQLSPECIALCOLUMNS 52
|
#define SQL_API_SQLSPECIALCOLUMNS 52
|
||||||
# define SQL_API_SQLSTATISTICS 53
|
#define SQL_API_SQLSTATISTICS 53
|
||||||
# define SQL_API_SQLTABLES 54
|
#define SQL_API_SQLTABLES 54
|
||||||
|
|
||||||
# define SQL_API_SQLBROWSECONNECT 55
|
#define SQL_API_SQLBROWSECONNECT 55
|
||||||
# define SQL_API_SQLCOLUMNPRIVILEGES 56
|
#define SQL_API_SQLCOLUMNPRIVILEGES 56
|
||||||
# define SQL_API_SQLDATASOURCES 57
|
#define SQL_API_SQLDATASOURCES 57
|
||||||
# define SQL_API_SQLDESCRIBEPARAM 58
|
#define SQL_API_SQLDESCRIBEPARAM 58
|
||||||
# define SQL_API_SQLEXTENDEDFETCH 59
|
#define SQL_API_SQLEXTENDEDFETCH 59
|
||||||
# define SQL_API_SQLFOREIGNKEYS 60
|
#define SQL_API_SQLFOREIGNKEYS 60
|
||||||
# define SQL_API_SQLMORERESULTS 61
|
#define SQL_API_SQLMORERESULTS 61
|
||||||
# define SQL_API_SQLNATIVESQL 62
|
#define SQL_API_SQLNATIVESQL 62
|
||||||
# define SQL_API_SQLNUMPARAMS 63
|
#define SQL_API_SQLNUMPARAMS 63
|
||||||
# define SQL_API_SQLPARAMOPTIONS 64
|
#define SQL_API_SQLPARAMOPTIONS 64
|
||||||
# define SQL_API_SQLPRIMARYKEYS 65
|
#define SQL_API_SQLPRIMARYKEYS 65
|
||||||
# define SQL_API_SQLPROCEDURECOLUMNS 66
|
#define SQL_API_SQLPROCEDURECOLUMNS 66
|
||||||
# define SQL_API_SQLPROCEDURES 67
|
#define SQL_API_SQLPROCEDURES 67
|
||||||
# define SQL_API_SQLSETPOS 68
|
#define SQL_API_SQLSETPOS 68
|
||||||
# define SQL_API_SQLSETSCROLLOPTIONS 69
|
#define SQL_API_SQLSETSCROLLOPTIONS 69
|
||||||
# define SQL_API_SQLTABLEPRIVILEGES 70
|
#define SQL_API_SQLTABLEPRIVILEGES 70
|
||||||
|
|
||||||
# define SQL_API_SQLDRIVERS 71
|
#define SQL_API_SQLDRIVERS 71
|
||||||
# define SQL_API_SQLBINDPARAMETER 72
|
#define SQL_API_SQLBINDPARAMETER 72
|
||||||
# define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER
|
#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER
|
||||||
#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST - SQL_EXT_API_START + 1)
|
#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST - SQL_EXT_API_START + 1)
|
||||||
|
|
||||||
# define SQL_API_ALL_FUNCTIONS 0
|
#define SQL_API_ALL_FUNCTIONS 0
|
||||||
|
|
||||||
/* SQLGetInfo infor number */
|
/* SQLGetInfo infor number */
|
||||||
# define SQL_INFO_FIRST 0
|
#define SQL_INFO_FIRST 0
|
||||||
# define SQL_DRIVER_HDBC 3
|
#define SQL_DRIVER_HDBC 3
|
||||||
# define SQL_DRIVER_HENV 4
|
#define SQL_DRIVER_HENV 4
|
||||||
# define SQL_DRIVER_HSTMT 5
|
#define SQL_DRIVER_HSTMT 5
|
||||||
# define SQL_DRIVER_NAME 6
|
#define SQL_DRIVER_NAME 6
|
||||||
# define SQL_ODBC_VER 10
|
#define SQL_ODBC_VER 10
|
||||||
# define SQL_CURSOR_COMMIT_BEHAVIOR 23
|
#define SQL_CURSOR_COMMIT_BEHAVIOR 23
|
||||||
# define SQL_CURSOR_ROLLBACK_BEHAVIOR 24
|
#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24
|
||||||
# define SQL_DEFAULT_TXN_ISOLATION 26
|
#define SQL_DEFAULT_TXN_ISOLATION 26
|
||||||
|
|
||||||
# define SQL_TXN_ISOLATION_OPTION 72
|
#define SQL_TXN_ISOLATION_OPTION 72
|
||||||
# define SQL_NON_NULLABLE_COLUMNS 75
|
#define SQL_NON_NULLABLE_COLUMNS 75
|
||||||
|
|
||||||
# define SQL_DRIVER_HLIB 76
|
#define SQL_DRIVER_HLIB 76
|
||||||
# define SQL_DRIVER_ODBC_VER 77
|
#define SQL_DRIVER_ODBC_VER 77
|
||||||
|
|
||||||
# define SQL_QUALIFIER_LOCATION 114
|
#define SQL_QUALIFIER_LOCATION 114
|
||||||
|
|
||||||
# define SQL_INFO_LAST SQL_QUALIFIER_LOCATION
|
#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION
|
||||||
|
|
||||||
# define SQL_INFO_DRIVER_START 1000
|
#define SQL_INFO_DRIVER_START 1000
|
||||||
|
|
||||||
|
|
||||||
/* SQL_TXN_ISOLATION_OPTION masks */
|
/* SQL_TXN_ISOLATION_OPTION masks */
|
||||||
# define SQL_TXN_READ_UNCOMMITTED 0x00000001L
|
#define SQL_TXN_READ_UNCOMMITTED 0x00000001L
|
||||||
# define SQL_TXN_READ_COMMITTED 0x00000002L
|
#define SQL_TXN_READ_COMMITTED 0x00000002L
|
||||||
# define SQL_TXN_REPEATABLE_READ 0x00000004L
|
#define SQL_TXN_REPEATABLE_READ 0x00000004L
|
||||||
# define SQL_TXN_SERIALIZABLE 0x00000008L
|
#define SQL_TXN_SERIALIZABLE 0x00000008L
|
||||||
# define SQL_TXN_VERSIONING 0x00000010L
|
#define SQL_TXN_VERSIONING 0x00000010L
|
||||||
|
|
||||||
/* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */
|
/* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */
|
||||||
|
|
||||||
# define SQL_CB_DELETE 0x0000
|
#define SQL_CB_DELETE 0x0000
|
||||||
# define SQL_CB_CLOSE 0x0001
|
#define SQL_CB_CLOSE 0x0001
|
||||||
# define SQL_CB_PRESERVE 0x0002
|
#define SQL_CB_PRESERVE 0x0002
|
||||||
|
|
||||||
/* options for SQLGetStmtOption/SQLSetStmtOption */
|
/* options for SQLGetStmtOption/SQLSetStmtOption */
|
||||||
# define SQL_QUERY_TIMEOUT 0
|
#define SQL_QUERY_TIMEOUT 0
|
||||||
# define SQL_MAX_ROWS 1
|
#define SQL_MAX_ROWS 1
|
||||||
# define SQL_NOSCAN 2
|
#define SQL_NOSCAN 2
|
||||||
# define SQL_MAX_LENGTH 3
|
#define SQL_MAX_LENGTH 3
|
||||||
# define SQL_ASYNC_ENABLE 4
|
#define SQL_ASYNC_ENABLE 4
|
||||||
# define SQL_BIND_TYPE 5
|
#define SQL_BIND_TYPE 5
|
||||||
# define SQL_CURSOR_TYPE 6
|
#define SQL_CURSOR_TYPE 6
|
||||||
# define SQL_CONCURRENCY 7
|
#define SQL_CONCURRENCY 7
|
||||||
# define SQL_KEYSET_SIZE 8
|
#define SQL_KEYSET_SIZE 8
|
||||||
# define SQL_ROWSET_SIZE 9
|
#define SQL_ROWSET_SIZE 9
|
||||||
# define SQL_SIMULATE_CURSOR 10
|
#define SQL_SIMULATE_CURSOR 10
|
||||||
# define SQL_RETRIEVE_DATA 11
|
#define SQL_RETRIEVE_DATA 11
|
||||||
# define SQL_USE_BOOKMARKS 12
|
#define SQL_USE_BOOKMARKS 12
|
||||||
# define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */
|
#define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */
|
||||||
# define SQL_ROW_NUMBER 14 /* GetStmtOption Only */
|
#define SQL_ROW_NUMBER 14 /* GetStmtOption Only */
|
||||||
# define SQL_STMT_OPT_MAX SQL_ROW_NUMBER
|
#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER
|
||||||
|
|
||||||
# define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT
|
#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ODBC 3.0 renames the above to SQL_ATTR_ values. At this time I don't
|
* ODBC 3.0 renames the above to SQL_ATTR_ values. At this time I don't
|
||||||
* know if they have also been renumbered or not, I will assume not.
|
* know if they have also been renumbered or not, I will assume not.
|
||||||
*/
|
*/
|
||||||
# define SQL_ATTR_QUERY_TIMEOUT 0
|
#define SQL_ATTR_QUERY_TIMEOUT 0
|
||||||
# define SQL_ATTR_MAX_ROWS 1
|
#define SQL_ATTR_MAX_ROWS 1
|
||||||
# define SQL_ATTR_NOSCAN 2
|
#define SQL_ATTR_NOSCAN 2
|
||||||
# define SQL_ATTR_MAX_LENGTH 3
|
#define SQL_ATTR_MAX_LENGTH 3
|
||||||
# define SQL_ATTR_ASYNC_ENABLE 4
|
#define SQL_ATTR_ASYNC_ENABLE 4
|
||||||
# define SQL_ATTR_BIND_TYPE 5
|
#define SQL_ATTR_BIND_TYPE 5
|
||||||
# define SQL_ATTR_CURSOR_TYPE 6
|
#define SQL_ATTR_CURSOR_TYPE 6
|
||||||
# define SQL_ATTR_CONCURRENCY 7
|
#define SQL_ATTR_CONCURRENCY 7
|
||||||
# define SQL_ATTR_KEYSET_SIZE 8
|
#define SQL_ATTR_KEYSET_SIZE 8
|
||||||
# define SQL_ATTR_ROWSET_SIZE 9
|
#define SQL_ATTR_ROWSET_SIZE 9
|
||||||
# define SQL_ATTR_SIMULATE_CURSOR 10
|
#define SQL_ATTR_SIMULATE_CURSOR 10
|
||||||
# define SQL_ATTR_RETRIEVE_DATA 11
|
#define SQL_ATTR_RETRIEVE_DATA 11
|
||||||
# define SQL_ATTR_USE_BOOKMARKS 12
|
#define SQL_ATTR_USE_BOOKMARKS 12
|
||||||
# define SQL_ATTR_GET_BOOKMARK 13 /* GetStmtOption Only */
|
#define SQL_ATTR_GET_BOOKMARK 13 /* GetStmtOption Only */
|
||||||
# define SQL_ATTR_ROW_NUMBER 14 /* GetStmtOption Only */
|
#define SQL_ATTR_ROW_NUMBER 14 /* GetStmtOption Only */
|
||||||
|
|
||||||
/* New in ODBC 3.0 */
|
/* New in ODBC 3.0 */
|
||||||
#define SQL_ATTR_APP_PARAM_DESC 15
|
#define SQL_ATTR_APP_PARAM_DESC 15
|
||||||
@ -236,80 +236,80 @@
|
|||||||
#define SQL_STMT_ATTR_MAX SQL_ATTR_ROWS_FETCHED_PTR
|
#define SQL_STMT_ATTR_MAX SQL_ATTR_ROWS_FETCHED_PTR
|
||||||
|
|
||||||
/* SQL_QUERY_TIMEOUT options */
|
/* SQL_QUERY_TIMEOUT options */
|
||||||
# define SQL_QUERY_TIMEOUT_DEFAULT 0UL
|
#define SQL_QUERY_TIMEOUT_DEFAULT 0UL
|
||||||
|
|
||||||
/* SQL_MAX_ROWS options */
|
/* SQL_MAX_ROWS options */
|
||||||
# define SQL_MAX_ROWS_DEFAULT 0UL
|
#define SQL_MAX_ROWS_DEFAULT 0UL
|
||||||
|
|
||||||
/* SQL_MAX_LENGTH options */
|
/* SQL_MAX_LENGTH options */
|
||||||
# define SQL_MAX_LENGTH_DEFAULT 0UL
|
#define SQL_MAX_LENGTH_DEFAULT 0UL
|
||||||
|
|
||||||
/* SQL_CONCURRENCY options */
|
/* SQL_CONCURRENCY options */
|
||||||
# define SQL_CONCUR_READ_ONLY 1
|
#define SQL_CONCUR_READ_ONLY 1
|
||||||
# define SQL_CONCUR_LOCK 2
|
#define SQL_CONCUR_LOCK 2
|
||||||
# define SQL_CONCUR_ROWVER 3
|
#define SQL_CONCUR_ROWVER 3
|
||||||
# define SQL_CONCUR_VALUES 4
|
#define SQL_CONCUR_VALUES 4
|
||||||
|
|
||||||
/* options for SQLSetConnectOption/SQLGetConnectOption */
|
/* options for SQLSetConnectOption/SQLGetConnectOption */
|
||||||
# define SQL_ACCESS_MODE 101
|
#define SQL_ACCESS_MODE 101
|
||||||
# define SQL_AUTOCOMMIT 102
|
#define SQL_AUTOCOMMIT 102
|
||||||
# define SQL_LOGIN_TIMEOUT 103
|
#define SQL_LOGIN_TIMEOUT 103
|
||||||
# define SQL_OPT_TRACE 104
|
#define SQL_OPT_TRACE 104
|
||||||
# define SQL_OPT_TRACEFILE 105
|
#define SQL_OPT_TRACEFILE 105
|
||||||
# define SQL_TRANSLATE_DLL 106
|
#define SQL_TRANSLATE_DLL 106
|
||||||
# define SQL_TRANSLATE_OPTION 107
|
#define SQL_TRANSLATE_OPTION 107
|
||||||
# define SQL_TXN_ISOLATION 108
|
#define SQL_TXN_ISOLATION 108
|
||||||
# define SQL_CURRENT_QUALIFIER 109
|
#define SQL_CURRENT_QUALIFIER 109
|
||||||
# define SQL_ODBC_CURSORS 110
|
#define SQL_ODBC_CURSORS 110
|
||||||
# define SQL_QUIET_MODE 111
|
#define SQL_QUIET_MODE 111
|
||||||
# define SQL_PACKET_SIZE 112
|
#define SQL_PACKET_SIZE 112
|
||||||
# define SQL_CONN_OPT_MAX SQL_PACKET_SIZE
|
#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE
|
||||||
# define SQL_CONNECT_OPT_DRVR_START 1000
|
#define SQL_CONNECT_OPT_DRVR_START 1000
|
||||||
|
|
||||||
# define SQL_CONN_OPT_MIN SQL_ACCESS_MODE
|
#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE
|
||||||
|
|
||||||
/* SQL_ACCESS_MODE options */
|
/* SQL_ACCESS_MODE options */
|
||||||
# define SQL_MODE_READ_WRITE 0UL
|
#define SQL_MODE_READ_WRITE 0UL
|
||||||
# define SQL_MODE_READ_ONLY 1UL
|
#define SQL_MODE_READ_ONLY 1UL
|
||||||
# define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE
|
#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE
|
||||||
|
|
||||||
/* SQL_AUTOCOMMIT options */
|
/* SQL_AUTOCOMMIT options */
|
||||||
# define SQL_AUTOCOMMIT_OFF 0UL
|
#define SQL_AUTOCOMMIT_OFF 0UL
|
||||||
# define SQL_AUTOCOMMIT_ON 1UL
|
#define SQL_AUTOCOMMIT_ON 1UL
|
||||||
# define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON
|
#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON
|
||||||
|
|
||||||
/* SQL_LOGIN_TIMEOUT options */
|
/* SQL_LOGIN_TIMEOUT options */
|
||||||
# define SQL_LOGIN_TIMEOUT_DEFAULT 15UL
|
#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL
|
||||||
|
|
||||||
/* SQL_OPT_TRACE options */
|
/* SQL_OPT_TRACE options */
|
||||||
# define SQL_OPT_TRACE_OFF 0UL
|
#define SQL_OPT_TRACE_OFF 0UL
|
||||||
# define SQL_OPT_TRACE_ON 1UL
|
#define SQL_OPT_TRACE_ON 1UL
|
||||||
# define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF
|
#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF
|
||||||
# define SQL_OPT_TRACE_FILE_DEFAULT "odbc.log"
|
#define SQL_OPT_TRACE_FILE_DEFAULT "odbc.log"
|
||||||
|
|
||||||
/* SQL_ODBC_CURSORS options */
|
/* SQL_ODBC_CURSORS options */
|
||||||
# define SQL_CUR_USE_IF_NEEDED 0UL
|
#define SQL_CUR_USE_IF_NEEDED 0UL
|
||||||
# define SQL_CUR_USE_ODBC 1UL
|
#define SQL_CUR_USE_ODBC 1UL
|
||||||
# define SQL_CUR_USE_DRIVER 2UL
|
#define SQL_CUR_USE_DRIVER 2UL
|
||||||
# define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER
|
#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER
|
||||||
|
|
||||||
/* Column types and scopes in SQLSpecialColumns. */
|
/* Column types and scopes in SQLSpecialColumns. */
|
||||||
# define SQL_BEST_ROWID 1
|
#define SQL_BEST_ROWID 1
|
||||||
# define SQL_ROWVER 2
|
#define SQL_ROWVER 2
|
||||||
|
|
||||||
# define SQL_SCOPE_CURROW 0
|
#define SQL_SCOPE_CURROW 0
|
||||||
# define SQL_SCOPE_TRANSACTION 1
|
#define SQL_SCOPE_TRANSACTION 1
|
||||||
# define SQL_SCOPE_SESSION 2
|
#define SQL_SCOPE_SESSION 2
|
||||||
|
|
||||||
|
|
||||||
/* SQLExtendedFetch flag values */
|
/* SQLExtendedFetch flag values */
|
||||||
# define SQL_FETCH_NEXT 1
|
#define SQL_FETCH_NEXT 1
|
||||||
# define SQL_FETCH_FIRST 2
|
#define SQL_FETCH_FIRST 2
|
||||||
# define SQL_FETCH_LAST 3
|
#define SQL_FETCH_LAST 3
|
||||||
# define SQL_FETCH_PRIOR 4
|
#define SQL_FETCH_PRIOR 4
|
||||||
# define SQL_FETCH_ABSOLUTE 5
|
#define SQL_FETCH_ABSOLUTE 5
|
||||||
# define SQL_FETCH_RELATIVE 6
|
#define SQL_FETCH_RELATIVE 6
|
||||||
# define SQL_FETCH_BOOKMARK 8
|
#define SQL_FETCH_BOOKMARK 8
|
||||||
|
|
||||||
/* Defines for SQLBindParameter/SQLProcedureColumns */
|
/* Defines for SQLBindParameter/SQLProcedureColumns */
|
||||||
#define SQL_PARAM_TYPE_UNKNOWN 0
|
#define SQL_PARAM_TYPE_UNKNOWN 0
|
||||||
@ -320,21 +320,21 @@
|
|||||||
#define SQL_RETURN_VALUE 5
|
#define SQL_RETURN_VALUE 5
|
||||||
|
|
||||||
/* Defines used by Driver Manager for mapping SQLSetParam to SQLBindParameter */
|
/* Defines used by Driver Manager for mapping SQLSetParam to SQLBindParameter */
|
||||||
# define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT
|
#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT
|
||||||
# define SQL_SETPARAM_VALUE_MAX (-1L)
|
#define SQL_SETPARAM_VALUE_MAX (-1L)
|
||||||
|
|
||||||
/* SQLStatistics flag values */
|
/* SQLStatistics flag values */
|
||||||
# define SQL_INDEX_UNIQUE 0
|
#define SQL_INDEX_UNIQUE 0
|
||||||
# define SQL_INDEX_ALL 1
|
#define SQL_INDEX_ALL 1
|
||||||
|
|
||||||
# define SQL_QUICK 0
|
#define SQL_QUICK 0
|
||||||
# define SQL_ENSURE 1
|
#define SQL_ENSURE 1
|
||||||
|
|
||||||
/* SQLSetScrollOption flag values */
|
/* SQLSetScrollOption flag values */
|
||||||
# define SQL_SCROLL_FORWARD_ONLY 0L
|
#define SQL_SCROLL_FORWARD_ONLY 0L
|
||||||
# define SQL_SCROLL_KEYSET_DRIVEN (-1L)
|
#define SQL_SCROLL_KEYSET_DRIVEN (-1L)
|
||||||
# define SQL_SCROLL_DYNAMIC (-2L)
|
#define SQL_SCROLL_DYNAMIC (-2L)
|
||||||
# define SQL_SCROLL_STATIC (-3L)
|
#define SQL_SCROLL_STATIC (-3L)
|
||||||
|
|
||||||
/* Everything below has been added to the original isqlext.h that comes
|
/* Everything below has been added to the original isqlext.h that comes
|
||||||
* with iodbc.
|
* with iodbc.
|
||||||
@ -362,33 +362,39 @@ typedef long long int ODBCINT64;
|
|||||||
typedef unsigned ODBCINT64 SQLUBIGINT;
|
typedef unsigned ODBCINT64 SQLUBIGINT;
|
||||||
typedef ODBCINT64 SQLBIGINT;
|
typedef ODBCINT64 SQLBIGINT;
|
||||||
|
|
||||||
#else /* Used even on platforms with 64 bit ints but not GCC */
|
#else /* Used even on platforms with 64 bit ints
|
||||||
|
* but not GCC */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
SQLUINTEGER dwLowWord;
|
SQLUINTEGER dwLowWord;
|
||||||
SQLUINTEGER dwHighWord;
|
SQLUINTEGER dwHighWord;
|
||||||
} SQLUBIGINT;
|
} SQLUBIGINT;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
SQLUINTEGER dwLowWord;
|
SQLUINTEGER dwLowWord;
|
||||||
SQLINTEGER dwHighWord;
|
SQLINTEGER dwHighWord;
|
||||||
} SQLBIGINT;
|
} SQLBIGINT;
|
||||||
|
|
||||||
#endif /* GCC */
|
#endif /* GCC */
|
||||||
|
|
||||||
typedef struct tagDATE_STRUCT {
|
typedef struct tagDATE_STRUCT
|
||||||
|
{
|
||||||
SQLSMALLINT year;
|
SQLSMALLINT year;
|
||||||
SQLUSMALLINT month;
|
SQLUSMALLINT month;
|
||||||
SQLUSMALLINT day;
|
SQLUSMALLINT day;
|
||||||
} DATE_STRUCT,SQL_DATE_STRUCT;
|
} DATE_STRUCT, SQL_DATE_STRUCT;
|
||||||
|
|
||||||
typedef struct tagTIME_STRUCT {
|
typedef struct tagTIME_STRUCT
|
||||||
|
{
|
||||||
SQLUSMALLINT hour;
|
SQLUSMALLINT hour;
|
||||||
SQLUSMALLINT minute;
|
SQLUSMALLINT minute;
|
||||||
SQLUSMALLINT second;
|
SQLUSMALLINT second;
|
||||||
} TIME_STRUCT,SQL_TIME_STRUCT;
|
} TIME_STRUCT, SQL_TIME_STRUCT;
|
||||||
|
|
||||||
typedef struct tagTIMESTAMP_STRUCT {
|
typedef struct tagTIMESTAMP_STRUCT
|
||||||
|
{
|
||||||
SQLSMALLINT year;
|
SQLSMALLINT year;
|
||||||
SQLUSMALLINT month;
|
SQLUSMALLINT month;
|
||||||
SQLUSMALLINT day;
|
SQLUSMALLINT day;
|
||||||
@ -396,7 +402,7 @@ typedef struct tagTIMESTAMP_STRUCT {
|
|||||||
SQLUSMALLINT minute;
|
SQLUSMALLINT minute;
|
||||||
SQLUSMALLINT second;
|
SQLUSMALLINT second;
|
||||||
SQLUINTEGER fraction;
|
SQLUINTEGER fraction;
|
||||||
} TIMESTAMP_STRUCT,SQL_TIMESTAMP_STRUCT;
|
} TIMESTAMP_STRUCT, SQL_TIMESTAMP_STRUCT;
|
||||||
|
|
||||||
/* postodbc doesn't use these but what the heck */
|
/* postodbc doesn't use these but what the heck */
|
||||||
/* Don't know what SQL_MAX_NUMERIC_LEN should be so I can't include this. It's
|
/* Don't know what SQL_MAX_NUMERIC_LEN should be so I can't include this. It's
|
||||||
@ -411,14 +417,16 @@ typedef struct tagSQL_NUMERIC_STRUCT {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct tagSQLGUID {
|
typedef struct tagSQLGUID
|
||||||
|
{
|
||||||
DWORD Data1;
|
DWORD Data1;
|
||||||
WORD Data2;
|
WORD Data2;
|
||||||
WORD Data3;
|
WORD Data3;
|
||||||
BYTE Data4[8];
|
BYTE Data4[8];
|
||||||
} SQLGUID;
|
} SQLGUID;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
SQL_IS_YEAR = 1,
|
SQL_IS_YEAR = 1,
|
||||||
SQL_IS_MONTH = 2,
|
SQL_IS_MONTH = 2,
|
||||||
SQL_IS_DAY = 3,
|
SQL_IS_DAY = 3,
|
||||||
@ -434,12 +442,14 @@ typedef enum {
|
|||||||
SQL_IS_MINUTE_TO_SECOND = 13
|
SQL_IS_MINUTE_TO_SECOND = 13
|
||||||
} SQLINTERVAL;
|
} SQLINTERVAL;
|
||||||
|
|
||||||
typedef struct tagSQL_YEAR_MONTH {
|
typedef struct tagSQL_YEAR_MONTH
|
||||||
|
{
|
||||||
SQLUINTEGER year;
|
SQLUINTEGER year;
|
||||||
SQLUINTEGER month;
|
SQLUINTEGER month;
|
||||||
} SQL_YEAR_MONTH_STRUCT;
|
} SQL_YEAR_MONTH_STRUCT;
|
||||||
|
|
||||||
typedef struct tagSQL_DAY_SECOND {
|
typedef struct tagSQL_DAY_SECOND
|
||||||
|
{
|
||||||
SQLUINTEGER day;
|
SQLUINTEGER day;
|
||||||
SQLUINTEGER hour;
|
SQLUINTEGER hour;
|
||||||
SQLUINTEGER minute;
|
SQLUINTEGER minute;
|
||||||
@ -447,10 +457,12 @@ typedef struct tagSQL_DAY_SECOND {
|
|||||||
SQLUINTEGER fraction;
|
SQLUINTEGER fraction;
|
||||||
} SQL_DAY_SECOND_STRUCT;
|
} SQL_DAY_SECOND_STRUCT;
|
||||||
|
|
||||||
typedef struct tagSQL_INTERVAL_STRUCT {
|
typedef struct tagSQL_INTERVAL_STRUCT
|
||||||
|
{
|
||||||
SQLINTERVAL interval_type;
|
SQLINTERVAL interval_type;
|
||||||
SQLSMALLINT interval_sign;
|
SQLSMALLINT interval_sign;
|
||||||
union {
|
union
|
||||||
|
{
|
||||||
SQL_YEAR_MONTH_STRUCT year_month;
|
SQL_YEAR_MONTH_STRUCT year_month;
|
||||||
SQL_DAY_SECOND_STRUCT day_second;
|
SQL_DAY_SECOND_STRUCT day_second;
|
||||||
} intval;
|
} intval;
|
||||||
@ -1317,17 +1329,18 @@ typedef struct tagSQL_INTERVAL_STRUCT {
|
|||||||
"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\
|
"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\
|
||||||
"VALUE,,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,YEAR"
|
"VALUE,,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,YEAR"
|
||||||
|
|
||||||
# ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
# endif
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetConnectOption (HDBC, UWORD, UDWORD);
|
RETCODE SQL_API SQLSetConnectOption(HDBC, UWORD, UDWORD);
|
||||||
RETCODE SQL_API SQLNumResultCols ( HSTMT, SWORD FAR* );
|
RETCODE SQL_API SQLNumResultCols(HSTMT, SWORD FAR *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* function prototypes previously missing from isqlext.h
|
* function prototypes previously missing from isqlext.h
|
||||||
*/
|
*/
|
||||||
RETCODE SQL_API SQLColumns (HSTMT hstmt,
|
RETCODE SQL_API SQLColumns(HSTMT hstmt,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
UCHAR FAR * szTableOwner,
|
UCHAR FAR * szTableOwner,
|
||||||
@ -1337,7 +1350,7 @@ RETCODE SQL_API SQLColumns (HSTMT hstmt,
|
|||||||
UCHAR FAR * szColumnName,
|
UCHAR FAR * szColumnName,
|
||||||
SWORD cbColumnName);
|
SWORD cbColumnName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLDriverConnect (HDBC hdbc,
|
RETCODE SQL_API SQLDriverConnect(HDBC hdbc,
|
||||||
HWND hwnd,
|
HWND hwnd,
|
||||||
UCHAR FAR * szConnStrIn,
|
UCHAR FAR * szConnStrIn,
|
||||||
SWORD cbConnStrIn,
|
SWORD cbConnStrIn,
|
||||||
@ -1346,46 +1359,46 @@ RETCODE SQL_API SQLDriverConnect (HDBC hdbc,
|
|||||||
SWORD FAR * pcbConnStrOut,
|
SWORD FAR * pcbConnStrOut,
|
||||||
UWORD fDriverCompletion);
|
UWORD fDriverCompletion);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetConnectOption (HDBC hdbc,
|
RETCODE SQL_API SQLGetConnectOption(HDBC hdbc,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
PTR pvParam);
|
PTR pvParam);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetData (HSTMT hstmt,
|
RETCODE SQL_API SQLGetData(HSTMT hstmt,
|
||||||
UWORD icol,
|
UWORD icol,
|
||||||
SWORD fCType,
|
SWORD fCType,
|
||||||
PTR rgbValue,
|
PTR rgbValue,
|
||||||
SDWORD cbValueMax,
|
SDWORD cbValueMax,
|
||||||
SDWORD FAR * pcbValue);
|
SDWORD FAR * pcbValue);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetFunctions (HDBC hdbc,
|
RETCODE SQL_API SQLGetFunctions(HDBC hdbc,
|
||||||
UWORD fFunction,
|
UWORD fFunction,
|
||||||
UWORD FAR * pfExists);
|
UWORD FAR * pfExists);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetInfo (HDBC hdbc,
|
RETCODE SQL_API SQLGetInfo(HDBC hdbc,
|
||||||
UWORD fInfoType,
|
UWORD fInfoType,
|
||||||
PTR rgbInfoValue,
|
PTR rgbInfoValue,
|
||||||
SWORD cbInfoValueMax,
|
SWORD cbInfoValueMax,
|
||||||
SWORD FAR * pcbInfoValue);
|
SWORD FAR * pcbInfoValue);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetStmtOption (HSTMT hstmt,
|
RETCODE SQL_API SQLGetStmtOption(HSTMT hstmt,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
PTR pvParam);
|
PTR pvParam);
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetTypeInfo (HSTMT hstmt,
|
RETCODE SQL_API SQLGetTypeInfo(HSTMT hstmt,
|
||||||
SWORD fSqlType);
|
SWORD fSqlType);
|
||||||
|
|
||||||
RETCODE SQL_API SQLParamData (HSTMT hstmt,
|
RETCODE SQL_API SQLParamData(HSTMT hstmt,
|
||||||
PTR FAR * prgbValue);
|
PTR FAR * prgbValue);
|
||||||
|
|
||||||
RETCODE SQL_API SQLPutData (HSTMT hstmt,
|
RETCODE SQL_API SQLPutData(HSTMT hstmt,
|
||||||
PTR rgbValue,
|
PTR rgbValue,
|
||||||
SDWORD cbValue);
|
SDWORD cbValue);
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetStmtOption (HSTMT hstmt,
|
RETCODE SQL_API SQLSetStmtOption(HSTMT hstmt,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
UDWORD vParam);
|
UDWORD vParam);
|
||||||
|
|
||||||
RETCODE SQL_API SQLSpecialColumns (HSTMT hstmt,
|
RETCODE SQL_API SQLSpecialColumns(HSTMT hstmt,
|
||||||
UWORD fColType,
|
UWORD fColType,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
@ -1396,7 +1409,7 @@ RETCODE SQL_API SQLSpecialColumns (HSTMT hstmt,
|
|||||||
UWORD fScope,
|
UWORD fScope,
|
||||||
UWORD fNullable);
|
UWORD fNullable);
|
||||||
|
|
||||||
RETCODE SQL_API SQLStatistics (HSTMT hstmt,
|
RETCODE SQL_API SQLStatistics(HSTMT hstmt,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
UCHAR FAR * szTableOwner,
|
UCHAR FAR * szTableOwner,
|
||||||
@ -1406,7 +1419,7 @@ RETCODE SQL_API SQLStatistics (HSTMT hstmt,
|
|||||||
UWORD fUnique,
|
UWORD fUnique,
|
||||||
UWORD fAccuracy);
|
UWORD fAccuracy);
|
||||||
|
|
||||||
RETCODE SQL_API SQLTables (HSTMT hstmt,
|
RETCODE SQL_API SQLTables(HSTMT hstmt,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
UCHAR FAR * szTableOwner,
|
UCHAR FAR * szTableOwner,
|
||||||
@ -1416,14 +1429,14 @@ RETCODE SQL_API SQLTables (HSTMT hstmt,
|
|||||||
UCHAR FAR * szTableType,
|
UCHAR FAR * szTableType,
|
||||||
SWORD cbTableType);
|
SWORD cbTableType);
|
||||||
|
|
||||||
RETCODE SQL_API SQLBrowseConnect (HDBC hdbc,
|
RETCODE SQL_API SQLBrowseConnect(HDBC hdbc,
|
||||||
UCHAR FAR * szConnStrIn,
|
UCHAR FAR * szConnStrIn,
|
||||||
SWORD cbConnStrIn,
|
SWORD cbConnStrIn,
|
||||||
UCHAR FAR * szConnStrOut,
|
UCHAR FAR * szConnStrOut,
|
||||||
SWORD cbConnStrOutMax,
|
SWORD cbConnStrOutMax,
|
||||||
SWORD FAR * pcbConnStrOut);
|
SWORD FAR * pcbConnStrOut);
|
||||||
|
|
||||||
RETCODE SQL_API SQLColumnPrivileges (HSTMT hstmt,
|
RETCODE SQL_API SQLColumnPrivileges(HSTMT hstmt,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
UCHAR FAR * szTableOwner,
|
UCHAR FAR * szTableOwner,
|
||||||
@ -1433,20 +1446,20 @@ RETCODE SQL_API SQLColumnPrivileges (HSTMT hstmt,
|
|||||||
UCHAR FAR * szColumnName,
|
UCHAR FAR * szColumnName,
|
||||||
SWORD cbColumnName);
|
SWORD cbColumnName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLDescribeParam (HSTMT hstmt,
|
RETCODE SQL_API SQLDescribeParam(HSTMT hstmt,
|
||||||
UWORD ipar,
|
UWORD ipar,
|
||||||
SWORD FAR * pfSqlType,
|
SWORD FAR * pfSqlType,
|
||||||
UDWORD FAR * pcbColDef,
|
UDWORD FAR * pcbColDef,
|
||||||
SWORD FAR * pibScale,
|
SWORD FAR * pibScale,
|
||||||
SWORD FAR * pfNullable);
|
SWORD FAR * pfNullable);
|
||||||
|
|
||||||
RETCODE SQL_API SQLExtendedFetch (HSTMT hstmt,
|
RETCODE SQL_API SQLExtendedFetch(HSTMT hstmt,
|
||||||
UWORD fFetchType,
|
UWORD fFetchType,
|
||||||
SDWORD irow,
|
SDWORD irow,
|
||||||
UDWORD FAR * pcrow,
|
UDWORD FAR * pcrow,
|
||||||
UWORD FAR * rgfRowStatus);
|
UWORD FAR * rgfRowStatus);
|
||||||
|
|
||||||
RETCODE SQL_API SQLForeignKeys (HSTMT hstmt,
|
RETCODE SQL_API SQLForeignKeys(HSTMT hstmt,
|
||||||
UCHAR FAR * szPkTableQualifier,
|
UCHAR FAR * szPkTableQualifier,
|
||||||
SWORD cbPkTableQualifier,
|
SWORD cbPkTableQualifier,
|
||||||
UCHAR FAR * szPkTableOwner,
|
UCHAR FAR * szPkTableOwner,
|
||||||
@ -1460,23 +1473,23 @@ RETCODE SQL_API SQLForeignKeys (HSTMT hstmt,
|
|||||||
UCHAR FAR * szFkTableName,
|
UCHAR FAR * szFkTableName,
|
||||||
SWORD cbFkTableName);
|
SWORD cbFkTableName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLMoreResults (HSTMT hstmt);
|
RETCODE SQL_API SQLMoreResults(HSTMT hstmt);
|
||||||
|
|
||||||
RETCODE SQL_API SQLNativeSql (HDBC hdbc,
|
RETCODE SQL_API SQLNativeSql(HDBC hdbc,
|
||||||
UCHAR FAR * szSqlStrIn,
|
UCHAR FAR * szSqlStrIn,
|
||||||
SDWORD cbSqlStrIn,
|
SDWORD cbSqlStrIn,
|
||||||
UCHAR FAR * szSqlStr,
|
UCHAR FAR * szSqlStr,
|
||||||
SDWORD cbSqlStrMax,
|
SDWORD cbSqlStrMax,
|
||||||
SDWORD FAR * pcbSqlStr);
|
SDWORD FAR * pcbSqlStr);
|
||||||
|
|
||||||
RETCODE SQL_API SQLNumParams (HSTMT hstmt,
|
RETCODE SQL_API SQLNumParams(HSTMT hstmt,
|
||||||
SWORD FAR * pcpar);
|
SWORD FAR * pcpar);
|
||||||
|
|
||||||
RETCODE SQL_API SQLParamOptions (HSTMT hstmt,
|
RETCODE SQL_API SQLParamOptions(HSTMT hstmt,
|
||||||
UDWORD crow,
|
UDWORD crow,
|
||||||
UDWORD FAR * pirow);
|
UDWORD FAR * pirow);
|
||||||
|
|
||||||
RETCODE SQL_API SQLPrimaryKeys (HSTMT hstmt,
|
RETCODE SQL_API SQLPrimaryKeys(HSTMT hstmt,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
UCHAR FAR * szTableOwner,
|
UCHAR FAR * szTableOwner,
|
||||||
@ -1484,7 +1497,7 @@ RETCODE SQL_API SQLPrimaryKeys (HSTMT hstmt,
|
|||||||
UCHAR FAR * szTableName,
|
UCHAR FAR * szTableName,
|
||||||
SWORD cbTableName);
|
SWORD cbTableName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLProcedureColumns (HSTMT hstmt,
|
RETCODE SQL_API SQLProcedureColumns(HSTMT hstmt,
|
||||||
UCHAR FAR * szProcQualifier,
|
UCHAR FAR * szProcQualifier,
|
||||||
SWORD cbProcQualifier,
|
SWORD cbProcQualifier,
|
||||||
UCHAR FAR * szProcOwner,
|
UCHAR FAR * szProcOwner,
|
||||||
@ -1494,7 +1507,7 @@ RETCODE SQL_API SQLProcedureColumns (HSTMT hstmt,
|
|||||||
UCHAR FAR * szColumnName,
|
UCHAR FAR * szColumnName,
|
||||||
SWORD cbColumnName);
|
SWORD cbColumnName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLProcedures (HSTMT hstmt,
|
RETCODE SQL_API SQLProcedures(HSTMT hstmt,
|
||||||
UCHAR FAR * szProcQualifier,
|
UCHAR FAR * szProcQualifier,
|
||||||
SWORD cbProcQualifier,
|
SWORD cbProcQualifier,
|
||||||
UCHAR FAR * szProcOwner,
|
UCHAR FAR * szProcOwner,
|
||||||
@ -1502,12 +1515,12 @@ RETCODE SQL_API SQLProcedures (HSTMT hstmt,
|
|||||||
UCHAR FAR * szProcName,
|
UCHAR FAR * szProcName,
|
||||||
SWORD cbProcName);
|
SWORD cbProcName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetPos (HSTMT hstmt,
|
RETCODE SQL_API SQLSetPos(HSTMT hstmt,
|
||||||
UWORD irow,
|
UWORD irow,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
UWORD fLock);
|
UWORD fLock);
|
||||||
|
|
||||||
RETCODE SQL_API SQLTablePrivileges (HSTMT hstmt,
|
RETCODE SQL_API SQLTablePrivileges(HSTMT hstmt,
|
||||||
UCHAR FAR * szTableQualifier,
|
UCHAR FAR * szTableQualifier,
|
||||||
SWORD cbTableQualifier,
|
SWORD cbTableQualifier,
|
||||||
UCHAR FAR * szTableOwner,
|
UCHAR FAR * szTableOwner,
|
||||||
@ -1515,7 +1528,7 @@ RETCODE SQL_API SQLTablePrivileges (HSTMT hstmt,
|
|||||||
UCHAR FAR * szTableName,
|
UCHAR FAR * szTableName,
|
||||||
SWORD cbTableName);
|
SWORD cbTableName);
|
||||||
|
|
||||||
RETCODE SQL_API SQLBindParameter (HSTMT hstmt,
|
RETCODE SQL_API SQLBindParameter(HSTMT hstmt,
|
||||||
UWORD ipar,
|
UWORD ipar,
|
||||||
SWORD fParamType,
|
SWORD fParamType,
|
||||||
SWORD fCType,
|
SWORD fCType,
|
||||||
@ -1526,14 +1539,15 @@ RETCODE SQL_API SQLBindParameter (HSTMT hstmt,
|
|||||||
SDWORD cbValueMax,
|
SDWORD cbValueMax,
|
||||||
SDWORD FAR * pcbValue);
|
SDWORD FAR * pcbValue);
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetScrollOptions (HSTMT hstmt,
|
RETCODE SQL_API SQLSetScrollOptions(HSTMT hstmt,
|
||||||
UWORD fConcurrency,
|
UWORD fConcurrency,
|
||||||
SDWORD crowKeyset,
|
SDWORD crowKeyset,
|
||||||
UWORD crowRowset);
|
UWORD crowRowset);
|
||||||
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,16 +16,17 @@
|
|||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
||||||
Oid
|
Oid
|
||||||
lo_creat(ConnectionClass *conn, int mode)
|
lo_creat(ConnectionClass * conn, int mode)
|
||||||
{
|
{
|
||||||
LO_ARG argv[1];
|
LO_ARG argv[1];
|
||||||
int retval, result_len;
|
int retval,
|
||||||
|
result_len;
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
argv[0].len = 4;
|
argv[0].len = 4;
|
||||||
argv[0].u.integer = mode;
|
argv[0].u.integer = mode;
|
||||||
|
|
||||||
if ( ! CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1))
|
if (!CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1))
|
||||||
return 0; /* invalid oid */
|
return 0; /* invalid oid */
|
||||||
else
|
else
|
||||||
return retval;
|
return retval;
|
||||||
@ -34,11 +35,11 @@ int retval, result_len;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_open(ConnectionClass *conn, int lobjId, int mode)
|
lo_open(ConnectionClass * conn, int lobjId, int mode)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int result_len;
|
int result_len;
|
||||||
LO_ARG argv[2];
|
LO_ARG argv[2];
|
||||||
|
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
@ -49,7 +50,7 @@ LO_ARG argv[2];
|
|||||||
argv[1].len = 4;
|
argv[1].len = 4;
|
||||||
argv[1].u.integer = mode;
|
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;
|
return -1;
|
||||||
|
|
||||||
if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0)
|
if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0)
|
||||||
@ -59,17 +60,18 @@ LO_ARG argv[2];
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_close(ConnectionClass *conn, int fd)
|
lo_close(ConnectionClass * conn, int fd)
|
||||||
{
|
{
|
||||||
LO_ARG argv[1];
|
LO_ARG argv[1];
|
||||||
int retval, result_len;
|
int retval,
|
||||||
|
result_len;
|
||||||
|
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
argv[0].len = 4;
|
argv[0].len = 4;
|
||||||
argv[0].u.integer = fd;
|
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;
|
return -1;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -79,10 +81,10 @@ int retval, result_len;
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_read(ConnectionClass *conn, int fd, char *buf, int len)
|
lo_read(ConnectionClass * conn, int fd, char *buf, int len)
|
||||||
{
|
{
|
||||||
LO_ARG argv[2];
|
LO_ARG argv[2];
|
||||||
int result_len;
|
int result_len;
|
||||||
|
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
@ -93,7 +95,7 @@ int result_len;
|
|||||||
argv[1].len = 4;
|
argv[1].len = 4;
|
||||||
argv[1].u.integer = len;
|
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;
|
return -1;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -101,10 +103,11 @@ int result_len;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_write(ConnectionClass *conn, int fd, char *buf, int len)
|
lo_write(ConnectionClass * conn, int fd, char *buf, int len)
|
||||||
{
|
{
|
||||||
LO_ARG argv[2];
|
LO_ARG argv[2];
|
||||||
int retval, result_len;
|
int retval,
|
||||||
|
result_len;
|
||||||
|
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
@ -118,7 +121,7 @@ int retval, result_len;
|
|||||||
argv[1].len = len;
|
argv[1].len = len;
|
||||||
argv[1].u.ptr = (char *) buf;
|
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;
|
return -1;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -126,10 +129,11 @@ int retval, result_len;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_lseek(ConnectionClass *conn, int fd, int offset, int whence)
|
lo_lseek(ConnectionClass * conn, int fd, int offset, int whence)
|
||||||
{
|
{
|
||||||
LO_ARG argv[3];
|
LO_ARG argv[3];
|
||||||
int retval, result_len;
|
int retval,
|
||||||
|
result_len;
|
||||||
|
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
@ -144,7 +148,7 @@ int retval, result_len;
|
|||||||
argv[2].len = 4;
|
argv[2].len = 4;
|
||||||
argv[2].u.integer = whence;
|
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;
|
return -1;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -152,17 +156,18 @@ int retval, result_len;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_tell(ConnectionClass *conn, int fd)
|
lo_tell(ConnectionClass * conn, int fd)
|
||||||
{
|
{
|
||||||
LO_ARG argv[1];
|
LO_ARG argv[1];
|
||||||
int retval, result_len;
|
int retval,
|
||||||
|
result_len;
|
||||||
|
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
argv[0].len = 4;
|
argv[0].len = 4;
|
||||||
argv[0].u.integer = fd;
|
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;
|
return -1;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -170,27 +175,20 @@ int retval, result_len;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lo_unlink(ConnectionClass *conn, Oid lobjId)
|
lo_unlink(ConnectionClass * conn, Oid lobjId)
|
||||||
{
|
{
|
||||||
LO_ARG argv[1];
|
LO_ARG argv[1];
|
||||||
int retval, result_len;
|
int retval,
|
||||||
|
result_len;
|
||||||
|
|
||||||
|
|
||||||
argv[0].isint = 1;
|
argv[0].isint = 1;
|
||||||
argv[0].len = 4;
|
argv[0].len = 4;
|
||||||
argv[0].u.integer = lobjId;
|
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;
|
return -1;
|
||||||
|
|
||||||
else
|
else
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
#include "psqlodbc.h"
|
#include "psqlodbc.h"
|
||||||
|
|
||||||
struct lo_arg {
|
struct lo_arg
|
||||||
|
{
|
||||||
int isint;
|
int isint;
|
||||||
int len;
|
int len;
|
||||||
union
|
union
|
||||||
@ -35,14 +36,13 @@ struct lo_arg {
|
|||||||
#define INV_WRITE 0x00020000
|
#define INV_WRITE 0x00020000
|
||||||
#define INV_READ 0x00040000
|
#define INV_READ 0x00040000
|
||||||
|
|
||||||
Oid lo_creat(ConnectionClass *conn, int mode);
|
Oid lo_creat(ConnectionClass * conn, int mode);
|
||||||
int lo_open(ConnectionClass *conn, int lobjId, int mode);
|
int lo_open(ConnectionClass * conn, int lobjId, int mode);
|
||||||
int lo_close(ConnectionClass *conn, int fd);
|
int lo_close(ConnectionClass * conn, int fd);
|
||||||
int lo_read(ConnectionClass *conn, int fd, char *buf, int len);
|
int lo_read(ConnectionClass * conn, int fd, char *buf, int len);
|
||||||
int lo_write(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_lseek(ConnectionClass * conn, int fd, int offset, int len);
|
||||||
int lo_tell(ConnectionClass *conn, int fd);
|
int lo_tell(ConnectionClass * conn, int fd);
|
||||||
int lo_unlink(ConnectionClass *conn, Oid lobjId);
|
int lo_unlink(ConnectionClass * conn, Oid lobjId);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,49 +24,54 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
extern GLOBAL_VALUES globals;
|
extern GLOBAL_VALUES globals;
|
||||||
void generate_filename(char*,char*,char*);
|
void generate_filename(char *, char *, char *);
|
||||||
|
|
||||||
void
|
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
|
#ifndef WIN32
|
||||||
struct passwd *ptr = 0;
|
struct passwd *ptr = 0;
|
||||||
|
|
||||||
ptr = getpwuid(getuid());
|
ptr = getpwuid(getuid());
|
||||||
#endif
|
#endif
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
if(dirname == 0 || filename == 0)
|
if (dirname == 0 || filename == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
strcpy(filename,dirname);
|
strcpy(filename, dirname);
|
||||||
strcat(filename,DIRSEPARATOR);
|
strcat(filename, DIRSEPARATOR);
|
||||||
if(prefix != 0)
|
if (prefix != 0)
|
||||||
strcat(filename,prefix);
|
strcat(filename, prefix);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
strcat(filename,ptr->pw_name);
|
strcat(filename, ptr->pw_name);
|
||||||
#endif
|
#endif
|
||||||
sprintf(filename,"%s%u%s",filename,pid,".log");
|
sprintf(filename, "%s%u%s", filename, pid, ".log");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MY_LOG
|
#ifdef MY_LOG
|
||||||
|
|
||||||
void
|
void
|
||||||
mylog(char * fmt, ...)
|
mylog(char *fmt,...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
char filebuf[80];
|
char filebuf[80];
|
||||||
FILE* LOGFP = globals.mylogFP;
|
FILE *LOGFP = globals.mylogFP;
|
||||||
|
|
||||||
if ( globals.debug) {
|
if (globals.debug)
|
||||||
|
{
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
if (! LOGFP) {
|
if (!LOGFP)
|
||||||
generate_filename(MYLOGDIR,MYLOGFILE,filebuf);
|
{
|
||||||
|
generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
|
||||||
LOGFP = fopen(filebuf, PG_BINARY_W);
|
LOGFP = fopen(filebuf, PG_BINARY_W);
|
||||||
globals.mylogFP = LOGFP;
|
globals.mylogFP = LOGFP;
|
||||||
setbuf(LOGFP, NULL);
|
setbuf(LOGFP, NULL);
|
||||||
@ -78,23 +83,26 @@ mylog(char * fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef Q_LOG
|
#ifdef Q_LOG
|
||||||
|
|
||||||
void
|
void
|
||||||
qlog(char * fmt, ...)
|
qlog(char *fmt,...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
char filebuf[80];
|
char filebuf[80];
|
||||||
FILE* LOGFP = globals.qlogFP;
|
FILE *LOGFP = globals.qlogFP;
|
||||||
|
|
||||||
if ( globals.commlog) {
|
if (globals.commlog)
|
||||||
|
{
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
if (! LOGFP) {
|
if (!LOGFP)
|
||||||
generate_filename(QLOGDIR,QLOGFILE,filebuf);
|
{
|
||||||
|
generate_filename(QLOGDIR, QLOGFILE, filebuf);
|
||||||
LOGFP = fopen(filebuf, PG_BINARY_W);
|
LOGFP = fopen(filebuf, PG_BINARY_W);
|
||||||
globals.qlogFP = LOGFP;
|
globals.qlogFP = LOGFP;
|
||||||
setbuf(LOGFP, NULL);
|
setbuf(LOGFP, NULL);
|
||||||
@ -106,6 +114,7 @@ qlog(char * fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Undefine these because windows.h will redefine and cause a warning */
|
/* Undefine these because windows.h will redefine and cause a warning */
|
||||||
@ -135,7 +144,8 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
|||||||
if (dst_len <= 0)
|
if (dst_len <= 0)
|
||||||
return STRCPY_FAIL;
|
return STRCPY_FAIL;
|
||||||
|
|
||||||
if (src_len == SQL_NULL_DATA) {
|
if (src_len == SQL_NULL_DATA)
|
||||||
|
{
|
||||||
dst[0] = '\0';
|
dst[0] = '\0';
|
||||||
return STRCPY_NULL;
|
return STRCPY_NULL;
|
||||||
}
|
}
|
||||||
@ -145,14 +155,17 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
|||||||
if (src_len <= 0)
|
if (src_len <= 0)
|
||||||
return STRCPY_FAIL;
|
return STRCPY_FAIL;
|
||||||
|
|
||||||
else {
|
else
|
||||||
if (src_len < dst_len) {
|
{
|
||||||
|
if (src_len < dst_len)
|
||||||
|
{
|
||||||
memcpy(dst, src, src_len);
|
memcpy(dst, src, src_len);
|
||||||
dst[src_len] = '\0';
|
dst[src_len] = '\0';
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
memcpy(dst, src, dst_len-1);
|
{
|
||||||
dst[dst_len-1] = '\0'; /* truncated */
|
memcpy(dst, src, dst_len - 1);
|
||||||
|
dst[dst_len - 1] = '\0'; /* truncated */
|
||||||
return STRCPY_TRUNCATED;
|
return STRCPY_TRUNCATED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,29 +177,30 @@ my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
|||||||
/* the destination string if src has len characters or more. */
|
/* the destination string if src has len characters or more. */
|
||||||
/* instead, I want it to copy up to len-1 characters and always */
|
/* instead, I want it to copy up to len-1 characters and always */
|
||||||
/* terminate the destination string. */
|
/* 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) {
|
if (NULL != dst)
|
||||||
|
{
|
||||||
|
|
||||||
/* Just in case, check for special lengths */
|
/* Just in case, check for special lengths */
|
||||||
if (len == SQL_NULL_DATA) {
|
if (len == SQL_NULL_DATA)
|
||||||
|
{
|
||||||
dst[0] = '\0';
|
dst[0] = '\0';
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (len == SQL_NTS)
|
else if (len == SQL_NTS)
|
||||||
len = strlen(src) + 1;
|
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];
|
dst[i] = src[i];
|
||||||
}
|
|
||||||
|
|
||||||
if(len > 0) {
|
if (len > 0)
|
||||||
dst[i] = '\0';
|
dst[i] = '\0';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,22 +210,24 @@ int i;
|
|||||||
char *
|
char *
|
||||||
make_string(char *s, int len, char *buf)
|
make_string(char *s, int len, char *buf)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
char *str;
|
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);
|
length = (len > 0) ? len : strlen(s);
|
||||||
|
|
||||||
if (buf) {
|
if (buf)
|
||||||
strncpy_null(buf, s, length+1);
|
{
|
||||||
|
strncpy_null(buf, s, length + 1);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = malloc(length + 1);
|
str = malloc(length + 1);
|
||||||
if ( ! str)
|
if (!str)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
strncpy_null(str, s, length+1);
|
strncpy_null(str, s, length + 1);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +242,8 @@ char *
|
|||||||
my_strcat(char *buf, char *fmt, char *s, int len)
|
my_strcat(char *buf, char *fmt, char *s, int len)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) {
|
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
|
||||||
|
{
|
||||||
int length = (len > 0) ? len : strlen(s);
|
int length = (len > 0) ? len : strlen(s);
|
||||||
|
|
||||||
int pos = strlen(buf);
|
int pos = strlen(buf);
|
||||||
@ -237,16 +254,17 @@ my_strcat(char *buf, char *fmt, char *s, int len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_newlines(char *string)
|
void
|
||||||
|
remove_newlines(char *string)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i=0; i < strlen(string); i++) {
|
for (i = 0; i < strlen(string); i++)
|
||||||
if((string[i] == '\n') ||
|
{
|
||||||
(string[i] == '\r')) {
|
if ((string[i] == '\n') ||
|
||||||
|
(string[i] == '\r'))
|
||||||
string[i] = ' ';
|
string[i] = ' ';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -254,7 +272,8 @@ 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] == ' ')
|
if (s[i] == ' ')
|
||||||
s[i] = '\0';
|
s[i] = '\0';
|
||||||
else
|
else
|
||||||
|
@ -39,35 +39,37 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifdef MY_LOG
|
#ifdef MY_LOG
|
||||||
#define MYLOGFILE "mylog_"
|
#define MYLOGFILE "mylog_"
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#define MYLOGDIR "/tmp"
|
#define MYLOGDIR "/tmp"
|
||||||
#else
|
|
||||||
#define MYLOGDIR "c:"
|
|
||||||
#endif
|
|
||||||
extern void mylog(char * fmt, ...);
|
|
||||||
#else
|
#else
|
||||||
#ifndef WIN32
|
#define MYLOGDIR "c:"
|
||||||
#define mylog(args...) /* GNU convention for variable arguments */
|
#endif
|
||||||
#else
|
extern void mylog(char *fmt,...);
|
||||||
#define mylog /* mylog */
|
|
||||||
#endif
|
#else
|
||||||
|
#ifndef WIN32
|
||||||
|
#define mylog(args...) /* GNU convention for variable arguments */
|
||||||
|
#else
|
||||||
|
#define mylog /* mylog */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_LOG
|
#ifdef Q_LOG
|
||||||
#define QLOGFILE "psqlodbc_"
|
#define QLOGFILE "psqlodbc_"
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#define QLOGDIR "/tmp"
|
#define QLOGDIR "/tmp"
|
||||||
#else
|
|
||||||
#define QLOGDIR "c:"
|
|
||||||
#endif
|
|
||||||
extern void qlog(char * fmt, ...);
|
|
||||||
#else
|
#else
|
||||||
#ifndef WIN32
|
#define QLOGDIR "c:"
|
||||||
#define qlog(args...) /* GNU convention for variable arguments */
|
#endif
|
||||||
#else
|
extern void qlog(char *fmt,...);
|
||||||
#define qlog /* qlog */
|
|
||||||
#endif
|
#else
|
||||||
|
#ifndef WIN32
|
||||||
|
#define qlog(args...) /* GNU convention for variable arguments */
|
||||||
|
#else
|
||||||
|
#define qlog /* qlog */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
@ -37,86 +37,108 @@
|
|||||||
|
|
||||||
extern GLOBAL_VALUES globals;
|
extern GLOBAL_VALUES globals;
|
||||||
|
|
||||||
RETCODE set_statement_option(ConnectionClass *conn,
|
RETCODE set_statement_option(ConnectionClass * conn,
|
||||||
StatementClass *stmt,
|
StatementClass * stmt,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
UDWORD vParam);
|
UDWORD vParam);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RETCODE set_statement_option(ConnectionClass *conn,
|
RETCODE
|
||||||
StatementClass *stmt,
|
set_statement_option(ConnectionClass * conn,
|
||||||
|
StatementClass * stmt,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
UDWORD vParam)
|
UDWORD vParam)
|
||||||
{
|
{
|
||||||
static char *func="set_statement_option";
|
static char *func = "set_statement_option";
|
||||||
char changed = FALSE;
|
char changed = FALSE;
|
||||||
|
|
||||||
|
|
||||||
switch(fOption) {
|
switch (fOption)
|
||||||
case SQL_ASYNC_ENABLE:/* ignored */
|
{
|
||||||
|
case SQL_ASYNC_ENABLE: /* ignored */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_BIND_TYPE:
|
case SQL_BIND_TYPE:
|
||||||
/* now support multi-column and multi-row binding */
|
/* now support multi-column and multi-row binding */
|
||||||
if (conn) conn->stmtOptions.bind_size = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.bind_size = vParam;
|
conn->stmtOptions.bind_size = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.bind_size = vParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_CONCURRENCY:
|
case SQL_CONCURRENCY:
|
||||||
/* positioned update isn't supported so cursor concurrency is read-only */
|
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.scroll_concurrency = vParam;
|
/*
|
||||||
if (stmt) stmt->options.scroll_concurrency = vParam;
|
* positioned update isn't supported so cursor concurrency is
|
||||||
|
* read-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (conn)
|
||||||
|
conn->stmtOptions.scroll_concurrency = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.scroll_concurrency = vParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (globals.lie) {
|
* if (globals.lie) { if (conn)
|
||||||
if (conn) conn->stmtOptions.scroll_concurrency = vParam;
|
* conn->stmtOptions.scroll_concurrency = vParam; if (stmt)
|
||||||
if (stmt) stmt->options.scroll_concurrency = vParam;
|
* stmt->options.scroll_concurrency = vParam; } else {
|
||||||
}
|
*
|
||||||
else {
|
* if (conn) conn->stmtOptions.scroll_concurrency =
|
||||||
|
* SQL_CONCUR_READ_ONLY; if (stmt)
|
||||||
if (conn) conn->stmtOptions.scroll_concurrency = SQL_CONCUR_READ_ONLY;
|
* stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
|
||||||
if (stmt) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
|
*
|
||||||
|
* if (vParam != SQL_CONCUR_READ_ONLY) changed = TRUE; } break;
|
||||||
if (vParam != SQL_CONCUR_READ_ONLY)
|
|
||||||
changed = TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case SQL_CURSOR_TYPE:
|
case SQL_CURSOR_TYPE:
|
||||||
/* if declare/fetch, then type can only be forward.
|
|
||||||
otherwise, it can only be forward or static.
|
/*
|
||||||
|
* if declare/fetch, then type can only be forward. otherwise,
|
||||||
|
* it can only be forward or static.
|
||||||
*/
|
*/
|
||||||
mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam);
|
mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam);
|
||||||
|
|
||||||
if (globals.lie) {
|
if (globals.lie)
|
||||||
|
{
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.cursor_type = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.cursor_type = vParam;
|
conn->stmtOptions.cursor_type = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.cursor_type = vParam;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (globals.use_declarefetch) {
|
{
|
||||||
|
if (globals.use_declarefetch)
|
||||||
|
{
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY;
|
if (conn)
|
||||||
if (stmt) stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY;
|
conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY;
|
||||||
|
|
||||||
if (vParam != SQL_CURSOR_FORWARD_ONLY)
|
if (vParam != SQL_CURSOR_FORWARD_ONLY)
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC) {
|
{
|
||||||
|
if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC)
|
||||||
|
{
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.cursor_type = vParam; /* valid type */
|
if (conn)
|
||||||
if (stmt) stmt->options.cursor_type = vParam; /* valid type */
|
conn->stmtOptions.cursor_type = vParam; /* valid type */
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.cursor_type = vParam; /* valid type */
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.cursor_type = SQL_CURSOR_STATIC;
|
if (conn)
|
||||||
if (stmt) stmt->options.cursor_type = SQL_CURSOR_STATIC;
|
conn->stmtOptions.cursor_type = SQL_CURSOR_STATIC;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.cursor_type = SQL_CURSOR_STATIC;
|
||||||
|
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
}
|
}
|
||||||
@ -127,78 +149,88 @@ char changed = FALSE;
|
|||||||
case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
|
case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
|
||||||
mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);
|
mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.keyset_size = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.keyset_size = vParam;
|
conn->stmtOptions.keyset_size = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.keyset_size = vParam;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (globals.lie)
|
* if (globals.lie) stmt->keyset_size = vParam; else {
|
||||||
stmt->keyset_size = vParam;
|
* stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||||
else {
|
* stmt->errormsg = "Driver does not support keyset size
|
||||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
* option"; SC_log_error(func, "", stmt); return SQL_ERROR; }
|
||||||
stmt->errormsg = "Driver does not support keyset size option";
|
|
||||||
SC_log_error(func, "", stmt);
|
|
||||||
return SQL_ERROR;
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case SQL_MAX_LENGTH:/* ignored, but saved */
|
case SQL_MAX_LENGTH: /* ignored, but saved */
|
||||||
mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
|
mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
|
||||||
if (conn) conn->stmtOptions.maxLength = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.maxLength = vParam;
|
conn->stmtOptions.maxLength = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.maxLength = vParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_MAX_ROWS: /* ignored, but saved */
|
case SQL_MAX_ROWS: /* ignored, but saved */
|
||||||
mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
|
mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
|
||||||
if (conn) conn->stmtOptions.maxRows = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.maxRows = vParam;
|
conn->stmtOptions.maxRows = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.maxRows = vParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_NOSCAN: /* ignored */
|
case SQL_NOSCAN: /* ignored */
|
||||||
mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
|
mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_QUERY_TIMEOUT: /* ignored */
|
case SQL_QUERY_TIMEOUT:/* ignored */
|
||||||
mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
|
mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
|
||||||
/* "0" returned in SQLGetStmtOption */
|
/* "0" returned in SQLGetStmtOption */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_RETRIEVE_DATA: /* ignored, but saved */
|
case SQL_RETRIEVE_DATA:/* ignored, but saved */
|
||||||
mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
|
mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
|
||||||
if (conn) conn->stmtOptions.retrieve_data = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.retrieve_data = vParam;
|
conn->stmtOptions.retrieve_data = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.retrieve_data = vParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_ROWSET_SIZE:
|
case SQL_ROWSET_SIZE:
|
||||||
mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);
|
mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);
|
||||||
|
|
||||||
|
|
||||||
/* Save old rowset size for SQLExtendedFetch purposes
|
/*
|
||||||
If the rowset_size is being changed since the last call
|
* Save old rowset size for SQLExtendedFetch purposes If the
|
||||||
to fetch rows.
|
* rowset_size is being changed since the last call to fetch
|
||||||
|
* rows.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0 )
|
if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0)
|
||||||
stmt->save_rowset_size = stmt->options.rowset_size;
|
stmt->save_rowset_size = stmt->options.rowset_size;
|
||||||
|
|
||||||
if (vParam < 1) {
|
if (vParam < 1)
|
||||||
|
{
|
||||||
vParam = 1;
|
vParam = 1;
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn) conn->stmtOptions.rowset_size = vParam;
|
if (conn)
|
||||||
if (stmt) stmt->options.rowset_size = vParam;
|
conn->stmtOptions.rowset_size = vParam;
|
||||||
|
if (stmt)
|
||||||
|
stmt->options.rowset_size = vParam;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
|
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
|
||||||
if (stmt) {
|
if (stmt)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||||
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
}
|
}
|
||||||
if (conn) {
|
if (conn)
|
||||||
|
{
|
||||||
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||||
conn->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
conn->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
@ -207,21 +239,25 @@ char changed = FALSE;
|
|||||||
|
|
||||||
case SQL_USE_BOOKMARKS:
|
case SQL_USE_BOOKMARKS:
|
||||||
|
|
||||||
if (stmt) stmt->options.use_bookmarks = vParam;
|
if (stmt)
|
||||||
if (conn) conn->stmtOptions.use_bookmarks = vParam;
|
stmt->options.use_bookmarks = vParam;
|
||||||
|
if (conn)
|
||||||
|
conn->stmtOptions.use_bookmarks = vParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char option[64];
|
char option[64];
|
||||||
|
|
||||||
if (stmt) {
|
if (stmt)
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||||
stmt->errormsg = "Unknown statement option (Set)";
|
stmt->errormsg = "Unknown statement option (Set)";
|
||||||
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
||||||
SC_log_error(func, option, stmt);
|
SC_log_error(func, option, stmt);
|
||||||
}
|
}
|
||||||
if (conn) {
|
if (conn)
|
||||||
|
{
|
||||||
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||||
conn->errormsg = "Unknown statement option (Set)";
|
conn->errormsg = "Unknown statement option (Set)";
|
||||||
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
||||||
@ -232,12 +268,15 @@ char changed = FALSE;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed)
|
||||||
if (stmt) {
|
{
|
||||||
|
if (stmt)
|
||||||
|
{
|
||||||
stmt->errormsg = "Requested value changed.";
|
stmt->errormsg = "Requested value changed.";
|
||||||
stmt->errornumber = STMT_OPTION_VALUE_CHANGED;
|
stmt->errornumber = STMT_OPTION_VALUE_CHANGED;
|
||||||
}
|
}
|
||||||
if (conn) {
|
if (conn)
|
||||||
|
{
|
||||||
conn->errormsg = "Requested value changed.";
|
conn->errormsg = "Requested value changed.";
|
||||||
conn->errornumber = STMT_OPTION_VALUE_CHANGED;
|
conn->errornumber = STMT_OPTION_VALUE_CHANGED;
|
||||||
}
|
}
|
||||||
@ -250,28 +289,33 @@ char changed = FALSE;
|
|||||||
|
|
||||||
|
|
||||||
/* Implements only SQL_AUTOCOMMIT */
|
/* Implements only SQL_AUTOCOMMIT */
|
||||||
RETCODE SQL_API SQLSetConnectOption(
|
RETCODE SQL_API
|
||||||
|
SQLSetConnectOption(
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
UDWORD vParam)
|
UDWORD vParam)
|
||||||
{
|
{
|
||||||
static char *func="SQLSetConnectOption";
|
static char *func = "SQLSetConnectOption";
|
||||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||||
char changed = FALSE;
|
char changed = FALSE;
|
||||||
RETCODE retval;
|
RETCODE retval;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if ( ! conn) {
|
if (!conn)
|
||||||
|
{
|
||||||
CC_log_error(func, "", NULL);
|
CC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (fOption) {
|
switch (fOption)
|
||||||
/* Statement Options
|
{
|
||||||
(apply to all stmts on the connection and become defaults for new stmts)
|
|
||||||
|
/*
|
||||||
|
* Statement Options (apply to all stmts on the connection and
|
||||||
|
* become defaults for new stmts)
|
||||||
*/
|
*/
|
||||||
case SQL_ASYNC_ENABLE:
|
case SQL_ASYNC_ENABLE:
|
||||||
case SQL_BIND_TYPE:
|
case SQL_BIND_TYPE:
|
||||||
@ -288,13 +332,16 @@ int i;
|
|||||||
case SQL_USE_BOOKMARKS:
|
case SQL_USE_BOOKMARKS:
|
||||||
|
|
||||||
/* Affect all current Statements */
|
/* Affect all current Statements */
|
||||||
for (i = 0; i < conn->num_stmts; i++) {
|
for (i = 0; i < conn->num_stmts; i++)
|
||||||
if ( conn->stmts[i]) {
|
{
|
||||||
|
if (conn->stmts[i])
|
||||||
set_statement_option(NULL, conn->stmts[i], fOption, vParam);
|
set_statement_option(NULL, conn->stmts[i], fOption, vParam);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Become the default for all future statements on this connection */
|
/*
|
||||||
|
* Become the default for all future statements on this
|
||||||
|
* connection
|
||||||
|
*/
|
||||||
retval = set_statement_option(conn, NULL, fOption, vParam);
|
retval = set_statement_option(conn, NULL, fOption, vParam);
|
||||||
|
|
||||||
if (retval == SQL_SUCCESS_WITH_INFO)
|
if (retval == SQL_SUCCESS_WITH_INFO)
|
||||||
@ -313,7 +360,8 @@ int i;
|
|||||||
|
|
||||||
case SQL_AUTOCOMMIT:
|
case SQL_AUTOCOMMIT:
|
||||||
|
|
||||||
if (CC_is_in_trans(conn)) {
|
if (CC_is_in_trans(conn))
|
||||||
|
{
|
||||||
conn->errormsg = "Cannot switch commit mode while a transaction is in progress";
|
conn->errormsg = "Cannot switch commit mode while a transaction is in progress";
|
||||||
conn->errornumber = CONN_TRANSACT_IN_PROGRES;
|
conn->errornumber = CONN_TRANSACT_IN_PROGRES;
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
@ -322,7 +370,8 @@ int i;
|
|||||||
|
|
||||||
mylog("SQLSetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
|
mylog("SQLSetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
|
||||||
|
|
||||||
switch(vParam) {
|
switch (vParam)
|
||||||
|
{
|
||||||
case SQL_AUTOCOMMIT_OFF:
|
case SQL_AUTOCOMMIT_OFF:
|
||||||
CC_set_autocommit_off(conn);
|
CC_set_autocommit_off(conn);
|
||||||
break;
|
break;
|
||||||
@ -343,7 +392,7 @@ int i;
|
|||||||
case SQL_CURRENT_QUALIFIER: /* ignored */
|
case SQL_CURRENT_QUALIFIER: /* ignored */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_LOGIN_TIMEOUT: /* ignored */
|
case SQL_LOGIN_TIMEOUT:/* ignored */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_PACKET_SIZE: /* ignored */
|
case SQL_PACKET_SIZE: /* ignored */
|
||||||
@ -352,7 +401,7 @@ int i;
|
|||||||
case SQL_QUIET_MODE: /* ignored */
|
case SQL_QUIET_MODE: /* ignored */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_TXN_ISOLATION: /* ignored */
|
case SQL_TXN_ISOLATION:/* ignored */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* These options should be handled by driver manager */
|
/* These options should be handled by driver manager */
|
||||||
@ -367,6 +416,7 @@ int i;
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char option[64];
|
char option[64];
|
||||||
|
|
||||||
conn->errormsg = "Unknown connect option (Set)";
|
conn->errormsg = "Unknown connect option (Set)";
|
||||||
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
||||||
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
||||||
@ -376,7 +426,8 @@ int i;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed)
|
||||||
|
{
|
||||||
conn->errornumber = CONN_OPTION_VALUE_CHANGED;
|
conn->errornumber = CONN_OPTION_VALUE_CHANGED;
|
||||||
conn->errormsg = "Requested value changed.";
|
conn->errormsg = "Requested value changed.";
|
||||||
return SQL_SUCCESS_WITH_INFO;
|
return SQL_SUCCESS_WITH_INFO;
|
||||||
@ -388,38 +439,41 @@ int i;
|
|||||||
/* - - - - - - - - - */
|
/* - - - - - - - - - */
|
||||||
|
|
||||||
/* This function just can tell you whether you are in Autcommit mode or not */
|
/* This function just can tell you whether you are in Autcommit mode or not */
|
||||||
RETCODE SQL_API SQLGetConnectOption(
|
RETCODE SQL_API
|
||||||
|
SQLGetConnectOption(
|
||||||
HDBC hdbc,
|
HDBC hdbc,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
PTR pvParam)
|
PTR pvParam)
|
||||||
{
|
{
|
||||||
static char *func="SQLGetConnectOption";
|
static char *func = "SQLGetConnectOption";
|
||||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if (! conn) {
|
if (!conn)
|
||||||
|
{
|
||||||
CC_log_error(func, "", NULL);
|
CC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fOption) {
|
switch (fOption)
|
||||||
case SQL_ACCESS_MODE:/* NOT SUPPORTED */
|
{
|
||||||
|
case SQL_ACCESS_MODE: /* NOT SUPPORTED */
|
||||||
*((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
|
*((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_AUTOCOMMIT:
|
case SQL_AUTOCOMMIT:
|
||||||
*((UDWORD *)pvParam) = (UDWORD)( CC_is_in_autocommit(conn) ?
|
*((UDWORD *) pvParam) = (UDWORD) (CC_is_in_autocommit(conn) ?
|
||||||
SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
|
SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
|
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
|
||||||
if(pvParam)
|
if (pvParam)
|
||||||
strcpy(pvParam, "");
|
strcpy(pvParam, "");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */
|
case SQL_LOGIN_TIMEOUT:/* NOT SUPPORTED */
|
||||||
*((UDWORD *) pvParam) = 0;
|
*((UDWORD *) pvParam) = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -427,7 +481,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||||||
*((UDWORD *) pvParam) = globals.socket_buffersize;
|
*((UDWORD *) pvParam) = globals.socket_buffersize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_QUIET_MODE:/* NOT SUPPORTED */
|
case SQL_QUIET_MODE: /* NOT SUPPORTED */
|
||||||
*((UDWORD *) pvParam) = (UDWORD) NULL;
|
*((UDWORD *) pvParam) = (UDWORD) NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -447,6 +501,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char option[64];
|
char option[64];
|
||||||
|
|
||||||
conn->errormsg = "Unknown connect option (Get)";
|
conn->errormsg = "Unknown connect option (Get)";
|
||||||
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
||||||
sprintf(option, "fOption=%d", fOption);
|
sprintf(option, "fOption=%d", fOption);
|
||||||
@ -462,13 +517,14 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||||||
|
|
||||||
/* - - - - - - - - - */
|
/* - - - - - - - - - */
|
||||||
|
|
||||||
RETCODE SQL_API SQLSetStmtOption(
|
RETCODE SQL_API
|
||||||
|
SQLSetStmtOption(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
UDWORD vParam)
|
UDWORD vParam)
|
||||||
{
|
{
|
||||||
static char *func="SQLSetStmtOption";
|
static char *func = "SQLSetStmtOption";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
@ -476,7 +532,8 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||||||
/* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
|
/* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
|
||||||
/* and expects the driver to reduce it to the real value */
|
/* and expects the driver to reduce it to the real value */
|
||||||
|
|
||||||
if( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
@ -487,14 +544,15 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||||||
|
|
||||||
/* - - - - - - - - - */
|
/* - - - - - - - - - */
|
||||||
|
|
||||||
RETCODE SQL_API SQLGetStmtOption(
|
RETCODE SQL_API
|
||||||
|
SQLGetStmtOption(
|
||||||
HSTMT hstmt,
|
HSTMT hstmt,
|
||||||
UWORD fOption,
|
UWORD fOption,
|
||||||
PTR pvParam)
|
PTR pvParam)
|
||||||
{
|
{
|
||||||
static char *func="SQLGetStmtOption";
|
static char *func = "SQLGetStmtOption";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
@ -502,29 +560,35 @@ QResultClass *res;
|
|||||||
/* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
|
/* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
|
||||||
/* and expects the driver to reduce it to the real value */
|
/* and expects the driver to reduce it to the real value */
|
||||||
|
|
||||||
if( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(fOption) {
|
switch (fOption)
|
||||||
|
{
|
||||||
case SQL_GET_BOOKMARK:
|
case SQL_GET_BOOKMARK:
|
||||||
case SQL_ROW_NUMBER:
|
case SQL_ROW_NUMBER:
|
||||||
|
|
||||||
res = stmt->result;
|
res = stmt->result;
|
||||||
|
|
||||||
if ( stmt->manual_result || ! globals.use_declarefetch) {
|
if (stmt->manual_result || !globals.use_declarefetch)
|
||||||
|
{
|
||||||
/* make sure we're positioned on a valid row */
|
/* make sure we're positioned on a valid row */
|
||||||
if((stmt->currTuple < 0) ||
|
if ((stmt->currTuple < 0) ||
|
||||||
(stmt->currTuple >= QR_get_num_tuples(res))) {
|
(stmt->currTuple >= QR_get_num_tuples(res)))
|
||||||
|
{
|
||||||
stmt->errormsg = "Not positioned on a valid row.";
|
stmt->errormsg = "Not positioned on a valid row.";
|
||||||
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (stmt->currTuple == -1 || ! res || ! res->tupleField) {
|
{
|
||||||
|
if (stmt->currTuple == -1 || !res || !res->tupleField)
|
||||||
|
{
|
||||||
stmt->errormsg = "Not positioned on a valid row.";
|
stmt->errormsg = "Not positioned on a valid row.";
|
||||||
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -532,7 +596,8 @@ QResultClass *res;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF) {
|
if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF)
|
||||||
|
{
|
||||||
stmt->errormsg = "Operation invalid because use bookmarks not enabled.";
|
stmt->errormsg = "Operation invalid because use bookmarks not enabled.";
|
||||||
stmt->errornumber = STMT_OPERATION_INVALID;
|
stmt->errornumber = STMT_OPERATION_INVALID;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -553,37 +618,37 @@ QResultClass *res;
|
|||||||
|
|
||||||
case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
|
case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
|
||||||
mylog("GetStmtOption(): SQL_CONCURRENCY\n");
|
mylog("GetStmtOption(): SQL_CONCURRENCY\n");
|
||||||
*((SDWORD *)pvParam) = stmt->options.scroll_concurrency;
|
*((SDWORD *) pvParam) = stmt->options.scroll_concurrency;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
|
case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
|
||||||
mylog("GetStmtOption(): SQL_CURSOR_TYPE\n");
|
mylog("GetStmtOption(): SQL_CURSOR_TYPE\n");
|
||||||
*((SDWORD *)pvParam) = stmt->options.cursor_type;
|
*((SDWORD *) pvParam) = stmt->options.cursor_type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
|
case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
|
||||||
mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
|
mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
|
||||||
*((SDWORD *)pvParam) = stmt->options.keyset_size;
|
*((SDWORD *) pvParam) = stmt->options.keyset_size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
|
case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
|
||||||
*((SDWORD *)pvParam) = stmt->options.maxLength;
|
*((SDWORD *) pvParam) = stmt->options.maxLength;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
|
case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
|
||||||
*((SDWORD *)pvParam) = stmt->options.maxRows;
|
*((SDWORD *) pvParam) = stmt->options.maxRows;
|
||||||
mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows);
|
mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_NOSCAN:/* NOT SUPPORTED */
|
case SQL_NOSCAN: /* NOT SUPPORTED */
|
||||||
*((SDWORD *) pvParam) = SQL_NOSCAN_ON;
|
*((SDWORD *) pvParam) = SQL_NOSCAN_ON;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */
|
case SQL_QUERY_TIMEOUT:/* NOT SUPPORTED */
|
||||||
*((SDWORD *) pvParam) = 0;
|
*((SDWORD *) pvParam) = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_RETRIEVE_DATA: /* NOT SUPPORTED, but saved */
|
case SQL_RETRIEVE_DATA:/* NOT SUPPORTED, but saved */
|
||||||
*((SDWORD *) pvParam) = stmt->options.retrieve_data;
|
*((SDWORD *) pvParam) = stmt->options.retrieve_data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -591,7 +656,7 @@ QResultClass *res;
|
|||||||
*((SDWORD *) pvParam) = stmt->options.rowset_size;
|
*((SDWORD *) pvParam) = stmt->options.rowset_size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_SIMULATE_CURSOR:/* NOT SUPPORTED */
|
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
|
||||||
*((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE;
|
*((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -602,6 +667,7 @@ QResultClass *res;
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char option[64];
|
char option[64];
|
||||||
|
|
||||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||||
stmt->errormsg = "Unknown statement option (Get)";
|
stmt->errormsg = "Unknown statement option (Get)";
|
||||||
sprintf(option, "fOption=%d", fOption);
|
sprintf(option, "fOption=%d", fOption);
|
||||||
|
@ -38,15 +38,16 @@
|
|||||||
#define COL_INCR 16
|
#define COL_INCR 16
|
||||||
|
|
||||||
char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric);
|
char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric);
|
||||||
void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k);
|
void getColInfo(COL_INFO * col_info, FIELD_INFO * fi, int k);
|
||||||
char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi);
|
char searchColInfo(COL_INFO * col_info, FIELD_INFO * fi);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric)
|
getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int out = 0;
|
int out = 0;
|
||||||
char qc, in_escape = FALSE;
|
char qc,
|
||||||
|
in_escape = FALSE;
|
||||||
|
|
||||||
if (smax <= 1)
|
if (smax <= 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -54,43 +55,54 @@ char qc, in_escape = FALSE;
|
|||||||
smax--;
|
smax--;
|
||||||
|
|
||||||
/* skip leading delimiters */
|
/* skip leading delimiters */
|
||||||
while (isspace((unsigned char) s[i]) || s[i] == ',') {
|
while (isspace((unsigned char) s[i]) || s[i] == ',')
|
||||||
|
{
|
||||||
/* mylog("skipping '%c'\n", s[i]); */
|
/* mylog("skipping '%c'\n", s[i]); */
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s[0] == '\0') {
|
if (s[0] == '\0')
|
||||||
|
{
|
||||||
token[0] = '\0';
|
token[0] = '\0';
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quote) *quote = FALSE;
|
if (quote)
|
||||||
if (dquote) *dquote = FALSE;
|
*quote = FALSE;
|
||||||
if (numeric) *numeric = FALSE;
|
if (dquote)
|
||||||
|
*dquote = FALSE;
|
||||||
|
if (numeric)
|
||||||
|
*numeric = FALSE;
|
||||||
|
|
||||||
/* get the next token */
|
/* get the next token */
|
||||||
while ( ! isspace((unsigned char) s[i]) && s[i] != ',' &&
|
while (!isspace((unsigned char) s[i]) && s[i] != ',' &&
|
||||||
s[i] != '\0' && out != smax) {
|
s[i] != '\0' && out != smax)
|
||||||
|
{
|
||||||
|
|
||||||
/* Handle quoted stuff */
|
/* Handle quoted stuff */
|
||||||
if ( out == 0 && (s[i] == '\"' || s[i] == '\'')) {
|
if (out == 0 && (s[i] == '\"' || s[i] == '\''))
|
||||||
|
{
|
||||||
qc = s[i];
|
qc = s[i];
|
||||||
if (qc == '\"') {
|
if (qc == '\"')
|
||||||
if (dquote) *dquote = TRUE;
|
{
|
||||||
|
if (dquote)
|
||||||
|
*dquote = TRUE;
|
||||||
}
|
}
|
||||||
if (qc == '\'') {
|
if (qc == '\'')
|
||||||
if (quote) *quote = TRUE;
|
{
|
||||||
|
if (quote)
|
||||||
|
*quote = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++; /* dont return the quote */
|
i++; /* dont return the quote */
|
||||||
while (s[i] != '\0' && out != smax) {
|
while (s[i] != '\0' && out != smax)
|
||||||
if (s[i] == qc && ! in_escape) {
|
{
|
||||||
|
if (s[i] == qc && !in_escape)
|
||||||
break;
|
break;
|
||||||
}
|
if (s[i] == '\\' && !in_escape)
|
||||||
if (s[i] == '\\' && ! in_escape) {
|
|
||||||
in_escape = TRUE;
|
in_escape = TRUE;
|
||||||
}
|
else
|
||||||
else {
|
{
|
||||||
in_escape = FALSE;
|
in_escape = FALSE;
|
||||||
token[out++] = s[i];
|
token[out++] = s[i];
|
||||||
}
|
}
|
||||||
@ -102,19 +114,23 @@ char qc, in_escape = FALSE;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for numeric literals */
|
/* Check for numeric literals */
|
||||||
if ( out == 0 && isdigit((unsigned char) s[i])) {
|
if (out == 0 && isdigit((unsigned char) s[i]))
|
||||||
if (numeric) *numeric = TRUE;
|
{
|
||||||
|
if (numeric)
|
||||||
|
*numeric = TRUE;
|
||||||
token[out++] = s[i++];
|
token[out++] = s[i++];
|
||||||
while ( isalnum((unsigned char) s[i]) || s[i] == '.')
|
while (isalnum((unsigned char) s[i]) || s[i] == '.')
|
||||||
token[out++] = s[i++];
|
token[out++] = s[i++];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ispunct((unsigned char) s[i]) && s[i] != '_') {
|
if (ispunct((unsigned char) s[i]) && s[i] != '_')
|
||||||
|
{
|
||||||
mylog("got ispunct: s[%d] = '%c'\n", i, s[i]);
|
mylog("got ispunct: s[%d] = '%c'\n", i, s[i]);
|
||||||
|
|
||||||
if (out == 0) {
|
if (out == 0)
|
||||||
|
{
|
||||||
token[out++] = s[i++];
|
token[out++] = s[i++];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -133,24 +149,29 @@ char qc, in_escape = FALSE;
|
|||||||
token[out] = '\0';
|
token[out] = '\0';
|
||||||
|
|
||||||
/* find the delimiter */
|
/* find the delimiter */
|
||||||
while ( isspace((unsigned char) s[i]))
|
while (isspace((unsigned char) s[i]))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
/* return the most priority delimiter */
|
/* return the most priority delimiter */
|
||||||
if (s[i] == ',') {
|
if (s[i] == ',')
|
||||||
if (delim) *delim = s[i];
|
{
|
||||||
|
if (delim)
|
||||||
|
*delim = s[i];
|
||||||
}
|
}
|
||||||
else if (s[i] == '\0') {
|
else if (s[i] == '\0')
|
||||||
if (delim) *delim = '\0';
|
{
|
||||||
|
if (delim)
|
||||||
|
*delim = '\0';
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (delim) *delim = ' ';
|
{
|
||||||
|
if (delim)
|
||||||
|
*delim = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip trailing blanks */
|
/* skip trailing blanks */
|
||||||
while ( isspace((unsigned char) s[i])) {
|
while (isspace((unsigned char) s[i]))
|
||||||
i++;
|
i++;
|
||||||
}
|
|
||||||
|
|
||||||
return &s[i];
|
return &s[i];
|
||||||
}
|
}
|
||||||
@ -176,28 +197,30 @@ QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k)
|
getColInfo(COL_INFO * col_info, FIELD_INFO * fi, int k)
|
||||||
{
|
{
|
||||||
if (fi->name[0] == '\0')
|
if (fi->name[0] == '\0')
|
||||||
strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3));
|
strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3));
|
||||||
|
|
||||||
fi->type = atoi( QR_get_value_manual(col_info->result, k, 13));
|
fi->type = atoi(QR_get_value_manual(col_info->result, k, 13));
|
||||||
fi->precision = atoi( QR_get_value_manual(col_info->result, k, 6));
|
fi->precision = atoi(QR_get_value_manual(col_info->result, k, 6));
|
||||||
fi->length = atoi( QR_get_value_manual(col_info->result, k, 7));
|
fi->length = atoi(QR_get_value_manual(col_info->result, k, 7));
|
||||||
fi->nullable = atoi( QR_get_value_manual(col_info->result, k, 10));
|
fi->nullable = atoi(QR_get_value_manual(col_info->result, k, 10));
|
||||||
fi->display_size = atoi( QR_get_value_manual(col_info->result, k, 12));
|
fi->display_size = atoi(QR_get_value_manual(col_info->result, k, 12));
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
searchColInfo(COL_INFO *col_info, FIELD_INFO *fi)
|
searchColInfo(COL_INFO * col_info, FIELD_INFO * fi)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
char *col;
|
char *col;
|
||||||
|
|
||||||
|
|
||||||
for (k = 0; k < QR_get_num_tuples(col_info->result); k++) {
|
for (k = 0; k < QR_get_num_tuples(col_info->result); k++)
|
||||||
|
{
|
||||||
col = QR_get_value_manual(col_info->result, k, 3);
|
col = QR_get_value_manual(col_info->result, k, 3);
|
||||||
if ( ! strcmp(col, fi->name)) {
|
if (!strcmp(col, fi->name))
|
||||||
|
{
|
||||||
getColInfo(col_info, fi, k);
|
getColInfo(col_info, fi, k);
|
||||||
|
|
||||||
mylog("PARSE: searchColInfo: \n");
|
mylog("PARSE: searchColInfo: \n");
|
||||||
@ -210,22 +233,39 @@ char *col;
|
|||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
parse_statement(StatementClass *stmt)
|
parse_statement(StatementClass * stmt)
|
||||||
{
|
{
|
||||||
static char *func="parse_statement";
|
static char *func = "parse_statement";
|
||||||
char token[256];
|
char token[256];
|
||||||
char delim, quote, dquote, numeric, unquoted;
|
char delim,
|
||||||
char *ptr;
|
quote,
|
||||||
char in_select = FALSE, in_distinct = FALSE, in_on = FALSE, in_from = FALSE, in_where = FALSE, in_table = FALSE;
|
dquote,
|
||||||
char in_field = FALSE, in_expr = FALSE, in_func = FALSE, in_dot = FALSE, in_as = FALSE;
|
numeric,
|
||||||
int j, i, k = 0, n, blevel = 0;
|
unquoted;
|
||||||
FIELD_INFO **fi;
|
char *ptr;
|
||||||
TABLE_INFO **ti;
|
char in_select = FALSE,
|
||||||
char parse;
|
in_distinct = FALSE,
|
||||||
ConnectionClass *conn = stmt->hdbc;
|
in_on = FALSE,
|
||||||
HSTMT hcol_stmt;
|
in_from = FALSE,
|
||||||
StatementClass *col_stmt;
|
in_where = FALSE,
|
||||||
RETCODE result;
|
in_table = FALSE;
|
||||||
|
char in_field = FALSE,
|
||||||
|
in_expr = FALSE,
|
||||||
|
in_func = FALSE,
|
||||||
|
in_dot = FALSE,
|
||||||
|
in_as = FALSE;
|
||||||
|
int j,
|
||||||
|
i,
|
||||||
|
k = 0,
|
||||||
|
n,
|
||||||
|
blevel = 0;
|
||||||
|
FIELD_INFO **fi;
|
||||||
|
TABLE_INFO **ti;
|
||||||
|
char parse;
|
||||||
|
ConnectionClass *conn = stmt->hdbc;
|
||||||
|
HSTMT hcol_stmt;
|
||||||
|
StatementClass *col_stmt;
|
||||||
|
RETCODE result;
|
||||||
|
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
@ -237,34 +277,39 @@ RETCODE result;
|
|||||||
stmt->nfld = 0;
|
stmt->nfld = 0;
|
||||||
stmt->ntab = 0;
|
stmt->ntab = 0;
|
||||||
|
|
||||||
while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL) {
|
while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
unquoted = ! ( quote || dquote );
|
unquoted = !(quote || dquote);
|
||||||
|
|
||||||
mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr);
|
mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr);
|
||||||
|
|
||||||
if ( unquoted && ! stricmp(token, "select")) {
|
if (unquoted && !stricmp(token, "select"))
|
||||||
|
{
|
||||||
in_select = TRUE;
|
in_select = TRUE;
|
||||||
|
|
||||||
mylog("SELECT\n");
|
mylog("SELECT\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( unquoted && in_select && ! stricmp(token, "distinct")) {
|
if (unquoted && in_select && !stricmp(token, "distinct"))
|
||||||
|
{
|
||||||
in_distinct = TRUE;
|
in_distinct = TRUE;
|
||||||
|
|
||||||
mylog("DISTINCT\n");
|
mylog("DISTINCT\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( unquoted && ! stricmp(token, "into")) {
|
if (unquoted && !stricmp(token, "into"))
|
||||||
|
{
|
||||||
in_select = FALSE;
|
in_select = FALSE;
|
||||||
|
|
||||||
mylog("INTO\n");
|
mylog("INTO\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( unquoted && ! stricmp(token, "from")) {
|
if (unquoted && !stricmp(token, "from"))
|
||||||
|
{
|
||||||
in_select = FALSE;
|
in_select = FALSE;
|
||||||
in_from = TRUE;
|
in_from = TRUE;
|
||||||
|
|
||||||
@ -272,11 +317,12 @@ RETCODE result;
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( unquoted && (! stricmp(token, "where") ||
|
if (unquoted && (!stricmp(token, "where") ||
|
||||||
! stricmp(token, "union") ||
|
!stricmp(token, "union") ||
|
||||||
! stricmp(token, "order") ||
|
!stricmp(token, "order") ||
|
||||||
! stricmp(token, "group") ||
|
!stricmp(token, "group") ||
|
||||||
! stricmp(token, "having"))) {
|
!stricmp(token, "having")))
|
||||||
|
{
|
||||||
|
|
||||||
in_select = FALSE;
|
in_select = FALSE;
|
||||||
in_from = FALSE;
|
in_from = FALSE;
|
||||||
@ -286,17 +332,21 @@ RETCODE result;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_select) {
|
if (in_select)
|
||||||
|
{
|
||||||
|
|
||||||
if ( in_distinct) {
|
if (in_distinct)
|
||||||
|
{
|
||||||
mylog("in distinct\n");
|
mylog("in distinct\n");
|
||||||
|
|
||||||
if (unquoted && ! stricmp(token, "on")) {
|
if (unquoted && !stricmp(token, "on"))
|
||||||
|
{
|
||||||
in_on = TRUE;
|
in_on = TRUE;
|
||||||
mylog("got on\n");
|
mylog("got on\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (in_on) {
|
if (in_on)
|
||||||
|
{
|
||||||
in_distinct = FALSE;
|
in_distinct = FALSE;
|
||||||
in_on = FALSE;
|
in_on = FALSE;
|
||||||
continue; /* just skip the unique on field */
|
continue; /* just skip the unique on field */
|
||||||
@ -305,25 +355,30 @@ RETCODE result;
|
|||||||
in_distinct = FALSE;
|
in_distinct = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( in_expr || in_func) { /* just eat the expression */
|
if (in_expr || in_func)
|
||||||
|
{ /* just eat the expression */
|
||||||
mylog("in_expr=%d or func=%d\n", in_expr, in_func);
|
mylog("in_expr=%d or func=%d\n", in_expr, in_func);
|
||||||
if (quote || dquote)
|
if (quote || dquote)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (in_expr && blevel == 0 && delim == ',') {
|
if (in_expr && blevel == 0 && delim == ',')
|
||||||
|
{
|
||||||
mylog("**** in_expr and Got comma\n");
|
mylog("**** in_expr and Got comma\n");
|
||||||
in_expr = FALSE;
|
in_expr = FALSE;
|
||||||
in_field = FALSE;
|
in_field = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token[0] == '(') {
|
else if (token[0] == '(')
|
||||||
|
{
|
||||||
blevel++;
|
blevel++;
|
||||||
mylog("blevel++ = %d\n", blevel);
|
mylog("blevel++ = %d\n", blevel);
|
||||||
}
|
}
|
||||||
else if (token[0] == ')') {
|
else if (token[0] == ')')
|
||||||
|
{
|
||||||
blevel--;
|
blevel--;
|
||||||
mylog("blevel-- = %d\n", blevel);
|
mylog("blevel-- = %d\n", blevel);
|
||||||
if (delim==',') {
|
if (delim == ',')
|
||||||
|
{
|
||||||
in_func = FALSE;
|
in_func = FALSE;
|
||||||
in_expr = FALSE;
|
in_expr = FALSE;
|
||||||
in_field = FALSE;
|
in_field = FALSE;
|
||||||
@ -332,23 +387,27 @@ RETCODE result;
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! in_field) {
|
if (!in_field)
|
||||||
|
{
|
||||||
|
|
||||||
if ( ! token[0])
|
if (!token[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( ! (stmt->nfld % FLD_INCR)) {
|
if (!(stmt->nfld % FLD_INCR))
|
||||||
|
{
|
||||||
mylog("reallocing at nfld=%d\n", stmt->nfld);
|
mylog("reallocing at nfld=%d\n", stmt->nfld);
|
||||||
fi = (FIELD_INFO **) realloc(fi, (stmt->nfld + FLD_INCR) * sizeof(FIELD_INFO *));
|
fi = (FIELD_INFO **) realloc(fi, (stmt->nfld + FLD_INCR) * sizeof(FIELD_INFO *));
|
||||||
if ( ! fi) {
|
if (!fi)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
stmt->fi = fi;
|
stmt->fi = fi;
|
||||||
}
|
}
|
||||||
|
|
||||||
fi[stmt->nfld] = (FIELD_INFO *) malloc( sizeof(FIELD_INFO));
|
fi[stmt->nfld] = (FIELD_INFO *) malloc(sizeof(FIELD_INFO));
|
||||||
if (fi[stmt->nfld] == NULL) {
|
if (fi[stmt->nfld] == NULL)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -360,15 +419,18 @@ RETCODE result;
|
|||||||
if (dquote)
|
if (dquote)
|
||||||
fi[stmt->nfld]->dquote = TRUE;
|
fi[stmt->nfld]->dquote = TRUE;
|
||||||
|
|
||||||
if (quote) {
|
if (quote)
|
||||||
|
{
|
||||||
fi[stmt->nfld++]->quote = TRUE;
|
fi[stmt->nfld++]->quote = TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (numeric) {
|
else if (numeric)
|
||||||
|
{
|
||||||
mylog("**** got numeric: nfld = %d\n", stmt->nfld);
|
mylog("**** got numeric: nfld = %d\n", stmt->nfld);
|
||||||
fi[stmt->nfld]->numeric = TRUE;
|
fi[stmt->nfld]->numeric = TRUE;
|
||||||
}
|
}
|
||||||
else if (token[0] == '(') { /* expression */
|
else if (token[0] == '(')
|
||||||
|
{ /* expression */
|
||||||
mylog("got EXPRESSION\n");
|
mylog("got EXPRESSION\n");
|
||||||
fi[stmt->nfld++]->expr = TRUE;
|
fi[stmt->nfld++]->expr = TRUE;
|
||||||
in_expr = TRUE;
|
in_expr = TRUE;
|
||||||
@ -376,18 +438,17 @@ RETCODE result;
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
strcpy(fi[stmt->nfld]->name, token);
|
strcpy(fi[stmt->nfld]->name, token);
|
||||||
fi[stmt->nfld]->dot[0] = '\0';
|
fi[stmt->nfld]->dot[0] = '\0';
|
||||||
}
|
}
|
||||||
mylog("got field='%s', dot='%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->dot);
|
mylog("got field='%s', dot='%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->dot);
|
||||||
|
|
||||||
if (delim == ',') {
|
if (delim == ',')
|
||||||
mylog("comma (1)\n");
|
mylog("comma (1)\n");
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
in_field = TRUE;
|
in_field = TRUE;
|
||||||
}
|
|
||||||
stmt->nfld++;
|
stmt->nfld++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -395,14 +456,16 @@ RETCODE result;
|
|||||||
/**************************/
|
/**************************/
|
||||||
/* We are in a field now */
|
/* We are in a field now */
|
||||||
/**************************/
|
/**************************/
|
||||||
if (in_dot) {
|
if (in_dot)
|
||||||
|
{
|
||||||
stmt->nfld--;
|
stmt->nfld--;
|
||||||
strcpy(fi[stmt->nfld]->dot, fi[stmt->nfld]->name);
|
strcpy(fi[stmt->nfld]->dot, fi[stmt->nfld]->name);
|
||||||
strcpy(fi[stmt->nfld]->name, token);
|
strcpy(fi[stmt->nfld]->name, token);
|
||||||
stmt->nfld++;
|
stmt->nfld++;
|
||||||
in_dot = FALSE;
|
in_dot = FALSE;
|
||||||
|
|
||||||
if (delim == ',') {
|
if (delim == ',')
|
||||||
|
{
|
||||||
mylog("in_dot: got comma\n");
|
mylog("in_dot: got comma\n");
|
||||||
in_field = FALSE;
|
in_field = FALSE;
|
||||||
}
|
}
|
||||||
@ -410,7 +473,8 @@ RETCODE result;
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_as) {
|
if (in_as)
|
||||||
|
{
|
||||||
stmt->nfld--;
|
stmt->nfld--;
|
||||||
strcpy(fi[stmt->nfld]->alias, token);
|
strcpy(fi[stmt->nfld]->alias, token);
|
||||||
mylog("alias for field '%s' is '%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->alias);
|
mylog("alias for field '%s' is '%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->alias);
|
||||||
@ -419,29 +483,35 @@ RETCODE result;
|
|||||||
|
|
||||||
stmt->nfld++;
|
stmt->nfld++;
|
||||||
|
|
||||||
if (delim == ',') {
|
if (delim == ',')
|
||||||
mylog("comma(2)\n");
|
mylog("comma(2)\n");
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function */
|
/* Function */
|
||||||
if (token[0] == '(') {
|
if (token[0] == '(')
|
||||||
|
{
|
||||||
in_func = TRUE;
|
in_func = TRUE;
|
||||||
blevel = 1;
|
blevel = 1;
|
||||||
fi[stmt->nfld-1]->func = TRUE;
|
fi[stmt->nfld - 1]->func = TRUE;
|
||||||
/* name will have the function name -- maybe useful some day */
|
|
||||||
mylog("**** got function = '%s'\n", fi[stmt->nfld-1]->name);
|
/*
|
||||||
|
* name will have the function name -- maybe useful some
|
||||||
|
* day
|
||||||
|
*/
|
||||||
|
mylog("**** got function = '%s'\n", fi[stmt->nfld - 1]->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token[0] == '.') {
|
if (token[0] == '.')
|
||||||
|
{
|
||||||
in_dot = TRUE;
|
in_dot = TRUE;
|
||||||
mylog("got dot\n");
|
mylog("got dot\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! stricmp(token, "as")) {
|
if (!stricmp(token, "as"))
|
||||||
|
{
|
||||||
in_as = TRUE;
|
in_as = TRUE;
|
||||||
mylog("got AS\n");
|
mylog("got AS\n");
|
||||||
continue;
|
continue;
|
||||||
@ -449,28 +519,33 @@ RETCODE result;
|
|||||||
|
|
||||||
/* otherwise, it's probably an expression */
|
/* otherwise, it's probably an expression */
|
||||||
in_expr = TRUE;
|
in_expr = TRUE;
|
||||||
fi[stmt->nfld-1]->expr = TRUE;
|
fi[stmt->nfld - 1]->expr = TRUE;
|
||||||
fi[stmt->nfld-1]->name[0] = '\0';
|
fi[stmt->nfld - 1]->name[0] = '\0';
|
||||||
mylog("*** setting expression\n");
|
mylog("*** setting expression\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_from) {
|
if (in_from)
|
||||||
|
{
|
||||||
|
|
||||||
if ( ! in_table) {
|
if (!in_table)
|
||||||
if ( ! token[0])
|
{
|
||||||
|
if (!token[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( ! (stmt->ntab % TAB_INCR)) {
|
if (!(stmt->ntab % TAB_INCR))
|
||||||
|
{
|
||||||
ti = (TABLE_INFO **) realloc(ti, (stmt->ntab + TAB_INCR) * sizeof(TABLE_INFO *));
|
ti = (TABLE_INFO **) realloc(ti, (stmt->ntab + TAB_INCR) * sizeof(TABLE_INFO *));
|
||||||
if ( ! ti) {
|
if (!ti)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
stmt->ti = ti;
|
stmt->ti = ti;
|
||||||
}
|
}
|
||||||
ti[stmt->ntab] = (TABLE_INFO *) malloc(sizeof(TABLE_INFO));
|
ti[stmt->ntab] = (TABLE_INFO *) malloc(sizeof(TABLE_INFO));
|
||||||
if (ti[stmt->ntab] == NULL) {
|
if (ti[stmt->ntab] == NULL)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -480,24 +555,21 @@ RETCODE result;
|
|||||||
strcpy(ti[stmt->ntab]->name, token);
|
strcpy(ti[stmt->ntab]->name, token);
|
||||||
mylog("got table = '%s'\n", ti[stmt->ntab]->name);
|
mylog("got table = '%s'\n", ti[stmt->ntab]->name);
|
||||||
|
|
||||||
if (delim == ',') {
|
if (delim == ',')
|
||||||
mylog("more than 1 tables\n");
|
mylog("more than 1 tables\n");
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
in_table = TRUE;
|
in_table = TRUE;
|
||||||
}
|
|
||||||
stmt->ntab++;
|
stmt->ntab++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(ti[stmt->ntab-1]->alias, token);
|
strcpy(ti[stmt->ntab - 1]->alias, token);
|
||||||
mylog("alias for table '%s' is '%s'\n", ti[stmt->ntab-1]->name, ti[stmt->ntab-1]->alias);
|
mylog("alias for table '%s' is '%s'\n", ti[stmt->ntab - 1]->name, ti[stmt->ntab - 1]->alias);
|
||||||
in_table = FALSE;
|
in_table = FALSE;
|
||||||
if (delim == ',') {
|
if (delim == ',')
|
||||||
mylog("more than 1 tables\n");
|
mylog("more than 1 tables\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
@ -507,16 +579,19 @@ RETCODE result;
|
|||||||
parse = TRUE;
|
parse = TRUE;
|
||||||
|
|
||||||
/* Resolve field names with tables */
|
/* Resolve field names with tables */
|
||||||
for (i = 0; i < stmt->nfld; i++) {
|
for (i = 0; i < stmt->nfld; i++)
|
||||||
|
{
|
||||||
|
|
||||||
if (fi[i]->func || fi[i]->expr || fi[i]->numeric) {
|
if (fi[i]->func || fi[i]->expr || fi[i]->numeric)
|
||||||
|
{
|
||||||
fi[i]->ti = NULL;
|
fi[i]->ti = NULL;
|
||||||
fi[i]->type = -1;
|
fi[i]->type = -1;
|
||||||
parse = FALSE;
|
parse = FALSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (fi[i]->quote) { /* handle as text */
|
else if (fi[i]->quote)
|
||||||
|
{ /* handle as text */
|
||||||
fi[i]->ti = NULL;
|
fi[i]->ti = NULL;
|
||||||
fi[i]->type = PG_TYPE_TEXT;
|
fi[i]->type = PG_TYPE_TEXT;
|
||||||
fi[i]->precision = 0;
|
fi[i]->precision = 0;
|
||||||
@ -524,13 +599,17 @@ RETCODE result;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* it's a dot, resolve to table or alias */
|
/* it's a dot, resolve to table or alias */
|
||||||
else if (fi[i]->dot[0]) {
|
else if (fi[i]->dot[0])
|
||||||
for (k = 0; k < stmt->ntab; k++) {
|
{
|
||||||
if ( ! stricmp(ti[k]->name, fi[i]->dot)) {
|
for (k = 0; k < stmt->ntab; k++)
|
||||||
|
{
|
||||||
|
if (!stricmp(ti[k]->name, fi[i]->dot))
|
||||||
|
{
|
||||||
fi[i]->ti = ti[k];
|
fi[i]->ti = ti[k];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ( ! stricmp(ti[k]->alias, fi[i]->dot)) {
|
else if (!stricmp(ti[k]->alias, fi[i]->dot))
|
||||||
|
{
|
||||||
fi[i]->ti = ti[k];
|
fi[i]->ti = ti[k];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -543,15 +622,15 @@ RETCODE result;
|
|||||||
mylog("--------------------------------------------\n");
|
mylog("--------------------------------------------\n");
|
||||||
mylog("nfld=%d, ntab=%d\n", stmt->nfld, stmt->ntab);
|
mylog("nfld=%d, ntab=%d\n", stmt->nfld, stmt->ntab);
|
||||||
|
|
||||||
for (i=0; i < stmt->nfld; i++) {
|
for (i = 0; i < stmt->nfld; i++)
|
||||||
|
{
|
||||||
mylog("Field %d: expr=%d, func=%d, quote=%d, dquote=%d, numeric=%d, name='%s', alias='%s', dot='%s'\n", i, fi[i]->expr, fi[i]->func, fi[i]->quote, fi[i]->dquote, fi[i]->numeric, fi[i]->name, fi[i]->alias, fi[i]->dot);
|
mylog("Field %d: expr=%d, func=%d, quote=%d, dquote=%d, numeric=%d, name='%s', alias='%s', dot='%s'\n", i, fi[i]->expr, fi[i]->func, fi[i]->quote, fi[i]->dquote, fi[i]->numeric, fi[i]->name, fi[i]->alias, fi[i]->dot);
|
||||||
if (fi[i]->ti)
|
if (fi[i]->ti)
|
||||||
mylog(" ----> table_name='%s', table_alias='%s'\n", fi[i]->ti->name, fi[i]->ti->alias);
|
mylog(" ----> table_name='%s', table_alias='%s'\n", fi[i]->ti->name, fi[i]->ti->alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i < stmt->ntab; i++) {
|
for (i = 0; i < stmt->ntab; i++)
|
||||||
mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias);
|
mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
@ -560,24 +639,30 @@ RETCODE result;
|
|||||||
|
|
||||||
|
|
||||||
/* Call SQLColumns for each table and store the result */
|
/* Call SQLColumns for each table and store the result */
|
||||||
for (i = 0; i < stmt->ntab; i++) {
|
for (i = 0; i < stmt->ntab; i++)
|
||||||
|
{
|
||||||
|
|
||||||
/* See if already got it */
|
/* See if already got it */
|
||||||
char found = FALSE;
|
char found = FALSE;
|
||||||
for (k = 0; k < conn->ntables; k++) {
|
|
||||||
if ( ! stricmp(conn->col_info[k]->name, ti[i]->name)) {
|
for (k = 0; k < conn->ntables; k++)
|
||||||
|
{
|
||||||
|
if (!stricmp(conn->col_info[k]->name, ti[i]->name))
|
||||||
|
{
|
||||||
mylog("FOUND col_info table='%s'\n", ti[i]->name);
|
mylog("FOUND col_info table='%s'\n", ti[i]->name);
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! found) {
|
if (!found)
|
||||||
|
{
|
||||||
|
|
||||||
mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name);
|
mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name);
|
||||||
|
|
||||||
result = SQLAllocStmt( stmt->hdbc, &hcol_stmt);
|
result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
|
||||||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
|
||||||
|
{
|
||||||
stmt->errormsg = "SQLAllocStmt failed in parse_statement for columns.";
|
stmt->errormsg = "SQLAllocStmt failed in parse_statement for columns.";
|
||||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
@ -591,14 +676,17 @@ RETCODE result;
|
|||||||
ti[i]->name, (SWORD) strlen(ti[i]->name), "", 0);
|
ti[i]->name, (SWORD) strlen(ti[i]->name), "", 0);
|
||||||
|
|
||||||
mylog(" Past SQLColumns\n");
|
mylog(" Past SQLColumns\n");
|
||||||
if (result == SQL_SUCCESS) {
|
if (result == SQL_SUCCESS)
|
||||||
|
{
|
||||||
mylog(" Success\n");
|
mylog(" Success\n");
|
||||||
if ( ! (conn->ntables % COL_INCR)) {
|
if (!(conn->ntables % COL_INCR))
|
||||||
|
{
|
||||||
|
|
||||||
mylog("PARSE: Allocing col_info at ntables=%d\n", conn->ntables);
|
mylog("PARSE: Allocing col_info at ntables=%d\n", conn->ntables);
|
||||||
|
|
||||||
conn->col_info = (COL_INFO **) realloc(conn->col_info, (conn->ntables + COL_INCR) * sizeof(COL_INFO *));
|
conn->col_info = (COL_INFO **) realloc(conn->col_info, (conn->ntables + COL_INCR) * sizeof(COL_INFO *));
|
||||||
if ( ! conn->col_info) {
|
if (!conn->col_info)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -606,17 +694,22 @@ RETCODE result;
|
|||||||
|
|
||||||
mylog("PARSE: malloc at conn->col_info[%d]\n", conn->ntables);
|
mylog("PARSE: malloc at conn->col_info[%d]\n", conn->ntables);
|
||||||
conn->col_info[conn->ntables] = (COL_INFO *) malloc(sizeof(COL_INFO));
|
conn->col_info[conn->ntables] = (COL_INFO *) malloc(sizeof(COL_INFO));
|
||||||
if ( ! conn->col_info[conn->ntables]) {
|
if (!conn->col_info[conn->ntables])
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the table name and the SQLColumns result structure */
|
/*
|
||||||
|
* Store the table name and the SQLColumns result
|
||||||
|
* structure
|
||||||
|
*/
|
||||||
strcpy(conn->col_info[conn->ntables]->name, ti[i]->name);
|
strcpy(conn->col_info[conn->ntables]->name, ti[i]->name);
|
||||||
conn->col_info[conn->ntables]->result = col_stmt->result;
|
conn->col_info[conn->ntables]->result = col_stmt->result;
|
||||||
|
|
||||||
/* The connection will now free the result structures, so make
|
/*
|
||||||
sure that the statement doesn't free it
|
* The connection will now free the result structures, so
|
||||||
|
* make sure that the statement doesn't free it
|
||||||
*/
|
*/
|
||||||
col_stmt->result = NULL;
|
col_stmt->result = NULL;
|
||||||
|
|
||||||
@ -625,7 +718,8 @@ RETCODE result;
|
|||||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||||
mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables);
|
mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -645,34 +739,41 @@ RETCODE result;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < stmt->nfld;) {
|
for (i = 0; i < stmt->nfld;)
|
||||||
|
{
|
||||||
|
|
||||||
/* Dont worry about functions or quotes */
|
/* Dont worry about functions or quotes */
|
||||||
if (fi[i]->func || fi[i]->quote || fi[i]->numeric) {
|
if (fi[i]->func || fi[i]->quote || fi[i]->numeric)
|
||||||
|
{
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stars get expanded to all fields in the table */
|
/* Stars get expanded to all fields in the table */
|
||||||
else if (fi[i]->name[0] == '*') {
|
else if (fi[i]->name[0] == '*')
|
||||||
|
{
|
||||||
|
|
||||||
char do_all_tables;
|
char do_all_tables;
|
||||||
int total_cols, old_size, need, cols;
|
int total_cols,
|
||||||
|
old_size,
|
||||||
|
need,
|
||||||
|
cols;
|
||||||
|
|
||||||
mylog("expanding field %d\n", i);
|
mylog("expanding field %d\n", i);
|
||||||
|
|
||||||
total_cols = 0;
|
total_cols = 0;
|
||||||
|
|
||||||
if (fi[i]->ti) /* The star represents only the qualified table */
|
if (fi[i]->ti) /* The star represents only the qualified
|
||||||
|
* table */
|
||||||
total_cols = QR_get_num_tuples(fi[i]->ti->col_info->result);
|
total_cols = QR_get_num_tuples(fi[i]->ti->col_info->result);
|
||||||
|
|
||||||
else { /* The star represents all tables */
|
else
|
||||||
|
{ /* The star represents all tables */
|
||||||
|
|
||||||
/* Calculate the total number of columns after expansion */
|
/* Calculate the total number of columns after expansion */
|
||||||
for (k = 0; k < stmt->ntab; k++) {
|
for (k = 0; k < stmt->ntab; k++)
|
||||||
total_cols += QR_get_num_tuples(ti[k]->col_info->result);
|
total_cols += QR_get_num_tuples(ti[k]->col_info->result);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
total_cols--; /* makes up for the star */
|
total_cols--; /* makes up for the star */
|
||||||
|
|
||||||
/* Allocate some more field pointers if necessary */
|
/* Allocate some more field pointers if necessary */
|
||||||
@ -680,21 +781,29 @@ RETCODE result;
|
|||||||
old_size = (stmt->nfld / FLD_INCR * FLD_INCR + FLD_INCR);
|
old_size = (stmt->nfld / FLD_INCR * FLD_INCR + FLD_INCR);
|
||||||
need = total_cols - (old_size - stmt->nfld);
|
need = total_cols - (old_size - stmt->nfld);
|
||||||
|
|
||||||
mylog("k=%d, total_cols=%d, old_size=%d, need=%d\n", k,total_cols,old_size,need);
|
mylog("k=%d, total_cols=%d, old_size=%d, need=%d\n", k, total_cols, old_size, need);
|
||||||
|
|
||||||
if (need > 0) {
|
if (need > 0)
|
||||||
|
{
|
||||||
int new_size = need / FLD_INCR * FLD_INCR + FLD_INCR;
|
int new_size = need / FLD_INCR * FLD_INCR + FLD_INCR;
|
||||||
|
|
||||||
mylog("need more cols: new_size = %d\n", new_size);
|
mylog("need more cols: new_size = %d\n", new_size);
|
||||||
fi = (FIELD_INFO **) realloc(fi, (old_size + new_size) * sizeof(FIELD_INFO *));
|
fi = (FIELD_INFO **) realloc(fi, (old_size + new_size) * sizeof(FIELD_INFO *));
|
||||||
if ( ! fi) {
|
if (!fi)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------- */
|
/*------------------------------------------------------------- */
|
||||||
/* copy any other fields (if there are any) up past the expansion */
|
|
||||||
for (j = stmt->nfld - 1; j > i; j--) {
|
/*
|
||||||
|
* copy any other fields (if there are any) up past the
|
||||||
|
* expansion
|
||||||
|
*/
|
||||||
|
for (j = stmt->nfld - 1; j > i; j--)
|
||||||
|
{
|
||||||
mylog("copying field %d to %d\n", j, total_cols + j);
|
mylog("copying field %d to %d\n", j, total_cols + j);
|
||||||
fi[total_cols + j] = fi[j];
|
fi[total_cols + j] = fi[j];
|
||||||
}
|
}
|
||||||
@ -712,19 +821,23 @@ RETCODE result;
|
|||||||
|
|
||||||
do_all_tables = (fi[i]->ti ? FALSE : TRUE);
|
do_all_tables = (fi[i]->ti ? FALSE : TRUE);
|
||||||
|
|
||||||
for (k = 0; k < (do_all_tables ? stmt->ntab : 1); k++) {
|
for (k = 0; k < (do_all_tables ? stmt->ntab : 1); k++)
|
||||||
|
{
|
||||||
|
|
||||||
TABLE_INFO *the_ti = do_all_tables ? ti[k] : fi[i]->ti;
|
TABLE_INFO *the_ti = do_all_tables ? ti[k] : fi[i]->ti;
|
||||||
|
|
||||||
cols = QR_get_num_tuples(the_ti->col_info->result);
|
cols = QR_get_num_tuples(the_ti->col_info->result);
|
||||||
|
|
||||||
for (n = 0; n < cols; n++) {
|
for (n = 0; n < cols; n++)
|
||||||
|
{
|
||||||
mylog("creating field info: n=%d\n", n);
|
mylog("creating field info: n=%d\n", n);
|
||||||
/* skip malloc (already did it for the Star) */
|
/* skip malloc (already did it for the Star) */
|
||||||
if (k > 0 || n > 0) {
|
if (k > 0 || n > 0)
|
||||||
|
{
|
||||||
mylog("allocating field info at %d\n", n + i);
|
mylog("allocating field info at %d\n", n + i);
|
||||||
fi[n + i] = (FIELD_INFO *) malloc( sizeof(FIELD_INFO));
|
fi[n + i] = (FIELD_INFO *) malloc(sizeof(FIELD_INFO));
|
||||||
if (fi[n + i] == NULL) {
|
if (fi[n + i] == NULL)
|
||||||
|
{
|
||||||
stmt->parse_status = STMT_PARSE_FATAL;
|
stmt->parse_status = STMT_PARSE_FATAL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -747,22 +860,28 @@ RETCODE result;
|
|||||||
/*------------------------------------------------------------- */
|
/*------------------------------------------------------------- */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We either know which table the field was in because it was qualified
|
/*
|
||||||
with a table name or alias -OR- there was only 1 table.
|
* We either know which table the field was in because it was
|
||||||
|
* qualified with a table name or alias -OR- there was only 1
|
||||||
|
* table.
|
||||||
*/
|
*/
|
||||||
else if (fi[i]->ti) {
|
else if (fi[i]->ti)
|
||||||
|
{
|
||||||
|
|
||||||
if ( ! searchColInfo(fi[i]->ti->col_info, fi[i]))
|
if (!searchColInfo(fi[i]->ti->col_info, fi[i]))
|
||||||
parse = FALSE;
|
parse = FALSE;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't know the table -- search all tables in "from" list */
|
/* Don't know the table -- search all tables in "from" list */
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
parse = FALSE;
|
parse = FALSE;
|
||||||
for (k = 0; k < stmt->ntab; k++) {
|
for (k = 0; k < stmt->ntab; k++)
|
||||||
if ( searchColInfo(ti[k]->col_info, fi[i])) {
|
{
|
||||||
|
if (searchColInfo(ti[k]->col_info, fi[i]))
|
||||||
|
{
|
||||||
fi[i]->ti = ti[k]; /* now know the table */
|
fi[i]->ti = ti[k]; /* now know the table */
|
||||||
parse = TRUE;
|
parse = TRUE;
|
||||||
break;
|
break;
|
||||||
@ -773,7 +892,7 @@ RETCODE result;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( ! parse)
|
if (!parse)
|
||||||
stmt->parse_status = STMT_PARSE_INCOMPLETE;
|
stmt->parse_status = STMT_PARSE_INCOMPLETE;
|
||||||
else
|
else
|
||||||
stmt->parse_status = STMT_PARSE_COMPLETE;
|
stmt->parse_status = STMT_PARSE_COMPLETE;
|
||||||
@ -782,4 +901,3 @@ RETCODE result;
|
|||||||
mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status);
|
mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status);
|
||||||
return parse;
|
return parse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
extern GLOBAL_VALUES globals;
|
extern GLOBAL_VALUES globals;
|
||||||
|
|
||||||
Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
|
Int4 getCharPrecision(StatementClass * stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||||
|
|
||||||
|
|
||||||
/* these are the types we support. all of the pgtype_ functions should */
|
/* these are the types we support. all of the pgtype_ functions should */
|
||||||
@ -79,7 +79,7 @@ Int4 pgtypes_defined[] = {
|
|||||||
|
|
||||||
|
|
||||||
/* These are NOW the SQL Types reported in SQLGetTypeInfo. */
|
/* These are NOW the SQL Types reported in SQLGetTypeInfo. */
|
||||||
Int2 sqlTypes [] = {
|
Int2 sqlTypes[] = {
|
||||||
SQL_BIGINT,
|
SQL_BIGINT,
|
||||||
/* SQL_BINARY, -- Commented out because VarBinary is more correct. */
|
/* SQL_BINARY, -- Commented out because VarBinary is more correct. */
|
||||||
SQL_BIT,
|
SQL_BIT,
|
||||||
@ -102,11 +102,13 @@ Int2 sqlTypes [] = {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
Int4 sqltype_to_pgtype(SWORD fSqlType)
|
Int4
|
||||||
|
sqltype_to_pgtype(SWORD fSqlType)
|
||||||
{
|
{
|
||||||
Int4 pgType;
|
Int4 pgType;
|
||||||
|
|
||||||
switch(fSqlType) {
|
switch (fSqlType)
|
||||||
|
{
|
||||||
|
|
||||||
case SQL_BINARY:
|
case SQL_BINARY:
|
||||||
pgType = PG_TYPE_BYTEA;
|
pgType = PG_TYPE_BYTEA;
|
||||||
@ -192,142 +194,211 @@ Int4 pgType;
|
|||||||
know. This allows for supporting
|
know. This allows for supporting
|
||||||
types that are unknown. All other pg routines in here return a suitable default.
|
types that are unknown. All other pg routines in here return a suitable default.
|
||||||
*/
|
*/
|
||||||
Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_to_sqltype(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_CHAR:
|
case PG_TYPE_CHAR:
|
||||||
case PG_TYPE_CHAR2:
|
case PG_TYPE_CHAR2:
|
||||||
case PG_TYPE_CHAR4:
|
case PG_TYPE_CHAR4:
|
||||||
case PG_TYPE_CHAR8:
|
case PG_TYPE_CHAR8:
|
||||||
case PG_TYPE_NAME: return SQL_CHAR;
|
case PG_TYPE_NAME:return SQL_CHAR;
|
||||||
|
|
||||||
case PG_TYPE_BPCHAR: return SQL_CHAR;
|
case PG_TYPE_BPCHAR:
|
||||||
|
return SQL_CHAR;
|
||||||
|
|
||||||
case PG_TYPE_VARCHAR: return SQL_VARCHAR;
|
case PG_TYPE_VARCHAR:
|
||||||
|
return SQL_VARCHAR;
|
||||||
|
|
||||||
case PG_TYPE_TEXT: return globals.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
|
case PG_TYPE_TEXT:
|
||||||
|
return globals.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
|
||||||
|
|
||||||
case PG_TYPE_BYTEA: return SQL_VARBINARY;
|
case PG_TYPE_BYTEA:
|
||||||
case PG_TYPE_LO: return SQL_LONGVARBINARY;
|
return SQL_VARBINARY;
|
||||||
|
case PG_TYPE_LO:
|
||||||
|
return SQL_LONGVARBINARY;
|
||||||
|
|
||||||
case PG_TYPE_INT2: return SQL_SMALLINT;
|
case PG_TYPE_INT2:
|
||||||
|
return SQL_SMALLINT;
|
||||||
|
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_XID:
|
case PG_TYPE_XID:
|
||||||
case PG_TYPE_INT4: return SQL_INTEGER;
|
case PG_TYPE_INT4:
|
||||||
|
return SQL_INTEGER;
|
||||||
|
|
||||||
/* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */
|
/* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */
|
||||||
case PG_TYPE_INT8: return SQL_CHAR;
|
case PG_TYPE_INT8:
|
||||||
|
return SQL_CHAR;
|
||||||
|
|
||||||
case PG_TYPE_NUMERIC: return SQL_NUMERIC;
|
case PG_TYPE_NUMERIC:
|
||||||
|
return SQL_NUMERIC;
|
||||||
|
|
||||||
case PG_TYPE_FLOAT4: return SQL_REAL;
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_FLOAT8: return SQL_FLOAT;
|
return SQL_REAL;
|
||||||
case PG_TYPE_DATE: return SQL_DATE;
|
case PG_TYPE_FLOAT8:
|
||||||
case PG_TYPE_TIME: return SQL_TIME;
|
return SQL_FLOAT;
|
||||||
|
case PG_TYPE_DATE:
|
||||||
|
return SQL_DATE;
|
||||||
|
case PG_TYPE_TIME:
|
||||||
|
return SQL_TIME;
|
||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP: return SQL_TIMESTAMP;
|
case PG_TYPE_TIMESTAMP:
|
||||||
case PG_TYPE_MONEY: return SQL_FLOAT;
|
return SQL_TIMESTAMP;
|
||||||
case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_CHAR : SQL_BIT;
|
case PG_TYPE_MONEY:
|
||||||
|
return SQL_FLOAT;
|
||||||
|
case PG_TYPE_BOOL:
|
||||||
|
return globals.bools_as_char ? SQL_CHAR : SQL_BIT;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
/* first, check to see if 'type' is in list. If not, look up with query.
|
/*
|
||||||
Add oid, name to list. If it's already in list, just return.
|
* first, check to see if 'type' is in list. If not, look up
|
||||||
|
* with query. Add oid, name to list. If it's already in
|
||||||
|
* list, just return.
|
||||||
*/
|
*/
|
||||||
if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */
|
if (type == stmt->hdbc->lobj_type) /* hack until permanent
|
||||||
|
* type is available */
|
||||||
return SQL_LONGVARBINARY;
|
return SQL_LONGVARBINARY;
|
||||||
|
|
||||||
return globals.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
|
return globals.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_to_ctype(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
case PG_TYPE_INT8: return SQL_C_CHAR;
|
{
|
||||||
case PG_TYPE_NUMERIC: return SQL_C_CHAR;
|
case PG_TYPE_INT8:return SQL_C_CHAR;
|
||||||
case PG_TYPE_INT2: return SQL_C_SSHORT;
|
case PG_TYPE_NUMERIC:
|
||||||
|
return SQL_C_CHAR;
|
||||||
|
case PG_TYPE_INT2:
|
||||||
|
return SQL_C_SSHORT;
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_XID:
|
case PG_TYPE_XID:
|
||||||
case PG_TYPE_INT4: return SQL_C_SLONG;
|
case PG_TYPE_INT4:
|
||||||
case PG_TYPE_FLOAT4: return SQL_C_FLOAT;
|
return SQL_C_SLONG;
|
||||||
case PG_TYPE_FLOAT8: return SQL_C_DOUBLE;
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_DATE: return SQL_C_DATE;
|
return SQL_C_FLOAT;
|
||||||
case PG_TYPE_TIME: return SQL_C_TIME;
|
case PG_TYPE_FLOAT8:
|
||||||
|
return SQL_C_DOUBLE;
|
||||||
|
case PG_TYPE_DATE:
|
||||||
|
return SQL_C_DATE;
|
||||||
|
case PG_TYPE_TIME:
|
||||||
|
return SQL_C_TIME;
|
||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP: return SQL_C_TIMESTAMP;
|
case PG_TYPE_TIMESTAMP:
|
||||||
case PG_TYPE_MONEY: return SQL_C_FLOAT;
|
return SQL_C_TIMESTAMP;
|
||||||
case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
|
case PG_TYPE_MONEY:
|
||||||
|
return SQL_C_FLOAT;
|
||||||
|
case PG_TYPE_BOOL:
|
||||||
|
return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
|
||||||
|
|
||||||
case PG_TYPE_BYTEA: return SQL_C_BINARY;
|
case PG_TYPE_BYTEA:
|
||||||
case PG_TYPE_LO: return SQL_C_BINARY;
|
return SQL_C_BINARY;
|
||||||
|
case PG_TYPE_LO:
|
||||||
|
return SQL_C_BINARY;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */
|
if (type == stmt->hdbc->lobj_type) /* hack until permanent
|
||||||
|
* type is available */
|
||||||
return SQL_C_BINARY;
|
return SQL_C_BINARY;
|
||||||
|
|
||||||
return SQL_C_CHAR;
|
return SQL_C_CHAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pgtype_to_name(StatementClass *stmt, Int4 type)
|
char *
|
||||||
|
pgtype_to_name(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
case PG_TYPE_CHAR: return "char";
|
{
|
||||||
case PG_TYPE_CHAR2: return "char2";
|
case PG_TYPE_CHAR:return "char";
|
||||||
case PG_TYPE_CHAR4: return "char4";
|
case PG_TYPE_CHAR2:
|
||||||
case PG_TYPE_CHAR8: return "char8";
|
return "char2";
|
||||||
case PG_TYPE_INT8: return "int8";
|
case PG_TYPE_CHAR4:
|
||||||
case PG_TYPE_NUMERIC: return "numeric";
|
return "char4";
|
||||||
case PG_TYPE_VARCHAR: return "varchar";
|
case PG_TYPE_CHAR8:
|
||||||
case PG_TYPE_BPCHAR: return "char";
|
return "char8";
|
||||||
case PG_TYPE_TEXT: return "text";
|
case PG_TYPE_INT8:
|
||||||
case PG_TYPE_NAME: return "name";
|
return "int8";
|
||||||
case PG_TYPE_INT2: return "int2";
|
case PG_TYPE_NUMERIC:
|
||||||
case PG_TYPE_OID: return "oid";
|
return "numeric";
|
||||||
case PG_TYPE_INT4: return "int4";
|
case PG_TYPE_VARCHAR:
|
||||||
case PG_TYPE_FLOAT4: return "float4";
|
return "varchar";
|
||||||
case PG_TYPE_FLOAT8: return "float8";
|
case PG_TYPE_BPCHAR:
|
||||||
case PG_TYPE_DATE: return "date";
|
return "char";
|
||||||
case PG_TYPE_TIME: return "time";
|
case PG_TYPE_TEXT:
|
||||||
case PG_TYPE_ABSTIME: return "abstime";
|
return "text";
|
||||||
case PG_TYPE_DATETIME: return "datetime";
|
case PG_TYPE_NAME:
|
||||||
case PG_TYPE_TIMESTAMP: return "timestamp";
|
return "name";
|
||||||
case PG_TYPE_MONEY: return "money";
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_BOOL: return "bool";
|
return "int2";
|
||||||
case PG_TYPE_BYTEA: return "bytea";
|
case PG_TYPE_OID:
|
||||||
|
return "oid";
|
||||||
|
case PG_TYPE_INT4:
|
||||||
|
return "int4";
|
||||||
|
case PG_TYPE_FLOAT4:
|
||||||
|
return "float4";
|
||||||
|
case PG_TYPE_FLOAT8:
|
||||||
|
return "float8";
|
||||||
|
case PG_TYPE_DATE:
|
||||||
|
return "date";
|
||||||
|
case PG_TYPE_TIME:
|
||||||
|
return "time";
|
||||||
|
case PG_TYPE_ABSTIME:
|
||||||
|
return "abstime";
|
||||||
|
case PG_TYPE_DATETIME:
|
||||||
|
return "datetime";
|
||||||
|
case PG_TYPE_TIMESTAMP:
|
||||||
|
return "timestamp";
|
||||||
|
case PG_TYPE_MONEY:
|
||||||
|
return "money";
|
||||||
|
case PG_TYPE_BOOL:
|
||||||
|
return "bool";
|
||||||
|
case PG_TYPE_BYTEA:
|
||||||
|
return "bytea";
|
||||||
|
|
||||||
case PG_TYPE_LO: return PG_TYPE_LO_NAME;
|
case PG_TYPE_LO:
|
||||||
|
|
||||||
default:
|
|
||||||
if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */
|
|
||||||
return PG_TYPE_LO_NAME;
|
return PG_TYPE_LO_NAME;
|
||||||
|
|
||||||
/* "unknown" can actually be used in alter table because it is a real PG type! */
|
default:
|
||||||
|
if (type == stmt->hdbc->lobj_type) /* hack until permanent
|
||||||
|
* type is available */
|
||||||
|
return PG_TYPE_LO_NAME;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "unknown" can actually be used in alter table because it is
|
||||||
|
* a real PG type!
|
||||||
|
*/
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int2
|
static Int2
|
||||||
getNumericScale(StatementClass *stmt, Int4 type, int col)
|
getNumericScale(StatementClass * stmt, Int4 type, int col)
|
||||||
{
|
{
|
||||||
Int4 atttypmod;
|
Int4 atttypmod;
|
||||||
QResultClass *result;
|
QResultClass *result;
|
||||||
ColumnInfoClass *flds;
|
ColumnInfoClass *flds;
|
||||||
|
|
||||||
mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type,col);
|
mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type, col);
|
||||||
|
|
||||||
if (col < 0)
|
if (col < 0)
|
||||||
return PG_NUMERIC_MAX_SCALE;
|
return PG_NUMERIC_MAX_SCALE;
|
||||||
|
|
||||||
result = SC_get_Result(stmt);
|
result = SC_get_Result(stmt);
|
||||||
|
|
||||||
/* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */
|
/*
|
||||||
if (stmt->manual_result) {
|
* Manual Result Sets -- use assigned column width (i.e., from
|
||||||
|
* set_tuplefield_string)
|
||||||
|
*/
|
||||||
|
if (stmt->manual_result)
|
||||||
|
{
|
||||||
flds = result->fields;
|
flds = result->fields;
|
||||||
if (flds)
|
if (flds)
|
||||||
return flds->adtsize[col];
|
return flds->adtsize[col];
|
||||||
@ -336,30 +407,34 @@ mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type,col);
|
|||||||
}
|
}
|
||||||
|
|
||||||
atttypmod = QR_get_atttypmod(result, col);
|
atttypmod = QR_get_atttypmod(result, col);
|
||||||
if ( atttypmod > -1 )
|
if (atttypmod > -1)
|
||||||
return (atttypmod & 0xffff);
|
return (atttypmod & 0xffff);
|
||||||
else
|
else
|
||||||
return ( QR_get_display_size(result, col) ?
|
return (QR_get_display_size(result, col) ?
|
||||||
QR_get_display_size(result, col) :
|
QR_get_display_size(result, col) :
|
||||||
PG_NUMERIC_MAX_SCALE);
|
PG_NUMERIC_MAX_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int4
|
static Int4
|
||||||
getNumericPrecision(StatementClass *stmt, Int4 type, int col)
|
getNumericPrecision(StatementClass * stmt, Int4 type, int col)
|
||||||
{
|
{
|
||||||
Int4 atttypmod;
|
Int4 atttypmod;
|
||||||
QResultClass *result;
|
QResultClass *result;
|
||||||
ColumnInfoClass *flds;
|
ColumnInfoClass *flds;
|
||||||
|
|
||||||
mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type,col);
|
mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type, col);
|
||||||
|
|
||||||
if (col < 0)
|
if (col < 0)
|
||||||
return PG_NUMERIC_MAX_PRECISION;
|
return PG_NUMERIC_MAX_PRECISION;
|
||||||
|
|
||||||
result = SC_get_Result(stmt);
|
result = SC_get_Result(stmt);
|
||||||
|
|
||||||
/* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */
|
/*
|
||||||
if (stmt->manual_result) {
|
* Manual Result Sets -- use assigned column width (i.e., from
|
||||||
|
* set_tuplefield_string)
|
||||||
|
*/
|
||||||
|
if (stmt->manual_result)
|
||||||
|
{
|
||||||
flds = result->fields;
|
flds = result->fields;
|
||||||
if (flds)
|
if (flds)
|
||||||
return flds->adtsize[col];
|
return flds->adtsize[col];
|
||||||
@ -368,25 +443,27 @@ mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type,col);
|
|||||||
}
|
}
|
||||||
|
|
||||||
atttypmod = QR_get_atttypmod(result, col);
|
atttypmod = QR_get_atttypmod(result, col);
|
||||||
if ( atttypmod > -1 )
|
if (atttypmod > -1)
|
||||||
return (atttypmod >> 16) & 0xffff;
|
return (atttypmod >> 16) & 0xffff;
|
||||||
else
|
else
|
||||||
return ( QR_get_display_size(result, col) >= 0 ?
|
return (QR_get_display_size(result, col) >= 0 ?
|
||||||
QR_get_display_size(result, col) :
|
QR_get_display_size(result, col) :
|
||||||
PG_NUMERIC_MAX_PRECISION );
|
PG_NUMERIC_MAX_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
Int4
|
Int4
|
||||||
getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
|
getCharPrecision(StatementClass * stmt, Int4 type, int col, int handle_unknown_size_as)
|
||||||
{
|
{
|
||||||
int p = -1, maxsize;
|
int p = -1,
|
||||||
QResultClass *result;
|
maxsize;
|
||||||
ColumnInfoClass *flds;
|
QResultClass *result;
|
||||||
|
ColumnInfoClass *flds;
|
||||||
|
|
||||||
mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type,col,handle_unknown_size_as);
|
mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type, col, handle_unknown_size_as);
|
||||||
|
|
||||||
/* Assign Maximum size based on parameters */
|
/* Assign Maximum size based on parameters */
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_TEXT:
|
case PG_TYPE_TEXT:
|
||||||
if (globals.text_as_longvarchar)
|
if (globals.text_as_longvarchar)
|
||||||
maxsize = globals.max_longvarchar_size;
|
maxsize = globals.max_longvarchar_size;
|
||||||
@ -407,16 +484,21 @@ mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type,col,handle_unkno
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Static Precision (i.e., the Maximum Precision of the datatype)
|
/*
|
||||||
This has nothing to do with a result set.
|
* Static Precision (i.e., the Maximum Precision of the datatype) This
|
||||||
|
* has nothing to do with a result set.
|
||||||
*/
|
*/
|
||||||
if (col < 0)
|
if (col < 0)
|
||||||
return maxsize;
|
return maxsize;
|
||||||
|
|
||||||
result = SC_get_Result(stmt);
|
result = SC_get_Result(stmt);
|
||||||
|
|
||||||
/* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */
|
/*
|
||||||
if (stmt->manual_result) {
|
* Manual Result Sets -- use assigned column width (i.e., from
|
||||||
|
* set_tuplefield_string)
|
||||||
|
*/
|
||||||
|
if (stmt->manual_result)
|
||||||
|
{
|
||||||
flds = result->fields;
|
flds = result->fields;
|
||||||
if (flds)
|
if (flds)
|
||||||
return flds->adtsize[col];
|
return flds->adtsize[col];
|
||||||
@ -428,7 +510,8 @@ mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type,col,handle_unkno
|
|||||||
if (QR_get_atttypmod(result, col) > -1)
|
if (QR_get_atttypmod(result, col) > -1)
|
||||||
return QR_get_atttypmod(result, col);
|
return QR_get_atttypmod(result, col);
|
||||||
|
|
||||||
if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST) {
|
if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST)
|
||||||
|
{
|
||||||
p = QR_get_display_size(result, col);
|
p = QR_get_display_size(result, col);
|
||||||
mylog("getCharPrecision: LONGEST: p = %d\n", p);
|
mylog("getCharPrecision: LONGEST: p = %d\n", p);
|
||||||
}
|
}
|
||||||
@ -445,47 +528,65 @@ mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type,col,handle_unkno
|
|||||||
If col >= 0, then will attempt to get the info from the result set.
|
If col >= 0, then will attempt to get the info from the result set.
|
||||||
This is used for functions SQLDescribeCol and SQLColAttributes.
|
This is used for functions SQLDescribeCol and SQLColAttributes.
|
||||||
*/
|
*/
|
||||||
Int4 pgtype_precision(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)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
|
|
||||||
case PG_TYPE_CHAR: return 1;
|
case PG_TYPE_CHAR:return 1;
|
||||||
case PG_TYPE_CHAR2: return 2;
|
case PG_TYPE_CHAR2:
|
||||||
case PG_TYPE_CHAR4: return 4;
|
return 2;
|
||||||
case PG_TYPE_CHAR8: return 8;
|
case PG_TYPE_CHAR4:
|
||||||
|
return 4;
|
||||||
|
case PG_TYPE_CHAR8:
|
||||||
|
return 8;
|
||||||
|
|
||||||
case PG_TYPE_NAME: return NAME_FIELD_SIZE;
|
case PG_TYPE_NAME:
|
||||||
|
return NAME_FIELD_SIZE;
|
||||||
|
|
||||||
case PG_TYPE_INT2: return 5;
|
case PG_TYPE_INT2:
|
||||||
|
return 5;
|
||||||
|
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_XID:
|
case PG_TYPE_XID:
|
||||||
case PG_TYPE_INT4: return 10;
|
case PG_TYPE_INT4:
|
||||||
|
return 10;
|
||||||
|
|
||||||
case PG_TYPE_INT8: return 19; /* signed */
|
case PG_TYPE_INT8:
|
||||||
|
return 19; /* signed */
|
||||||
|
|
||||||
case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col);
|
case PG_TYPE_NUMERIC:
|
||||||
|
return getNumericPrecision(stmt, type, col);
|
||||||
|
|
||||||
case PG_TYPE_FLOAT4:
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_MONEY: return 7;
|
case PG_TYPE_MONEY:
|
||||||
|
return 7;
|
||||||
|
|
||||||
case PG_TYPE_FLOAT8: return 15;
|
case PG_TYPE_FLOAT8:
|
||||||
|
return 15;
|
||||||
|
|
||||||
case PG_TYPE_DATE: return 10;
|
case PG_TYPE_DATE:
|
||||||
case PG_TYPE_TIME: return 8;
|
return 10;
|
||||||
|
case PG_TYPE_TIME:
|
||||||
|
return 8;
|
||||||
|
|
||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP: return 19;
|
case PG_TYPE_TIMESTAMP:
|
||||||
|
return 19;
|
||||||
|
|
||||||
case PG_TYPE_BOOL: return 1;
|
case PG_TYPE_BOOL:
|
||||||
|
return 1;
|
||||||
|
|
||||||
case PG_TYPE_LO: return SQL_NO_TOTAL;
|
case PG_TYPE_LO:
|
||||||
|
return SQL_NO_TOTAL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */
|
if (type == stmt->hdbc->lobj_type) /* hack until permanent
|
||||||
|
* type is available */
|
||||||
return SQL_NO_TOTAL;
|
return SQL_NO_TOTAL;
|
||||||
|
|
||||||
/* Handle Character types and unknown types */
|
/* Handle Character types and unknown types */
|
||||||
@ -493,26 +594,35 @@ Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unkno
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int4 pgtype_display_size(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)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(type) {
|
switch (type)
|
||||||
case PG_TYPE_INT2: return 6;
|
{
|
||||||
|
case PG_TYPE_INT2:return 6;
|
||||||
|
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_XID: return 10;
|
case PG_TYPE_XID:
|
||||||
|
return 10;
|
||||||
|
|
||||||
case PG_TYPE_INT4: return 11;
|
case PG_TYPE_INT4:
|
||||||
|
return 11;
|
||||||
|
|
||||||
case PG_TYPE_INT8: return 20; /* signed: 19 digits + sign */
|
case PG_TYPE_INT8:
|
||||||
|
return 20; /* signed: 19 digits + sign */
|
||||||
|
|
||||||
case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col) + 2;
|
case PG_TYPE_NUMERIC:
|
||||||
|
return getNumericPrecision(stmt, type, col) + 2;
|
||||||
|
|
||||||
case PG_TYPE_MONEY: return 15; /* ($9,999,999.99) */
|
case PG_TYPE_MONEY:
|
||||||
|
return 15; /* ($9,999,999.99) */
|
||||||
|
|
||||||
case PG_TYPE_FLOAT4: return 13;
|
case PG_TYPE_FLOAT4:
|
||||||
|
return 13;
|
||||||
|
|
||||||
case PG_TYPE_FLOAT8: return 22;
|
case PG_TYPE_FLOAT8:
|
||||||
|
return 22;
|
||||||
|
|
||||||
/* Character types use regular precision */
|
/* Character types use regular precision */
|
||||||
default:
|
default:
|
||||||
@ -523,32 +633,41 @@ Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_un
|
|||||||
/* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
|
/* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
|
||||||
override this length with the atttypmod length from pg_attribute
|
override this length with the atttypmod length from pg_attribute
|
||||||
*/
|
*/
|
||||||
Int4 pgtype_length(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)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
|
|
||||||
case PG_TYPE_INT2: return 2;
|
case PG_TYPE_INT2:return 2;
|
||||||
|
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_XID:
|
case PG_TYPE_XID:
|
||||||
case PG_TYPE_INT4: return 4;
|
case PG_TYPE_INT4:
|
||||||
|
return 4;
|
||||||
|
|
||||||
case PG_TYPE_INT8: return 20; /* signed: 19 digits + sign */
|
case PG_TYPE_INT8:
|
||||||
|
return 20; /* signed: 19 digits + sign */
|
||||||
|
|
||||||
case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col) + 2;
|
case PG_TYPE_NUMERIC:
|
||||||
|
return getNumericPrecision(stmt, type, col) + 2;
|
||||||
|
|
||||||
case PG_TYPE_FLOAT4:
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_MONEY: return 4;
|
case PG_TYPE_MONEY:
|
||||||
|
return 4;
|
||||||
|
|
||||||
case PG_TYPE_FLOAT8: return 8;
|
case PG_TYPE_FLOAT8:
|
||||||
|
return 8;
|
||||||
|
|
||||||
case PG_TYPE_DATE:
|
case PG_TYPE_DATE:
|
||||||
case PG_TYPE_TIME: return 6;
|
case PG_TYPE_TIME:
|
||||||
|
return 6;
|
||||||
|
|
||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP: return 16;
|
case PG_TYPE_TIMESTAMP:
|
||||||
|
return 16;
|
||||||
|
|
||||||
|
|
||||||
/* Character types (and NUMERIC) use the default precision */
|
/* Character types (and NUMERIC) use the default precision */
|
||||||
@ -557,9 +676,11 @@ Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col)
|
Int2
|
||||||
|
pgtype_scale(StatementClass * stmt, Int4 type, int col)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
|
|
||||||
case PG_TYPE_INT2:
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
@ -571,21 +692,28 @@ Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col)
|
|||||||
case PG_TYPE_MONEY:
|
case PG_TYPE_MONEY:
|
||||||
case PG_TYPE_BOOL:
|
case PG_TYPE_BOOL:
|
||||||
|
|
||||||
/* Number of digits to the right of the decimal point in "yyyy-mm=dd hh:mm:ss[.f...]" */
|
/*
|
||||||
|
* Number of digits to the right of the decimal point in
|
||||||
|
* "yyyy-mm=dd hh:mm:ss[.f...]"
|
||||||
|
*/
|
||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP: return 0;
|
case PG_TYPE_TIMESTAMP:return 0;
|
||||||
|
|
||||||
case PG_TYPE_NUMERIC: return getNumericScale(stmt,type,col);
|
case PG_TYPE_NUMERIC:
|
||||||
|
return getNumericScale(stmt, type, col);
|
||||||
|
|
||||||
default: return -1;
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Int2 pgtype_radix(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_radix(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_INT2:
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_INT4:
|
case PG_TYPE_INT4:
|
||||||
@ -593,20 +721,24 @@ Int2 pgtype_radix(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_NUMERIC:
|
case PG_TYPE_NUMERIC:
|
||||||
case PG_TYPE_FLOAT4:
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_MONEY:
|
case PG_TYPE_MONEY:
|
||||||
case PG_TYPE_FLOAT8: return 10;
|
case PG_TYPE_FLOAT8:return 10;
|
||||||
|
|
||||||
default: return -1;
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_nullable(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_nullable(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
return SQL_NULLABLE; /* everything should be nullable */
|
return SQL_NULLABLE; /* everything should be nullable */
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_auto_increment(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
|
|
||||||
case PG_TYPE_INT2:
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
@ -623,15 +755,18 @@ Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_TIME:
|
case PG_TYPE_TIME:
|
||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP: return FALSE;
|
case PG_TYPE_TIMESTAMP:return FALSE;
|
||||||
|
|
||||||
default: return -1;
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_case_sensitive(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_CHAR:
|
case PG_TYPE_CHAR:
|
||||||
|
|
||||||
case PG_TYPE_CHAR2:
|
case PG_TYPE_CHAR2:
|
||||||
@ -641,23 +776,29 @@ Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_VARCHAR:
|
case PG_TYPE_VARCHAR:
|
||||||
case PG_TYPE_BPCHAR:
|
case PG_TYPE_BPCHAR:
|
||||||
case PG_TYPE_TEXT:
|
case PG_TYPE_TEXT:
|
||||||
case PG_TYPE_NAME: return TRUE;
|
case PG_TYPE_NAME:return TRUE;
|
||||||
|
|
||||||
default: return FALSE;
|
default:
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_money(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_money(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
case PG_TYPE_MONEY: return TRUE;
|
{
|
||||||
default: return FALSE;
|
case PG_TYPE_MONEY:return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_searchable(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_searchable(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_CHAR:
|
case PG_TYPE_CHAR:
|
||||||
case PG_TYPE_CHAR2:
|
case PG_TYPE_CHAR2:
|
||||||
case PG_TYPE_CHAR4:
|
case PG_TYPE_CHAR4:
|
||||||
@ -666,17 +807,20 @@ Int2 pgtype_searchable(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_VARCHAR:
|
case PG_TYPE_VARCHAR:
|
||||||
case PG_TYPE_BPCHAR:
|
case PG_TYPE_BPCHAR:
|
||||||
case PG_TYPE_TEXT:
|
case PG_TYPE_TEXT:
|
||||||
case PG_TYPE_NAME: return SQL_SEARCHABLE;
|
case PG_TYPE_NAME:return SQL_SEARCHABLE;
|
||||||
|
|
||||||
default: return SQL_ALL_EXCEPT_LIKE;
|
default:
|
||||||
|
return SQL_ALL_EXCEPT_LIKE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Int2 pgtype_unsigned(StatementClass *stmt, Int4 type)
|
Int2
|
||||||
|
pgtype_unsigned(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
case PG_TYPE_XID: return TRUE;
|
case PG_TYPE_XID:return TRUE;
|
||||||
|
|
||||||
case PG_TYPE_INT2:
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_INT4:
|
case PG_TYPE_INT4:
|
||||||
@ -684,15 +828,19 @@ Int2 pgtype_unsigned(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_NUMERIC:
|
case PG_TYPE_NUMERIC:
|
||||||
case PG_TYPE_FLOAT4:
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_FLOAT8:
|
case PG_TYPE_FLOAT8:
|
||||||
case PG_TYPE_MONEY: return FALSE;
|
case PG_TYPE_MONEY:
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
default: return -1;
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pgtype_literal_prefix(StatementClass *stmt, Int4 type)
|
char *
|
||||||
|
pgtype_literal_prefix(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
|
|
||||||
case PG_TYPE_INT2:
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
@ -702,15 +850,18 @@ char *pgtype_literal_prefix(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_NUMERIC:
|
case PG_TYPE_NUMERIC:
|
||||||
case PG_TYPE_FLOAT4:
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_FLOAT8:
|
case PG_TYPE_FLOAT8:
|
||||||
case PG_TYPE_MONEY: return NULL;
|
case PG_TYPE_MONEY:return NULL;
|
||||||
|
|
||||||
default: return "'";
|
default:
|
||||||
|
return "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pgtype_literal_suffix(StatementClass *stmt, Int4 type)
|
char *
|
||||||
|
pgtype_literal_suffix(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
|
|
||||||
case PG_TYPE_INT2:
|
case PG_TYPE_INT2:
|
||||||
case PG_TYPE_OID:
|
case PG_TYPE_OID:
|
||||||
@ -720,27 +871,33 @@ char *pgtype_literal_suffix(StatementClass *stmt, Int4 type)
|
|||||||
case PG_TYPE_NUMERIC:
|
case PG_TYPE_NUMERIC:
|
||||||
case PG_TYPE_FLOAT4:
|
case PG_TYPE_FLOAT4:
|
||||||
case PG_TYPE_FLOAT8:
|
case PG_TYPE_FLOAT8:
|
||||||
case PG_TYPE_MONEY: return NULL;
|
case PG_TYPE_MONEY:return NULL;
|
||||||
|
|
||||||
default: return "'";
|
default:
|
||||||
|
return "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pgtype_create_params(StatementClass *stmt, Int4 type)
|
char *
|
||||||
|
pgtype_create_params(StatementClass * stmt, Int4 type)
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PG_TYPE_CHAR:
|
case PG_TYPE_CHAR:
|
||||||
case PG_TYPE_VARCHAR: return "max. length";
|
case PG_TYPE_VARCHAR:return "max. length";
|
||||||
default: return NULL;
|
default:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Int2 sqltype_to_default_ctype(Int2 sqltype)
|
Int2
|
||||||
|
sqltype_to_default_ctype(Int2 sqltype)
|
||||||
{
|
{
|
||||||
/* from the table on page 623 of ODBC 2.0 Programmer's Reference */
|
/* from the table on page 623 of ODBC 2.0 Programmer's Reference */
|
||||||
/* (Appendix D) */
|
/* (Appendix D) */
|
||||||
switch(sqltype) {
|
switch (sqltype)
|
||||||
|
{
|
||||||
case SQL_CHAR:
|
case SQL_CHAR:
|
||||||
case SQL_VARCHAR:
|
case SQL_VARCHAR:
|
||||||
case SQL_LONGVARCHAR:
|
case SQL_LONGVARCHAR:
|
||||||
@ -786,4 +943,3 @@ Int2 sqltype_to_default_ctype(Int2 sqltype)
|
|||||||
return SQL_C_CHAR;
|
return SQL_C_CHAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define PG_TYPE_LO ???? /* waiting for permanent type */
|
#define PG_TYPE_LO ????/* waiting for permanent type */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PG_TYPE_BOOL 16
|
#define PG_TYPE_BOOL 16
|
||||||
@ -71,28 +71,27 @@ extern Int2 sqlTypes[];
|
|||||||
|
|
||||||
Int4 sqltype_to_pgtype(Int2 fSqlType);
|
Int4 sqltype_to_pgtype(Int2 fSqlType);
|
||||||
|
|
||||||
Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type);
|
Int2 pgtype_to_sqltype(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type);
|
Int2 pgtype_to_ctype(StatementClass * stmt, Int4 type);
|
||||||
char *pgtype_to_name(StatementClass *stmt, Int4 type);
|
char *pgtype_to_name(StatementClass * stmt, Int4 type);
|
||||||
|
|
||||||
/* These functions can use static numbers or result sets(col parameter) */
|
/* 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_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_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_length(StatementClass * stmt, Int4 type, int col, int handle_unknown_size_as);
|
||||||
|
|
||||||
Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col);
|
Int2 pgtype_scale(StatementClass * stmt, Int4 type, int col);
|
||||||
Int2 pgtype_radix(StatementClass *stmt, Int4 type);
|
Int2 pgtype_radix(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_nullable(StatementClass *stmt, Int4 type);
|
Int2 pgtype_nullable(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type);
|
Int2 pgtype_auto_increment(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type);
|
Int2 pgtype_case_sensitive(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_money(StatementClass *stmt, Int4 type);
|
Int2 pgtype_money(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_searchable(StatementClass *stmt, Int4 type);
|
Int2 pgtype_searchable(StatementClass * stmt, Int4 type);
|
||||||
Int2 pgtype_unsigned(StatementClass *stmt, Int4 type);
|
Int2 pgtype_unsigned(StatementClass * stmt, Int4 type);
|
||||||
char *pgtype_literal_prefix(StatementClass *stmt, Int4 type);
|
char *pgtype_literal_prefix(StatementClass * stmt, Int4 type);
|
||||||
char *pgtype_literal_suffix(StatementClass *stmt, Int4 type);
|
char *pgtype_literal_suffix(StatementClass * stmt, Int4 type);
|
||||||
char *pgtype_create_params(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
|
#endif
|
||||||
|
|
||||||
|
@ -38,24 +38,27 @@ RETCODE SQL_API SQLDummyOrdinal(void);
|
|||||||
HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
||||||
|
|
||||||
/* This is where the Driver Manager attaches to this Driver */
|
/* 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;
|
WORD wVersionRequested;
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
|
||||||
switch (ul_reason_for_call) {
|
switch (ul_reason_for_call)
|
||||||
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
s_hModule = hInst; /* Save for dialog boxes */
|
s_hModule = hInst; /* Save for dialog boxes */
|
||||||
|
|
||||||
/* Load the WinSock Library */
|
/* Load the WinSock Library */
|
||||||
wVersionRequested = MAKEWORD(1, 1);
|
wVersionRequested = MAKEWORD(1, 1);
|
||||||
|
|
||||||
if ( WSAStartup(wVersionRequested, &wsaData))
|
if (WSAStartup(wVersionRequested, &wsaData))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Verify that this is the minimum version of WinSock */
|
/* Verify that this is the minimum version of WinSock */
|
||||||
if ( LOBYTE( wsaData.wVersion ) != 1 ||
|
if (LOBYTE(wsaData.wVersion) != 1 ||
|
||||||
HIBYTE( wsaData.wVersion ) != 1 ) {
|
HIBYTE(wsaData.wVersion) != 1)
|
||||||
|
{
|
||||||
|
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -134,8 +137,8 @@ _fini(void)
|
|||||||
Driver Manager do this. Also, the ordinal values of the
|
Driver Manager do this. Also, the ordinal values of the
|
||||||
functions must match the value of fFunction in SQLGetFunctions()
|
functions must match the value of fFunction in SQLGetFunctions()
|
||||||
*/
|
*/
|
||||||
RETCODE SQL_API SQLDummyOrdinal(void)
|
RETCODE SQL_API
|
||||||
|
SQLDummyOrdinal(void)
|
||||||
{
|
{
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Comments: See "notice.txt" for copyright and license information.
|
* Comments: See "notice.txt" for copyright and license information.
|
||||||
*
|
*
|
||||||
* $Id: psqlodbc.h,v 1.31 2001/02/10 06:57:53 momjian Exp $
|
* $Id: psqlodbc.h,v 1.32 2001/02/10 07:01:19 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PSQLODBC_H__
|
#ifndef __PSQLODBC_H__
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#define UInt2 unsigned short
|
#define UInt2 unsigned short
|
||||||
typedef float SFLOAT;
|
typedef float SFLOAT;
|
||||||
typedef double SDOUBLE;
|
typedef double SDOUBLE;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define Int4 int
|
#define Int4 int
|
||||||
#define UInt4 unsigned int
|
#define UInt4 unsigned int
|
||||||
@ -54,14 +55,18 @@ typedef UInt4 Oid;
|
|||||||
#define BLCKSZ 4096
|
#define BLCKSZ 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_MESSAGE_LEN 65536 /* This puts a limit on query size but I don't */
|
#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 */
|
/* see an easy way round this - DJP 24-1-2001 */
|
||||||
#define MAX_CONNECT_STRING 4096
|
#define MAX_CONNECT_STRING 4096
|
||||||
#define ERROR_MSG_LENGTH 4096
|
#define ERROR_MSG_LENGTH 4096
|
||||||
#define FETCH_MAX 100 /* default number of rows to cache for declare/fetch */
|
#define FETCH_MAX 100 /* default number of rows to cache
|
||||||
|
* for declare/fetch */
|
||||||
#define TUPLE_MALLOC_INC 100
|
#define TUPLE_MALLOC_INC 100
|
||||||
#define SOCK_BUFFER_SIZE 4096 /* default socket buffer size */
|
#define SOCK_BUFFER_SIZE 4096 /* default socket buffer
|
||||||
#define MAX_CONNECTIONS 128 /* conns per environment (arbitrary) */
|
* size */
|
||||||
|
#define MAX_CONNECTIONS 128 /* conns per environment
|
||||||
|
* (arbitrary) */
|
||||||
#define MAX_FIELDS 512
|
#define MAX_FIELDS 512
|
||||||
#define BYTELEN 8
|
#define BYTELEN 8
|
||||||
#define VARHDRSZ sizeof(Int4)
|
#define VARHDRSZ sizeof(Int4)
|
||||||
@ -72,7 +77,8 @@ typedef UInt4 Oid;
|
|||||||
|
|
||||||
/* Registry length limits */
|
/* Registry length limits */
|
||||||
#define LARGE_REGISTRY_LEN 4096 /* used for special cases */
|
#define LARGE_REGISTRY_LEN 4096 /* used for special cases */
|
||||||
#define MEDIUM_REGISTRY_LEN 256 /* normal size for user,database,etc. */
|
#define MEDIUM_REGISTRY_LEN 256 /* normal size for
|
||||||
|
* user,database,etc. */
|
||||||
#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */
|
#define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */
|
||||||
|
|
||||||
|
|
||||||
@ -83,8 +89,10 @@ typedef UInt4 Oid;
|
|||||||
/* Info limits */
|
/* Info limits */
|
||||||
#define MAX_INFO_STRING 128
|
#define MAX_INFO_STRING 128
|
||||||
#define MAX_KEYPARTS 20
|
#define MAX_KEYPARTS 20
|
||||||
#define MAX_KEYLEN 512 /* max key of the form "date+outlet+invoice" */
|
#define MAX_KEYLEN 512 /* max key of the form
|
||||||
#define MAX_ROW_SIZE 0 /* Unlimited rowsize with the Tuple Toaster */
|
* "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_STATEMENT_LEN 0 /* Unlimited statement size with 7.0 */
|
||||||
|
|
||||||
/* Previously, numerous query strings were defined of length MAX_STATEMENT_LEN */
|
/* Previously, numerous query strings were defined of length MAX_STATEMENT_LEN */
|
||||||
@ -120,7 +128,8 @@ typedef struct GlobalValues_
|
|||||||
char disable_optimizer;
|
char disable_optimizer;
|
||||||
char ksqo;
|
char ksqo;
|
||||||
char unique_index;
|
char unique_index;
|
||||||
char onlyread; /* readonly is reserved on Digital C++ compiler */
|
char onlyread; /* readonly is reserved on Digital C++
|
||||||
|
* compiler */
|
||||||
char use_declarefetch;
|
char use_declarefetch;
|
||||||
char text_as_longvarchar;
|
char text_as_longvarchar;
|
||||||
char unknowns_as_longvarchar;
|
char unknowns_as_longvarchar;
|
||||||
@ -130,15 +139,18 @@ typedef struct GlobalValues_
|
|||||||
char cancel_as_freestmt;
|
char cancel_as_freestmt;
|
||||||
char extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
|
char extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
|
||||||
char conn_settings[LARGE_REGISTRY_LEN];
|
char conn_settings[LARGE_REGISTRY_LEN];
|
||||||
/* Protocol is not used anymore, but kept in case
|
|
||||||
* it is useful in the future. bjm 2001-02-10
|
/*
|
||||||
|
* Protocol is not used anymore, but kept in case it is useful in the
|
||||||
|
* future. bjm 2001-02-10
|
||||||
*/
|
*/
|
||||||
char protocol[SMALL_REGISTRY_LEN];
|
char protocol[SMALL_REGISTRY_LEN];
|
||||||
FILE* mylogFP;
|
FILE *mylogFP;
|
||||||
FILE* qlogFP;
|
FILE *qlogFP;
|
||||||
} GLOBAL_VALUES;
|
} GLOBAL_VALUES;
|
||||||
|
|
||||||
typedef struct StatementOptions_ {
|
typedef struct StatementOptions_
|
||||||
|
{
|
||||||
int maxRows;
|
int maxRows;
|
||||||
int maxLength;
|
int maxLength;
|
||||||
int rowset_size;
|
int rowset_size;
|
||||||
@ -146,26 +158,32 @@ typedef struct StatementOptions_ {
|
|||||||
int cursor_type;
|
int cursor_type;
|
||||||
int scroll_concurrency;
|
int scroll_concurrency;
|
||||||
int retrieve_data;
|
int retrieve_data;
|
||||||
int bind_size; /* size of each structure if using Row Binding */
|
int bind_size; /* size of each structure if using Row
|
||||||
|
* Binding */
|
||||||
int use_bookmarks;
|
int use_bookmarks;
|
||||||
} StatementOptions;
|
} StatementOptions;
|
||||||
|
|
||||||
/* Used to pass extra query info to send_query */
|
/* Used to pass extra query info to send_query */
|
||||||
typedef struct QueryInfo_ {
|
typedef struct QueryInfo_
|
||||||
|
{
|
||||||
int row_size;
|
int row_size;
|
||||||
QResultClass *result_in;
|
QResultClass *result_in;
|
||||||
char *cursor;
|
char *cursor;
|
||||||
} QueryInfo;
|
} QueryInfo;
|
||||||
|
|
||||||
|
|
||||||
#define PG_TYPE_LO -999 /* hack until permanent type available */
|
#define PG_TYPE_LO -999 /* hack until permanent type
|
||||||
|
* available */
|
||||||
#define PG_TYPE_LO_NAME "lo"
|
#define PG_TYPE_LO_NAME "lo"
|
||||||
#define OID_ATTNUM -2 /* the attnum in pg_index of the oid */
|
#define OID_ATTNUM -2 /* the attnum in pg_index of the
|
||||||
|
* oid */
|
||||||
|
|
||||||
/* sizes */
|
/* sizes */
|
||||||
#define TEXT_FIELD_SIZE 8190 /* size of text fields (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 NAME_FIELD_SIZE 32 /* size of name fields */
|
||||||
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not including null term) */
|
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not
|
||||||
|
* including null term) */
|
||||||
|
|
||||||
#define PG_NUMERIC_MAX_PRECISION 1000
|
#define PG_NUMERIC_MAX_PRECISION 1000
|
||||||
#define PG_NUMERIC_MAX_SCALE 1000
|
#define PG_NUMERIC_MAX_SCALE 1000
|
||||||
|
@ -34,12 +34,12 @@ 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. */
|
/* All info functions call this function to create the manual result set. */
|
||||||
void
|
void
|
||||||
QR_set_num_fields(QResultClass *self, int new_num_fields)
|
QR_set_num_fields(QResultClass * self, int new_num_fields)
|
||||||
{
|
{
|
||||||
mylog("in QR_set_num_fields\n");
|
mylog("in QR_set_num_fields\n");
|
||||||
|
|
||||||
CI_set_num_fields(self->fields, new_num_fields);
|
CI_set_num_fields(self->fields, new_num_fields);
|
||||||
if(self->manual_tuples)
|
if (self->manual_tuples)
|
||||||
TL_Destructor(self->manual_tuples);
|
TL_Destructor(self->manual_tuples);
|
||||||
|
|
||||||
self->manual_tuples = TL_Constructor(new_num_fields);
|
self->manual_tuples = TL_Constructor(new_num_fields);
|
||||||
@ -48,25 +48,25 @@ QR_set_num_fields(QResultClass *self, int new_num_fields)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_set_position(QResultClass *self, int pos)
|
QR_set_position(QResultClass * self, int pos)
|
||||||
{
|
{
|
||||||
self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields);
|
self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_set_cache_size(QResultClass *self, int cache_size)
|
QR_set_cache_size(QResultClass * self, int cache_size)
|
||||||
{
|
{
|
||||||
self->cache_size = cache_size;
|
self->cache_size = cache_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_set_rowset_size(QResultClass *self, int rowset_size)
|
QR_set_rowset_size(QResultClass * self, int rowset_size)
|
||||||
{
|
{
|
||||||
self->rowset_size = rowset_size;
|
self->rowset_size = rowset_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_inc_base(QResultClass *self, int base_inc)
|
QR_inc_base(QResultClass * self, int base_inc)
|
||||||
{
|
{
|
||||||
self->base += base_inc;
|
self->base += base_inc;
|
||||||
}
|
}
|
||||||
@ -78,16 +78,18 @@ QR_inc_base(QResultClass *self, int base_inc)
|
|||||||
QResultClass *
|
QResultClass *
|
||||||
QR_Constructor(void)
|
QR_Constructor(void)
|
||||||
{
|
{
|
||||||
QResultClass *rv;
|
QResultClass *rv;
|
||||||
|
|
||||||
mylog("in QR_Constructor\n");
|
mylog("in QR_Constructor\n");
|
||||||
rv = (QResultClass *) malloc(sizeof(QResultClass));
|
rv = (QResultClass *) malloc(sizeof(QResultClass));
|
||||||
|
|
||||||
if (rv != NULL) {
|
if (rv != NULL)
|
||||||
|
{
|
||||||
rv->status = PGRES_EMPTY_QUERY;
|
rv->status = PGRES_EMPTY_QUERY;
|
||||||
|
|
||||||
/* construct the column info */
|
/* construct the column info */
|
||||||
if ( ! (rv->fields = CI_Constructor())) {
|
if (!(rv->fields = CI_Constructor()))
|
||||||
|
{
|
||||||
free(rv);
|
free(rv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -116,7 +118,7 @@ QResultClass *rv;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_Destructor(QResultClass *self)
|
QR_Destructor(QResultClass * self)
|
||||||
{
|
{
|
||||||
mylog("QResult: in DESTRUCTOR\n");
|
mylog("QResult: in DESTRUCTOR\n");
|
||||||
|
|
||||||
@ -154,7 +156,7 @@ QR_Destructor(QResultClass *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_set_command(QResultClass *self, char *msg)
|
QR_set_command(QResultClass * self, char *msg)
|
||||||
{
|
{
|
||||||
if (self->command)
|
if (self->command)
|
||||||
free(self->command);
|
free(self->command);
|
||||||
@ -163,7 +165,7 @@ QR_set_command(QResultClass *self, char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_set_notice(QResultClass *self, char *msg)
|
QR_set_notice(QResultClass * self, char *msg)
|
||||||
{
|
{
|
||||||
if (self->notice)
|
if (self->notice)
|
||||||
free(self->notice);
|
free(self->notice);
|
||||||
@ -172,26 +174,31 @@ QR_set_notice(QResultClass *self, char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QR_free_memory(QResultClass *self)
|
QR_free_memory(QResultClass * self)
|
||||||
{
|
{
|
||||||
register int lf, row;
|
register int lf,
|
||||||
register TupleField *tuple = self->backend_tuples;
|
row;
|
||||||
int fcount = self->fcount;
|
register TupleField *tuple = self->backend_tuples;
|
||||||
int num_fields = self->num_fields;
|
int fcount = self->fcount;
|
||||||
|
int num_fields = self->num_fields;
|
||||||
|
|
||||||
mylog("QResult: free memory in, fcount=%d\n", fcount);
|
mylog("QResult: free memory in, fcount=%d\n", fcount);
|
||||||
|
|
||||||
if ( self->backend_tuples) {
|
if (self->backend_tuples)
|
||||||
|
{
|
||||||
|
|
||||||
for (row = 0; row < fcount; row++) {
|
for (row = 0; row < fcount; row++)
|
||||||
|
{
|
||||||
mylog("row = %d, num_fields = %d\n", row, num_fields);
|
mylog("row = %d, num_fields = %d\n", row, num_fields);
|
||||||
for (lf=0; lf < num_fields; lf++) {
|
for (lf = 0; lf < num_fields; lf++)
|
||||||
if (tuple[lf].value != NULL) {
|
{
|
||||||
|
if (tuple[lf].value != NULL)
|
||||||
|
{
|
||||||
mylog("free [lf=%d] %u\n", lf, tuple[lf].value);
|
mylog("free [lf=%d] %u\n", lf, tuple[lf].value);
|
||||||
free(tuple[lf].value);
|
free(tuple[lf].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tuple += num_fields; /* next row */
|
tuple += num_fields;/* next row */
|
||||||
}
|
}
|
||||||
|
|
||||||
free(self->backend_tuples);
|
free(self->backend_tuples);
|
||||||
@ -205,25 +212,28 @@ int num_fields = self->num_fields;
|
|||||||
|
|
||||||
/* This function is called by send_query() */
|
/* This function is called by send_query() */
|
||||||
char
|
char
|
||||||
QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
|
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), */
|
/* If called from send_query the first time (conn != NULL), */
|
||||||
/* then set the inTuples state, */
|
/* then set the inTuples state, */
|
||||||
/* and read the tuples. If conn is NULL, */
|
/* and read the tuples. If conn is NULL, */
|
||||||
/* it implies that we are being called from next_tuple(), */
|
/* it implies that we are being called from next_tuple(), */
|
||||||
/* like to get more rows so don't call next_tuple again! */
|
/* like to get more rows so don't call next_tuple again! */
|
||||||
if (conn != NULL) {
|
if (conn != NULL)
|
||||||
|
{
|
||||||
self->conn = conn;
|
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)
|
if (self->cursor)
|
||||||
free(self->cursor);
|
free(self->cursor);
|
||||||
|
|
||||||
if ( globals.use_declarefetch) {
|
if (globals.use_declarefetch)
|
||||||
if (! cursor || cursor[0] == '\0') {
|
{
|
||||||
|
if (!cursor || cursor[0] == '\0')
|
||||||
|
{
|
||||||
self->status = PGRES_INTERNAL_ERROR;
|
self->status = PGRES_INTERNAL_ERROR;
|
||||||
QR_set_message(self, "Internal Error -- no cursor for fetch");
|
QR_set_message(self, "Internal Error -- no cursor for fetch");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -233,11 +243,13 @@ int tuple_size;
|
|||||||
|
|
||||||
/* Read the field attributes. */
|
/* Read the field attributes. */
|
||||||
/* $$$$ Should do some error control HERE! $$$$ */
|
/* $$$$ Should do some error control HERE! $$$$ */
|
||||||
if ( CI_read_fields(self->fields, self->conn)) {
|
if (CI_read_fields(self->fields, self->conn))
|
||||||
|
{
|
||||||
self->status = PGRES_FIELDS_OK;
|
self->status = PGRES_FIELDS_OK;
|
||||||
self->num_fields = CI_get_num_fields(self->fields);
|
self->num_fields = CI_get_num_fields(self->fields);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
self->status = PGRES_BAD_RESPONSE;
|
self->status = PGRES_BAD_RESPONSE;
|
||||||
QR_set_message(self, "Error reading field information");
|
QR_set_message(self, "Error reading field information");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -253,7 +265,8 @@ int tuple_size;
|
|||||||
/* allocate memory for the tuple cache */
|
/* allocate memory for the tuple cache */
|
||||||
mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
|
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);
|
self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);
|
||||||
if ( ! self->backend_tuples) {
|
if (!self->backend_tuples)
|
||||||
|
{
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
QR_set_message(self, "Could not get memory for tuple cache.");
|
QR_set_message(self, "Could not get memory for tuple cache.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -263,18 +276,20 @@ int tuple_size;
|
|||||||
|
|
||||||
|
|
||||||
/* Force a read to occur in next_tuple */
|
/* Force a read to occur in next_tuple */
|
||||||
self->fcount = tuple_size+1;
|
self->fcount = tuple_size + 1;
|
||||||
self->fetch_count = tuple_size+1;
|
self->fetch_count = tuple_size + 1;
|
||||||
self->base = 0;
|
self->base = 0;
|
||||||
|
|
||||||
return QR_next_tuple(self);
|
return QR_next_tuple(self);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
|
|
||||||
/* Always have to read the field attributes. */
|
/* Always have to read the field attributes. */
|
||||||
/* But we dont have to reallocate memory for them! */
|
/* But we dont have to reallocate memory for them! */
|
||||||
|
|
||||||
if ( ! CI_read_fields(NULL, self->conn)) {
|
if (!CI_read_fields(NULL, self->conn))
|
||||||
|
{
|
||||||
self->status = PGRES_BAD_RESPONSE;
|
self->status = PGRES_BAD_RESPONSE;
|
||||||
QR_set_message(self, "Error reading field information");
|
QR_set_message(self, "Error reading field information");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -286,11 +301,12 @@ int tuple_size;
|
|||||||
/* Close the cursor and end the transaction (if no cursors left) */
|
/* Close the cursor and end the transaction (if no cursors left) */
|
||||||
/* We only close cursor/end the transaction if a cursor was used. */
|
/* We only close cursor/end the transaction if a cursor was used. */
|
||||||
int
|
int
|
||||||
QR_close(QResultClass *self)
|
QR_close(QResultClass * self)
|
||||||
{
|
{
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
|
|
||||||
if (globals.use_declarefetch && self->conn && self->cursor) {
|
if (globals.use_declarefetch && self->conn && self->cursor)
|
||||||
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
sprintf(buf, "close %s", self->cursor);
|
sprintf(buf, "close %s", self->cursor);
|
||||||
@ -304,21 +320,24 @@ QResultClass *res;
|
|||||||
free(self->cursor);
|
free(self->cursor);
|
||||||
self->cursor = NULL;
|
self->cursor = NULL;
|
||||||
|
|
||||||
if (res == NULL) {
|
if (res == NULL)
|
||||||
|
{
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
QR_set_message(self, "Error closing cursor.");
|
QR_set_message(self, "Error closing cursor.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End the transaction if there are no cursors left on this conn */
|
/* End the transaction if there are no cursors left on this conn */
|
||||||
if (CC_cursor_count(self->conn) == 0) {
|
if (CC_cursor_count(self->conn) == 0)
|
||||||
|
{
|
||||||
mylog("QResult: END transaction on conn=%u\n", self->conn);
|
mylog("QResult: END transaction on conn=%u\n", self->conn);
|
||||||
|
|
||||||
res = CC_send_query(self->conn, "END", NULL);
|
res = CC_send_query(self->conn, "END", NULL);
|
||||||
|
|
||||||
CC_set_no_trans(self->conn);
|
CC_set_no_trans(self->conn);
|
||||||
|
|
||||||
if (res == NULL) {
|
if (res == NULL)
|
||||||
|
{
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
QR_set_message(self, "Error ending transaction.");
|
QR_set_message(self, "Error ending transaction.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -332,54 +351,65 @@ QResultClass *res;
|
|||||||
|
|
||||||
/* This function is called by fetch_tuples() AND SQLFetch() */
|
/* This function is called by fetch_tuples() AND SQLFetch() */
|
||||||
int
|
int
|
||||||
QR_next_tuple(QResultClass *self)
|
QR_next_tuple(QResultClass * self)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
SocketClass *sock;
|
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;
|
|
||||||
|
|
||||||
if (fetch_count < fcount) { /* return a row from cache */
|
/* 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;
|
||||||
|
|
||||||
|
if (fetch_count < fcount)
|
||||||
|
{ /* return a row from cache */
|
||||||
mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, fcount);
|
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++;
|
self->fetch_count++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (self->fcount < self->cache_size) { /* last row from cache */
|
else if (self->fcount < self->cache_size)
|
||||||
|
{ /* last row from cache */
|
||||||
/* We are done because we didn't even get CACHE_SIZE tuples */
|
/* 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);
|
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
|
||||||
self->tupleField = NULL;
|
self->tupleField = NULL;
|
||||||
self->status = PGRES_END_TUPLES;
|
self->status = PGRES_END_TUPLES;
|
||||||
return -1; /* end of tuples */
|
return -1; /* end of tuples */
|
||||||
}
|
}
|
||||||
else {
|
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.
|
* 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;
|
self->tupleField = NULL;
|
||||||
|
|
||||||
if ( ! self->inTuples) {
|
if (!self->inTuples)
|
||||||
|
{
|
||||||
|
|
||||||
if ( ! globals.use_declarefetch) {
|
if (!globals.use_declarefetch)
|
||||||
|
{
|
||||||
mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count);
|
mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count);
|
||||||
self->tupleField = NULL;
|
self->tupleField = NULL;
|
||||||
self->status = PGRES_END_TUPLES;
|
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)
|
if (globals.fetch_max % self->rowset_size == 0)
|
||||||
@ -392,7 +422,8 @@ QueryInfo qi;
|
|||||||
self->cache_size = fetch_size;
|
self->cache_size = fetch_size;
|
||||||
self->fetch_count = 1;
|
self->fetch_count = 1;
|
||||||
}
|
}
|
||||||
else { /* need to correct */
|
else
|
||||||
|
{ /* need to correct */
|
||||||
|
|
||||||
corrected = TRUE;
|
corrected = TRUE;
|
||||||
|
|
||||||
@ -407,7 +438,8 @@ QueryInfo qi;
|
|||||||
|
|
||||||
|
|
||||||
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
|
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
|
||||||
if ( ! self->backend_tuples) {
|
if (!self->backend_tuples)
|
||||||
|
{
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
QR_set_message(self, "Out of memory while reading tuples.");
|
QR_set_message(self, "Out of memory while reading tuples.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -421,24 +453,29 @@ QueryInfo qi;
|
|||||||
qi.result_in = self;
|
qi.result_in = self;
|
||||||
qi.cursor = NULL;
|
qi.cursor = NULL;
|
||||||
res = CC_send_query(self->conn, fetch, &qi);
|
res = CC_send_query(self->conn, fetch, &qi);
|
||||||
if (res == NULL) {
|
if (res == NULL)
|
||||||
|
{
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
QR_set_message(self, "Error fetching next group.");
|
QR_set_message(self, "Error fetching next group.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
self->inTuples = TRUE;
|
self->inTuples = TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->fcount, self->fetch_count);
|
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;
|
self->fetch_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! corrected) {
|
if (!corrected)
|
||||||
|
{
|
||||||
self->base = 0;
|
self->base = 0;
|
||||||
self->fcount = 0;
|
self->fcount = 0;
|
||||||
}
|
}
|
||||||
@ -447,11 +484,13 @@ QueryInfo qi;
|
|||||||
sock = CC_get_socket(self->conn);
|
sock = CC_get_socket(self->conn);
|
||||||
self->tupleField = NULL;
|
self->tupleField = NULL;
|
||||||
|
|
||||||
for ( ; ;) {
|
for (;;)
|
||||||
|
{
|
||||||
|
|
||||||
id = SOCK_get_char(sock);
|
id = SOCK_get_char(sock);
|
||||||
|
|
||||||
switch (id) {
|
switch (id)
|
||||||
|
{
|
||||||
case 'T': /* Tuples within tuples cannot be handled */
|
case 'T': /* Tuples within tuples cannot be handled */
|
||||||
self->status = PGRES_BAD_RESPONSE;
|
self->status = PGRES_BAD_RESPONSE;
|
||||||
QR_set_message(self, "Tuples within tuples cannot be handled");
|
QR_set_message(self, "Tuples within tuples cannot be handled");
|
||||||
@ -459,19 +498,23 @@ QueryInfo qi;
|
|||||||
case 'B': /* Tuples in binary format */
|
case 'B': /* Tuples in binary format */
|
||||||
case 'D': /* Tuples in ASCII format */
|
case 'D': /* Tuples in ASCII format */
|
||||||
|
|
||||||
if ( ! globals.use_declarefetch && self->fcount > 0 && ! (self->fcount % TUPLE_MALLOC_INC)) {
|
if (!globals.use_declarefetch && self->fcount > 0 && !(self->fcount % TUPLE_MALLOC_INC))
|
||||||
|
{
|
||||||
size_t old_size = self->fcount * self->num_fields * sizeof(TupleField);
|
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));
|
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC));
|
||||||
if ( ! self->backend_tuples) {
|
if (!self->backend_tuples)
|
||||||
|
{
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
QR_set_message(self, "Out of memory while reading tuples.");
|
QR_set_message(self, "Out of memory while reading tuples.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! QR_read_tuple(self, (char) (id == 0))) {
|
if (!QR_read_tuple(self, (char) (id == 0)))
|
||||||
|
{
|
||||||
self->status = PGRES_BAD_RESPONSE;
|
self->status = PGRES_BAD_RESPONSE;
|
||||||
QR_set_message(self, "Error reading the tuple");
|
QR_set_message(self, "Error reading the tuple");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -488,7 +531,8 @@ QueryInfo qi;
|
|||||||
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
|
mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
|
||||||
|
|
||||||
self->inTuples = FALSE;
|
self->inTuples = FALSE;
|
||||||
if (self->fcount > 0) {
|
if (self->fcount > 0)
|
||||||
|
{
|
||||||
|
|
||||||
qlog(" [ fetched %d rows ]\n", self->fcount);
|
qlog(" [ fetched %d rows ]\n", self->fcount);
|
||||||
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
|
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
|
||||||
@ -497,7 +541,9 @@ QueryInfo qi;
|
|||||||
self->tupleField = self->backend_tuples + (offset * self->num_fields);
|
self->tupleField = self->backend_tuples + (offset * self->num_fields);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else { /* We are surely done here (we read 0 tuples) */
|
else
|
||||||
|
{ /* We are surely done here (we read 0
|
||||||
|
* tuples) */
|
||||||
qlog(" [ fetched 0 rows ]\n");
|
qlog(" [ fetched 0 rows ]\n");
|
||||||
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
|
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
|
||||||
return -1; /* end of tuples */
|
return -1; /* end of tuples */
|
||||||
@ -508,7 +554,7 @@ QueryInfo qi;
|
|||||||
QR_set_message(self, msgbuffer);
|
QR_set_message(self, msgbuffer);
|
||||||
self->status = PGRES_FATAL_ERROR;
|
self->status = PGRES_FATAL_ERROR;
|
||||||
|
|
||||||
if ( ! strncmp(msgbuffer, "FATAL", 5))
|
if (!strncmp(msgbuffer, "FATAL", 5))
|
||||||
CC_set_no_trans(self->conn);
|
CC_set_no_trans(self->conn);
|
||||||
|
|
||||||
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
|
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
|
||||||
@ -522,7 +568,8 @@ QueryInfo qi;
|
|||||||
qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
|
qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default: /* this should only happen if the backend dumped core */
|
default: /* this should only happen if the backend
|
||||||
|
* dumped core */
|
||||||
mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
|
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);
|
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");
|
QR_set_message(self, "Unexpected result from backend. It probably crashed");
|
||||||
@ -535,19 +582,20 @@ QueryInfo qi;
|
|||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
QR_read_tuple(QResultClass *self, char binary)
|
QR_read_tuple(QResultClass * self, char binary)
|
||||||
{
|
{
|
||||||
Int2 field_lf;
|
Int2 field_lf;
|
||||||
TupleField *this_tuplefield;
|
TupleField *this_tuplefield;
|
||||||
char bmp, bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
|
char bmp,
|
||||||
Int2 bitmaplen; /* len of the bitmap in bytes */
|
bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
|
||||||
Int2 bitmap_pos;
|
Int2 bitmaplen; /* len of the bitmap in bytes */
|
||||||
Int2 bitcnt;
|
Int2 bitmap_pos;
|
||||||
Int4 len;
|
Int2 bitcnt;
|
||||||
char *buffer;
|
Int4 len;
|
||||||
int num_fields = self->num_fields; /* speed up access */
|
char *buffer;
|
||||||
SocketClass *sock = CC_get_socket(self->conn);
|
int num_fields = self->num_fields; /* speed up access */
|
||||||
ColumnInfoClass *flds;
|
SocketClass *sock = CC_get_socket(self->conn);
|
||||||
|
ColumnInfoClass *flds;
|
||||||
|
|
||||||
|
|
||||||
/* set the current row to read the fields into */
|
/* set the current row to read the fields into */
|
||||||
@ -558,8 +606,8 @@ ColumnInfoClass *flds;
|
|||||||
bitmaplen++;
|
bitmaplen++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At first the server sends a bitmap that indicates which
|
* At first the server sends a bitmap that indicates which database
|
||||||
database fields are null
|
* fields are null
|
||||||
*/
|
*/
|
||||||
SOCK_get_n_char(sock, bitmap, bitmaplen);
|
SOCK_get_n_char(sock, bitmap, bitmaplen);
|
||||||
|
|
||||||
@ -567,22 +615,27 @@ ColumnInfoClass *flds;
|
|||||||
bitcnt = 0;
|
bitcnt = 0;
|
||||||
bmp = bitmap[bitmap_pos];
|
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 */
|
/* Check if the current field is NULL */
|
||||||
if(!(bmp & 0200)) {
|
if (!(bmp & 0200))
|
||||||
|
{
|
||||||
/* YES, it is NULL ! */
|
/* YES, it is NULL ! */
|
||||||
this_tuplefield[field_lf].len = 0;
|
this_tuplefield[field_lf].len = 0;
|
||||||
this_tuplefield[field_lf].value = 0;
|
this_tuplefield[field_lf].value = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NO, the field is not null. so get at first the
|
* NO, the field is not null. so get at first the length of
|
||||||
length of the field (four bytes)
|
* the field (four bytes)
|
||||||
*/
|
*/
|
||||||
len = SOCK_get_int(sock, VARHDRSZ);
|
len = SOCK_get_int(sock, VARHDRSZ);
|
||||||
if (!binary)
|
if (!binary)
|
||||||
len -= VARHDRSZ;
|
len -= VARHDRSZ;
|
||||||
|
|
||||||
buffer = (char *)malloc(len+1);
|
buffer = (char *) malloc(len + 1);
|
||||||
SOCK_get_n_char(sock, buffer, len);
|
SOCK_get_n_char(sock, buffer, len);
|
||||||
buffer[len] = '\0';
|
buffer[len] = '\0';
|
||||||
|
|
||||||
@ -591,27 +644,31 @@ ColumnInfoClass *flds;
|
|||||||
this_tuplefield[field_lf].len = len;
|
this_tuplefield[field_lf].len = len;
|
||||||
this_tuplefield[field_lf].value = buffer;
|
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
|
* This can be used to set the longest length of the column
|
||||||
text fields to use this since a tuple cache is only 100 rows.
|
* for any row in the tuple cache. It would not be accurate
|
||||||
Bpchar can be handled since the strlen of all rows is fixed,
|
* for varchar and text fields to use this since a tuple cache
|
||||||
assuming there are not 100 nulls in a row!
|
* 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;
|
flds = self->fields;
|
||||||
if (flds->display_size[field_lf] < len)
|
if (flds->display_size[field_lf] < len)
|
||||||
flds->display_size[field_lf] = len;
|
flds->display_size[field_lf] = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Now adjust for the next bit to be scanned in the
|
* Now adjust for the next bit to be scanned in the next loop.
|
||||||
next loop.
|
|
||||||
*/
|
*/
|
||||||
bitcnt++;
|
bitcnt++;
|
||||||
if (BYTELEN == bitcnt) {
|
if (BYTELEN == bitcnt)
|
||||||
|
{
|
||||||
bitmap_pos++;
|
bitmap_pos++;
|
||||||
bmp = bitmap[bitmap_pos];
|
bmp = bitmap[bitmap_pos];
|
||||||
bitcnt = 0;
|
bitcnt = 0;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
bmp <<= 1;
|
bmp <<= 1;
|
||||||
}
|
}
|
||||||
self->currTuple++;
|
self->currTuple++;
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
#include "psqlodbc.h"
|
#include "psqlodbc.h"
|
||||||
#include "tuple.h"
|
#include "tuple.h"
|
||||||
|
|
||||||
enum QueryResultCode_ {
|
enum QueryResultCode_
|
||||||
|
{
|
||||||
PGRES_EMPTY_QUERY = 0,
|
PGRES_EMPTY_QUERY = 0,
|
||||||
PGRES_COMMAND_OK, /* a query command that doesn't return */
|
PGRES_COMMAND_OK, /* a query command that doesn't return */
|
||||||
/* anything was executed properly by the backend */
|
/* anything was executed properly by the backend */
|
||||||
@ -26,20 +27,24 @@ enum QueryResultCode_ {
|
|||||||
/* contains the resulttuples */
|
/* contains the resulttuples */
|
||||||
PGRES_COPY_OUT,
|
PGRES_COPY_OUT,
|
||||||
PGRES_COPY_IN,
|
PGRES_COPY_IN,
|
||||||
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the backend */
|
PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from
|
||||||
|
* the backend */
|
||||||
PGRES_NONFATAL_ERROR,
|
PGRES_NONFATAL_ERROR,
|
||||||
PGRES_FATAL_ERROR,
|
PGRES_FATAL_ERROR,
|
||||||
PGRES_FIELDS_OK, /* field information from a query was successful */
|
PGRES_FIELDS_OK, /* field information from a query was
|
||||||
|
* successful */
|
||||||
PGRES_END_TUPLES,
|
PGRES_END_TUPLES,
|
||||||
PGRES_INTERNAL_ERROR
|
PGRES_INTERNAL_ERROR
|
||||||
};
|
};
|
||||||
typedef enum QueryResultCode_ QueryResultCode;
|
typedef enum QueryResultCode_ QueryResultCode;
|
||||||
|
|
||||||
|
|
||||||
struct QResultClass_ {
|
struct QResultClass_
|
||||||
|
{
|
||||||
ColumnInfoClass *fields; /* the Column information */
|
ColumnInfoClass *fields; /* the Column information */
|
||||||
TupleListClass *manual_tuples; /* manual result tuple list */
|
TupleListClass *manual_tuples; /* manual result tuple list */
|
||||||
ConnectionClass *conn; /* the connection this result is using (backend) */
|
ConnectionClass *conn; /* the connection this result is using
|
||||||
|
* (backend) */
|
||||||
|
|
||||||
/* Stuff for declare/fetch tuples */
|
/* Stuff for declare/fetch tuples */
|
||||||
int fetch_count; /* logical rows read so far */
|
int fetch_count; /* logical rows read so far */
|
||||||
@ -54,14 +59,16 @@ struct QResultClass_ {
|
|||||||
QueryResultCode status;
|
QueryResultCode status;
|
||||||
|
|
||||||
char *message;
|
char *message;
|
||||||
char *cursor; /* The name of the cursor for select statements */
|
char *cursor; /* The name of the cursor for select
|
||||||
|
* statements */
|
||||||
char *command;
|
char *command;
|
||||||
char *notice;
|
char *notice;
|
||||||
|
|
||||||
TupleField *backend_tuples; /* data from the backend (the tuple cache) */
|
TupleField *backend_tuples; /* data from the backend (the tuple cache) */
|
||||||
TupleField *tupleField; /* current backend tuple being retrieved */
|
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)
|
#define QR_get_fields(self) (self->fields)
|
||||||
@ -99,20 +106,20 @@ struct QResultClass_ {
|
|||||||
|
|
||||||
/* Core Functions */
|
/* Core Functions */
|
||||||
QResultClass *QR_Constructor(void);
|
QResultClass *QR_Constructor(void);
|
||||||
void QR_Destructor(QResultClass *self);
|
void QR_Destructor(QResultClass * self);
|
||||||
char QR_read_tuple(QResultClass *self, char binary);
|
char QR_read_tuple(QResultClass * self, char binary);
|
||||||
int QR_next_tuple(QResultClass *self);
|
int QR_next_tuple(QResultClass * self);
|
||||||
int QR_close(QResultClass *self);
|
int QR_close(QResultClass * self);
|
||||||
char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor);
|
char QR_fetch_tuples(QResultClass * self, ConnectionClass * conn, char *cursor);
|
||||||
void QR_free_memory(QResultClass *self);
|
void QR_free_memory(QResultClass * self);
|
||||||
void QR_set_command(QResultClass *self, char *msg);
|
void QR_set_command(QResultClass * self, char *msg);
|
||||||
void QR_set_notice(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_set_num_fields(QResultClass * self, int new_num_fields); /* manual result only */
|
||||||
|
|
||||||
void QR_inc_base(QResultClass *self, int base_inc);
|
void QR_inc_base(QResultClass * self, int base_inc);
|
||||||
void QR_set_cache_size(QResultClass *self, int cache_size);
|
void QR_set_cache_size(QResultClass * self, int cache_size);
|
||||||
void QR_set_rowset_size(QResultClass *self, int rowset_size);
|
void QR_set_rowset_size(QResultClass * self, int rowset_size);
|
||||||
void QR_set_position(QResultClass *self, int pos);
|
void QR_set_position(QResultClass * self, int pos);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#define INTFUNC __stdcall
|
#define INTFUNC __stdcall
|
||||||
|
|
||||||
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
|
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
|
||||||
extern GLOBAL_VALUES globals;
|
extern GLOBAL_VALUES globals;
|
||||||
|
|
||||||
/* Constants --------------------------------------------------------------- */
|
/* Constants --------------------------------------------------------------- */
|
||||||
@ -42,7 +42,8 @@ extern GLOBAL_VALUES globals;
|
|||||||
|
|
||||||
/* Globals ----------------------------------------------------------------- */
|
/* Globals ----------------------------------------------------------------- */
|
||||||
/* NOTE: All these are used by the dialog procedures */
|
/* NOTE: All these are used by the dialog procedures */
|
||||||
typedef struct tagSETUPDLG {
|
typedef struct tagSETUPDLG
|
||||||
|
{
|
||||||
HWND hwndParent; /* Parent window handle */
|
HWND hwndParent; /* Parent window handle */
|
||||||
LPCSTR lpszDrvr; /* Driver description */
|
LPCSTR lpszDrvr; /* Driver description */
|
||||||
ConnInfo ci;
|
ConnInfo ci;
|
||||||
@ -50,14 +51,14 @@ typedef struct tagSETUPDLG {
|
|||||||
BOOL fNewDSN; /* New data source flag */
|
BOOL fNewDSN; /* New data source flag */
|
||||||
BOOL fDefault; /* Default data source flag */
|
BOOL fDefault; /* Default data source flag */
|
||||||
|
|
||||||
} SETUPDLG, FAR *LPSETUPDLG;
|
} SETUPDLG, FAR * LPSETUPDLG;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes -------------------------------------------------------------- */
|
/* Prototypes -------------------------------------------------------------- */
|
||||||
void INTFUNC CenterDialog(HWND hdlg);
|
void INTFUNC CenterDialog(HWND hdlg);
|
||||||
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
|
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
|
||||||
void INTFUNC ParseAttributes (LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
|
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
|
||||||
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
|
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
|
||||||
|
|
||||||
|
|
||||||
@ -72,21 +73,22 @@ BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
|
|||||||
Output : TRUE success, FALSE otherwise
|
Output : TRUE success, FALSE otherwise
|
||||||
--------------------------------------------------------------------------*/
|
--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
BOOL CALLBACK ConfigDSN (HWND hwnd,
|
BOOL CALLBACK
|
||||||
|
ConfigDSN(HWND hwnd,
|
||||||
WORD fRequest,
|
WORD fRequest,
|
||||||
LPCSTR lpszDriver,
|
LPCSTR lpszDriver,
|
||||||
LPCSTR lpszAttributes)
|
LPCSTR lpszAttributes)
|
||||||
{
|
{
|
||||||
BOOL fSuccess; /* Success/fail flag */
|
BOOL fSuccess; /* Success/fail flag */
|
||||||
GLOBALHANDLE hglbAttr;
|
GLOBALHANDLE hglbAttr;
|
||||||
LPSETUPDLG lpsetupdlg;
|
LPSETUPDLG lpsetupdlg;
|
||||||
|
|
||||||
|
|
||||||
/* Allocate attribute array */
|
/* Allocate attribute array */
|
||||||
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
|
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
|
||||||
if (!hglbAttr)
|
if (!hglbAttr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
lpsetupdlg = (LPSETUPDLG)GlobalLock(hglbAttr);
|
lpsetupdlg = (LPSETUPDLG) GlobalLock(hglbAttr);
|
||||||
|
|
||||||
/* Parse attribute string */
|
/* Parse attribute string */
|
||||||
if (lpszAttributes)
|
if (lpszAttributes)
|
||||||
@ -99,7 +101,8 @@ LPSETUPDLG lpsetupdlg;
|
|||||||
lpsetupdlg->szDSN[0] = '\0';
|
lpsetupdlg->szDSN[0] = '\0';
|
||||||
|
|
||||||
/* Remove data source */
|
/* Remove data source */
|
||||||
if (ODBC_REMOVE_DSN == fRequest) {
|
if (ODBC_REMOVE_DSN == fRequest)
|
||||||
|
{
|
||||||
/* Fail if no data source name was supplied */
|
/* Fail if no data source name was supplied */
|
||||||
if (!lpsetupdlg->ci.dsn[0])
|
if (!lpsetupdlg->ci.dsn[0])
|
||||||
fSuccess = FALSE;
|
fSuccess = FALSE;
|
||||||
@ -110,21 +113,26 @@ LPSETUPDLG lpsetupdlg;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add or Configure data source */
|
/* Add or Configure data source */
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* Save passed variables for global access (e.g., dialog access) */
|
/* Save passed variables for global access (e.g., dialog access) */
|
||||||
lpsetupdlg->hwndParent = hwnd;
|
lpsetupdlg->hwndParent = hwnd;
|
||||||
lpsetupdlg->lpszDrvr = lpszDriver;
|
lpsetupdlg->lpszDrvr = lpszDriver;
|
||||||
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
|
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
|
||||||
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
|
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
|
||||||
|
|
||||||
/* Display the appropriate dialog (if parent window handle supplied) */
|
/*
|
||||||
if (hwnd) {
|
* Display the appropriate dialog (if parent window handle
|
||||||
|
* supplied)
|
||||||
|
*/
|
||||||
|
if (hwnd)
|
||||||
|
{
|
||||||
/* Display dialog(s) */
|
/* Display dialog(s) */
|
||||||
fSuccess = (IDOK == DialogBoxParam(s_hModule,
|
fSuccess = (IDOK == DialogBoxParam(s_hModule,
|
||||||
MAKEINTRESOURCE(DLG_CONFIG),
|
MAKEINTRESOURCE(DLG_CONFIG),
|
||||||
hwnd,
|
hwnd,
|
||||||
ConfigDlgProc,
|
ConfigDlgProc,
|
||||||
(LONG)(LPSTR)lpsetupdlg));
|
(LONG) (LPSTR) lpsetupdlg));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (lpsetupdlg->ci.dsn[0])
|
else if (lpsetupdlg->ci.dsn[0])
|
||||||
@ -145,11 +153,15 @@ LPSETUPDLG lpsetupdlg;
|
|||||||
Input : hdlg -- Dialog window handle
|
Input : hdlg -- Dialog window handle
|
||||||
Output : None
|
Output : None
|
||||||
--------------------------------------------------------------------------*/
|
--------------------------------------------------------------------------*/
|
||||||
void INTFUNC CenterDialog(HWND hdlg)
|
void INTFUNC
|
||||||
|
CenterDialog(HWND hdlg)
|
||||||
{
|
{
|
||||||
HWND hwndFrame;
|
HWND hwndFrame;
|
||||||
RECT rcDlg, rcScr, rcFrame;
|
RECT rcDlg,
|
||||||
int cx, cy;
|
rcScr,
|
||||||
|
rcFrame;
|
||||||
|
int cx,
|
||||||
|
cy;
|
||||||
|
|
||||||
hwndFrame = GetParent(hdlg);
|
hwndFrame = GetParent(hdlg);
|
||||||
|
|
||||||
@ -158,8 +170,8 @@ void INTFUNC CenterDialog(HWND hdlg)
|
|||||||
cy = rcDlg.bottom - rcDlg.top;
|
cy = rcDlg.bottom - rcDlg.top;
|
||||||
|
|
||||||
GetClientRect(hwndFrame, &rcFrame);
|
GetClientRect(hwndFrame, &rcFrame);
|
||||||
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.left));
|
ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.left));
|
||||||
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.right));
|
ClientToScreen(hwndFrame, (LPPOINT) (&rcFrame.right));
|
||||||
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
|
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
|
||||||
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
|
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
|
||||||
rcDlg.bottom = rcDlg.top + cy;
|
rcDlg.bottom = rcDlg.top + cy;
|
||||||
@ -177,8 +189,10 @@ void INTFUNC CenterDialog(HWND hdlg)
|
|||||||
rcDlg.left = rcDlg.right - cx;
|
rcDlg.left = rcDlg.right - cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcDlg.left < 0) rcDlg.left = 0;
|
if (rcDlg.left < 0)
|
||||||
if (rcDlg.top < 0) rcDlg.top = 0;
|
rcDlg.left = 0;
|
||||||
|
if (rcDlg.top < 0)
|
||||||
|
rcDlg.top = 0;
|
||||||
|
|
||||||
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
|
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
|
||||||
return;
|
return;
|
||||||
@ -194,13 +208,15 @@ void INTFUNC CenterDialog(HWND hdlg)
|
|||||||
--------------------------------------------------------------------------*/
|
--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
int CALLBACK ConfigDlgProc(HWND hdlg,
|
int CALLBACK
|
||||||
|
ConfigDlgProc(HWND hdlg,
|
||||||
WORD wMsg,
|
WORD wMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (wMsg) {
|
switch (wMsg)
|
||||||
|
{
|
||||||
/* Initialize the dialog */
|
/* Initialize the dialog */
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
{
|
{
|
||||||
@ -213,7 +229,10 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
|||||||
SetWindowLong(hdlg, DWL_USER, lParam);
|
SetWindowLong(hdlg, DWL_USER, lParam);
|
||||||
CenterDialog(hdlg); /* Center dialog */
|
CenterDialog(hdlg); /* Center dialog */
|
||||||
|
|
||||||
/* NOTE: Values supplied in the attribute string will always */
|
/*
|
||||||
|
* NOTE: Values supplied in the attribute string will
|
||||||
|
* always
|
||||||
|
*/
|
||||||
/* override settings in ODBC.INI */
|
/* override settings in ODBC.INI */
|
||||||
|
|
||||||
/* Get the rest of the common attributes */
|
/* Get the rest of the common attributes */
|
||||||
@ -227,16 +246,17 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
|||||||
SetDlgStuff(hdlg, ci);
|
SetDlgStuff(hdlg, ci);
|
||||||
|
|
||||||
|
|
||||||
if (lpsetupdlg->fDefault) {
|
if (lpsetupdlg->fDefault)
|
||||||
|
{
|
||||||
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
|
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
|
||||||
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
|
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SendDlgItemMessage(hdlg, IDC_DSNAME,
|
SendDlgItemMessage(hdlg, IDC_DSNAME,
|
||||||
EM_LIMITTEXT, (WPARAM)(MAXDSNAME-1), 0L);
|
EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
|
||||||
|
|
||||||
SendDlgItemMessage(hdlg, IDC_DESC,
|
SendDlgItemMessage(hdlg, IDC_DESC,
|
||||||
EM_LIMITTEXT, (WPARAM)(MAXDESC-1), 0L);
|
EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
|
||||||
return TRUE; /* Focus was not set */
|
return TRUE; /* Focus was not set */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,8 +264,13 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
|||||||
/* Process buttons */
|
/* Process buttons */
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
|
|
||||||
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
/* Ensure the OK button is enabled only when a data source name */
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure the OK button is enabled only when a data
|
||||||
|
* source name
|
||||||
|
*/
|
||||||
/* is entered */
|
/* is entered */
|
||||||
case IDC_DSNAME:
|
case IDC_DSNAME:
|
||||||
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
|
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
|
||||||
@ -266,7 +291,7 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
|||||||
{
|
{
|
||||||
LPSETUPDLG lpsetupdlg;
|
LPSETUPDLG lpsetupdlg;
|
||||||
|
|
||||||
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
|
lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
|
||||||
/* Retrieve dialog values */
|
/* Retrieve dialog values */
|
||||||
if (!lpsetupdlg->fDefault)
|
if (!lpsetupdlg->fDefault)
|
||||||
GetDlgItemText(hdlg, IDC_DSNAME,
|
GetDlgItemText(hdlg, IDC_DSNAME,
|
||||||
@ -297,10 +322,10 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
|||||||
{
|
{
|
||||||
LPSETUPDLG lpsetupdlg;
|
LPSETUPDLG lpsetupdlg;
|
||||||
|
|
||||||
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
|
lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
|
||||||
|
|
||||||
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
|
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
|
||||||
hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
|
hdlg, ds_optionsProc, (LPARAM) & lpsetupdlg->ci);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -319,18 +344,20 @@ int CALLBACK ConfigDlgProc(HWND hdlg,
|
|||||||
Input : lpszAttributes - Pointer to attribute string
|
Input : lpszAttributes - Pointer to attribute string
|
||||||
Output : None (global aAttr normally updated)
|
Output : None (global aAttr normally updated)
|
||||||
--------------------------------------------------------------------------*/
|
--------------------------------------------------------------------------*/
|
||||||
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
|
void INTFUNC
|
||||||
|
ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
|
||||||
{
|
{
|
||||||
LPCSTR lpsz;
|
LPCSTR lpsz;
|
||||||
LPCSTR lpszStart;
|
LPCSTR lpszStart;
|
||||||
char aszKey[MAXKEYLEN];
|
char aszKey[MAXKEYLEN];
|
||||||
int cbKey;
|
int cbKey;
|
||||||
char value[MAXPGPATH];
|
char value[MAXPGPATH];
|
||||||
|
|
||||||
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
|
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
|
||||||
|
|
||||||
for (lpsz=lpszAttributes; *lpsz; lpsz++)
|
for (lpsz = lpszAttributes; *lpsz; lpsz++)
|
||||||
{ /* Extract key name (e.g., DSN), it must be terminated by an equals */
|
{ /* Extract key name (e.g., DSN), it must
|
||||||
|
* be terminated by an equals */
|
||||||
lpszStart = lpsz;
|
lpszStart = lpsz;
|
||||||
for (;; lpsz++)
|
for (;; lpsz++)
|
||||||
{
|
{
|
||||||
@ -354,7 +381,7 @@ char value[MAXPGPATH];
|
|||||||
|
|
||||||
|
|
||||||
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
|
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
|
||||||
_fmemcpy(value, lpszStart, MIN(lpsz-lpszStart+1, MAXPGPATH));
|
_fmemcpy(value, lpszStart, MIN(lpsz - lpszStart + 1, MAXPGPATH));
|
||||||
|
|
||||||
mylog("aszKey='%s', value='%s'\n", aszKey, value);
|
mylog("aszKey='%s', value='%s'\n", aszKey, value);
|
||||||
|
|
||||||
@ -371,9 +398,10 @@ char value[MAXPGPATH];
|
|||||||
Output : TRUE if successful, FALSE otherwise
|
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;
|
||||||
|
|
||||||
@ -404,8 +432,6 @@ LPCSTR lpszDSN; /* Pointer to da
|
|||||||
|
|
||||||
/* If the data source name has changed, remove the old name */
|
/* If the data source name has changed, remove the old name */
|
||||||
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
|
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
|
||||||
{
|
|
||||||
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
|
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ extern GLOBAL_VALUES globals;
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_clear_error(SocketClass *self)
|
SOCK_clear_error(SocketClass * self)
|
||||||
{
|
{
|
||||||
self->errornumber = 0;
|
self->errornumber = 0;
|
||||||
self->errormsg = NULL;
|
self->errormsg = NULL;
|
||||||
@ -45,22 +45,23 @@ SOCK_clear_error(SocketClass *self)
|
|||||||
SocketClass *
|
SocketClass *
|
||||||
SOCK_Constructor()
|
SOCK_Constructor()
|
||||||
{
|
{
|
||||||
SocketClass *rv;
|
SocketClass *rv;
|
||||||
|
|
||||||
rv = (SocketClass *) malloc(sizeof(SocketClass));
|
rv = (SocketClass *) malloc(sizeof(SocketClass));
|
||||||
|
|
||||||
if (rv != NULL) {
|
if (rv != NULL)
|
||||||
rv->socket = (SOCKETFD) -1;
|
{
|
||||||
|
rv->socket = (SOCKETFD) - 1;
|
||||||
rv->buffer_filled_in = 0;
|
rv->buffer_filled_in = 0;
|
||||||
rv->buffer_filled_out = 0;
|
rv->buffer_filled_out = 0;
|
||||||
rv->buffer_read_in = 0;
|
rv->buffer_read_in = 0;
|
||||||
|
|
||||||
rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize);
|
rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize);
|
||||||
if ( ! rv->buffer_in)
|
if (!rv->buffer_in)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize);
|
rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize);
|
||||||
if ( ! rv->buffer_out)
|
if (!rv->buffer_out)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rv->errormsg = NULL;
|
rv->errormsg = NULL;
|
||||||
@ -73,10 +74,11 @@ SocketClass *rv;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_Destructor(SocketClass *self)
|
SOCK_Destructor(SocketClass * self)
|
||||||
{
|
{
|
||||||
if (self->socket != -1) {
|
if (self->socket != -1)
|
||||||
if ( ! shutdown(self->socket, 2)) /* no sends or receives */
|
{
|
||||||
|
if (!shutdown(self->socket, 2)) /* no sends or receives */
|
||||||
{
|
{
|
||||||
SOCK_put_char(self, 'X');
|
SOCK_put_char(self, 'X');
|
||||||
SOCK_flush_output(self);
|
SOCK_flush_output(self);
|
||||||
@ -96,27 +98,30 @@ SOCK_Destructor(SocketClass *self)
|
|||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
|
SOCK_connect_to(SocketClass * self, unsigned short port, char *hostname)
|
||||||
{
|
{
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
struct sockaddr_in sadr;
|
struct sockaddr_in sadr;
|
||||||
unsigned long iaddr;
|
unsigned long iaddr;
|
||||||
|
|
||||||
if (self->socket != -1) {
|
if (self->socket != -1)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_ALREADY_CONNECTED;
|
self->errornumber = SOCKET_ALREADY_CONNECTED;
|
||||||
self->errormsg = "Socket is already connected";
|
self->errormsg = "Socket is already connected";
|
||||||
return 0;
|
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);
|
iaddr = inet_addr(hostname);
|
||||||
if (iaddr == INADDR_NONE) {
|
if (iaddr == INADDR_NONE)
|
||||||
|
{
|
||||||
host = gethostbyname(hostname);
|
host = gethostbyname(hostname);
|
||||||
if (host == NULL) {
|
if (host == NULL)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_HOST_NOT_FOUND;
|
self->errornumber = SOCKET_HOST_NOT_FOUND;
|
||||||
self->errormsg = "Could not resolve hostname.";
|
self->errormsg = "Could not resolve hostname.";
|
||||||
return 0;
|
return 0;
|
||||||
@ -124,25 +129,27 @@ unsigned long iaddr;
|
|||||||
memcpy(&(sadr.sin_addr), host->h_addr, host->h_length);
|
memcpy(&(sadr.sin_addr), host->h_addr, host->h_length);
|
||||||
}
|
}
|
||||||
else
|
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_family = AF_INET;
|
||||||
sadr.sin_port = htons(port);
|
sadr.sin_port = htons(port);
|
||||||
|
|
||||||
self->socket = socket(AF_INET, SOCK_STREAM, 0);
|
self->socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (self->socket == -1) {
|
if (self->socket == -1)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET;
|
self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET;
|
||||||
self->errormsg = "Could not create Socket.";
|
self->errormsg = "Could not create Socket.";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( connect(self->socket, (struct sockaddr *)&(sadr),
|
if (connect(self->socket, (struct sockaddr *) & (sadr),
|
||||||
sizeof(sadr)) < 0) {
|
sizeof(sadr)) < 0)
|
||||||
|
{
|
||||||
|
|
||||||
self->errornumber = SOCKET_COULD_NOT_CONNECT;
|
self->errornumber = SOCKET_COULD_NOT_CONNECT;
|
||||||
self->errormsg = "Could not connect to remote socket.";
|
self->errormsg = "Could not connect to remote socket.";
|
||||||
closesocket(self->socket);
|
closesocket(self->socket);
|
||||||
self->socket = (SOCKETFD) -1;
|
self->socket = (SOCKETFD) - 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -150,34 +157,36 @@ unsigned long iaddr;
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_get_n_char(SocketClass *self, char *buffer, int len)
|
SOCK_get_n_char(SocketClass * self, char *buffer, int len)
|
||||||
{
|
{
|
||||||
int lf;
|
int lf;
|
||||||
|
|
||||||
if ( ! buffer) {
|
if (!buffer)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
|
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
|
||||||
self->errormsg = "get_n_char was called with NULL-Pointer";
|
self->errormsg = "get_n_char was called with NULL-Pointer";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(lf=0; lf < len; lf++)
|
for (lf = 0; lf < len; lf++)
|
||||||
buffer[lf] = SOCK_get_next_byte(self);
|
buffer[lf] = SOCK_get_next_byte(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_put_n_char(SocketClass *self, char *buffer, int len)
|
SOCK_put_n_char(SocketClass * self, char *buffer, int len)
|
||||||
{
|
{
|
||||||
int lf;
|
int lf;
|
||||||
|
|
||||||
if ( ! buffer) {
|
if (!buffer)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
|
self->errornumber = SOCKET_NULLPOINTER_PARAMETER;
|
||||||
self->errormsg = "put_n_char was called with NULL-Pointer";
|
self->errormsg = "put_n_char was called with NULL-Pointer";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(lf=0; lf < len; lf++)
|
for (lf = 0; lf < len; lf++)
|
||||||
SOCK_put_next_byte(self, (unsigned char)buffer[lf]);
|
SOCK_put_next_byte(self, (unsigned char) buffer[lf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,50 +194,51 @@ int lf;
|
|||||||
will read at most bufsize-1 characters + null.
|
will read at most bufsize-1 characters + null.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
|
SOCK_get_string(SocketClass * self, char *buffer, int bufsize)
|
||||||
{
|
{
|
||||||
register int lf = 0;
|
register int lf = 0;
|
||||||
|
|
||||||
for (lf = 0; lf < bufsize; lf++)
|
for (lf = 0; lf < bufsize; lf++)
|
||||||
if ( ! (buffer[lf] = SOCK_get_next_byte(self)))
|
if (!(buffer[lf] = SOCK_get_next_byte(self)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
buffer[bufsize-1] = '\0';
|
buffer[bufsize - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_put_string(SocketClass *self, char *string)
|
SOCK_put_string(SocketClass * self, char *string)
|
||||||
{
|
{
|
||||||
register int lf;
|
register int lf;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = strlen(string)+1;
|
len = strlen(string) + 1;
|
||||||
|
|
||||||
for(lf = 0; lf < len; lf++)
|
for (lf = 0; lf < len; lf++)
|
||||||
SOCK_put_next_byte(self, (unsigned char)string[lf]);
|
SOCK_put_next_byte(self, (unsigned char) string[lf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SOCK_get_int(SocketClass *self, short len)
|
SOCK_get_int(SocketClass * self, short len)
|
||||||
{
|
{
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
|
||||||
switch (len) {
|
switch (len)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
SOCK_get_n_char(self, buf, len);
|
SOCK_get_n_char(self, buf, len);
|
||||||
if (self->reverse)
|
if (self->reverse)
|
||||||
return *((unsigned short *) buf);
|
return *((unsigned short *) buf);
|
||||||
else
|
else
|
||||||
return ntohs( *((unsigned short *) buf) );
|
return ntohs(*((unsigned short *) buf));
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
SOCK_get_n_char(self, buf, len);
|
SOCK_get_n_char(self, buf, len);
|
||||||
if (self->reverse)
|
if (self->reverse)
|
||||||
return *((unsigned int *) buf);
|
return *((unsigned int *) buf);
|
||||||
else
|
else
|
||||||
return ntohl( *((unsigned int *) buf) );
|
return ntohl(*((unsigned int *) buf));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
|
self->errornumber = SOCKET_GET_INT_WRONG_LENGTH;
|
||||||
@ -239,18 +249,19 @@ char buf[4];
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_put_int(SocketClass *self, int value, short len)
|
SOCK_put_int(SocketClass * self, int value, short len)
|
||||||
{
|
{
|
||||||
unsigned int rv;
|
unsigned int rv;
|
||||||
|
|
||||||
switch (len) {
|
switch (len)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
rv = self->reverse ? value : htons( (unsigned short) value);
|
rv = self->reverse ? value : htons((unsigned short) value);
|
||||||
SOCK_put_n_char(self, (char *) &rv, 2);
|
SOCK_put_n_char(self, (char *) &rv, 2);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
rv = self->reverse ? value : htonl( (unsigned int) value);
|
rv = self->reverse ? value : htonl((unsigned int) value);
|
||||||
SOCK_put_n_char(self, (char *) &rv, 4);
|
SOCK_put_n_char(self, (char *) &rv, 4);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -263,12 +274,13 @@ unsigned int rv;
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_flush_output(SocketClass *self)
|
SOCK_flush_output(SocketClass * self)
|
||||||
{
|
{
|
||||||
int written;
|
int written;
|
||||||
|
|
||||||
written = send(self->socket, (char *)self->buffer_out, self->buffer_filled_out, 0);
|
written = send(self->socket, (char *) self->buffer_out, self->buffer_filled_out, 0);
|
||||||
if (written != self->buffer_filled_out) {
|
if (written != self->buffer_filled_out)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_WRITE_ERROR;
|
self->errornumber = SOCKET_WRITE_ERROR;
|
||||||
self->errormsg = "Could not flush socket buffer.";
|
self->errormsg = "Could not flush socket buffer.";
|
||||||
}
|
}
|
||||||
@ -276,24 +288,27 @@ int written;
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
SOCK_get_next_byte(SocketClass *self)
|
SOCK_get_next_byte(SocketClass * self)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (self->buffer_read_in >= self->buffer_filled_in) {
|
if (self->buffer_read_in >= self->buffer_filled_in)
|
||||||
|
{
|
||||||
/* there are no more bytes left in the buffer -> */
|
/* there are no more bytes left in the buffer -> */
|
||||||
/* reload the buffer */
|
/* reload the buffer */
|
||||||
|
|
||||||
self->buffer_read_in = 0;
|
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 == -1) {
|
if (self->buffer_filled_in == -1)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_READ_ERROR;
|
self->errornumber = SOCKET_READ_ERROR;
|
||||||
self->errormsg = "Error while reading from the socket.";
|
self->errormsg = "Error while reading from the socket.";
|
||||||
self->buffer_filled_in = 0;
|
self->buffer_filled_in = 0;
|
||||||
}
|
}
|
||||||
if (self->buffer_filled_in == 0) {
|
if (self->buffer_filled_in == 0)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_CLOSED;
|
self->errornumber = SOCKET_CLOSED;
|
||||||
self->errormsg = "Socket has been closed.";
|
self->errormsg = "Socket has been closed.";
|
||||||
self->buffer_filled_in = 0;
|
self->buffer_filled_in = 0;
|
||||||
@ -304,16 +319,18 @@ SOCK_get_next_byte(SocketClass *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SOCK_put_next_byte(SocketClass *self, unsigned char next_byte)
|
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;
|
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 */
|
/* buffer is full, so write it out */
|
||||||
bytes_sent = send(self->socket, (char *)self->buffer_out, globals.socket_buffersize, 0);
|
bytes_sent = send(self->socket, (char *) self->buffer_out, globals.socket_buffersize, 0);
|
||||||
if (bytes_sent != globals.socket_buffersize) {
|
if (bytes_sent != globals.socket_buffersize)
|
||||||
|
{
|
||||||
self->errornumber = SOCKET_WRITE_ERROR;
|
self->errornumber = SOCKET_WRITE_ERROR;
|
||||||
self->errormsg = "Error while writing to the socket.";
|
self->errormsg = "Error while writing to the socket.";
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#ifndef _IN_ADDR_T
|
#ifndef _IN_ADDR_T
|
||||||
#define _IN_ADDR_T
|
#define _IN_ADDR_T
|
||||||
typedef unsigned int in_addr_t;
|
typedef unsigned int in_addr_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#define INADDR_NONE ((in_addr_t)-1)
|
#define INADDR_NONE ((in_addr_t)-1)
|
||||||
#endif
|
#endif
|
||||||
@ -52,7 +53,8 @@ typedef unsigned int in_addr_t;
|
|||||||
#define SOCKET_CLOSED 10
|
#define SOCKET_CLOSED 10
|
||||||
|
|
||||||
|
|
||||||
struct SocketClass_ {
|
struct SocketClass_
|
||||||
|
{
|
||||||
|
|
||||||
int buffer_filled_in;
|
int buffer_filled_in;
|
||||||
int buffer_filled_out;
|
int buffer_filled_out;
|
||||||
@ -65,7 +67,8 @@ struct SocketClass_ {
|
|||||||
char *errormsg;
|
char *errormsg;
|
||||||
int errornumber;
|
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) */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,17 +83,17 @@ struct SocketClass_ {
|
|||||||
|
|
||||||
/* Socket prototypes */
|
/* Socket prototypes */
|
||||||
SocketClass *SOCK_Constructor(void);
|
SocketClass *SOCK_Constructor(void);
|
||||||
void SOCK_Destructor(SocketClass *self);
|
void SOCK_Destructor(SocketClass * self);
|
||||||
char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
|
char SOCK_connect_to(SocketClass * self, unsigned short port, char *hostname);
|
||||||
void SOCK_get_n_char(SocketClass *self, char *buffer, int len);
|
void SOCK_get_n_char(SocketClass * self, char *buffer, int len);
|
||||||
void SOCK_put_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_get_string(SocketClass * self, char *buffer, int bufsize);
|
||||||
void SOCK_put_string(SocketClass *self, char *string);
|
void SOCK_put_string(SocketClass * self, char *string);
|
||||||
int SOCK_get_int(SocketClass *self, short len);
|
int SOCK_get_int(SocketClass * self, short len);
|
||||||
void SOCK_put_int(SocketClass *self, int value, short len);
|
void SOCK_put_int(SocketClass * self, int value, short len);
|
||||||
void SOCK_flush_output(SocketClass *self);
|
void SOCK_flush_output(SocketClass * self);
|
||||||
unsigned char SOCK_get_next_byte(SocketClass *self);
|
unsigned char SOCK_get_next_byte(SocketClass * self);
|
||||||
void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte);
|
void SOCK_put_next_byte(SocketClass * self, unsigned char next_byte);
|
||||||
void SOCK_clear_error(SocketClass *self);
|
void SOCK_clear_error(SocketClass * self);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,33 +45,58 @@ extern GLOBAL_VALUES globals;
|
|||||||
#define PRN_NULLCHECK
|
#define PRN_NULLCHECK
|
||||||
|
|
||||||
/* Map sql commands to statement types */
|
/* Map sql commands to statement types */
|
||||||
static struct {
|
static struct
|
||||||
|
{
|
||||||
int type;
|
int type;
|
||||||
char *s;
|
char *s;
|
||||||
} Statement_Type[] = {
|
} Statement_Type[] =
|
||||||
{ STMT_TYPE_SELECT, "SELECT" },
|
|
||||||
{ STMT_TYPE_INSERT, "INSERT" },
|
{
|
||||||
{ STMT_TYPE_UPDATE, "UPDATE" },
|
{
|
||||||
{ STMT_TYPE_DELETE, "DELETE" },
|
STMT_TYPE_SELECT, "SELECT"
|
||||||
{ STMT_TYPE_CREATE, "CREATE" },
|
},
|
||||||
{ STMT_TYPE_ALTER, "ALTER" },
|
{
|
||||||
{ STMT_TYPE_DROP, "DROP" },
|
STMT_TYPE_INSERT, "INSERT"
|
||||||
{ STMT_TYPE_GRANT, "GRANT" },
|
},
|
||||||
{ STMT_TYPE_REVOKE, "REVOKE" },
|
{
|
||||||
{ 0, NULL }
|
STMT_TYPE_UPDATE, "UPDATE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
STMT_TYPE_DELETE, "DELETE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
STMT_TYPE_CREATE, "CREATE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
STMT_TYPE_ALTER, "ALTER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
STMT_TYPE_DROP, "DROP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
STMT_TYPE_GRANT, "GRANT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
STMT_TYPE_REVOKE, "REVOKE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0, NULL
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
RETCODE SQL_API SQLAllocStmt(HDBC hdbc,
|
RETCODE SQL_API
|
||||||
HSTMT FAR *phstmt)
|
SQLAllocStmt(HDBC hdbc,
|
||||||
|
HSTMT FAR * phstmt)
|
||||||
{
|
{
|
||||||
static char *func="SQLAllocStmt";
|
static char *func = "SQLAllocStmt";
|
||||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||||
StatementClass *stmt;
|
StatementClass *stmt;
|
||||||
|
|
||||||
mylog("%s: entering...\n", func);
|
mylog("%s: entering...\n", func);
|
||||||
|
|
||||||
if( ! conn) {
|
if (!conn)
|
||||||
|
{
|
||||||
CC_log_error(func, "", NULL);
|
CC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
@ -80,7 +105,8 @@ StatementClass *stmt;
|
|||||||
|
|
||||||
mylog("**** SQLAllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt);
|
mylog("**** SQLAllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt);
|
||||||
|
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
conn->errornumber = CONN_STMT_ALLOC_ERROR;
|
conn->errornumber = CONN_STMT_ALLOC_ERROR;
|
||||||
conn->errormsg = "No more memory to allocate a further SQL-statement";
|
conn->errormsg = "No more memory to allocate a further SQL-statement";
|
||||||
*phstmt = SQL_NULL_HSTMT;
|
*phstmt = SQL_NULL_HSTMT;
|
||||||
@ -88,7 +114,8 @@ StatementClass *stmt;
|
|||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! CC_add_statement(conn, stmt)) {
|
if (!CC_add_statement(conn, stmt))
|
||||||
|
{
|
||||||
conn->errormsg = "Maximum number of connections exceeded.";
|
conn->errormsg = "Maximum number of connections exceeded.";
|
||||||
conn->errornumber = CONN_STMT_ALLOC_ERROR;
|
conn->errornumber = CONN_STMT_ALLOC_ERROR;
|
||||||
CC_log_error(func, "", conn);
|
CC_log_error(func, "", conn);
|
||||||
@ -99,7 +126,8 @@ StatementClass *stmt;
|
|||||||
|
|
||||||
*phstmt = (HSTMT) stmt;
|
*phstmt = (HSTMT) stmt;
|
||||||
|
|
||||||
/* Copy default statement options based from Connection options
|
/*
|
||||||
|
* Copy default statement options based from Connection options
|
||||||
*/
|
*/
|
||||||
stmt->options = conn->stmtOptions;
|
stmt->options = conn->stmtOptions;
|
||||||
|
|
||||||
@ -111,33 +139,40 @@ StatementClass *stmt;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
|
RETCODE SQL_API
|
||||||
|
SQLFreeStmt(HSTMT hstmt,
|
||||||
UWORD fOption)
|
UWORD fOption)
|
||||||
{
|
{
|
||||||
static char *func="SQLFreeStmt";
|
static char *func = "SQLFreeStmt";
|
||||||
StatementClass *stmt = (StatementClass *) hstmt;
|
StatementClass *stmt = (StatementClass *) hstmt;
|
||||||
|
|
||||||
mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption);
|
mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption);
|
||||||
|
|
||||||
if ( ! stmt) {
|
if (!stmt)
|
||||||
|
{
|
||||||
SC_log_error(func, "", NULL);
|
SC_log_error(func, "", NULL);
|
||||||
return SQL_INVALID_HANDLE;
|
return SQL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fOption == SQL_DROP) {
|
if (fOption == SQL_DROP)
|
||||||
|
{
|
||||||
ConnectionClass *conn = stmt->hdbc;
|
ConnectionClass *conn = stmt->hdbc;
|
||||||
|
|
||||||
/* Remove the statement from the connection's statement list */
|
/* Remove the statement from the connection's statement list */
|
||||||
if ( conn) {
|
if (conn)
|
||||||
if ( ! CC_remove_statement(conn, stmt)) {
|
{
|
||||||
|
if (!CC_remove_statement(conn, stmt))
|
||||||
|
{
|
||||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
stmt->errormsg = "Statement is currently executing a transaction.";
|
stmt->errormsg = "Statement is currently executing a transaction.";
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR; /* stmt may be executing a transaction */
|
return SQL_ERROR; /* stmt may be executing a
|
||||||
|
* transaction */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free any cursors and discard any result info */
|
/* Free any cursors and discard any result info */
|
||||||
if (stmt->result) {
|
if (stmt->result)
|
||||||
|
{
|
||||||
QR_Destructor(stmt->result);
|
QR_Destructor(stmt->result);
|
||||||
stmt->result = NULL;
|
stmt->result = NULL;
|
||||||
}
|
}
|
||||||
@ -146,22 +181,31 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||||||
/* Destroy the statement and free any results, cursors, etc. */
|
/* Destroy the statement and free any results, cursors, etc. */
|
||||||
SC_Destructor(stmt);
|
SC_Destructor(stmt);
|
||||||
|
|
||||||
} else if (fOption == SQL_UNBIND) {
|
}
|
||||||
|
else if (fOption == SQL_UNBIND)
|
||||||
|
{
|
||||||
SC_unbind_cols(stmt);
|
SC_unbind_cols(stmt);
|
||||||
|
|
||||||
} else if (fOption == SQL_CLOSE) {
|
}
|
||||||
|
else if (fOption == SQL_CLOSE)
|
||||||
|
{
|
||||||
/* this should discard all the results, but leave the statement */
|
/* this should discard all the results, but leave the statement */
|
||||||
/* itself in place (it can be executed again) */
|
/* itself in place (it can be executed again) */
|
||||||
if (!SC_recycle_statement(stmt)) {
|
if (!SC_recycle_statement(stmt))
|
||||||
|
{
|
||||||
/* errormsg passed in above */
|
/* errormsg passed in above */
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(fOption == SQL_RESET_PARAMS) {
|
}
|
||||||
|
else if (fOption == SQL_RESET_PARAMS)
|
||||||
|
{
|
||||||
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
|
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
stmt->errormsg = "Invalid option passed to SQLFreeStmt.";
|
stmt->errormsg = "Invalid option passed to SQLFreeStmt.";
|
||||||
stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;
|
stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;
|
||||||
SC_log_error(func, "", stmt);
|
SC_log_error(func, "", stmt);
|
||||||
@ -177,7 +221,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||||||
* StatementClass implementation
|
* StatementClass implementation
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
InitializeStatementOptions(StatementOptions *opt)
|
InitializeStatementOptions(StatementOptions * opt)
|
||||||
{
|
{
|
||||||
opt->maxRows = 0; /* driver returns all rows */
|
opt->maxRows = 0; /* driver returns all rows */
|
||||||
opt->maxLength = 0; /* driver returns all data for char/binary */
|
opt->maxLength = 0; /* driver returns all data for char/binary */
|
||||||
@ -193,10 +237,11 @@ InitializeStatementOptions(StatementOptions *opt)
|
|||||||
StatementClass *
|
StatementClass *
|
||||||
SC_Constructor(void)
|
SC_Constructor(void)
|
||||||
{
|
{
|
||||||
StatementClass *rv;
|
StatementClass *rv;
|
||||||
|
|
||||||
rv = (StatementClass *) malloc(sizeof(StatementClass));
|
rv = (StatementClass *) malloc(sizeof(StatementClass));
|
||||||
if (rv) {
|
if (rv)
|
||||||
|
{
|
||||||
rv->hdbc = NULL; /* no connection associated yet */
|
rv->hdbc = NULL; /* no connection associated yet */
|
||||||
rv->phstmt = NULL;
|
rv->phstmt = NULL;
|
||||||
rv->result = NULL;
|
rv->result = NULL;
|
||||||
@ -251,18 +296,20 @@ StatementClass *rv;
|
|||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
SC_Destructor(StatementClass *self)
|
SC_Destructor(StatementClass * self)
|
||||||
{
|
{
|
||||||
|
|
||||||
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc);
|
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc);
|
||||||
if (STMT_EXECUTING == self->status) {
|
if (STMT_EXECUTING == self->status)
|
||||||
|
{
|
||||||
self->errornumber = STMT_SEQUENCE_ERROR;
|
self->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
self->errormsg = "Statement is currently executing a transaction.";
|
self->errormsg = "Statement is currently executing a transaction.";
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->result) {
|
if (self->result)
|
||||||
if ( ! self->hdbc)
|
{
|
||||||
|
if (!self->hdbc)
|
||||||
self->result->conn = NULL; /* prevent any dbase activity */
|
self->result->conn = NULL; /* prevent any dbase activity */
|
||||||
|
|
||||||
QR_Destructor(self->result);
|
QR_Destructor(self->result);
|
||||||
@ -273,29 +320,38 @@ SC_Destructor(StatementClass *self)
|
|||||||
|
|
||||||
SC_free_params(self, STMT_FREE_PARAMS_ALL);
|
SC_free_params(self, STMT_FREE_PARAMS_ALL);
|
||||||
|
|
||||||
/* the memory pointed to by the bindings is not deallocated by the driver */
|
/*
|
||||||
/* by by the application that uses that driver, so we don't have to care */
|
* the memory pointed to by the bindings is not deallocated by the
|
||||||
|
* driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* by by the application that uses that driver, so we don't have to
|
||||||
|
* care
|
||||||
|
*/
|
||||||
/* about that here. */
|
/* about that here. */
|
||||||
if (self->bindings)
|
if (self->bindings)
|
||||||
free(self->bindings);
|
free(self->bindings);
|
||||||
|
|
||||||
|
|
||||||
/* Free the parsed table information */
|
/* Free the parsed table information */
|
||||||
if (self->ti) {
|
if (self->ti)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < self->ntab; i++) {
|
|
||||||
|
for (i = 0; i < self->ntab; i++)
|
||||||
free(self->ti[i]);
|
free(self->ti[i]);
|
||||||
}
|
|
||||||
|
|
||||||
free(self->ti);
|
free(self->ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the parsed field information */
|
/* Free the parsed field information */
|
||||||
if (self->fi) {
|
if (self->fi)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < self->nfld; i++) {
|
|
||||||
|
for (i = 0; i < self->nfld; i++)
|
||||||
free(self->fi[i]);
|
free(self->fi[i]);
|
||||||
}
|
|
||||||
free(self->fi);
|
free(self->fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,24 +367,28 @@ SC_Destructor(StatementClass *self)
|
|||||||
data-at-execution parameters that was allocated in SQLPutData.
|
data-at-execution parameters that was allocated in SQLPutData.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SC_free_params(StatementClass *self, char option)
|
SC_free_params(StatementClass * self, char option)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mylog("SC_free_params: ENTER, self=%d\n", self);
|
mylog("SC_free_params: ENTER, self=%d\n", self);
|
||||||
|
|
||||||
if( ! self->parameters)
|
if (!self->parameters)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < self->parameters_allocated; i++) {
|
for (i = 0; i < self->parameters_allocated; i++)
|
||||||
if (self->parameters[i].data_at_exec == TRUE) {
|
{
|
||||||
|
if (self->parameters[i].data_at_exec == TRUE)
|
||||||
|
{
|
||||||
|
|
||||||
if (self->parameters[i].EXEC_used) {
|
if (self->parameters[i].EXEC_used)
|
||||||
|
{
|
||||||
free(self->parameters[i].EXEC_used);
|
free(self->parameters[i].EXEC_used);
|
||||||
self->parameters[i].EXEC_used = NULL;
|
self->parameters[i].EXEC_used = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->parameters[i].EXEC_buffer) {
|
if (self->parameters[i].EXEC_buffer)
|
||||||
|
{
|
||||||
if (self->parameters[i].SQLType != SQL_LONGVARBINARY)
|
if (self->parameters[i].SQLType != SQL_LONGVARBINARY)
|
||||||
free(self->parameters[i].EXEC_buffer);
|
free(self->parameters[i].EXEC_buffer);
|
||||||
self->parameters[i].EXEC_buffer = NULL;
|
self->parameters[i].EXEC_buffer = NULL;
|
||||||
@ -339,7 +399,8 @@ int i;
|
|||||||
self->current_exec_param = -1;
|
self->current_exec_param = -1;
|
||||||
self->put_data = FALSE;
|
self->put_data = FALSE;
|
||||||
|
|
||||||
if (option == STMT_FREE_PARAMS_ALL) {
|
if (option == STMT_FREE_PARAMS_ALL)
|
||||||
|
{
|
||||||
free(self->parameters);
|
free(self->parameters);
|
||||||
self->parameters = NULL;
|
self->parameters = NULL;
|
||||||
self->parameters_allocated = 0;
|
self->parameters_allocated = 0;
|
||||||
@ -352,14 +413,14 @@ int i;
|
|||||||
int
|
int
|
||||||
statement_type(char *statement)
|
statement_type(char *statement)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* ignore leading whitespace in query string */
|
/* ignore leading whitespace in query string */
|
||||||
while (*statement && isspace((unsigned char) *statement))
|
while (*statement && isspace((unsigned char) *statement))
|
||||||
statement++;
|
statement++;
|
||||||
|
|
||||||
for (i = 0; Statement_Type[i].s; i++)
|
for (i = 0; Statement_Type[i].s; i++)
|
||||||
if ( ! strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s)))
|
if (!strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s)))
|
||||||
return Statement_Type[i].type;
|
return Statement_Type[i].type;
|
||||||
|
|
||||||
return STMT_TYPE_OTHER;
|
return STMT_TYPE_OTHER;
|
||||||
@ -371,14 +432,15 @@ int i;
|
|||||||
from SQLFreeStmt(SQL_CLOSE)
|
from SQLFreeStmt(SQL_CLOSE)
|
||||||
*/
|
*/
|
||||||
char
|
char
|
||||||
SC_recycle_statement(StatementClass *self)
|
SC_recycle_statement(StatementClass * self)
|
||||||
{
|
{
|
||||||
ConnectionClass *conn;
|
ConnectionClass *conn;
|
||||||
|
|
||||||
mylog("recycle statement: self= %u\n", self);
|
mylog("recycle statement: self= %u\n", self);
|
||||||
|
|
||||||
/* This would not happen */
|
/* This would not happen */
|
||||||
if (self->status == STMT_EXECUTING) {
|
if (self->status == STMT_EXECUTING)
|
||||||
|
{
|
||||||
self->errornumber = STMT_SEQUENCE_ERROR;
|
self->errornumber = STMT_SEQUENCE_ERROR;
|
||||||
self->errormsg = "Statement is currently executing a transaction.";
|
self->errormsg = "Statement is currently executing a transaction.";
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -388,7 +450,8 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
self->errornumber = 0;
|
self->errornumber = 0;
|
||||||
self->errormsg_created = FALSE;
|
self->errormsg_created = FALSE;
|
||||||
|
|
||||||
switch (self->status) {
|
switch (self->status)
|
||||||
|
{
|
||||||
case STMT_ALLOCATED:
|
case STMT_ALLOCATED:
|
||||||
/* this statement does not need to be recycled */
|
/* this statement does not need to be recycled */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -397,11 +460,15 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STMT_PREMATURE:
|
case STMT_PREMATURE:
|
||||||
/* Premature execution of the statement might have caused the start of a transaction.
|
|
||||||
If so, we have to rollback that transaction.
|
/*
|
||||||
|
* Premature execution of the statement might have caused the
|
||||||
|
* start of a transaction. If so, we have to rollback that
|
||||||
|
* transaction.
|
||||||
*/
|
*/
|
||||||
conn = SC_get_conn(self);
|
conn = SC_get_conn(self);
|
||||||
if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) {
|
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
|
||||||
|
{
|
||||||
|
|
||||||
CC_send_query(conn, "ABORT", NULL);
|
CC_send_query(conn, "ABORT", NULL);
|
||||||
CC_set_no_trans(conn);
|
CC_set_no_trans(conn);
|
||||||
@ -418,11 +485,12 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free the parsed table information */
|
/* Free the parsed table information */
|
||||||
if (self->ti) {
|
if (self->ti)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < self->ntab; i++) {
|
|
||||||
|
for (i = 0; i < self->ntab; i++)
|
||||||
free(self->ti[i]);
|
free(self->ti[i]);
|
||||||
}
|
|
||||||
|
|
||||||
free(self->ti);
|
free(self->ti);
|
||||||
self->ti = NULL;
|
self->ti = NULL;
|
||||||
@ -430,11 +498,12 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free the parsed field information */
|
/* Free the parsed field information */
|
||||||
if (self->fi) {
|
if (self->fi)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < self->nfld; i++) {
|
|
||||||
|
for (i = 0; i < self->nfld; i++)
|
||||||
free(self->fi[i]);
|
free(self->fi[i]);
|
||||||
}
|
|
||||||
free(self->fi);
|
free(self->fi);
|
||||||
self->fi = NULL;
|
self->fi = NULL;
|
||||||
self->nfld = 0;
|
self->nfld = 0;
|
||||||
@ -442,7 +511,8 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
self->parse_status = STMT_PARSE_NONE;
|
self->parse_status = STMT_PARSE_NONE;
|
||||||
|
|
||||||
/* Free any cursors */
|
/* Free any cursors */
|
||||||
if (self->result) {
|
if (self->result)
|
||||||
|
{
|
||||||
QR_Destructor(self->result);
|
QR_Destructor(self->result);
|
||||||
self->result = NULL;
|
self->result = NULL;
|
||||||
}
|
}
|
||||||
@ -452,7 +522,7 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
||||||
self->status = STMT_READY;
|
self->status = STMT_READY;
|
||||||
self->manual_result = FALSE; /* very important */
|
self->manual_result = FALSE;/* very important */
|
||||||
|
|
||||||
self->currTuple = -1;
|
self->currTuple = -1;
|
||||||
self->rowset_start = -1;
|
self->rowset_start = -1;
|
||||||
@ -476,17 +546,19 @@ mylog("recycle statement: self= %u\n", self);
|
|||||||
|
|
||||||
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
|
/* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */
|
||||||
void
|
void
|
||||||
SC_pre_execute(StatementClass *self)
|
SC_pre_execute(StatementClass * self)
|
||||||
{
|
{
|
||||||
|
|
||||||
mylog("SC_pre_execute: status = %d\n", self->status);
|
mylog("SC_pre_execute: status = %d\n", self->status);
|
||||||
|
|
||||||
if (self->status == STMT_READY) {
|
if (self->status == STMT_READY)
|
||||||
|
{
|
||||||
mylog(" preprocess: status = READY\n");
|
mylog(" preprocess: status = READY\n");
|
||||||
|
|
||||||
SQLExecute(self);
|
SQLExecute(self);
|
||||||
|
|
||||||
if (self->status == STMT_FINISHED) {
|
if (self->status == STMT_FINISHED)
|
||||||
|
{
|
||||||
mylog(" preprocess: after status = FINISHED, so set PREMATURE\n");
|
mylog(" preprocess: after status = FINISHED, so set PREMATURE\n");
|
||||||
self->status = STMT_PREMATURE;
|
self->status = STMT_PREMATURE;
|
||||||
}
|
}
|
||||||
@ -495,11 +567,12 @@ SC_pre_execute(StatementClass *self)
|
|||||||
|
|
||||||
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
|
/* This is only called from SQLFreeStmt(SQL_UNBIND) */
|
||||||
char
|
char
|
||||||
SC_unbind_cols(StatementClass *self)
|
SC_unbind_cols(StatementClass * self)
|
||||||
{
|
{
|
||||||
Int2 lf;
|
Int2 lf;
|
||||||
|
|
||||||
for(lf = 0; lf < self->bindings_allocated; lf++) {
|
for (lf = 0; lf < self->bindings_allocated; lf++)
|
||||||
|
{
|
||||||
self->bindings[lf].data_left = -1;
|
self->bindings[lf].data_left = -1;
|
||||||
self->bindings[lf].buflen = 0;
|
self->bindings[lf].buflen = 0;
|
||||||
self->bindings[lf].buffer = NULL;
|
self->bindings[lf].buffer = NULL;
|
||||||
@ -514,7 +587,7 @@ Int2 lf;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SC_clear_error(StatementClass *self)
|
SC_clear_error(StatementClass * self)
|
||||||
{
|
{
|
||||||
self->errornumber = 0;
|
self->errornumber = 0;
|
||||||
self->errormsg = NULL;
|
self->errormsg = NULL;
|
||||||
@ -525,12 +598,12 @@ SC_clear_error(StatementClass *self)
|
|||||||
/* This function creates an error msg which is the concatenation */
|
/* This function creates an error msg which is the concatenation */
|
||||||
/* of the result, statement, connection, and socket messages. */
|
/* of the result, statement, connection, and socket messages. */
|
||||||
char *
|
char *
|
||||||
SC_create_errormsg(StatementClass *self)
|
SC_create_errormsg(StatementClass * self)
|
||||||
{
|
{
|
||||||
QResultClass *res = self->result;
|
QResultClass *res = self->result;
|
||||||
ConnectionClass *conn = self->hdbc;
|
ConnectionClass *conn = self->hdbc;
|
||||||
int pos;
|
int pos;
|
||||||
static char msg[4096];
|
static char msg[4096];
|
||||||
|
|
||||||
msg[0] = '\0';
|
msg[0] = '\0';
|
||||||
|
|
||||||
@ -540,15 +613,18 @@ static char msg[4096];
|
|||||||
else if (self->errormsg)
|
else if (self->errormsg)
|
||||||
strcpy(msg, self->errormsg);
|
strcpy(msg, self->errormsg);
|
||||||
|
|
||||||
if (conn) {
|
if (conn)
|
||||||
|
{
|
||||||
SocketClass *sock = conn->sock;
|
SocketClass *sock = conn->sock;
|
||||||
|
|
||||||
if (conn->errormsg && conn->errormsg[0] != '\0') {
|
if (conn->errormsg && conn->errormsg[0] != '\0')
|
||||||
|
{
|
||||||
pos = strlen(msg);
|
pos = strlen(msg);
|
||||||
sprintf(&msg[pos], ";\n%s", conn->errormsg);
|
sprintf(&msg[pos], ";\n%s", conn->errormsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sock && sock->errormsg && sock->errormsg[0] != '\0') {
|
if (sock && sock->errormsg && sock->errormsg[0] != '\0')
|
||||||
|
{
|
||||||
pos = strlen(msg);
|
pos = strlen(msg);
|
||||||
sprintf(&msg[pos], ";\n%s", sock->errormsg);
|
sprintf(&msg[pos], ";\n%s", sock->errormsg);
|
||||||
}
|
}
|
||||||
@ -558,17 +634,19 @@ static char msg[4096];
|
|||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
SC_get_error(StatementClass *self, int *number, char **message)
|
SC_get_error(StatementClass * self, int *number, char **message)
|
||||||
{
|
{
|
||||||
char rv;
|
char rv;
|
||||||
|
|
||||||
/* Create a very informative errormsg if it hasn't been done yet. */
|
/* Create a very informative errormsg if it hasn't been done yet. */
|
||||||
if ( ! self->errormsg_created) {
|
if (!self->errormsg_created)
|
||||||
|
{
|
||||||
self->errormsg = SC_create_errormsg(self);
|
self->errormsg = SC_create_errormsg(self);
|
||||||
self->errormsg_created = TRUE;
|
self->errormsg_created = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( self->errornumber) {
|
if (self->errornumber)
|
||||||
|
{
|
||||||
*number = self->errornumber;
|
*number = self->errornumber;
|
||||||
*message = self->errormsg;
|
*message = self->errormsg;
|
||||||
self->errormsg = NULL;
|
self->errormsg = NULL;
|
||||||
@ -585,21 +663,24 @@ char rv;
|
|||||||
someday, such as mapping a key to a 32 bit value
|
someday, such as mapping a key to a 32 bit value
|
||||||
*/
|
*/
|
||||||
unsigned long
|
unsigned long
|
||||||
SC_get_bookmark(StatementClass *self)
|
SC_get_bookmark(StatementClass * self)
|
||||||
{
|
{
|
||||||
return (self->currTuple + 1);
|
return (self->currTuple + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
RETCODE
|
RETCODE
|
||||||
SC_fetch(StatementClass *self)
|
SC_fetch(StatementClass * self)
|
||||||
{
|
{
|
||||||
static char *func = "SC_fetch";
|
static char *func = "SC_fetch";
|
||||||
QResultClass *res = self->result;
|
QResultClass *res = self->result;
|
||||||
int retval, result;
|
int retval,
|
||||||
Int2 num_cols, lf;
|
result;
|
||||||
Oid type;
|
Int2 num_cols,
|
||||||
char *value;
|
lf;
|
||||||
ColumnInfoClass *ci;
|
Oid type;
|
||||||
|
char *value;
|
||||||
|
ColumnInfoClass *ci;
|
||||||
|
|
||||||
/* TupleField *tupleField; */
|
/* TupleField *tupleField; */
|
||||||
|
|
||||||
self->last_fetch_count = 0;
|
self->last_fetch_count = 0;
|
||||||
@ -607,13 +688,16 @@ ColumnInfoClass *ci;
|
|||||||
|
|
||||||
mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, globals.use_declarefetch);
|
mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, globals.use_declarefetch);
|
||||||
|
|
||||||
if ( self->manual_result || ! globals.use_declarefetch) {
|
if (self->manual_result || !globals.use_declarefetch)
|
||||||
|
{
|
||||||
|
|
||||||
if (self->currTuple >= QR_get_num_tuples(res) -1 ||
|
if (self->currTuple >= QR_get_num_tuples(res) - 1 ||
|
||||||
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) {
|
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))
|
||||||
|
{
|
||||||
|
|
||||||
/* if at the end of the tuples, return "no data found"
|
/*
|
||||||
and set the cursor past the end of the result set
|
* if at the end of the tuples, return "no data found" and set
|
||||||
|
* the cursor past the end of the result set
|
||||||
*/
|
*/
|
||||||
self->currTuple = QR_get_num_tuples(res);
|
self->currTuple = QR_get_num_tuples(res);
|
||||||
return SQL_NO_DATA_FOUND;
|
return SQL_NO_DATA_FOUND;
|
||||||
@ -622,18 +706,21 @@ ColumnInfoClass *ci;
|
|||||||
mylog("**** SQLFetch: manual_result\n");
|
mylog("**** SQLFetch: manual_result\n");
|
||||||
(self->currTuple)++;
|
(self->currTuple)++;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
|
|
||||||
/* read from the cache or the physical next tuple */
|
/* read from the cache or the physical next tuple */
|
||||||
retval = QR_next_tuple(res);
|
retval = QR_next_tuple(res);
|
||||||
if (retval < 0) {
|
if (retval < 0)
|
||||||
|
{
|
||||||
mylog("**** SQLFetch: end_tuples\n");
|
mylog("**** SQLFetch: end_tuples\n");
|
||||||
return SQL_NO_DATA_FOUND;
|
return SQL_NO_DATA_FOUND;
|
||||||
}
|
}
|
||||||
else if (retval > 0)
|
else if (retval > 0)
|
||||||
(self->currTuple)++; /* all is well */
|
(self->currTuple)++;/* all is well */
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
mylog("SQLFetch: error\n");
|
mylog("SQLFetch: error\n");
|
||||||
self->errornumber = STMT_EXEC_ERROR;
|
self->errornumber = STMT_EXEC_ERROR;
|
||||||
self->errormsg = "Error fetching next row";
|
self->errormsg = "Error fetching next row";
|
||||||
@ -647,12 +734,14 @@ ColumnInfoClass *ci;
|
|||||||
result = SQL_SUCCESS;
|
result = SQL_SUCCESS;
|
||||||
self->last_fetch_count = 1;
|
self->last_fetch_count = 1;
|
||||||
|
|
||||||
/* If the bookmark column was bound then return a bookmark.
|
/*
|
||||||
Since this is used with SQLExtendedFetch, and the rowset size
|
* If the bookmark column was bound then return a bookmark. Since this
|
||||||
may be greater than 1, and an application can use row or column wise
|
* is used with SQLExtendedFetch, and the rowset size may be greater
|
||||||
binding, use the code in copy_and_convert_field() to handle that.
|
* than 1, and an application can use row or column wise binding, use
|
||||||
|
* the code in copy_and_convert_field() to handle that.
|
||||||
*/
|
*/
|
||||||
if (self->bookmark.buffer) {
|
if (self->bookmark.buffer)
|
||||||
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
sprintf(buf, "%ld", SC_get_bookmark(self));
|
sprintf(buf, "%ld", SC_get_bookmark(self));
|
||||||
@ -660,14 +749,16 @@ ColumnInfoClass *ci;
|
|||||||
SQL_C_ULONG, self->bookmark.buffer, 0, self->bookmark.used);
|
SQL_C_ULONG, self->bookmark.buffer, 0, self->bookmark.used);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lf=0; lf < num_cols; lf++) {
|
for (lf = 0; lf < num_cols; lf++)
|
||||||
|
{
|
||||||
|
|
||||||
mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self, self->bindings, self->bindings[lf].buffer);
|
mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self, self->bindings, self->bindings[lf].buffer);
|
||||||
|
|
||||||
/* reset for SQLGetData */
|
/* reset for SQLGetData */
|
||||||
self->bindings[lf].data_left = -1;
|
self->bindings[lf].data_left = -1;
|
||||||
|
|
||||||
if (self->bindings[lf].buffer != NULL) {
|
if (self->bindings[lf].buffer != NULL)
|
||||||
|
{
|
||||||
/* this column has a binding */
|
/* this column has a binding */
|
||||||
|
|
||||||
/* type = QR_get_field_type(res, lf); */
|
/* type = QR_get_field_type(res, lf); */
|
||||||
@ -675,23 +766,24 @@ ColumnInfoClass *ci;
|
|||||||
|
|
||||||
mylog("type = %d\n", type);
|
mylog("type = %d\n", type);
|
||||||
|
|
||||||
if (self->manual_result) {
|
if (self->manual_result)
|
||||||
|
{
|
||||||
value = QR_get_value_manual(res, self->currTuple, lf);
|
value = QR_get_value_manual(res, self->currTuple, lf);
|
||||||
mylog("manual_result\n");
|
mylog("manual_result\n");
|
||||||
}
|
}
|
||||||
else if (globals.use_declarefetch)
|
else if (globals.use_declarefetch)
|
||||||
value = QR_get_value_backend(res, lf);
|
value = QR_get_value_backend(res, lf);
|
||||||
else {
|
else
|
||||||
value = QR_get_value_backend_row(res, self->currTuple, lf);
|
value = QR_get_value_backend_row(res, self->currTuple, lf);
|
||||||
}
|
|
||||||
|
|
||||||
mylog("value = '%s'\n", (value==NULL)?"<NULL>":value);
|
mylog("value = '%s'\n", (value == NULL) ? "<NULL>" : value);
|
||||||
|
|
||||||
retval = copy_and_convert_field_bindinfo(self, type, value, lf);
|
retval = copy_and_convert_field_bindinfo(self, type, value, lf);
|
||||||
|
|
||||||
mylog("copy_and_convert: retval = %d\n", retval);
|
mylog("copy_and_convert: retval = %d\n", retval);
|
||||||
|
|
||||||
switch(retval) {
|
switch (retval)
|
||||||
|
{
|
||||||
case COPY_OK:
|
case COPY_OK:
|
||||||
break; /* OK, do next bound column */
|
break; /* OK, do next bound column */
|
||||||
|
|
||||||
@ -715,7 +807,8 @@ ColumnInfoClass *ci;
|
|||||||
result = SQL_SUCCESS_WITH_INFO;
|
result = SQL_SUCCESS_WITH_INFO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COPY_GENERAL_ERROR: /* error msg already filled in */
|
case COPY_GENERAL_ERROR: /* error msg already
|
||||||
|
* filled in */
|
||||||
SC_log_error(func, "", self);
|
SC_log_error(func, "", self);
|
||||||
result = SQL_ERROR;
|
result = SQL_ERROR;
|
||||||
break;
|
break;
|
||||||
@ -738,35 +831,40 @@ ColumnInfoClass *ci;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RETCODE SC_execute(StatementClass *self)
|
RETCODE
|
||||||
|
SC_execute(StatementClass * self)
|
||||||
{
|
{
|
||||||
static char *func="SC_execute";
|
static char *func = "SC_execute";
|
||||||
ConnectionClass *conn;
|
ConnectionClass *conn;
|
||||||
QResultClass *res;
|
QResultClass *res;
|
||||||
char ok, was_ok, was_nonfatal;
|
char ok,
|
||||||
Int2 oldstatus, numcols;
|
was_ok,
|
||||||
QueryInfo qi;
|
was_nonfatal;
|
||||||
|
Int2 oldstatus,
|
||||||
|
numcols;
|
||||||
|
QueryInfo qi;
|
||||||
|
|
||||||
|
|
||||||
conn = SC_get_conn(self);
|
conn = SC_get_conn(self);
|
||||||
|
|
||||||
/* Begin a transaction if one is not already in progress */
|
/* Begin a transaction if one is not already in progress */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Basically we don't have to begin a transaction in
|
* Basically we don't have to begin a transaction in autocommit mode
|
||||||
autocommit mode because Postgres backend runs in
|
* because Postgres backend runs in autocomit mode. We issue "BEGIN"
|
||||||
autocomit mode.
|
* in the following cases. 1) we use declare/fetch and the statement
|
||||||
We issue "BEGIN" in the following cases.
|
* is SELECT (because declare/fetch must be called in a transaction).
|
||||||
1) we use declare/fetch and the statement is SELECT
|
* 2) we are not in autocommit state and the statement is of type
|
||||||
(because declare/fetch must be called in a transaction).
|
* UPDATE.
|
||||||
2) we are not in autocommit state and the statement
|
|
||||||
is of type UPDATE.
|
|
||||||
*/
|
*/
|
||||||
if ( ! self->internal && ! CC_is_in_trans(conn) &&
|
if (!self->internal && !CC_is_in_trans(conn) &&
|
||||||
((globals.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) || (! CC_is_in_autocommit(conn) && STMT_UPDATE(self)))) {
|
((globals.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) || (!CC_is_in_autocommit(conn) && STMT_UPDATE(self))))
|
||||||
|
{
|
||||||
|
|
||||||
mylog(" about to begin a transaction on statement = %u\n", self);
|
mylog(" about to begin a transaction on statement = %u\n", self);
|
||||||
res = CC_send_query(conn, "BEGIN", NULL);
|
res = CC_send_query(conn, "BEGIN", NULL);
|
||||||
if ( ! res) {
|
if (!res)
|
||||||
|
{
|
||||||
self->errormsg = "Could not begin a transaction";
|
self->errormsg = "Could not begin a transaction";
|
||||||
self->errornumber = STMT_EXEC_ERROR;
|
self->errornumber = STMT_EXEC_ERROR;
|
||||||
SC_log_error(func, "", self);
|
SC_log_error(func, "", self);
|
||||||
@ -779,7 +877,8 @@ QueryInfo qi;
|
|||||||
|
|
||||||
QR_Destructor(res);
|
QR_Destructor(res);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
|
{
|
||||||
self->errormsg = "Could not begin a transaction";
|
self->errormsg = "Could not begin a transaction";
|
||||||
self->errornumber = STMT_EXEC_ERROR;
|
self->errornumber = STMT_EXEC_ERROR;
|
||||||
SC_log_error(func, "", self);
|
SC_log_error(func, "", self);
|
||||||
@ -795,9 +894,14 @@ QueryInfo qi;
|
|||||||
|
|
||||||
|
|
||||||
/* If it's a SELECT statement, use a cursor. */
|
/* If it's a SELECT statement, use a cursor. */
|
||||||
/* Note that the declare cursor has already been prepended to the statement */
|
|
||||||
|
/*
|
||||||
|
* Note that the declare cursor has already been prepended to the
|
||||||
|
* statement
|
||||||
|
*/
|
||||||
/* in copy_statement... */
|
/* in copy_statement... */
|
||||||
if (self->statement_type == STMT_TYPE_SELECT) {
|
if (self->statement_type == STMT_TYPE_SELECT)
|
||||||
|
{
|
||||||
|
|
||||||
char fetch[128];
|
char fetch[128];
|
||||||
|
|
||||||
@ -808,38 +912,50 @@ QueryInfo qi;
|
|||||||
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
|
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
|
||||||
|
|
||||||
if (globals.use_declarefetch && self->result != NULL &&
|
if (globals.use_declarefetch && self->result != NULL &&
|
||||||
QR_command_successful(self->result)) {
|
QR_command_successful(self->result))
|
||||||
|
{
|
||||||
|
|
||||||
QR_Destructor(self->result);
|
QR_Destructor(self->result);
|
||||||
|
|
||||||
/* That worked, so now send the fetch to start getting data back */
|
/*
|
||||||
|
* That worked, so now send the fetch to start getting data
|
||||||
|
* back
|
||||||
|
*/
|
||||||
qi.result_in = NULL;
|
qi.result_in = NULL;
|
||||||
qi.cursor = self->cursor_name;
|
qi.cursor = self->cursor_name;
|
||||||
qi.row_size = globals.fetch_max;
|
qi.row_size = globals.fetch_max;
|
||||||
|
|
||||||
/* Most likely the rowset size will not be set by the application until
|
/*
|
||||||
after the statement is executed, so might as well use the cache size.
|
* Most likely the rowset size will not be set by the
|
||||||
The qr_next_tuple() function will correct for any discrepancies in
|
* application until after the statement is executed, so might
|
||||||
sizes and adjust the cache accordingly.
|
* as well use the cache size. The qr_next_tuple() function
|
||||||
|
* will correct for any discrepancies in sizes and adjust the
|
||||||
|
* cache accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
|
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
|
||||||
|
|
||||||
self->result = CC_send_query( conn, fetch, &qi);
|
self->result = CC_send_query(conn, fetch, &qi);
|
||||||
}
|
}
|
||||||
mylog(" done sending the query:\n");
|
mylog(" done sending the query:\n");
|
||||||
}
|
}
|
||||||
else { /* not a SELECT statement so don't use a cursor */
|
else
|
||||||
|
{ /* not a SELECT statement so don't use a
|
||||||
|
* cursor */
|
||||||
mylog(" it's NOT a select statement: stmt=%u\n", self);
|
mylog(" it's NOT a select statement: stmt=%u\n", self);
|
||||||
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
|
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
|
||||||
|
|
||||||
/* We shouldn't send COMMIT. Postgres backend does the
|
/*
|
||||||
autocommit if neccessary. (Zoltan, 04/26/2000)
|
* We shouldn't send COMMIT. Postgres backend does the autocommit
|
||||||
|
* if neccessary. (Zoltan, 04/26/2000)
|
||||||
*/
|
*/
|
||||||
/* Even in case of autocommit, started transactions
|
|
||||||
must be committed. (Hiroshi, 09/02/2001)
|
/*
|
||||||
|
* Even in case of autocommit, started transactions must be
|
||||||
|
* committed. (Hiroshi, 09/02/2001)
|
||||||
*/
|
*/
|
||||||
if ( ! self->internal && CC_is_in_autocommit(conn) && CC_is_in_trans(conn) && STMT_UPDATE(self)) {
|
if (!self->internal && CC_is_in_autocommit(conn) && CC_is_in_trans(conn) && STMT_UPDATE(self))
|
||||||
|
{
|
||||||
res = CC_send_query(conn, "COMMIT", NULL);
|
res = CC_send_query(conn, "COMMIT", NULL);
|
||||||
QR_Destructor(res);
|
QR_Destructor(res);
|
||||||
CC_set_no_trans(conn);
|
CC_set_no_trans(conn);
|
||||||
@ -850,17 +966,19 @@ QueryInfo qi;
|
|||||||
self->status = STMT_FINISHED;
|
self->status = STMT_FINISHED;
|
||||||
|
|
||||||
/* Check the status of the result */
|
/* Check the status of the result */
|
||||||
if (self->result) {
|
if (self->result)
|
||||||
|
{
|
||||||
|
|
||||||
was_ok = QR_command_successful(self->result);
|
was_ok = QR_command_successful(self->result);
|
||||||
was_nonfatal = QR_command_nonfatal(self->result);
|
was_nonfatal = QR_command_nonfatal(self->result);
|
||||||
|
|
||||||
if ( was_ok)
|
if (was_ok)
|
||||||
self->errornumber = STMT_OK;
|
self->errornumber = STMT_OK;
|
||||||
else
|
else
|
||||||
self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND;
|
self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND;
|
||||||
|
|
||||||
self->currTuple = -1; /* set cursor before the first tuple in the list */
|
self->currTuple = -1; /* set cursor before the first tuple in
|
||||||
|
* the list */
|
||||||
self->current_col = -1;
|
self->current_col = -1;
|
||||||
self->rowset_start = -1;
|
self->rowset_start = -1;
|
||||||
|
|
||||||
@ -868,9 +986,11 @@ QueryInfo qi;
|
|||||||
numcols = QR_NumResultCols(self->result);
|
numcols = QR_NumResultCols(self->result);
|
||||||
|
|
||||||
/* now allocate the array to hold the binding info */
|
/* now allocate the array to hold the binding info */
|
||||||
if (numcols > 0) {
|
if (numcols > 0)
|
||||||
|
{
|
||||||
extend_bindings(self, numcols);
|
extend_bindings(self, numcols);
|
||||||
if (self->bindings == NULL) {
|
if (self->bindings == NULL)
|
||||||
|
{
|
||||||
self->errornumber = STMT_NO_MEMORY_ERROR;
|
self->errornumber = STMT_NO_MEMORY_ERROR;
|
||||||
self->errormsg = "Could not get enough free memory to store the binding information";
|
self->errormsg = "Could not get enough free memory to store the binding information";
|
||||||
SC_log_error(func, "", self);
|
SC_log_error(func, "", self);
|
||||||
@ -878,32 +998,40 @@ QueryInfo qi;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* in autocommit mode declare/fetch error must be aborted */
|
/* in autocommit mode declare/fetch error must be aborted */
|
||||||
if ( ! was_ok && ! self->internal && CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
|
if (!was_ok && !self->internal && CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
|
||||||
CC_abort(conn);
|
CC_abort(conn);
|
||||||
} else { /* Bad Error -- The error message will be in the Connection */
|
}
|
||||||
|
else
|
||||||
|
{ /* Bad Error -- The error message will be
|
||||||
|
* in the Connection */
|
||||||
|
|
||||||
if (self->statement_type == STMT_TYPE_CREATE) {
|
if (self->statement_type == STMT_TYPE_CREATE)
|
||||||
|
{
|
||||||
self->errornumber = STMT_CREATE_TABLE_ERROR;
|
self->errornumber = STMT_CREATE_TABLE_ERROR;
|
||||||
self->errormsg = "Error creating the table";
|
self->errormsg = "Error creating the table";
|
||||||
/* This would allow the table to already exists, thus appending
|
|
||||||
rows to it. BUT, if the table didn't have the same attributes,
|
/*
|
||||||
it would fail.
|
* This would allow the table to already exists, thus
|
||||||
return SQL_SUCCESS_WITH_INFO;
|
* appending rows to it. BUT, if the table didn't have the
|
||||||
|
* same attributes, it would fail. return
|
||||||
|
* SQL_SUCCESS_WITH_INFO;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
self->errornumber = STMT_EXEC_ERROR;
|
self->errornumber = STMT_EXEC_ERROR;
|
||||||
self->errormsg = "Error while executing the query";
|
self->errormsg = "Error while executing the query";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! self->internal)
|
if (!self->internal)
|
||||||
CC_abort(conn);
|
CC_abort(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->errornumber == STMT_OK)
|
if (self->errornumber == STMT_OK)
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* Modified, 2000-04-29, Zoltan */
|
/* Modified, 2000-04-29, Zoltan */
|
||||||
if (self->errornumber == STMT_INFO_ONLY)
|
if (self->errornumber == STMT_INFO_ONLY)
|
||||||
self->errormsg = "Error while executing the query (non-fatal)";
|
self->errormsg = "Error while executing the query (non-fatal)";
|
||||||
@ -915,12 +1043,13 @@ QueryInfo qi;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SC_log_error(char *func, char *desc, StatementClass *self)
|
SC_log_error(char *func, char *desc, StatementClass * self)
|
||||||
{
|
{
|
||||||
#ifdef PRN_NULLCHECK
|
#ifdef PRN_NULLCHECK
|
||||||
#define nullcheck(a) (a ? a : "(NULL)")
|
#define nullcheck(a) (a ? a : "(NULL)")
|
||||||
#endif
|
#endif
|
||||||
if (self) {
|
if (self)
|
||||||
|
{
|
||||||
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
|
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
|
||||||
mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
|
mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
|
||||||
qlog(" ------------------------------------------------------------\n");
|
qlog(" ------------------------------------------------------------\n");
|
||||||
@ -937,8 +1066,10 @@ SC_log_error(char *func, char *desc, StatementClass *self)
|
|||||||
|
|
||||||
qlog(" ----------------QResult Info -------------------------------\n");
|
qlog(" ----------------QResult Info -------------------------------\n");
|
||||||
|
|
||||||
if (self->result) {
|
if (self->result)
|
||||||
|
{
|
||||||
QResultClass *res = self->result;
|
QResultClass *res = self->result;
|
||||||
|
|
||||||
qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn);
|
qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn);
|
||||||
qlog(" fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, nullcheck(res->cursor));
|
qlog(" fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, nullcheck(res->cursor));
|
||||||
qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice));
|
qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice));
|
||||||
|
@ -33,21 +33,28 @@
|
|||||||
#define TRUE (BOOL)1
|
#define TRUE (BOOL)1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
STMT_ALLOCATED, /* The statement handle is allocated, but not used so far */
|
{
|
||||||
|
STMT_ALLOCATED, /* The statement handle is allocated, but
|
||||||
|
* not used so far */
|
||||||
STMT_READY, /* the statement is waiting to be executed */
|
STMT_READY, /* the statement is waiting to be executed */
|
||||||
STMT_PREMATURE, /* ODBC states that it is legal to call e.g. SQLDescribeCol before
|
STMT_PREMATURE, /* ODBC states that it is legal to call
|
||||||
a call to SQLExecute, but after SQLPrepare. To get all the necessary
|
* e.g. SQLDescribeCol before a call to
|
||||||
information in such a case, we simply execute the query _before_ the
|
* SQLExecute, but after SQLPrepare. To
|
||||||
actual call to SQLExecute, so that statement is considered to be "premature".
|
* 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_FINISHED, /* statement execution has finished */
|
||||||
STMT_EXECUTING /* statement execution is still going on */
|
STMT_EXECUTING /* statement execution is still going on */
|
||||||
} STMT_Status;
|
} STMT_Status;
|
||||||
|
|
||||||
#define STMT_TRUNCATED -2
|
#define STMT_TRUNCATED -2
|
||||||
#define STMT_INFO_ONLY -1 /* not an error message, just a notification to be returned by SQLError */
|
#define STMT_INFO_ONLY -1 /* not an error message, just a
|
||||||
#define STMT_OK 0 /* will be interpreted as "no error pending" */
|
* notification to be returned by SQLError */
|
||||||
|
#define STMT_OK 0 /* will be interpreted as "no error
|
||||||
|
* pending" */
|
||||||
#define STMT_EXEC_ERROR 1
|
#define STMT_EXEC_ERROR 1
|
||||||
#define STMT_STATUS_ERROR 2
|
#define STMT_STATUS_ERROR 2
|
||||||
#define STMT_SEQUENCE_ERROR 3
|
#define STMT_SEQUENCE_ERROR 3
|
||||||
@ -77,7 +84,8 @@ typedef enum {
|
|||||||
#define STMT_BAD_ERROR 27
|
#define STMT_BAD_ERROR 27
|
||||||
|
|
||||||
/* statement types */
|
/* statement types */
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
STMT_TYPE_UNKNOWN = -2,
|
STMT_TYPE_UNKNOWN = -2,
|
||||||
STMT_TYPE_OTHER = -1,
|
STMT_TYPE_OTHER = -1,
|
||||||
STMT_TYPE_SELECT = 0,
|
STMT_TYPE_SELECT = 0,
|
||||||
@ -95,7 +103,8 @@ enum {
|
|||||||
|
|
||||||
|
|
||||||
/* Parsing status */
|
/* Parsing status */
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
STMT_PARSE_NONE = 0,
|
STMT_PARSE_NONE = 0,
|
||||||
STMT_PARSE_COMPLETE,
|
STMT_PARSE_COMPLETE,
|
||||||
STMT_PARSE_INCOMPLETE,
|
STMT_PARSE_INCOMPLETE,
|
||||||
@ -103,19 +112,22 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Result style */
|
/* Result style */
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
STMT_FETCH_NONE = 0,
|
STMT_FETCH_NONE = 0,
|
||||||
STMT_FETCH_NORMAL,
|
STMT_FETCH_NORMAL,
|
||||||
STMT_FETCH_EXTENDED,
|
STMT_FETCH_EXTENDED,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
COL_INFO *col_info; /* cached SQLColumns info for this table */
|
COL_INFO *col_info; /* cached SQLColumns info for this table */
|
||||||
char name[MAX_TABLE_LEN+1];
|
char name[MAX_TABLE_LEN + 1];
|
||||||
char alias[MAX_TABLE_LEN+1];
|
char alias[MAX_TABLE_LEN + 1];
|
||||||
} TABLE_INFO;
|
} TABLE_INFO;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
TABLE_INFO *ti; /* resolve to explicit table names */
|
TABLE_INFO *ti; /* resolve to explicit table names */
|
||||||
int precision;
|
int precision;
|
||||||
int display_size;
|
int display_size;
|
||||||
@ -127,15 +139,17 @@ typedef struct {
|
|||||||
char quote;
|
char quote;
|
||||||
char dquote;
|
char dquote;
|
||||||
char numeric;
|
char numeric;
|
||||||
char dot[MAX_TABLE_LEN+1];
|
char dot[MAX_TABLE_LEN + 1];
|
||||||
char name[MAX_COLUMN_LEN+1];
|
char name[MAX_COLUMN_LEN + 1];
|
||||||
char alias[MAX_COLUMN_LEN+1];
|
char alias[MAX_COLUMN_LEN + 1];
|
||||||
} FIELD_INFO;
|
} FIELD_INFO;
|
||||||
|
|
||||||
|
|
||||||
/******** Statement Handle ***********/
|
/******** Statement Handle ***********/
|
||||||
struct StatementClass_ {
|
struct StatementClass_
|
||||||
ConnectionClass *hdbc; /* pointer to ConnectionClass this statement belongs to */
|
{
|
||||||
|
ConnectionClass *hdbc; /* pointer to ConnectionClass this
|
||||||
|
* statement belongs to */
|
||||||
QResultClass *result; /* result of the current statement */
|
QResultClass *result; /* result of the current statement */
|
||||||
HSTMT FAR *phstmt;
|
HSTMT FAR *phstmt;
|
||||||
StatementOptions options;
|
StatementOptions options;
|
||||||
@ -153,15 +167,22 @@ struct StatementClass_ {
|
|||||||
int parameters_allocated;
|
int parameters_allocated;
|
||||||
ParameterInfoClass *parameters;
|
ParameterInfoClass *parameters;
|
||||||
|
|
||||||
Int4 currTuple; /* current absolute row number (GetData, SetPos, SQLFetch) */
|
Int4 currTuple; /* current absolute row number (GetData,
|
||||||
int save_rowset_size; /* saved rowset size in case of change/FETCH_NEXT */
|
* SetPos, SQLFetch) */
|
||||||
int rowset_start; /* start of rowset (an absolute row number) */
|
int save_rowset_size; /* saved rowset size in case of
|
||||||
int bind_row; /* current offset for Multiple row/column binding */
|
* change/FETCH_NEXT */
|
||||||
int last_fetch_count; /* number of rows retrieved in last fetch/extended fetch */
|
int rowset_start; /* start of rowset (an absolute row
|
||||||
int current_col; /* current column for GetData -- used to handle multiple calls */
|
* 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 */
|
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;
|
TABLE_INFO **ti;
|
||||||
FIELD_INFO **fi;
|
FIELD_INFO **fi;
|
||||||
@ -172,19 +193,25 @@ struct StatementClass_ {
|
|||||||
|
|
||||||
int statement_type; /* According to the defines above */
|
int statement_type; /* According to the defines above */
|
||||||
int data_at_exec; /* Number of params needing SQLPutData */
|
int data_at_exec; /* Number of params needing SQLPutData */
|
||||||
int current_exec_param; /* The current parameter for 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 errormsg_created; /* has an informative error msg
|
||||||
|
* been created? */
|
||||||
char manual_result; /* Is the statement result manually built? */
|
char manual_result; /* Is the statement result manually built? */
|
||||||
char prepare; /* is this statement a prepared statement or direct */
|
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 */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -197,22 +224,22 @@ struct StatementClass_ {
|
|||||||
|
|
||||||
/* Statement prototypes */
|
/* Statement prototypes */
|
||||||
StatementClass *SC_Constructor(void);
|
StatementClass *SC_Constructor(void);
|
||||||
void InitializeStatementOptions(StatementOptions *opt);
|
void InitializeStatementOptions(StatementOptions * opt);
|
||||||
char SC_Destructor(StatementClass *self);
|
char SC_Destructor(StatementClass * self);
|
||||||
int statement_type(char *statement);
|
int statement_type(char *statement);
|
||||||
char parse_statement(StatementClass *stmt);
|
char parse_statement(StatementClass * stmt);
|
||||||
void SC_pre_execute(StatementClass *self);
|
void SC_pre_execute(StatementClass * self);
|
||||||
char SC_unbind_cols(StatementClass *self);
|
char SC_unbind_cols(StatementClass * self);
|
||||||
char SC_recycle_statement(StatementClass *self);
|
char SC_recycle_statement(StatementClass * self);
|
||||||
|
|
||||||
void SC_clear_error(StatementClass *self);
|
void SC_clear_error(StatementClass * self);
|
||||||
char SC_get_error(StatementClass *self, int *number, char **message);
|
char SC_get_error(StatementClass * self, int *number, char **message);
|
||||||
char *SC_create_errormsg(StatementClass *self);
|
char *SC_create_errormsg(StatementClass * self);
|
||||||
RETCODE SC_execute(StatementClass *self);
|
RETCODE SC_execute(StatementClass * self);
|
||||||
RETCODE SC_fetch(StatementClass *self);
|
RETCODE SC_fetch(StatementClass * self);
|
||||||
void SC_free_params(StatementClass *self, char option);
|
void SC_free_params(StatementClass * self, char option);
|
||||||
void SC_log_error(char *func, char *desc, StatementClass *self);
|
void SC_log_error(char *func, char *desc, StatementClass * self);
|
||||||
unsigned long SC_get_bookmark(StatementClass *self);
|
unsigned long SC_get_bookmark(StatementClass * self);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,39 +18,43 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void set_tuplefield_null(TupleField *tuple_field)
|
void
|
||||||
|
set_tuplefield_null(TupleField * tuple_field)
|
||||||
{
|
{
|
||||||
tuple_field->len = 0;
|
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->len = strlen(string);
|
||||||
tuple_field->value = malloc(strlen(string)+1);
|
tuple_field->value = malloc(strlen(string) + 1);
|
||||||
strcpy(tuple_field->value, string);
|
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-...) */
|
/* +1 ... is this correct (better be on the save side-...) */
|
||||||
tuple_field->value = strdup(buffer);
|
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-...) */
|
/* +1 ... is this correct (better be on the save side-...) */
|
||||||
tuple_field->value = strdup(buffer);
|
tuple_field->value = strdup(buffer);
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,17 @@
|
|||||||
#include "psqlodbc.h"
|
#include "psqlodbc.h"
|
||||||
|
|
||||||
/* Used by backend data AND manual result sets */
|
/* Used by backend data AND manual result sets */
|
||||||
struct TupleField_ {
|
struct TupleField_
|
||||||
|
{
|
||||||
Int4 len; /* length of the current Tuple */
|
Int4 len; /* length of the current Tuple */
|
||||||
void *value; /* an array representing the value */
|
void *value; /* an array representing the value */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used ONLY for manual result sets */
|
/* Used ONLY for manual result sets */
|
||||||
struct TupleNode_ {
|
struct TupleNode_
|
||||||
struct TupleNode_ *prev, *next;
|
{
|
||||||
|
struct TupleNode_ *prev,
|
||||||
|
*next;
|
||||||
TupleField tuple[1];
|
TupleField tuple[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,9 +39,9 @@ struct TupleNode_ {
|
|||||||
#define set_nullfield_int2(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int2(FLD, (VAL)) : set_tuplefield_null(FLD))
|
#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))
|
#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_null(TupleField * tuple_field);
|
||||||
void set_tuplefield_string(TupleField *tuple_field, char *string);
|
void set_tuplefield_string(TupleField * tuple_field, char *string);
|
||||||
void set_tuplefield_int2(TupleField *tuple_field, Int2 value);
|
void set_tuplefield_int2(TupleField * tuple_field, Int2 value);
|
||||||
void set_tuplefield_int4(TupleField *tuple_field, Int4 value);
|
void set_tuplefield_int4(TupleField * tuple_field, Int4 value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,12 +18,13 @@
|
|||||||
TupleListClass *
|
TupleListClass *
|
||||||
TL_Constructor(UInt4 fieldcnt)
|
TL_Constructor(UInt4 fieldcnt)
|
||||||
{
|
{
|
||||||
TupleListClass *rv;
|
TupleListClass *rv;
|
||||||
|
|
||||||
mylog("in TL_Constructor\n");
|
mylog("in TL_Constructor\n");
|
||||||
|
|
||||||
rv = (TupleListClass *) malloc(sizeof(TupleListClass));
|
rv = (TupleListClass *) malloc(sizeof(TupleListClass));
|
||||||
if (rv) {
|
if (rv)
|
||||||
|
{
|
||||||
|
|
||||||
rv->num_fields = fieldcnt;
|
rv->num_fields = fieldcnt;
|
||||||
rv->num_tuples = 0;
|
rv->num_tuples = 0;
|
||||||
@ -39,19 +40,20 @@ TupleListClass *rv;
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TL_Destructor(TupleListClass *self)
|
TL_Destructor(TupleListClass * self)
|
||||||
{
|
{
|
||||||
int lf;
|
int lf;
|
||||||
TupleNode *node, *tp;
|
TupleNode *node,
|
||||||
|
*tp;
|
||||||
|
|
||||||
mylog("TupleList: in DESTRUCTOR\n");
|
mylog("TupleList: in DESTRUCTOR\n");
|
||||||
|
|
||||||
node = self->list_start;
|
node = self->list_start;
|
||||||
while(node != NULL) {
|
while (node != NULL)
|
||||||
for (lf=0; lf < self->num_fields; lf++)
|
{
|
||||||
if (node->tuple[lf].value != NULL) {
|
for (lf = 0; lf < self->num_fields; lf++)
|
||||||
|
if (node->tuple[lf].value != NULL)
|
||||||
free(node->tuple[lf].value);
|
free(node->tuple[lf].value);
|
||||||
}
|
|
||||||
tp = node->next;
|
tp = node->next;
|
||||||
free(node);
|
free(node);
|
||||||
node = tp;
|
node = tp;
|
||||||
@ -64,12 +66,14 @@ TupleNode *node, *tp;
|
|||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno)
|
TL_get_fieldval(TupleListClass * self, Int4 tupleno, Int2 fieldno)
|
||||||
{
|
{
|
||||||
Int4 lf;
|
Int4 lf;
|
||||||
Int4 delta, from_end;
|
Int4 delta,
|
||||||
char end_is_closer, start_is_closer;
|
from_end;
|
||||||
TupleNode *rv;
|
char end_is_closer,
|
||||||
|
start_is_closer;
|
||||||
|
TupleNode *rv;
|
||||||
|
|
||||||
if (self->last_indexed == -1)
|
if (self->last_indexed == -1)
|
||||||
/* we have an empty tuple list */
|
/* we have an empty tuple list */
|
||||||
@ -84,9 +88,10 @@ TupleNode *rv;
|
|||||||
/* illegel field number range */
|
/* illegel field number range */
|
||||||
return NULL;
|
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
|
* check if we are accessing the same tuple that was used in the last
|
||||||
another. Do this to speed things up
|
* fetch (e.g: for fetching all the fields one after another. Do this
|
||||||
|
* to speed things up
|
||||||
*/
|
*/
|
||||||
if (tupleno == self->last_indexed)
|
if (tupleno == self->last_indexed)
|
||||||
return self->lastref->tuple[fieldno].value;
|
return self->lastref->tuple[fieldno].value;
|
||||||
@ -94,56 +99,76 @@ TupleNode *rv;
|
|||||||
/* now for the tricky part... */
|
/* now for the tricky part... */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Since random access is quite inefficient for linked lists we use
|
* Since random access is quite inefficient for linked lists we use
|
||||||
the lastref pointer that points to the last element referenced
|
* the lastref pointer that points to the last element referenced by a
|
||||||
by a get_fieldval() call in conjunction with the its index number
|
* get_fieldval() call in conjunction with the its index number that
|
||||||
that is stored in last_indexed. (So we use some locality of
|
* is stored in last_indexed. (So we use some locality of reference
|
||||||
reference principle to speed things up)
|
* principle to speed things up)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
delta = tupleno - self->last_indexed;
|
delta = tupleno - self->last_indexed;
|
||||||
/* if delta is positive, we have to go forward */
|
/* 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;
|
from_end = (self->num_tuples - 1) - tupleno;
|
||||||
|
|
||||||
start_is_closer = labs(delta) > 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;
|
end_is_closer = labs(delta) > from_end;
|
||||||
/* true if we are closer at the end of the list */
|
/* 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... */
|
/* scanning from the end is the shortest way. so we do that... */
|
||||||
rv = self->list_end;
|
rv = self->list_end;
|
||||||
for (lf=0; lf < from_end; lf++)
|
for (lf = 0; lf < from_end; lf++)
|
||||||
rv = rv->prev;
|
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;
|
rv = self->list_start;
|
||||||
for (lf=0; lf < tupleno; lf++)
|
for (lf = 0; lf < tupleno; lf++)
|
||||||
rv = rv->next;
|
rv = rv->next;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* the closest way is starting from our lastref - pointer */
|
/* the closest way is starting from our lastref - pointer */
|
||||||
rv = self->lastref;
|
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 */
|
/* we have to search backwards */
|
||||||
for(lf=0; lf < (-1)*delta; lf++)
|
for (lf = 0; lf < (-1) * delta; lf++)
|
||||||
rv = rv->prev;
|
rv = rv->prev;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* ok, we have to search forward... */
|
/* ok, we have to search forward... */
|
||||||
for (lf=0; lf < delta; lf++)
|
for (lf = 0; lf < delta; lf++)
|
||||||
rv = rv->next;
|
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->lastref = rv;
|
||||||
self->last_indexed = tupleno;
|
self->last_indexed = tupleno;
|
||||||
@ -154,24 +179,31 @@ TupleNode *rv;
|
|||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
TL_add_tuple(TupleListClass *self, TupleNode *new_field)
|
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->prev = NULL;
|
||||||
new_field->next = 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 */
|
/* the list is empty, we have to add the first tuple */
|
||||||
self->list_start = new_field;
|
self->list_start = new_field;
|
||||||
self->list_end = new_field;
|
self->list_end = new_field;
|
||||||
self->lastref = new_field;
|
self->lastref = new_field;
|
||||||
self->last_indexed = 0;
|
self->last_indexed = 0;
|
||||||
} else {
|
}
|
||||||
/* there is already an element in the list, so add the new
|
else
|
||||||
one at the end of the list
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
self->list_end->next = new_field;
|
||||||
new_field->prev = self->list_end;
|
new_field->prev = self->list_end;
|
||||||
@ -182,5 +214,3 @@ TL_add_tuple(TupleListClass *self, TupleNode *new_field)
|
|||||||
/* this method of building a list cannot fail, so we return 1 */
|
/* this method of building a list cannot fail, so we return 1 */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,10 +15,13 @@
|
|||||||
|
|
||||||
#include "psqlodbc.h"
|
#include "psqlodbc.h"
|
||||||
|
|
||||||
struct TupleListClass_ {
|
struct TupleListClass_
|
||||||
|
{
|
||||||
Int4 num_fields;
|
Int4 num_fields;
|
||||||
Int4 num_tuples;
|
Int4 num_tuples;
|
||||||
TupleNode *list_start, *list_end, *lastref;
|
TupleNode *list_start,
|
||||||
|
*list_end,
|
||||||
|
*lastref;
|
||||||
Int4 last_indexed;
|
Int4 last_indexed;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,8 +29,8 @@ struct TupleListClass_ {
|
|||||||
|
|
||||||
/* Create a TupleList. Each tuple consits of fieldcnt columns */
|
/* Create a TupleList. Each tuple consits of fieldcnt columns */
|
||||||
TupleListClass *TL_Constructor(UInt4 fieldcnt);
|
TupleListClass *TL_Constructor(UInt4 fieldcnt);
|
||||||
void TL_Destructor(TupleListClass *self);
|
void TL_Destructor(TupleListClass * self);
|
||||||
void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno);
|
void *TL_get_fieldval(TupleListClass * self, Int4 tupleno, Int2 fieldno);
|
||||||
char TL_add_tuple(TupleListClass *self, TupleNode *new_field);
|
char TL_add_tuple(TupleListClass * self, TupleNode * new_field);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,7 +3,7 @@ This can format all PostgreSQL *.c and *.h files, excluding libpq++,
|
|||||||
|
|
||||||
On 09/06/1997, from the top directory, I ran:
|
On 09/06/1997, from the top directory, I ran:
|
||||||
|
|
||||||
find . -name '*.[ch]' -type f -print | egrep -v '\+\+|/odbc/|s_lock.h' | xargs -n100 pgindent
|
find . -name '*.[ch]' -type f -print | egrep -v '\+\+|s_lock.h' | xargs -n100 pgindent
|
||||||
|
|
||||||
The stock BSD indent has two bugs. First, a comment after the word 'else'
|
The stock BSD indent has two bugs. First, a comment after the word 'else'
|
||||||
causes the rest of the file to be ignored. Second, it silently ignores
|
causes the rest of the file to be ignored. Second, it silently ignores
|
||||||
|
Loading…
x
Reference in New Issue
Block a user