--- sql/odbc/parser3odbc.C 2002/02/08 08:36:51 1.5 +++ sql/odbc/parser3odbc.C 2002/05/15 14:06:07 1.9 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char *RCSId="$Id: parser3odbc.C,v 1.5 2002/02/08 08:36:51 paf Exp $"; +static const char *RCSId="$Id: parser3odbc.C,v 1.9 2002/05/15 14:06:07 paf Exp $"; #ifndef _MSC_VER # error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)] @@ -21,6 +21,19 @@ static const char *RCSId="$Id: parser3od #include #define MAX_STRING 0x400 +#define MAX_NUMBER 40 + +// MSSQL2000 +#ifndef SQL_NVARCHAR +#define SQL_NVARCHAR (-9) +#endif +#ifndef SQL_NTEXT +#define SQL_NTEXT (-10) +#endif +#ifndef SQL_SMALLDATETIME +#define SQL_SMALLDATETIME 11 +#endif +// create table test (id int, a smalldatetime, b ntext, c nvarchar(100)) #define snprintf _snprintf #ifndef strncasecmp @@ -135,13 +148,37 @@ public: statement++; TRY { - if(strncasecmp(statement, "select", 6)==0) { + // mk:@MSITStore:C:\Program%20Files\Microsoft%20SQL%20Server\80\Tools\Books\adosql.chm::/adoprg02_4g33.htm + // Server cursors are created only for statements that begin with: + // SELECT + // EXEC[ute] procedure_name + // call procedure_name + // mk:@MSITStore:C:\Program%20Files\Microsoft%20SQL%20Server\80\Tools\Books\odbcsql.chm::/od_6_035_5dnp.htm + // The ODBC CALL escape sequence for calling a procedure is: + // {[?=]call procedure_name[([parameter][,[parameter]]...)]} + if(strncasecmp(statement, "select", 6)==0 + || strncasecmp(statement, "EXEC", 4)==0 + || 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) @@ -167,13 +204,28 @@ public: if(row>=offset) { handlers.add_row(); for(int i=0; iExecuteSQL(statement); } - } - CATCH_ALL (e) { + } CATCH_ALL (e) { _throw(services, e); + } END_CATCH_ALL + } + + void getFromDBVariant(SQL_Driver_services& services, CDBVariant& v, void *& ptr, size_t& size) { + switch(v.m_dwType) { + case DBVT_NULL: // No union member is valid for access. + ptr=0; + size=0; + break; +/* case DBVT_BOOL: + ptr=v.m_boolVal?"1":"0"; + size=1; + break;*/ +/* case DBVT_UCHAR: + size=strlen(ptr=v.m_chVal); + break; + case DBVT_SHORT: + char buf[MAX_NUMBER]; + size=snprintf(HEAPIZE buf, "%d", v.m_iVal); + break;*/ +/* case DBVT_LONG: + { + char local_buf[MAX_NUMBER]; + size=snprintf(local_buf, MAX_NUMBER, "%ld", v.m_lVal); + ptr=services.malloc(size); + memcpy(ptr, local_buf, size); + break; + }*/ + /*case DBVT_SINGLE: + m_fltVal + break; + case DBVT_DOUBLE m_dblVal + case DBVT_STRING m_pstring + case DBVT_BINARY m_pbinary */ + case DBVT_DATE: + { + char local_buf[MAX_STRING]; + size=snprintf(local_buf, MAX_STRING, + "%04d-%02d-%02d %02d:%02d:%02d.%03d", + v.m_pdate->year, + v.m_pdate->month, + v.m_pdate->day, + v.m_pdate->hour, + v.m_pdate->minute, + v.m_pdate->second, + v.m_pdate->fraction); + ptr=services.malloc(size); + memcpy(ptr, local_buf, size); + break; + } + default: + char msg[MAX_STRING]; + snprintf(msg, MAX_STRING, "unknown column return variant type (%d)", + v.m_dwType); + services._throw(msg); + } + } + + void getFromString(SQL_Driver_services& services, CString& s, void *& ptr, size_t& size) { + if(s.IsEmpty()) { + ptr=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); } - END_CATCH_ALL } void _throw(SQL_Driver_services& services, CException *e) {