--- sql/odbc/parser3odbc.C 2002/05/15 10:21:46 1.8 +++ sql/odbc/parser3odbc.C 2003/11/10 08:44:53 1.16 @@ -1,11 +1,11 @@ /** @file Parser ODBC driver. - Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Copyright(c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char *RCSId="$Id: parser3odbc.C,v 1.8 2002/05/15 10:21:46 paf Exp $"; +static const char *RCSId="$Id: parser3odbc.C,v 1.16 2003/11/10 08:44:53 paf Exp $"; #ifndef _MSC_VER # error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)] @@ -18,12 +18,17 @@ static const char *RCSId="$Id: parser3od #include "pa_sql_driver.h" +#define WINVER 0x0400 #include +// defines + +#define MAX_COLS 500 + #define MAX_STRING 0x400 #define MAX_NUMBER 40 -// MSSQL2000 +// new in MSSQL2000, no MFC constants #ifndef SQL_NVARCHAR #define SQL_NVARCHAR (-9) #endif @@ -122,20 +127,19 @@ public: return true; } - unsigned int quote( - SQL_Driver_services&, void *connection, - char *to, const char *from, unsigned int length) { - if(to) { // store mode - unsigned int result=length; - while(length--) { - if(*from=='\'') { // ' -> '' - *to++='\''; result++; - } - *to++=*from++; + const char* quote( + SQL_Driver_services& services, void *connection, + const char *from, unsigned int length) { + char *result=(char*)services.malloc_atomic(length*2+1); + char *to=result; + while(length--) { + if(*from=='\'') { // ' -> '' + *to++='\''; } - return result; - } else // estimate mode - return length*2; + *to++=*from++; + } + *to=0; + return result; } void query( SQL_Driver_services& services, void *connection, @@ -161,60 +165,78 @@ public: || strncasecmp(statement, "call", 4)==0 || strncasecmp(statement, "{", 1)==0) { CRecordset rs(db); - rs.Open( - CRecordset::forwardOnly, - statement, - CRecordset::executeDirect - ); + TRY { + rs.Open( + CRecordset::forwardOnly, + statement, + CRecordset::executeDirect + ); + } CATCH_ALL (e) { + // could not fetch a table + TRY { + // then try resultless query + db->ExecuteSQL(statement); + // OK then + return; + } CATCH_ALL (e2) { + // still nothing good + _throw(services, e); // throw ORIGINAL exception + } END_CATCH_ALL + } END_CATCH_ALL int column_count=rs.GetODBCFieldCount(); if(!column_count) services._throw("result contains no columns"); + SWORD column_types[MAX_COLS]; + if(column_count>MAX_COLS) + column_count=MAX_COLS; + + SQL_Error sql_error; +#define CHECK(afailed) if(afailed) services._throw(sql_error) + for(int i=0; i=offset) { - handlers.add_row(); - for(int i=0; iExecuteSQL(statement); } - } - CATCH_ALL (e) { + } CATCH_ALL (e) { _throw(services, e); - } - END_CATCH_ALL + } END_CATCH_ALL } - void getFromDBVariant(SQL_Driver_services& services, CDBVariant& v, void *& ptr, size_t& size) { + void getFromDBVariant(SQL_Driver_services& services, CDBVariant& v, char*& str, size_t& size) { switch(v.m_dwType) { + case DBVT_BINARY: /* << would cause problems with current String implementation + now falling into NULL case, effectively ignoring such columns [not failing] + { + if(size=v.m_pbinary->m_dwDataLength) { + str=services.malloc_atomic(size+1); + memcpy(ptr, ::GlobalLock(v.m_pbinary->m_hData), size); + ::GlobalUnlock(v.m_pbinary->m_hData); + } else + str=0; + break; + }*/ case DBVT_NULL: // No union member is valid for access. - ptr=0; + str=0; size=0; break; /* case DBVT_BOOL: @@ -252,7 +283,7 @@ public: { char local_buf[MAX_NUMBER]; size=snprintf(local_buf, MAX_NUMBER, "%ld", v.m_lVal); - ptr=services.malloc(size); + ptr=services.malloc_atomic(size); memcpy(ptr, local_buf, size); break; }*/ @@ -260,8 +291,7 @@ public: m_fltVal break; case DBVT_DOUBLE m_dblVal - case DBVT_STRING m_pstring - case DBVT_BINARY m_pbinary */ + case DBVT_STRING m_pstring */ case DBVT_DATE: { char local_buf[MAX_STRING]; @@ -274,8 +304,8 @@ public: v.m_pdate->minute, v.m_pdate->second, v.m_pdate->fraction); - ptr=services.malloc(size); - memcpy(ptr, local_buf, size); + str=(char*)services.malloc_atomic(size+1); + memcpy(str, local_buf, size+1); break; } default: @@ -286,15 +316,15 @@ public: } } - void getFromString(SQL_Driver_services& services, CString& s, void *& ptr, size_t& size) { + void getFromString(SQL_Driver_services& services, CString& s, char*& astr, size_t& size) { if(s.IsEmpty()) { - ptr=0; + astr=0; size=0; } else { const char *cstr=LPCTSTR(s); size=strlen(cstr); //string.GetLength() works wrong with non-string types: - ptr=services.malloc(size); - memcpy(ptr, cstr, size); + astr=(char*)services.malloc_atomic(size+1); + memcpy(astr, cstr, size+1); } }