From e22791606feadcc2bd122cd9c88a601a43c6a60d Mon Sep 17 00:00:00 2001 From: Dan Villiom Podlaski Christiansen Date: Mon, 28 Sep 2015 13:21:35 +0200 Subject: [PATCH] odbc: support reading OLE entries This adds support for reading OLE objects to the ODBC driver. The APIs for reading OLE appear somewhat idiosyncratic, so we read the string fully and stash it in a static variable. Tested by reading an old Access database, with checking for memory leaks. --- src/odbc/odbc.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index 3f8fda2..e56e571 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -82,6 +82,7 @@ typedef struct { TypeInfo type_info[] = { {(SQLCHAR*)"text", SQL_VARCHAR, 255, NULL, NULL, NULL, SQL_TRUE, SQL_TRUE, SQL_TRUE, NULL, SQL_FALSE, SQL_FALSE, NULL, 0, 255, SQL_VARCHAR, NULL, NULL, NULL}, {(SQLCHAR*)"memo", SQL_VARCHAR, 4096, NULL, NULL, NULL, SQL_TRUE, SQL_TRUE, SQL_TRUE, NULL, SQL_FALSE, SQL_FALSE, NULL, 0, 4096, SQL_VARCHAR, NULL, NULL, NULL}, + {(SQLCHAR*)"ole", SQL_VARCHAR, MDB_BIND_SIZE, NULL, NULL, NULL, SQL_TRUE, SQL_TRUE, SQL_TRUE, NULL, SQL_FALSE, SQL_FALSE, NULL, 0, MDB_BIND_SIZE, SQL_VARCHAR, NULL, NULL, NULL}, {(SQLCHAR*)"text", SQL_CHAR, 255, NULL, NULL, NULL, SQL_TRUE, SQL_TRUE, SQL_TRUE, NULL, SQL_FALSE, SQL_FALSE, NULL, 0, 255, SQL_CHAR, NULL, NULL, NULL}, {(SQLCHAR*)"numeric", SQL_NUMERIC, 255, NULL, NULL, NULL, SQL_TRUE, SQL_TRUE, SQL_TRUE, NULL, SQL_FALSE, SQL_FALSE, NULL, 0, 255, SQL_NUMERIC, NULL, NULL, NULL}, {(SQLCHAR*)"numeric", SQL_DECIMAL, 255, NULL, NULL, NULL, SQL_TRUE, SQL_TRUE, SQL_TRUE, NULL, SQL_FALSE, SQL_FALSE, NULL, 0, 255, SQL_DECIMAL, NULL, NULL, NULL}, @@ -1797,35 +1798,48 @@ static SQLRETURN SQL_API _SQLGetData( default: /* FIXME here we assume fCType == SQL_C_CHAR */ to_c_char: { - char *str = mdb_col_to_string(mdb, mdb->pg_buf, - col->cur_value_start, col->col_type, col->cur_value_len); - int len = strlen(str); + static size_t len = 0; + static char *str = NULL; + + if (col->col_type == MDB_OLE) { + if (stmt->pos == 0) { + str = mdb_ole_read_full(mdb, col, &len); + } + } else { + str = mdb_col_to_string(mdb, mdb->pg_buf, + col->cur_value_start, col->col_type, col->cur_value_len); + len = strlen(str); + } + if (stmt->pos >= len) { free(str); + str = NULL; return SQL_NO_DATA; } + if (pcbValue) { + *pcbValue = len; + } if (!cbValueMax) { - if (pcbValue) - *pcbValue = len; free(str); + str = NULL; return SQL_SUCCESS_WITH_INFO; } if (len - stmt->pos > cbValueMax) { /* the buffer we were given is too small, so truncate it to the size of the buffer */ - strncpy(rgbValue, str, cbValueMax); - if (pcbValue) - *pcbValue = cbValueMax; - stmt->pos += cbValueMax; - free(str); + memcpy(rgbValue, str, cbValueMax); + stmt->pos += cbValueMax - 1; + if (col->col_type != MDB_OLE) { free(str); str = NULL; } strcpy(sqlState, "01004"); // trunctated return SQL_SUCCESS_WITH_INFO; } - strncpy(rgbValue, str + stmt->pos, len - stmt->pos); + + memcpy(rgbValue, str + stmt->pos, len - stmt->pos); if (pcbValue) *pcbValue = len - stmt->pos; stmt->pos += len - stmt->pos; free(str); + str = NULL; break; } } @@ -2480,6 +2494,8 @@ static SQLSMALLINT _odbc_get_client_type(MdbColumn *col) return SQL_TYPE_TIMESTAMP; #endif // returns text otherwise case MDB_TEXT: + case MDB_MEMO: + case MDB_OLE: return SQL_VARCHAR; default: // fprintf(stderr,"Unknown type %d\n",srv_type);