diff options
Diffstat (limited to 'src/interfaces/odbc/convert.c')
-rw-r--r-- | src/interfaces/odbc/convert.c | 1940 |
1 files changed, 1057 insertions, 883 deletions
diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index 12739f32aaf..72aa717ae50 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -1,18 +1,18 @@ -/* Module: convert.c +/* Module: convert.c * - * Description: This module contains routines related to - * converting parameters and columns into requested data types. - * Parameters are converted from their SQL_C data types into - * the appropriate postgres type. Columns are converted from - * their postgres type (SQL type) into the appropriate SQL_C - * data type. + * Description: This module contains routines related to + * converting parameters and columns into requested data types. + * Parameters are converted from their SQL_C data types into + * the appropriate postgres type. Columns are converted from + * their postgres type (SQL type) into the appropriate SQL_C + * data type. * - * Classes: n/a + * Classes: n/a * * API functions: none * - * Comments: See "notice.txt" for copyright and license information. + * Comments: See "notice.txt" for copyright and license information. * */ /* Multibyte support Eiji Tokuya 2001-03-15 */ @@ -58,6 +58,7 @@ #endif #ifndef SCHAR typedef signed char SCHAR; + #endif #endif @@ -69,76 +70,76 @@ extern GLOBAL_VALUES globals; * http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm * - thomas 2000-04-03 */ -char *mapFuncs[][2] = { -/* { "ASCII", "ascii" }, */ - { "CHAR", "chr" }, - { "CONCAT", "textcat" }, +char *mapFuncs[][2] = { +/* { "ASCII", "ascii" }, */ + {"CHAR", "chr"}, + {"CONCAT", "textcat"}, /* { "DIFFERENCE", "difference" }, */ -/* { "INSERT", "insert" }, */ - { "LCASE", "lower" }, - { "LEFT", "ltrunc" }, - { "LOCATE", "strpos" }, - { "LENGTH", "char_length"}, -/* { "LTRIM", "ltrim" }, */ - { "RIGHT", "rtrunc" }, -/* { "REPEAT", "repeat" }, */ -/* { "REPLACE", "replace" }, */ -/* { "RTRIM", "rtrim" }, */ -/* { "SOUNDEX", "soundex" }, */ - { "SUBSTRING", "substr" }, - { "UCASE", "upper" }, - -/* { "ABS", "abs" }, */ -/* { "ACOS", "acos" }, */ -/* { "ASIN", "asin" }, */ -/* { "ATAN", "atan" }, */ -/* { "ATAN2", "atan2" }, */ - { "CEILING", "ceil" }, -/* { "COS", "cos" }, */ -/* { "COT", "cot" }, */ -/* { "DEGREES", "degrees" }, */ -/* { "EXP", "exp" }, */ -/* { "FLOOR", "floor" }, */ - { "LOG", "ln" }, - { "LOG10", "log" }, -/* { "MOD", "mod" }, */ -/* { "PI", "pi" }, */ - { "POWER", "pow" }, -/* { "RADIANS", "radians" }, */ - { "RAND", "random" }, -/* { "ROUND", "round" }, */ -/* { "SIGN", "sign" }, */ -/* { "SIN", "sin" }, */ -/* { "SQRT", "sqrt" }, */ -/* { "TAN", "tan" }, */ - { "TRUNCATE", "trunc" }, - -/* { "CURDATE", "curdate" }, */ -/* { "CURTIME", "curtime" }, */ -/* { "DAYNAME", "dayname" }, */ +/* { "INSERT", "insert" }, */ + {"LCASE", "lower"}, + {"LEFT", "ltrunc"}, + {"LOCATE", "strpos"}, + {"LENGTH", "char_length"}, +/* { "LTRIM", "ltrim" }, */ + {"RIGHT", "rtrunc"}, +/* { "REPEAT", "repeat" }, */ +/* { "REPLACE", "replace" }, */ +/* { "RTRIM", "rtrim" }, */ +/* { "SOUNDEX", "soundex" }, */ + {"SUBSTRING", "substr"}, + {"UCASE", "upper"}, + +/* { "ABS", "abs" }, */ +/* { "ACOS", "acos" }, */ +/* { "ASIN", "asin" }, */ +/* { "ATAN", "atan" }, */ +/* { "ATAN2", "atan2" }, */ + {"CEILING", "ceil"}, +/* { "COS", "cos" }, */ +/* { "COT", "cot" }, */ +/* { "DEGREES", "degrees" }, */ +/* { "EXP", "exp" }, */ +/* { "FLOOR", "floor" }, */ + {"LOG", "ln"}, + {"LOG10", "log"}, +/* { "MOD", "mod" }, */ +/* { "PI", "pi" }, */ + {"POWER", "pow"}, +/* { "RADIANS", "radians" }, */ + {"RAND", "random"}, +/* { "ROUND", "round" }, */ +/* { "SIGN", "sign" }, */ +/* { "SIN", "sin" }, */ +/* { "SQRT", "sqrt" }, */ +/* { "TAN", "tan" }, */ + {"TRUNCATE", "trunc"}, + +/* { "CURDATE", "curdate" }, */ +/* { "CURTIME", "curtime" }, */ +/* { "DAYNAME", "dayname" }, */ /* { "DAYOFMONTH", "dayofmonth" }, */ -/* { "DAYOFWEEK", "dayofweek" }, */ -/* { "DAYOFYEAR", "dayofyear" }, */ -/* { "HOUR", "hour" }, */ -/* { "MINUTE", "minute" }, */ -/* { "MONTH", "month" }, */ -/* { "MONTHNAME", "monthname" }, */ -/* { "NOW", "now" }, */ -/* { "QUARTER", "quarter" }, */ -/* { "SECOND", "second" }, */ -/* { "WEEK", "week" }, */ -/* { "YEAR", "year" }, */ - -/* { "DATABASE", "database" }, */ - { "IFNULL", "coalesce" }, - { "USER", "odbc_user" }, - { 0, 0 } +/* { "DAYOFWEEK", "dayofweek" }, */ +/* { "DAYOFYEAR", "dayofyear" }, */ +/* { "HOUR", "hour" }, */ +/* { "MINUTE", "minute" }, */ +/* { "MONTH", "month" }, */ +/* { "MONTHNAME", "monthname" }, */ +/* { "NOW", "now" }, */ +/* { "QUARTER", "quarter" }, */ +/* { "SECOND", "second" }, */ +/* { "WEEK", "week" }, */ +/* { "YEAR", "year" }, */ + +/* { "DATABASE", "database" }, */ + {"IFNULL", "coalesce"}, + {"USER", "odbc_user"}, + {0, 0} }; -char *mapFunction(char *func); +char *mapFunction(char *func); unsigned int conv_from_octal(unsigned char *s); unsigned int conv_from_hex(unsigned char *s); -char *conv_to_octal(unsigned char val); +char *conv_to_octal(unsigned char val); /******** A Guide for date/time/timestamp conversions ************** @@ -150,10 +151,10 @@ char *conv_to_octal(unsigned char val); PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME PG_TYPE_TIME SQL_C_TIME SQL_C_TIME PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date) - PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP - PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated) - PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated) - PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP + PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP + PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated) + PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated) + PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP ******************************************************************************/ @@ -161,36 +162,41 @@ char *conv_to_octal(unsigned char val); int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col) { -BindInfoClass *bic = &(stmt->bindings[col]); + BindInfoClass *bic = &(stmt->bindings[col]); - return copy_and_convert_field(stmt, field_type, value, (Int2)bic->returntype, (PTR)bic->buffer, - (SDWORD)bic->buflen, (SDWORD *)bic->used); + return copy_and_convert_field(stmt, field_type, value, (Int2) bic->returntype, (PTR) bic->buffer, + (SDWORD) bic->buflen, (SDWORD *) bic->used); } /* This is called by SQLGetData() */ int -copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, +copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue) { - Int4 len = 0, copy_len = 0; + Int4 len = 0, + copy_len = 0; SIMPLE_TIME st; - time_t t = time(NULL); - struct tm *tim; - int pcbValueOffset, rgbValueOffset; - char *rgbValueBindRow, *ptr; - int bind_row = stmt->bind_row; - int bind_size = stmt->options.bind_size; - int result = COPY_OK; - char tempBuf[TEXT_FIELD_SIZE+5]; + time_t t = time(NULL); + struct tm *tim; + int pcbValueOffset, + rgbValueOffset; + char *rgbValueBindRow, + *ptr; + int bind_row = stmt->bind_row; + int bind_size = stmt->options.bind_size; + int result = COPY_OK; + char tempBuf[TEXT_FIELD_SIZE + 5]; /* rgbValueOffset is *ONLY* for character and binary data */ /* pcbValueOffset is for computing any pcbValue location */ - if (bind_size > 0) { + if (bind_size > 0) + { pcbValueOffset = rgbValueOffset = (bind_size * bind_row); } - else { + else + { pcbValueOffset = bind_row * sizeof(SDWORD); rgbValueOffset = bind_row * cbValueMax; @@ -199,31 +205,33 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 memset(&st, 0, sizeof(SIMPLE_TIME)); - /* Initialize current date */ + /* Initialize current date */ tim = localtime(&t); st.m = tim->tm_mon + 1; st.d = tim->tm_mday; st.y = tim->tm_year + 1900; - mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value==NULL)?"<NULL>":value, cbValueMax); + mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value == NULL) ? "<NULL>" : value, cbValueMax); - if ( ! value) { - /* handle a null just by returning SQL_NULL_DATA in pcbValue, */ - /* and doing nothing to the buffer. */ - if(pcbValue) { + if (!value) + { + /* handle a null just by returning SQL_NULL_DATA in pcbValue, */ + /* and doing nothing to the buffer. */ + if (pcbValue) *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA; - } return COPY_OK; } - if (stmt->hdbc->DataSourceToDriver != NULL) { - int length = strlen (value); - stmt->hdbc->DataSourceToDriver (stmt->hdbc->translation_option, - SQL_CHAR, - value, length, - value, length, NULL, - NULL, 0, NULL); + if (stmt->hdbc->DataSourceToDriver != NULL) + { + int length = strlen(value); + + stmt->hdbc->DataSourceToDriver(stmt->hdbc->translation_option, + SQL_CHAR, + value, length, + value, length, NULL, + NULL, 0, NULL); } @@ -231,111 +239,131 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 First convert any specific postgres types into more useable data. - NOTE: Conversions from PG char/varchar of a date/time/timestamp - value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported + NOTE: Conversions from PG char/varchar of a date/time/timestamp + value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported *********************************************************************/ - switch(field_type) { - /* $$$ need to add parsing for date/time/timestamp strings in PG_TYPE_CHAR,VARCHAR $$$ */ - case PG_TYPE_DATE: - sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d); - break; - - case PG_TYPE_TIME: - sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss); - break; - - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP: - if (strnicmp(value, "invalid", 7) != 0) { - sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss); - - } else { /* The timestamp is invalid so set something conspicuous, like the epoch */ - t = 0; - tim = localtime(&t); - st.m = tim->tm_mon + 1; - st.d = tim->tm_mday; - st.y = tim->tm_year + 1900; - st.hh = tim->tm_hour; - st.mm = tim->tm_min; - st.ss = tim->tm_sec; - } - break; - - case PG_TYPE_BOOL: { /* change T/F to 1/0 */ - char *s = (char *) value; - if (s[0] == 'T' || s[0] == 't') - s[0] = '1'; - else - s[0] = '0'; - } - break; - - /* This is for internal use by SQLStatistics() */ - case PG_TYPE_INT2VECTOR: { - int nval, i; - char *vp; - /* this is an array of eight integers */ - short *short_array = (short *) ( (char *) rgbValue + rgbValueOffset); - - len = 32; - vp = value; - nval = 0; -mylog("index=("); - for (i = 0; i < 16; i++) - { - if (sscanf(vp, "%hd", &short_array[i]) != 1) - break; + switch (field_type) + { -mylog(" %d", short_array[i]); - nval++; + /* + * $$$ need to add parsing for date/time/timestamp strings in + * PG_TYPE_CHAR,VARCHAR $$$ + */ + case PG_TYPE_DATE: + sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d); + break; - /* skip the current token */ - while ((*vp != '\0') && (! isspace((unsigned char) *vp))) vp++; - /* and skip the space to the next token */ - while ((*vp != '\0') && (isspace((unsigned char) *vp))) vp++; - if (*vp == '\0') - break; - } -mylog(") nval = %d\n", nval); + case PG_TYPE_TIME: + sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss); + break; - for (i = nval; i < 16; i++) - { - short_array[i] = 0; - } + case PG_TYPE_ABSTIME: + case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP: + if (strnicmp(value, "invalid", 7) != 0) + { + sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss); + + } + else + { /* The timestamp is invalid so set + * something conspicuous, like the epoch */ + t = 0; + tim = localtime(&t); + st.m = tim->tm_mon + 1; + st.d = tim->tm_mday; + st.y = tim->tm_year + 1900; + st.hh = tim->tm_hour; + st.mm = tim->tm_min; + st.ss = tim->tm_sec; + } + break; + + case PG_TYPE_BOOL: + { /* change T/F to 1/0 */ + char *s = (char *) value; + + if (s[0] == 'T' || s[0] == 't') + s[0] = '1'; + else + s[0] = '0'; + } + break; + + /* This is for internal use by SQLStatistics() */ + case PG_TYPE_INT2VECTOR: + { + int nval, + i; + char *vp; + + /* this is an array of eight integers */ + short *short_array = (short *) ((char *) rgbValue + rgbValueOffset); + + len = 32; + vp = value; + nval = 0; + mylog("index=("); + for (i = 0; i < 16; i++) + { + if (sscanf(vp, "%hd", &short_array[i]) != 1) + break; + + mylog(" %d", short_array[i]); + nval++; + + /* skip the current token */ + while ((*vp != '\0') && (!isspace((unsigned char) *vp))) + vp++; + /* and skip the space to the next token */ + while ((*vp != '\0') && (isspace((unsigned char) *vp))) + vp++; + if (*vp == '\0') + break; + } + mylog(") nval = %d\n", nval); + + for (i = nval; i < 16; i++) + short_array[i] = 0; #if 0 - sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd", - &short_array[0], - &short_array[1], - &short_array[2], - &short_array[3], - &short_array[4], - &short_array[5], - &short_array[6], - &short_array[7]); + sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd", + &short_array[0], + &short_array[1], + &short_array[2], + &short_array[3], + &short_array[4], + &short_array[5], + &short_array[6], + &short_array[7]); #endif - /* There is no corresponding fCType for this. */ - if(pcbValue) - *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len; + /* There is no corresponding fCType for this. */ + if (pcbValue) + *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len; - return COPY_OK; /* dont go any further or the data will be trashed */ - } + return COPY_OK; /* dont go any further or the data will be + * trashed */ + } - /* This is a large object OID, which is used to store LONGVARBINARY objects. */ - case PG_TYPE_LO: + /* + * This is a large object OID, which is used to store + * LONGVARBINARY objects. + */ + case PG_TYPE_LO: - return convert_lo( stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); + return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); - default: + default: - if (field_type == stmt->hdbc->lobj_type) /* hack until permanent type available */ - return convert_lo( stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); + if (field_type == stmt->hdbc->lobj_type) /* hack until permanent + * type available */ + return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); } - /* Change default into something useable */ - if (fCType == SQL_C_DEFAULT) { + /* Change default into something useable */ + if (fCType == SQL_C_DEFAULT) + { fCType = pgtype_to_ctype(stmt, field_type); mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType); @@ -344,297 +372,318 @@ mylog(") nval = %d\n", nval); rgbValueBindRow = (char *) rgbValue + rgbValueOffset; - if(fCType == SQL_C_CHAR) { + if (fCType == SQL_C_CHAR) + { - /* Special character formatting as required */ - /* These really should return error if cbValueMax is not big enough. */ - switch(field_type) { - case PG_TYPE_DATE: - len = 10; - if (cbValueMax > len) - sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d", st.y, st.m, st.d); - break; + /* Special character formatting as required */ - case PG_TYPE_TIME: - len = 8; - if (cbValueMax > len) - sprintf(rgbValueBindRow, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss); - break; - - case PG_TYPE_ABSTIME: - case PG_TYPE_DATETIME: - case PG_TYPE_TIMESTAMP: - len = 19; - if (cbValueMax > len) - sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", - st.y, st.m, st.d, st.hh, st.mm, st.ss); - break; + /* + * These really should return error if cbValueMax is not big + * enough. + */ + switch (field_type) + { + case PG_TYPE_DATE: + len = 10; + if (cbValueMax > len) + sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d", st.y, st.m, st.d); + break; - case PG_TYPE_BOOL: - len = 1; - if (cbValueMax > len) { - strcpy(rgbValueBindRow, value); - mylog("PG_TYPE_BOOL: rgbValueBindRow = '%s'\n", rgbValueBindRow); - } - break; + case PG_TYPE_TIME: + len = 8; + if (cbValueMax > len) + sprintf(rgbValueBindRow, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss); + break; - /* Currently, data is SILENTLY TRUNCATED for BYTEA and character data - types if there is not enough room in cbValueMax because the driver - can't handle multiple calls to SQLGetData for these, yet. Most likely, - the buffer passed in will be big enough to handle the maximum limit of - postgres, anyway. + case PG_TYPE_ABSTIME: + case PG_TYPE_DATETIME: + case PG_TYPE_TIMESTAMP: + len = 19; + if (cbValueMax > len) + sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", + st.y, st.m, st.d, st.hh, st.mm, st.ss); + break; - LongVarBinary types are handled correctly above, observing truncation - and all that stuff since there is essentially no limit on the large - object used to store those. - */ - case PG_TYPE_BYTEA: /* convert binary data to hex strings (i.e, 255 = "FF") */ - len = convert_pgbinary_to_char(value, rgbValueBindRow, cbValueMax); + case PG_TYPE_BOOL: + len = 1; + if (cbValueMax > len) + { + strcpy(rgbValueBindRow, value); + mylog("PG_TYPE_BOOL: rgbValueBindRow = '%s'\n", rgbValueBindRow); + } + break; - /***** THIS IS NOT PROPERLY IMPLEMENTED *****/ - break; + /* + * Currently, data is SILENTLY TRUNCATED for BYTEA and + * character data types if there is not enough room in + * cbValueMax because the driver can't handle multiple + * calls to SQLGetData for these, yet. Most likely, the + * buffer passed in will be big enough to handle the + * maximum limit of postgres, anyway. + * + * LongVarBinary types are handled correctly above, observing + * truncation and all that stuff since there is + * essentially no limit on the large object used to store + * those. + */ + case PG_TYPE_BYTEA:/* convert binary data to hex strings + * (i.e, 255 = "FF") */ + len = convert_pgbinary_to_char(value, rgbValueBindRow, cbValueMax); + + /***** THIS IS NOT PROPERLY IMPLEMENTED *****/ + break; - default: - /* convert linefeeds to carriage-return/linefeed */ - len = convert_linefeeds(value, tempBuf, sizeof(tempBuf)); - ptr = tempBuf; - - mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr); - - if (stmt->current_col >= 0) { - if (stmt->bindings[stmt->current_col].data_left == 0) - return COPY_NO_DATA_FOUND; - else if (stmt->bindings[stmt->current_col].data_left > 0) { - ptr += len - stmt->bindings[stmt->current_col].data_left; - len = stmt->bindings[stmt->current_col].data_left; + default: + /* convert linefeeds to carriage-return/linefeed */ + len = convert_linefeeds(value, tempBuf, sizeof(tempBuf)); + ptr = tempBuf; + + mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr); + + if (stmt->current_col >= 0) + { + if (stmt->bindings[stmt->current_col].data_left == 0) + return COPY_NO_DATA_FOUND; + else if (stmt->bindings[stmt->current_col].data_left > 0) + { + ptr += len - stmt->bindings[stmt->current_col].data_left; + len = stmt->bindings[stmt->current_col].data_left; + } + else + stmt->bindings[stmt->current_col].data_left = strlen(ptr); } - else - stmt->bindings[stmt->current_col].data_left = strlen(ptr); - } - if (cbValueMax > 0) { - - copy_len = (len >= cbValueMax) ? cbValueMax -1 : len; + if (cbValueMax > 0) + { + + copy_len = (len >= cbValueMax) ? cbValueMax - 1 : len; - /* Copy the data */ - strncpy_null(rgbValueBindRow, ptr, copy_len + 1); + /* Copy the data */ + strncpy_null(rgbValueBindRow, ptr, copy_len + 1); - /* Adjust data_left for next time */ - if (stmt->current_col >= 0) { - stmt->bindings[stmt->current_col].data_left -= copy_len; + /* Adjust data_left for next time */ + if (stmt->current_col >= 0) + stmt->bindings[stmt->current_col].data_left -= copy_len; } - } - /* Finally, check for truncation so that proper status can be returned */ - if ( len >= cbValueMax) - result = COPY_RESULT_TRUNCATED; + /* + * Finally, check for truncation so that proper status can + * be returned + */ + if (len >= cbValueMax) + result = COPY_RESULT_TRUNCATED; - mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValueBindRow = '%s'\n", len, cbValueMax, rgbValueBindRow); - break; + mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValueBindRow = '%s'\n", len, cbValueMax, rgbValueBindRow); + break; } - } else { + } + else + { - /* for SQL_C_CHAR, it's probably ok to leave currency symbols in. But - to convert to numeric types, it is necessary to get rid of those. - */ + /* + * for SQL_C_CHAR, it's probably ok to leave currency symbols in. + * But to convert to numeric types, it is necessary to get rid of + * those. + */ if (field_type == PG_TYPE_MONEY) convert_money(value); - switch(fCType) { - case SQL_C_DATE: - len = 6; - { - DATE_STRUCT *ds; - - if (bind_size > 0) { - ds = (DATE_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - } else { - ds = (DATE_STRUCT *) rgbValue + bind_row; - } - ds->year = st.y; - ds->month = st.m; - ds->day = st.d; - } - break; + switch (fCType) + { + case SQL_C_DATE: + len = 6; + { + DATE_STRUCT *ds; + + if (bind_size > 0) + ds = (DATE_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); + else + ds = (DATE_STRUCT *) rgbValue + bind_row; + ds->year = st.y; + ds->month = st.m; + ds->day = st.d; + } + break; - case SQL_C_TIME: - len = 6; - { - TIME_STRUCT *ts; - - if (bind_size > 0) { - ts = (TIME_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - } else { - ts = (TIME_STRUCT *) rgbValue + bind_row; - } - ts->hour = st.hh; - ts->minute = st.mm; - ts->second = st.ss; - } - break; + case SQL_C_TIME: + len = 6; + { + TIME_STRUCT *ts; + + if (bind_size > 0) + ts = (TIME_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); + else + ts = (TIME_STRUCT *) rgbValue + bind_row; + ts->hour = st.hh; + ts->minute = st.mm; + ts->second = st.ss; + } + break; - case SQL_C_TIMESTAMP: - len = 16; - { - TIMESTAMP_STRUCT *ts; - if (bind_size > 0) { - ts = (TIMESTAMP_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); - } else { - ts = (TIMESTAMP_STRUCT *) rgbValue + bind_row; - } - ts->year = st.y; - ts->month = st.m; - ts->day = st.d; - ts->hour = st.hh; - ts->minute = st.mm; - ts->second = st.ss; - ts->fraction = 0; - } - break; + case SQL_C_TIMESTAMP: + len = 16; + { + TIMESTAMP_STRUCT *ts; + + if (bind_size > 0) + ts = (TIMESTAMP_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); + else + ts = (TIMESTAMP_STRUCT *) rgbValue + bind_row; + ts->year = st.y; + ts->month = st.m; + ts->day = st.d; + ts->hour = st.hh; + ts->minute = st.mm; + ts->second = st.ss; + ts->fraction = 0; + } + break; - case SQL_C_BIT: - len = 1; - if (bind_size > 0) { - *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); - } else { - *((UCHAR *)rgbValue + bind_row) = atoi(value); - } - /* mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", atoi(value), cbValueMax, *((UCHAR *)rgbValue)); */ - break; + case SQL_C_BIT: + len = 1; + if (bind_size > 0) + *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); + else + *((UCHAR *) rgbValue + bind_row) = atoi(value); - case SQL_C_STINYINT: - case SQL_C_TINYINT: - len = 1; - if (bind_size > 0) { - *(SCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); - } else { - *((SCHAR *) rgbValue + bind_row) = atoi(value); - } - break; + /* + * mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", + * atoi(value), cbValueMax, *((UCHAR *)rgbValue)); + */ + break; - case SQL_C_UTINYINT: - len = 1; - if (bind_size > 0) { - *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); - } else { - *((UCHAR *) rgbValue + bind_row) = atoi(value); - } - break; + case SQL_C_STINYINT: + case SQL_C_TINYINT: + len = 1; + if (bind_size > 0) + *(SCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); + else + *((SCHAR *) rgbValue + bind_row) = atoi(value); + break; - case SQL_C_FLOAT: - len = 4; - if (bind_size > 0) { - *(SFLOAT *) ((char *) rgbValue + (bind_row * bind_size)) = (float) atof(value); - } else { - *((SFLOAT *)rgbValue + bind_row) = (float) atof(value); - } - break; + case SQL_C_UTINYINT: + len = 1; + if (bind_size > 0) + *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); + else + *((UCHAR *) rgbValue + bind_row) = atoi(value); + break; - case SQL_C_DOUBLE: - len = 8; - if (bind_size > 0) { - *(SDOUBLE *) ((char *) rgbValue + (bind_row * bind_size)) = atof(value); - } else { - *((SDOUBLE *)rgbValue + bind_row) = atof(value); - } - break; + case SQL_C_FLOAT: + len = 4; + if (bind_size > 0) + *(SFLOAT *) ((char *) rgbValue + (bind_row * bind_size)) = (float) atof(value); + else + *((SFLOAT *) rgbValue + bind_row) = (float) atof(value); + break; - case SQL_C_SSHORT: - case SQL_C_SHORT: - len = 2; - if (bind_size > 0) { - *(SWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); - } else { - *((SWORD *)rgbValue + bind_row) = atoi(value); - } - break; + case SQL_C_DOUBLE: + len = 8; + if (bind_size > 0) + *(SDOUBLE *) ((char *) rgbValue + (bind_row * bind_size)) = atof(value); + else + *((SDOUBLE *) rgbValue + bind_row) = atof(value); + break; - case SQL_C_USHORT: - len = 2; - if (bind_size > 0) { - *(UWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); - } else { - *((UWORD *)rgbValue + bind_row) = atoi(value); - } - break; + case SQL_C_SSHORT: + case SQL_C_SHORT: + len = 2; + if (bind_size > 0) + *(SWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); + else + *((SWORD *) rgbValue + bind_row) = atoi(value); + break; - case SQL_C_SLONG: - case SQL_C_LONG: - len = 4; - if (bind_size > 0) { - *(SDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); - } else { - *((SDWORD *)rgbValue + bind_row) = atol(value); - } - break; + case SQL_C_USHORT: + len = 2; + if (bind_size > 0) + *(UWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); + else + *((UWORD *) rgbValue + bind_row) = atoi(value); + break; - case SQL_C_ULONG: - len = 4; - if (bind_size > 0) { - *(UDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); - } else { - *((UDWORD *)rgbValue + bind_row) = atol(value); - } - break; + case SQL_C_SLONG: + case SQL_C_LONG: + len = 4; + if (bind_size > 0) + *(SDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); + else + *((SDWORD *) rgbValue + bind_row) = atol(value); + break; + + case SQL_C_ULONG: + len = 4; + if (bind_size > 0) + *(UDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); + else + *((UDWORD *) rgbValue + bind_row) = atol(value); + break; - case SQL_C_BINARY: + case SQL_C_BINARY: - /* truncate if necessary */ - /* convert octal escapes to bytes */ + /* truncate if necessary */ + /* convert octal escapes to bytes */ - len = convert_from_pgbinary(value, tempBuf, sizeof(tempBuf)); - ptr = tempBuf; + len = convert_from_pgbinary(value, tempBuf, sizeof(tempBuf)); + ptr = tempBuf; - if (stmt->current_col >= 0) { + if (stmt->current_col >= 0) + { - /* No more data left for this column */ - if (stmt->bindings[stmt->current_col].data_left == 0) - return COPY_NO_DATA_FOUND; + /* No more data left for this column */ + if (stmt->bindings[stmt->current_col].data_left == 0) + return COPY_NO_DATA_FOUND; - /* Second (or more) call to SQLGetData so move the pointer */ - else if (stmt->bindings[stmt->current_col].data_left > 0) { - ptr += len - stmt->bindings[stmt->current_col].data_left; - len = stmt->bindings[stmt->current_col].data_left; - } + /* + * Second (or more) call to SQLGetData so move the + * pointer + */ + else if (stmt->bindings[stmt->current_col].data_left > 0) + { + ptr += len - stmt->bindings[stmt->current_col].data_left; + len = stmt->bindings[stmt->current_col].data_left; + } - /* First call to SQLGetData so initialize data_left */ - else - stmt->bindings[stmt->current_col].data_left = len; + /* First call to SQLGetData so initialize data_left */ + else + stmt->bindings[stmt->current_col].data_left = len; - } + } - if (cbValueMax > 0) { - copy_len = (len > cbValueMax) ? cbValueMax : len; + if (cbValueMax > 0) + { + copy_len = (len > cbValueMax) ? cbValueMax : len; - /* Copy the data */ - memcpy(rgbValueBindRow, ptr, copy_len); + /* Copy the data */ + memcpy(rgbValueBindRow, ptr, copy_len); - /* Adjust data_left for next time */ - if (stmt->current_col >= 0) { - stmt->bindings[stmt->current_col].data_left -= copy_len; + /* Adjust data_left for next time */ + if (stmt->current_col >= 0) + stmt->bindings[stmt->current_col].data_left -= copy_len; } - } - /* Finally, check for truncation so that proper status can be returned */ - if ( len > cbValueMax) - result = COPY_RESULT_TRUNCATED; + /* + * Finally, check for truncation so that proper status can + * be returned + */ + if (len > cbValueMax) + result = COPY_RESULT_TRUNCATED; - mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len); - break; - - default: - return COPY_UNSUPPORTED_TYPE; + mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len); + break; + + default: + return COPY_UNSUPPORTED_TYPE; } } - /* store the length of what was copied, if there's a place for it */ - if(pcbValue) { - *(SDWORD *) ((char *)pcbValue + pcbValueOffset) = len; - } + /* store the length of what was copied, if there's a place for it */ + if (pcbValue) + *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len; return result; @@ -648,91 +697,111 @@ mylog(") nval = %d\n", nval); int copy_statement_with_parameters(StatementClass *stmt) { -static char *func="copy_statement_with_parameters"; -unsigned int opos, npos, oldstmtlen; -char param_string[128], tmp[256], cbuf[TEXT_FIELD_SIZE+5]; -int param_number; -Int2 param_ctype, param_sqltype; -char *old_statement = stmt->statement; -char *new_statement = stmt->stmt_with_params; -SIMPLE_TIME st; -time_t t = time(NULL); -struct tm *tim; -SDWORD used; -char *buffer, *buf; -char in_quote = FALSE; -Oid lobj_oid; -int lobj_fd, retval; - - - if ( ! old_statement) { + static char *func = "copy_statement_with_parameters"; + unsigned int opos, + npos, + oldstmtlen; + char param_string[128], + tmp[256], + cbuf[TEXT_FIELD_SIZE + 5]; + int param_number; + Int2 param_ctype, + param_sqltype; + char *old_statement = stmt->statement; + char *new_statement = stmt->stmt_with_params; + SIMPLE_TIME st; + time_t t = time(NULL); + struct tm *tim; + SDWORD used; + char *buffer, + *buf; + char in_quote = FALSE; + Oid lobj_oid; + int lobj_fd, + retval; + + + if (!old_statement) + { SC_log_error(func, "No statement string", stmt); return SQL_ERROR; } memset(&st, 0, sizeof(SIMPLE_TIME)); - /* Initialize current date */ + /* Initialize current date */ tim = localtime(&t); st.m = tim->tm_mon + 1; st.d = tim->tm_mday; st.y = tim->tm_year + 1900; - /* If the application hasn't set a cursor name, then generate one */ - if ( stmt->cursor_name[0] == '\0') + /* If the application hasn't set a cursor name, then generate one */ + if (stmt->cursor_name[0] == '\0') sprintf(stmt->cursor_name, "SQL_CUR%p", stmt); - /* For selects, prepend a declare cursor to the statement */ - if (stmt->statement_type == STMT_TYPE_SELECT && globals.use_declarefetch) { + /* For selects, prepend a declare cursor to the statement */ + if (stmt->statement_type == STMT_TYPE_SELECT && globals.use_declarefetch) + { sprintf(new_statement, "declare %s cursor for ", stmt->cursor_name); npos = strlen(new_statement); } - else { + else + { new_statement[0] = '0'; npos = 0; } - param_number = -1; + param_number = -1; oldstmtlen = strlen(old_statement); #ifdef MULTIBYTE - multibyte_init(); + multibyte_init(); #endif - for (opos = 0; opos < oldstmtlen; opos++) { + for (opos = 0; opos < oldstmtlen; opos++) + { - /* Squeeze carriage-return/linefeed pairs to linefeed only */ - if (old_statement[opos] == '\r' && opos+1 < oldstmtlen && - old_statement[opos+1] == '\n') { + /* Squeeze carriage-return/linefeed pairs to linefeed only */ + if (old_statement[opos] == '\r' && opos + 1 < oldstmtlen && + old_statement[opos + 1] == '\n') continue; - } - /* Handle literals (date, time, timestamp) and ODBC scalar functions */ + /* + * Handle literals (date, time, timestamp) and ODBC scalar + * functions + */ #ifdef MULTIBYTE - else if (multibyte_char_check(old_statement[opos]) == 0 && old_statement[opos] == '{') { + else if (multibyte_char_check(old_statement[opos]) == 0 && old_statement[opos] == '{') + { #else - else if (old_statement[opos] == '{') { + else if (old_statement[opos] == '{') + { #endif - char *esc; - char *begin = &old_statement[opos + 1]; + char *esc; + char *begin = &old_statement[opos + 1]; + #ifdef MULTIBYTE - char *end = multibyte_strchr(begin, '}'); + char *end = multibyte_strchr(begin, '}'); + #else - char *end = strchr(begin, '}'); + char *end = strchr(begin, '}'); + #endif - if ( ! end) + if (!end) continue; *end = '\0'; esc = convert_escape(begin); - if (esc) { + if (esc) + { memcpy(&new_statement[npos], esc, strlen(esc)); npos += strlen(esc); } - else { /* it's not a valid literal so just copy */ - *end = '}'; + else + { /* it's not a valid literal so just copy */ + *end = '}'; new_statement[npos++] = old_statement[opos]; continue; } @@ -744,12 +813,15 @@ int lobj_fd, retval; continue; } - /* Can you have parameter markers inside of quotes? I dont think so. - All the queries I've seen expect the driver to put quotes if needed. - */ + /* + * Can you have parameter markers inside of quotes? I dont think + * so. All the queries I've seen expect the driver to put quotes + * if needed. + */ else if (old_statement[opos] == '?' && !in_quote) - ; /* ok */ - else { + ; /* ok */ + else + { if (old_statement[opos] == '\'') in_quote = (in_quote ? FALSE : TRUE); @@ -760,390 +832,433 @@ int lobj_fd, retval; /****************************************************/ - /* Its a '?' parameter alright */ + /* Its a '?' parameter alright */ /****************************************************/ param_number++; - if (param_number >= stmt->parameters_allocated) + if (param_number >= stmt->parameters_allocated) break; - /* Assign correct buffers based on data at exec param or not */ - if ( stmt->parameters[param_number].data_at_exec) { + /* Assign correct buffers based on data at exec param or not */ + if (stmt->parameters[param_number].data_at_exec) + { used = stmt->parameters[param_number].EXEC_used ? *stmt->parameters[param_number].EXEC_used : SQL_NTS; buffer = stmt->parameters[param_number].EXEC_buffer; } - else { + else + { used = stmt->parameters[param_number].used ? *stmt->parameters[param_number].used : SQL_NTS; buffer = stmt->parameters[param_number].buffer; } - /* Handle NULL parameter data */ - if (used == SQL_NULL_DATA) { + /* Handle NULL parameter data */ + if (used == SQL_NULL_DATA) + { strcpy(&new_statement[npos], "NULL"); npos += 4; continue; } - /* If no buffer, and it's not null, then what the hell is it? - Just leave it alone then. - */ - if ( ! buffer) { + /* + * If no buffer, and it's not null, then what the hell is it? Just + * leave it alone then. + */ + if (!buffer) + { new_statement[npos++] = '?'; continue; } param_ctype = stmt->parameters[param_number].CType; param_sqltype = stmt->parameters[param_number].SQLType; - + mylog("copy_statement_with_params: from(fcType)=%d, to(fSqlType)=%d\n", param_ctype, param_sqltype); - + /* replace DEFAULT with something we can use */ - if(param_ctype == SQL_C_DEFAULT) + if (param_ctype == SQL_C_DEFAULT) param_ctype = sqltype_to_default_ctype(param_sqltype); buf = NULL; param_string[0] = '\0'; cbuf[0] = '\0'; - - /* Convert input C type to a neutral format */ - switch(param_ctype) { - case SQL_C_BINARY: - case SQL_C_CHAR: - buf = buffer; - break; - case SQL_C_DOUBLE: - sprintf(param_string, "%f", - *((SDOUBLE *) buffer)); - break; + /* Convert input C type to a neutral format */ + switch (param_ctype) + { + case SQL_C_BINARY: + case SQL_C_CHAR: + buf = buffer; + break; - case SQL_C_FLOAT: - sprintf(param_string, "%f", - *((SFLOAT *) buffer)); - break; + case SQL_C_DOUBLE: + sprintf(param_string, "%f", + *((SDOUBLE *) buffer)); + break; - case SQL_C_SLONG: - case SQL_C_LONG: - sprintf(param_string, "%ld", - *((SDWORD *) buffer)); - break; + case SQL_C_FLOAT: + sprintf(param_string, "%f", + *((SFLOAT *) buffer)); + break; - case SQL_C_SSHORT: - case SQL_C_SHORT: - sprintf(param_string, "%d", - *((SWORD *) buffer)); - break; + case SQL_C_SLONG: + case SQL_C_LONG: + sprintf(param_string, "%ld", + *((SDWORD *) buffer)); + break; - case SQL_C_STINYINT: - case SQL_C_TINYINT: - sprintf(param_string, "%d", - *((SCHAR *) buffer)); - break; + case SQL_C_SSHORT: + case SQL_C_SHORT: + sprintf(param_string, "%d", + *((SWORD *) buffer)); + break; - case SQL_C_ULONG: - sprintf(param_string, "%lu", - *((UDWORD *) buffer)); - break; + case SQL_C_STINYINT: + case SQL_C_TINYINT: + sprintf(param_string, "%d", + *((SCHAR *) buffer)); + break; - case SQL_C_USHORT: - sprintf(param_string, "%u", - *((UWORD *) buffer)); - break; + case SQL_C_ULONG: + sprintf(param_string, "%lu", + *((UDWORD *) buffer)); + break; - case SQL_C_UTINYINT: - sprintf(param_string, "%u", - *((UCHAR *) buffer)); - break; + case SQL_C_USHORT: + sprintf(param_string, "%u", + *((UWORD *) buffer)); + break; - case SQL_C_BIT: { - int i = *((UCHAR *) buffer); - - sprintf(param_string, "%d", i ? 1 : 0); - break; - } + case SQL_C_UTINYINT: + sprintf(param_string, "%u", + *((UCHAR *) buffer)); + break; - case SQL_C_DATE: { - DATE_STRUCT *ds = (DATE_STRUCT *) buffer; - st.m = ds->month; - st.d = ds->day; - st.y = ds->year; + case SQL_C_BIT: + { + int i = *((UCHAR *) buffer); - break; - } + sprintf(param_string, "%d", i ? 1 : 0); + break; + } - case SQL_C_TIME: { - TIME_STRUCT *ts = (TIME_STRUCT *) buffer; - st.hh = ts->hour; - st.mm = ts->minute; - st.ss = ts->second; + case SQL_C_DATE: + { + DATE_STRUCT *ds = (DATE_STRUCT *) buffer; - break; - } + st.m = ds->month; + st.d = ds->day; + st.y = ds->year; - case SQL_C_TIMESTAMP: { - TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer; - st.m = tss->month; - st.d = tss->day; - st.y = tss->year; - st.hh = tss->hour; - st.mm = tss->minute; - st.ss = tss->second; + break; + } - mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss); + case SQL_C_TIME: + { + TIME_STRUCT *ts = (TIME_STRUCT *) buffer; - break; + st.hh = ts->hour; + st.mm = ts->minute; + st.ss = ts->second; - } - default: - /* error */ - stmt->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters"; - stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - new_statement[npos] = '\0'; /* just in case */ - SC_log_error(func, "", stmt); - return SQL_ERROR; - } + break; + } - /* Now that the input data is in a neutral format, convert it to - the desired output format (sqltype) - */ + case SQL_C_TIMESTAMP: + { + TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer; - switch(param_sqltype) { - case SQL_CHAR: - case SQL_VARCHAR: - case SQL_LONGVARCHAR: + st.m = tss->month; + st.d = tss->day; + st.y = tss->year; + st.hh = tss->hour; + st.mm = tss->minute; + st.ss = tss->second; - new_statement[npos++] = '\''; /* Open Quote */ + mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss); - /* it was a SQL_C_CHAR */ - if (buf) { - convert_special_chars(buf, &new_statement[npos], used); - npos += strlen(&new_statement[npos]); - } + break; - /* it was a numeric type */ - else if (param_string[0] != '\0') { - strcpy(&new_statement[npos], param_string); - npos += strlen(param_string); - } + } + default: + /* error */ + stmt->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters"; + stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; + new_statement[npos] = '\0'; /* just in case */ + SC_log_error(func, "", stmt); + return SQL_ERROR; + } - /* it was date,time,timestamp -- use m,d,y,hh,mm,ss */ - else { - sprintf(tmp, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", - st.y, st.m, st.d, st.hh, st.mm, st.ss); + /* + * Now that the input data is in a neutral format, convert it to + * the desired output format (sqltype) + */ - strcpy(&new_statement[npos], tmp); - npos += strlen(tmp); - } + switch (param_sqltype) + { + case SQL_CHAR: + case SQL_VARCHAR: + case SQL_LONGVARCHAR: - new_statement[npos++] = '\''; /* Close Quote */ + new_statement[npos++] = '\''; /* Open Quote */ - break; + /* it was a SQL_C_CHAR */ + if (buf) + { + convert_special_chars(buf, &new_statement[npos], used); + npos += strlen(&new_statement[npos]); + } - case SQL_DATE: - if (buf) { /* copy char data to time */ - my_strcpy(cbuf, sizeof(cbuf), buf, used); - parse_datetime(cbuf, &st); - } + /* it was a numeric type */ + else if (param_string[0] != '\0') + { + strcpy(&new_statement[npos], param_string); + npos += strlen(param_string); + } - sprintf(tmp, "'%.4d-%.2d-%.2d'", st.y, st.m, st.d); + /* it was date,time,timestamp -- use m,d,y,hh,mm,ss */ + else + { + sprintf(tmp, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", + st.y, st.m, st.d, st.hh, st.mm, st.ss); - strcpy(&new_statement[npos], tmp); - npos += strlen(tmp); - break; + strcpy(&new_statement[npos], tmp); + npos += strlen(tmp); + } - case SQL_TIME: - if (buf) { /* copy char data to time */ - my_strcpy(cbuf, sizeof(cbuf), buf, used); - parse_datetime(cbuf, &st); - } + new_statement[npos++] = '\''; /* Close Quote */ - sprintf(tmp, "'%.2d:%.2d:%.2d'", st.hh, st.mm, st.ss); + break; - strcpy(&new_statement[npos], tmp); - npos += strlen(tmp); - break; + case SQL_DATE: + if (buf) + { /* copy char data to time */ + my_strcpy(cbuf, sizeof(cbuf), buf, used); + parse_datetime(cbuf, &st); + } - case SQL_TIMESTAMP: + sprintf(tmp, "'%.4d-%.2d-%.2d'", st.y, st.m, st.d); - if (buf) { - my_strcpy(cbuf, sizeof(cbuf), buf, used); - parse_datetime(cbuf, &st); - } + strcpy(&new_statement[npos], tmp); + npos += strlen(tmp); + break; - sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'", - st.y, st.m, st.d, st.hh, st.mm, st.ss); + case SQL_TIME: + if (buf) + { /* copy char data to time */ + my_strcpy(cbuf, sizeof(cbuf), buf, used); + parse_datetime(cbuf, &st); + } - strcpy(&new_statement[npos], tmp); - npos += strlen(tmp); + sprintf(tmp, "'%.2d:%.2d:%.2d'", st.hh, st.mm, st.ss); - break; + strcpy(&new_statement[npos], tmp); + npos += strlen(tmp); + break; - case SQL_BINARY: - case SQL_VARBINARY: /* non-ascii characters should be converted to octal */ - new_statement[npos++] = '\''; /* Open Quote */ + case SQL_TIMESTAMP: - mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used); + if (buf) + { + my_strcpy(cbuf, sizeof(cbuf), buf, used); + parse_datetime(cbuf, &st); + } - npos += convert_to_pgbinary(buf, &new_statement[npos], used); + sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'", + st.y, st.m, st.d, st.hh, st.mm, st.ss); - new_statement[npos++] = '\''; /* Close Quote */ - - break; + strcpy(&new_statement[npos], tmp); + npos += strlen(tmp); - case SQL_LONGVARBINARY: + break; - if ( stmt->parameters[param_number].data_at_exec) { + case SQL_BINARY: + case SQL_VARBINARY:/* non-ascii characters should be + * converted to octal */ + new_statement[npos++] = '\''; /* Open Quote */ - lobj_oid = stmt->parameters[param_number].lobj_oid; + mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used); - } - else { - - /* begin transaction if needed */ - if(!CC_is_in_trans(stmt->hdbc)) { - QResultClass *res; - char ok; - - res = CC_send_query(stmt->hdbc, "BEGIN", NULL); - if (!res) { - stmt->errormsg = "Could not begin (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } - ok = QR_command_successful(res); - QR_Destructor(res); - if (!ok) { - stmt->errormsg = "Could not begin (in-line) a transaction"; - stmt->errornumber = STMT_EXEC_ERROR; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } + npos += convert_to_pgbinary(buf, &new_statement[npos], used); - CC_set_in_trans(stmt->hdbc); - } + new_statement[npos++] = '\''; /* Close Quote */ - /* store the oid */ - lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); - if (lobj_oid == 0) { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Couldnt create (in-line) large object."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } + break; - /* store the fd */ - lobj_fd = lo_open(stmt->hdbc, lobj_oid, INV_WRITE); - if ( lobj_fd < 0) { - stmt->errornumber = STMT_EXEC_ERROR; - stmt->errormsg = "Couldnt open (in-line) large object for writing."; - SC_log_error(func, "", stmt); - return SQL_ERROR; - } + case SQL_LONGVARBINARY: + + if (stmt->parameters[param_number].data_at_exec) + { - retval = lo_write(stmt->hdbc, lobj_fd, buffer, used); + lobj_oid = stmt->parameters[param_number].lobj_oid; - lo_close(stmt->hdbc, lobj_fd); + } + else + { + + /* begin transaction if needed */ + if (!CC_is_in_trans(stmt->hdbc)) + { + QResultClass *res; + char ok; + + res = CC_send_query(stmt->hdbc, "BEGIN", NULL); + if (!res) + { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) + { + stmt->errormsg = "Could not begin (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } - /* commit transaction if needed */ - if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { - QResultClass *res; - char ok; + CC_set_in_trans(stmt->hdbc); + } - res = CC_send_query(stmt->hdbc, "COMMIT", NULL); - if (!res) { - stmt->errormsg = "Could not commit (in-line) a transaction"; + /* store the oid */ + lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); + if (lobj_oid == 0) + { stmt->errornumber = STMT_EXEC_ERROR; + stmt->errormsg = "Couldnt create (in-line) large object."; SC_log_error(func, "", stmt); return SQL_ERROR; } - ok = QR_command_successful(res); - QR_Destructor(res); - if (!ok) { - stmt->errormsg = "Could not commit (in-line) a transaction"; + + /* store the fd */ + lobj_fd = lo_open(stmt->hdbc, lobj_oid, INV_WRITE); + if (lobj_fd < 0) + { stmt->errornumber = STMT_EXEC_ERROR; + stmt->errormsg = "Couldnt open (in-line) large object for writing."; SC_log_error(func, "", stmt); return SQL_ERROR; } - CC_set_no_trans(stmt->hdbc); - } - } + retval = lo_write(stmt->hdbc, lobj_fd, buffer, used); - /* the oid of the large object -- just put that in for the - parameter marker -- the data has already been sent to the large object - */ - sprintf(param_string, "'%d'", lobj_oid); - strcpy(&new_statement[npos], param_string); - npos += strlen(param_string); + lo_close(stmt->hdbc, lobj_fd); - break; + /* commit transaction if needed */ + if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) + { + QResultClass *res; + char ok; - /* because of no conversion operator for bool and int4, SQL_BIT */ - /* must be quoted (0 or 1 is ok to use inside the quotes) */ + res = CC_send_query(stmt->hdbc, "COMMIT", NULL); + if (!res) + { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } + ok = QR_command_successful(res); + QR_Destructor(res); + if (!ok) + { + stmt->errormsg = "Could not commit (in-line) a transaction"; + stmt->errornumber = STMT_EXEC_ERROR; + SC_log_error(func, "", stmt); + return SQL_ERROR; + } - case SQL_REAL: - if (buf) - my_strcpy(param_string, sizeof(param_string), buf, used); - sprintf(tmp, "'%s'::float4", param_string); - strcpy(&new_statement[npos], tmp); - npos += strlen(tmp); - break; - case SQL_FLOAT: - case SQL_DOUBLE: - if (buf) - my_strcpy(param_string, sizeof(param_string), buf, used); - sprintf(tmp, "'%s'::float8", param_string); - strcpy(&new_statement[npos], tmp); - npos += strlen(tmp); - break; - case SQL_NUMERIC: - if (buf) - { - cbuf[0] = '\''; - my_strcpy(cbuf + 1, sizeof(cbuf) - 12, buf, used); /* 12 = 1('\'') + strlen("'::numeric") + 1('\0') */ - strcat(cbuf, "'::numeric"); - } - else - sprintf(cbuf, "'%s'::numeric", param_string); - my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos - 1, cbuf, strlen(cbuf)); - npos += strlen(&new_statement[npos]); - break; - default: /* a numeric type or SQL_BIT */ - if (param_sqltype == SQL_BIT) - new_statement[npos++] = '\''; /* Open Quote */ + CC_set_no_trans(stmt->hdbc); + } + } - if (buf) { - my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos, buf, used); - npos += strlen(&new_statement[npos]); - } - else { + /* + * the oid of the large object -- just put that in for the + * parameter marker -- the data has already been sent to + * the large object + */ + sprintf(param_string, "'%d'", lobj_oid); strcpy(&new_statement[npos], param_string); npos += strlen(param_string); - } - if (param_sqltype == SQL_BIT) - new_statement[npos++] = '\''; /* Close Quote */ + break; + + /* + * because of no conversion operator for bool and int4, + * SQL_BIT + */ + /* must be quoted (0 or 1 is ok to use inside the quotes) */ - break; + case SQL_REAL: + if (buf) + my_strcpy(param_string, sizeof(param_string), buf, used); + sprintf(tmp, "'%s'::float4", param_string); + strcpy(&new_statement[npos], tmp); + npos += strlen(tmp); + break; + case SQL_FLOAT: + case SQL_DOUBLE: + if (buf) + my_strcpy(param_string, sizeof(param_string), buf, used); + sprintf(tmp, "'%s'::float8", param_string); + strcpy(&new_statement[npos], tmp); + npos += strlen(tmp); + break; + case SQL_NUMERIC: + if (buf) + { + cbuf[0] = '\''; + my_strcpy(cbuf + 1, sizeof(cbuf) - 12, buf, used); /* 12 = 1('\'') + + * strlen("'::numeric") + * + 1('\0') */ + strcat(cbuf, "'::numeric"); + } + else + sprintf(cbuf, "'%s'::numeric", param_string); + my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos - 1, cbuf, strlen(cbuf)); + npos += strlen(&new_statement[npos]); + break; + default: /* a numeric type or SQL_BIT */ + if (param_sqltype == SQL_BIT) + new_statement[npos++] = '\''; /* Open Quote */ + + if (buf) + { + my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos, buf, used); + npos += strlen(&new_statement[npos]); + } + else + { + strcpy(&new_statement[npos], param_string); + npos += strlen(param_string); + } + + if (param_sqltype == SQL_BIT) + new_statement[npos++] = '\''; /* Close Quote */ + + break; } - } /* end, for */ + } /* end, for */ /* make sure new_statement is always null-terminated */ new_statement[npos] = '\0'; - if(stmt->hdbc->DriverToDataSource != NULL) { - int length = strlen (new_statement); - stmt->hdbc->DriverToDataSource (stmt->hdbc->translation_option, - SQL_CHAR, - new_statement, length, - new_statement, length, NULL, - NULL, 0, NULL); + if (stmt->hdbc->DriverToDataSource != NULL) + { + int length = strlen(new_statement); + + stmt->hdbc->DriverToDataSource(stmt->hdbc->translation_option, + SQL_CHAR, + new_statement, length, + new_statement, length, NULL, + NULL, 0, NULL); } @@ -1153,10 +1268,10 @@ int lobj_fd, retval; char * mapFunction(char *func) { -int i; + int i; for (i = 0; mapFuncs[i][0]; i++) - if ( ! stricmp(mapFuncs[i][0], func)) + if (!stricmp(mapFuncs[i][0], func)) return mapFuncs[i][1]; return NULL; @@ -1168,34 +1283,40 @@ int i; char * convert_escape(char *value) { -static char escape[1024]; -char key[33]; + static char escape[1024]; + char key[33]; /* Separate off the key, skipping leading and trailing whitespace */ - while ((*value != '\0') && isspace((unsigned char) *value)) value++; + while ((*value != '\0') && isspace((unsigned char) *value)) + value++; sscanf(value, "%32s", key); - while ((*value != '\0') && (! isspace((unsigned char) *value))) value++; - while ((*value != '\0') && isspace((unsigned char) *value)) value++; + while ((*value != '\0') && (!isspace((unsigned char) *value))) + value++; + while ((*value != '\0') && isspace((unsigned char) *value)) + value++; mylog("convert_escape: key='%s', val='%s'\n", key, value); - if ( (strcmp(key, "d") == 0) || - (strcmp(key, "t") == 0) || - (strcmp(key, "ts") == 0)) { + if ((strcmp(key, "d") == 0) || + (strcmp(key, "t") == 0) || + (strcmp(key, "ts") == 0)) + { /* Literal; return the escape part as-is */ - strncpy(escape, value, sizeof(escape)-1); + strncpy(escape, value, sizeof(escape) - 1); } - else if (strcmp(key, "fn") == 0) { - /* Function invocation - * Separate off the func name, - * skipping trailing whitespace. + else if (strcmp(key, "fn") == 0) + { + + /* + * Function invocation Separate off the func name, skipping + * trailing whitespace. */ - char *funcEnd = value; - char svchar; - char *mapFunc; + char *funcEnd = value; + char svchar; + char *mapFunc; while ((*funcEnd != '\0') && (*funcEnd != '(') && - (! isspace((unsigned char) *funcEnd))) + (!isspace((unsigned char) *funcEnd))) funcEnd++; svchar = *funcEnd; *funcEnd = '\0'; @@ -1204,28 +1325,33 @@ char key[33]; while ((*funcEnd != '\0') && isspace((unsigned char) *funcEnd)) funcEnd++; - /* We expect left parenthesis here, - * else return fn body as-is since it is - * one of those "function constants". + /* + * We expect left parenthesis here, else return fn body as-is + * since it is one of those "function constants". */ - if (*funcEnd != '(') { - strncpy(escape, value, sizeof(escape)-1); + if (*funcEnd != '(') + { + strncpy(escape, value, sizeof(escape) - 1); return escape; } mapFunc = mapFunction(key); - /* We could have mapFunction() return key if not in table... - * - thomas 2000-04-03 + + /* + * We could have mapFunction() return key if not in table... - + * thomas 2000-04-03 */ - if (mapFunc == NULL) { + if (mapFunc == NULL) + { /* If unrecognized function name, return fn body as-is */ - strncpy(escape, value, sizeof(escape)-1); + strncpy(escape, value, sizeof(escape) - 1); return escape; } /* copy mapped name and remaining input string */ strcpy(escape, mapFunc); - strncat(escape, funcEnd, sizeof(escape)-1-strlen(mapFunc)); + strncat(escape, funcEnd, sizeof(escape) - 1 - strlen(mapFunc)); } - else { + else + { /* Bogus key, leave untranslated */ return NULL; } @@ -1238,11 +1364,13 @@ char key[33]; char * convert_money(char *s) { -size_t i = 0, out = 0; + size_t i = 0, + out = 0; - for (i = 0; i < strlen(s); i++) { + for (i = 0; i < strlen(s); i++) + { if (s[i] == '$' || s[i] == ',' || s[i] == ')') - ; /* skip these characters */ + ; /* skip these characters */ else if (s[i] == '(') s[out++] = '-'; else @@ -1259,17 +1387,23 @@ size_t i = 0, out = 0; char parse_datetime(char *buf, SIMPLE_TIME *st) { -int y,m,d,hh,mm,ss; -int nf; - + int y, + m, + d, + hh, + mm, + ss; + int nf; + y = m = d = hh = mm = ss = 0; - if (buf[4] == '-') /* year first */ - nf = sscanf(buf, "%4d-%2d-%2d %2d:%2d:%2d", &y,&m,&d,&hh,&mm,&ss); + if (buf[4] == '-') /* year first */ + nf = sscanf(buf, "%4d-%2d-%2d %2d:%2d:%2d", &y, &m, &d, &hh, &mm, &ss); else - nf = sscanf(buf, "%2d-%2d-%4d %2d:%2d:%2d", &m,&d,&y,&hh,&mm,&ss); + nf = sscanf(buf, "%2d-%2d-%4d %2d:%2d:%2d", &m, &d, &y, &hh, &mm, &ss); - if (nf == 5 || nf == 6) { + if (nf == 5 || nf == 6) + { st->y = y; st->m = m; st->d = d; @@ -1280,12 +1414,13 @@ int nf; return TRUE; } - if (buf[4] == '-') /* year first */ + if (buf[4] == '-') /* year first */ nf = sscanf(buf, "%4d-%2d-%2d", &y, &m, &d); else nf = sscanf(buf, "%2d-%2d-%4d", &m, &d, &y); - if (nf == 3) { + if (nf == 3) + { st->y = y; st->m = m; st->d = d; @@ -1294,7 +1429,8 @@ int nf; } nf = sscanf(buf, "%2d:%2d:%2d", &hh, &mm, &ss); - if (nf == 2 || nf == 3) { + if (nf == 2 || nf == 3) + { st->hh = hh; st->mm = mm; st->ss = ss; @@ -1309,12 +1445,16 @@ int nf; int convert_linefeeds(char *si, char *dst, size_t max) { -size_t i = 0, out = 0; + size_t i = 0, + out = 0; - for (i = 0; i < strlen(si) && out < max - 1; i++) { - if (si[i] == '\n') { - /* Only add the carriage-return if needed */ - if (i > 0 && si[i-1] == '\r') { + for (i = 0; i < strlen(si) && out < max - 1; i++) + { + if (si[i] == '\n') + { + /* Only add the carriage-return if needed */ + if (i > 0 && si[i - 1] == '\r') + { dst[out++] = si[i]; continue; } @@ -1329,15 +1469,17 @@ size_t i = 0, out = 0; return out; } -/* Change carriage-return/linefeed to just linefeed +/* Change carriage-return/linefeed to just linefeed Plus, escape any special characters. */ char * convert_special_chars(char *si, char *dst, int used) { -size_t i = 0, out = 0, max; -static char sout[TEXT_FIELD_SIZE+5]; -char *p; + size_t i = 0, + out = 0, + max; + static char sout[TEXT_FIELD_SIZE + 5]; + char *p; if (dst) p = dst; @@ -1354,8 +1496,9 @@ char *p; multibyte_init(); #endif - for (i = 0; i < max; i++) { - if (si[i] == '\r' && i+1 < strlen(si) && si[i+1] == '\n') + for (i = 0; i < max; i++) + { + if (si[i] == '\r' && i + 1 < strlen(si) && si[i + 1] == '\n') continue; #ifdef MULTIBYTE else if (multibyte_char_check(si[i]) == 0 && (si[i] == '\'' || si[i] == '\\')) @@ -1383,11 +1526,11 @@ convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax) unsigned int conv_from_octal(unsigned char *s) { -int i, y=0; + int i, + y = 0; - for (i = 1; i <= 3; i++) { - y += (s[i] - 48) * (int) pow(8, 3-i); - } + for (i = 1; i <= 3; i++) + y += (s[i] - 48) * (int) pow(8, 3 - i); return y; @@ -1396,18 +1539,21 @@ int i, y=0; unsigned int conv_from_hex(unsigned char *s) { -int i, y=0, val; + int i, + y = 0, + val; - for (i = 1; i <= 2; i++) { + for (i = 1; i <= 2; i++) + { - if (s[i] >= 'a' && s[i] <= 'f') - val = s[i] - 'a' + 10; - else if (s[i] >= 'A' && s[i] <= 'F') - val = s[i] - 'A' + 10; - else - val = s[i] - '0'; + if (s[i] >= 'a' && s[i] <= 'f') + val = s[i] - 'a' + 10; + else if (s[i] >= 'A' && s[i] <= 'F') + val = s[i] - 'A' + 10; + else + val = s[i] - '0'; - y += val * (int) pow(16, 2-i); + y += val * (int) pow(16, 2 - i); } return y; @@ -1417,23 +1563,24 @@ int i, y=0, val; int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax) { -size_t i; -int o=0; + size_t i; + int o = 0; - - for (i = 0; i < strlen(value); ) { - if (value[i] == '\\') { + + for (i = 0; i < strlen(value);) + { + if (value[i] == '\\') + { rgbValue[o] = conv_from_octal(&value[i]); i += 4; } - else { + else rgbValue[o] = value[i++]; - } mylog("convert_from_pgbinary: i=%d, rgbValue[%d] = %d, %c\n", i, o, rgbValue[o], rgbValue[o]); o++; } - rgbValue[o] = '\0'; /* extra protection */ + rgbValue[o] = '\0'; /* extra protection */ return o; } @@ -1442,14 +1589,15 @@ int o=0; char * conv_to_octal(unsigned char val) { -int i; -static char x[6]; + int i; + static char x[6]; x[0] = '\\'; x[1] = '\\'; x[5] = '\0'; - for (i = 4; i > 1; i--) { + for (i = 4; i > 1; i--) + { x[i] = (val & 7) + 48; val >>= 3; } @@ -1461,16 +1609,18 @@ static char x[6]; int convert_to_pgbinary(unsigned char *in, char *out, int len) { -int i, o=0; + int i, + o = 0; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) + { mylog("convert_to_pgbinary: in[%d] = %d, %c\n", i, in[i], in[i]); - if ( isalnum(in[i]) || in[i] == ' ') { + if (isalnum(in[i]) || in[i] == ' ') out[o++] = in[i]; - } - else { - strcpy(&out[o], conv_to_octal(in[i])); + else + { + strcpy(&out[o], conv_to_octal(in[i])); o += 5; } @@ -1485,17 +1635,20 @@ int i, o=0; void encode(char *in, char *out) { - unsigned int i, o = 0; + unsigned int i, + o = 0; - for (i = 0; i < strlen(in); i++) { - if ( in[i] == '+') { + for (i = 0; i < strlen(in); i++) + { + if (in[i] == '+') + { sprintf(&out[o], "%%2B"); o += 3; } - else if ( isspace((unsigned char) in[i])) { + else if (isspace((unsigned char) in[i])) out[o++] = '+'; - } - else if ( ! isalnum((unsigned char) in[i])) { + else if (!isalnum((unsigned char) in[i])) + { sprintf(&out[o], "%%%02x", (unsigned char) in[i]); o += 3; } @@ -1509,14 +1662,17 @@ encode(char *in, char *out) void decode(char *in, char *out) { -unsigned int i, o = 0; + unsigned int i, + o = 0; - for (i = 0; i < strlen(in); i++) { + for (i = 0; i < strlen(in); i++) + { if (in[i] == '+') out[o++] = ' '; - else if (in[i] == '%') { + else if (in[i] == '%') + { sprintf(&out[o++], "%c", conv_from_hex(&in[i])); - i+=2; + i += 2; } else out[o++] = in[i]; @@ -1536,45 +1692,53 @@ unsigned int i, o = 0; CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only data type currently mapped to a PG_TYPE_LO. But, if any other types - are desired to map to a large object (PG_TYPE_LO), then that would + are desired to map to a large object (PG_TYPE_LO), then that would need to be handled here. For example, LONGVARCHAR could possibly be mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now. */ int -convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, +convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue) { - Oid oid; - int retval, result, left = -1; + Oid oid; + int retval, + result, + left = -1; BindInfoClass *bindInfo = NULL; /* If using SQLGetData, then current_col will be set */ - if (stmt->current_col >= 0) { + if (stmt->current_col >= 0) + { bindInfo = &stmt->bindings[stmt->current_col]; left = bindInfo->data_left; } - /* if this is the first call for this column, - open the large object for reading - */ + /* + * if this is the first call for this column, open the large object + * for reading + */ - if ( ! bindInfo || bindInfo->data_left == -1) { + if (!bindInfo || bindInfo->data_left == -1) + { /* begin transaction if needed */ - if(!CC_is_in_trans(stmt->hdbc)) { + if (!CC_is_in_trans(stmt->hdbc)) + { QResultClass *res; - char ok; + char ok; res = CC_send_query(stmt->hdbc, "BEGIN", NULL); - if (!res) { + if (!res) + { stmt->errormsg = "Could not begin (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; return COPY_GENERAL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); - if (!ok) { + if (!ok) + { stmt->errormsg = "Could not begin (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; return COPY_GENERAL_ERROR; @@ -1585,53 +1749,59 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, oid = atoi(value); stmt->lobj_fd = lo_open(stmt->hdbc, oid, INV_READ); - if (stmt->lobj_fd < 0) { + if (stmt->lobj_fd < 0) + { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Couldnt open large object for reading."; return COPY_GENERAL_ERROR; } - /* Get the size */ + /* Get the size */ retval = lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_END); - if (retval >= 0) { + if (retval >= 0) + { left = lo_tell(stmt->hdbc, stmt->lobj_fd); if (bindInfo) bindInfo->data_left = left; - /* return to beginning */ + /* return to beginning */ lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_SET); } } - if (left == 0) { + if (left == 0) return COPY_NO_DATA_FOUND; - } - if (stmt->lobj_fd < 0) { + if (stmt->lobj_fd < 0) + { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Large object FD undefined for multiple read."; return COPY_GENERAL_ERROR; } retval = lo_read(stmt->hdbc, stmt->lobj_fd, (char *) rgbValue, cbValueMax); - if (retval < 0) { + if (retval < 0) + { lo_close(stmt->hdbc, stmt->lobj_fd); /* 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; - char ok; + char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); - if (!res) { + if (!res) + { stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; return COPY_GENERAL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); - if (!ok) { + if (!ok) + { stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; return COPY_GENERAL_ERROR; @@ -1656,27 +1826,31 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, *pcbValue = left < 0 ? SQL_NO_TOTAL : left; - if (bindInfo && bindInfo->data_left > 0) + if (bindInfo && bindInfo->data_left > 0) bindInfo->data_left -= retval; - if (! bindInfo || bindInfo->data_left == 0) { + if (!bindInfo || bindInfo->data_left == 0) + { lo_close(stmt->hdbc, stmt->lobj_fd); /* 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; - char ok; + char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); - if (!res) { + if (!res) + { stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; return COPY_GENERAL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); - if (!ok) { + if (!ok) + { stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; return COPY_GENERAL_ERROR; @@ -1685,7 +1859,7 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, CC_set_no_trans(stmt->hdbc); } - stmt->lobj_fd = -1; /* prevent further reading */ + stmt->lobj_fd = -1; /* prevent further reading */ } |