You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by ma...@apache.org on 2015/07/15 11:42:46 UTC

[13/14] incubator-kylin git commit: add odbc driver to maven repository

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/ReadMe.txt
----------------------------------------------------------------------
diff --git a/odbc/Common/ReadMe.txt b/odbc/Common/ReadMe.txt
new file mode 100644
index 0000000..514fbd1
--- /dev/null
+++ b/odbc/Common/ReadMe.txt
@@ -0,0 +1,29 @@
+========================================================================
+    STATIC LIBRARY : Common Project Overview
+========================================================================
+
+AppWizard has created this Common library project for you.
+
+No source files were created as part of your project.
+
+
+Common.vcxproj
+    This is the main project file for VC++ projects generated using an Application Wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+Common.vcxproj.filters
+    This is the filters file for VC++ projects generated using an Application Wizard. 
+    It contains information about the association between the files in your project 
+    and the filters. This association is used in the IDE to show grouping of files with
+    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+    "Source Files" filter).
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/StringUtils.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/StringUtils.cpp b/odbc/Common/StringUtils.cpp
new file mode 100644
index 0000000..4dd336b
--- /dev/null
+++ b/odbc/Common/StringUtils.cpp
@@ -0,0 +1,165 @@
+#include <iostream>
+#include <stdlib.h>
+#include <string>
+
+#include "atlbase.h"
+#include "atlstr.h"
+#include "comutil.h"
+
+
+#include "StringUtils.h"
+#include "Base64.h"
+
+using namespace std;
+
+std::unique_ptr<char[]> str_base64_encode ( char* raw ) {
+    trimwhitespace ( raw );
+    string encStr = base64_encode ( ( const unsigned char* ) raw, strlen ( raw ) );
+    std::unique_ptr<char[]> temp ( new char[encStr.length() + 1] );
+    strcpy ( temp.get(), encStr.c_str() );
+    return temp;
+}
+
+std::unique_ptr<char[]> str_base64_decode ( char* enc ) {
+    string s ( enc );
+    string decStr = base64_decode ( s );
+    std::unique_ptr<char[]> temp ( new char[decStr.length() + 1] );
+    strcpy ( temp.get(), decStr.c_str() );
+    return temp;
+}
+
+void trimwhitespace ( char* str ) {
+    if ( str == NULL || strlen ( str ) == 0 )
+    { return; }
+    
+    char* start = str;
+    char* end;
+    
+    // Trim leading space
+    while ( isspace ( *start ) ) { start++; }
+    
+    if ( *start == 0 ) { // All spaces?
+        str[0] = '\0';
+        return;
+    }
+    
+    // Trim trailing space
+    end = start + strlen ( start ) - 1;
+    
+    while ( end > start && isspace ( *end ) ) { end--; }
+    
+    // Write new null terminator
+    * ( end + 1 ) = 0;
+    memmove ( str, start, end - start + 2 );
+}
+
+void copyTrimmed ( char** dest, char* src ) {
+    // check if previous value exists
+    if ( *dest ) {
+        delete[] ( *dest );
+        *dest = NULL;
+    }
+    
+    *dest = new char[strlen ( src ) + 1];
+    strcpy ( *dest, src );
+    trimwhitespace ( *dest );
+}
+
+std::unique_ptr<wchar_t[]> char2wchar ( char* orig ) {
+    if ( orig == NULL )
+    { return NULL; }
+    
+    size_t newsize = strlen ( orig ) + 1;
+    std::unique_ptr<wchar_t[]> wcstring ( new wchar_t[newsize] );
+    size_t convertedChars = 0;
+    mbstowcs_s ( &convertedChars, wcstring.get(), newsize, orig, _TRUNCATE );
+    return wcstring;
+}
+
+std::unique_ptr<wchar_t[]>  char2wchar ( const char* orig ) {
+    if ( orig == NULL )
+    { return NULL; }
+    
+    size_t newsize = strlen ( orig ) + 1;
+    std::unique_ptr<wchar_t[]> wcstring ( new wchar_t[newsize] );
+    size_t convertedChars = 0;
+    mbstowcs_s ( &convertedChars, wcstring.get(), newsize, orig, _TRUNCATE );
+    return wcstring;
+}
+
+//specifying the destination
+void char2wchar ( char* orig, wchar_t* dest, int destBufferLength ) {
+    if ( orig == NULL )
+    { return; }
+    
+    if ( destBufferLength > 0 ) {
+        if ( destBufferLength <= ( int ) strlen ( orig ) ) {
+            throw - 1;
+        }
+    }
+    
+    size_t newsize = strlen ( orig ) + 1;
+    size_t convertedChars = 0;
+    mbstowcs_s ( &convertedChars, dest, newsize, orig, _TRUNCATE );
+}
+
+std::unique_ptr<char[]> wchar2char ( wchar_t* orig ) {
+    if ( orig == NULL )
+    { return NULL; }
+    
+    size_t origsize = wcslen ( orig ) + 1;
+    size_t convertedChars = 0;
+    const size_t newsize = origsize;
+    std::unique_ptr<char[]> nstring ( new char[newsize] );
+    wcstombs_s ( &convertedChars, nstring.get(), newsize, orig, _TRUNCATE );
+    return nstring;
+}
+
+std::unique_ptr<char[]>  wchar2char ( const wchar_t* orig ) {
+    if ( orig == NULL )
+    { return NULL; }
+    
+    size_t origsize = wcslen ( orig ) + 1;
+    size_t convertedChars = 0;
+    const size_t newsize = origsize;
+    std::unique_ptr<char[]> nstring ( new char[newsize] );
+    wcstombs_s ( &convertedChars, nstring.get(), newsize, orig, _TRUNCATE );
+    return nstring;
+}
+
+void wchar2char ( wchar_t* orig, char* dest, int destBufferLength ) {
+    if ( orig == NULL )
+    { return; }
+    
+    if ( destBufferLength > 0 ) {
+        if ( destBufferLength <= ( int ) wcslen ( orig ) ) {
+            throw - 1;
+        }
+    }
+    
+    size_t origsize = wcslen ( orig ) + 1;
+    size_t convertedChars = 0;
+    const size_t newsize = origsize;
+    wcstombs_s ( &convertedChars, dest, newsize, orig, _TRUNCATE );
+}
+
+
+std::wstring string2wstring ( std::string& orig ) {
+    std::wstring ws;
+    ws.assign ( orig.begin(), orig.end() );
+    return ws;
+}
+
+std::string wstring2string ( std::wstring& orig ) {
+    std::string s;
+    s.assign ( orig.begin(), orig.end() );
+    return s;
+}
+
+std::unique_ptr<char[]> make_unique_str ( int size ) {
+    return std::unique_ptr<char[]> ( new char[size + 1] );
+}
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/StringUtils.h
----------------------------------------------------------------------
diff --git a/odbc/Common/StringUtils.h b/odbc/Common/StringUtils.h
new file mode 100644
index 0000000..154f06b
--- /dev/null
+++ b/odbc/Common/StringUtils.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <memory>
+#include <string>
+
+
+//UTIL
+std::unique_ptr<wchar_t[]> char2wchar ( char* orig );
+std::unique_ptr<wchar_t[]> char2wchar ( const char* orig );
+void char2wchar ( char* orig, wchar_t* dest, int destLength );
+
+std::unique_ptr<char[]> wchar2char ( wchar_t* orig );
+std::unique_ptr<char[]> wchar2char ( const wchar_t* orig );
+void wchar2char ( wchar_t* orig, char* dest, int destLength );
+
+std::wstring string2wstring ( std::string& orig );
+std::string wstring2string ( std::wstring& orig );
+
+void trimwhitespace ( char* str );
+void copyTrimmed ( char** dest, char* src );
+
+std::unique_ptr<char[]> str_base64_encode ( char* raw );
+std::unique_ptr<char[]> str_base64_decode ( char* enc );
+
+std::unique_ptr<char[]> make_unique_str ( int size );
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/Win32/Release/.gitignore
----------------------------------------------------------------------
diff --git a/odbc/Common/Win32/Release/.gitignore b/odbc/Common/Win32/Release/.gitignore
new file mode 100644
index 0000000..7fa2b99
--- /dev/null
+++ b/odbc/Common/Win32/Release/.gitignore
@@ -0,0 +1 @@
+*.lastbuildstate

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/base64.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/base64.cpp b/odbc/Common/base64.cpp
new file mode 100644
index 0000000..e5f2427
--- /dev/null
+++ b/odbc/Common/base64.cpp
@@ -0,0 +1,97 @@
+#include "Base64.h"
+#include <iostream>
+
+static const std::string base64_chars =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "abcdefghijklmnopqrstuvwxyz"
+    "0123456789+/";
+
+
+static inline bool is_base64 ( unsigned char c ) {
+    return ( isalnum ( c ) || ( c == '+' ) || ( c == '/' ) );
+}
+
+std::string base64_encode ( unsigned char const* bytes_to_encode, unsigned int in_len ) {
+    std::string ret;
+    int i = 0;
+    int j = 0;
+    unsigned char char_array_3[3];
+    unsigned char char_array_4[4];
+    
+    while ( in_len-- ) {
+        char_array_3[i++] = * ( bytes_to_encode++ );
+        
+        if ( i == 3 ) {
+            char_array_4[0] = ( char_array_3[0] & 0xfc ) >> 2;
+            char_array_4[1] = ( ( char_array_3[0] & 0x03 ) << 4 ) + ( ( char_array_3[1] & 0xf0 ) >> 4 );
+            char_array_4[2] = ( ( char_array_3[1] & 0x0f ) << 2 ) + ( ( char_array_3[2] & 0xc0 ) >> 6 );
+            char_array_4[3] = char_array_3[2] & 0x3f;
+            
+            for ( i = 0; ( i < 4 ) ; i++ )
+            { ret += base64_chars[char_array_4[i]]; }
+            
+            i = 0;
+        }
+    }
+    
+    if ( i ) {
+        for ( j = i; j < 3; j++ )
+        { char_array_3[j] = '\0'; }
+        
+        char_array_4[0] = ( char_array_3[0] & 0xfc ) >> 2;
+        char_array_4[1] = ( ( char_array_3[0] & 0x03 ) << 4 ) + ( ( char_array_3[1] & 0xf0 ) >> 4 );
+        char_array_4[2] = ( ( char_array_3[1] & 0x0f ) << 2 ) + ( ( char_array_3[2] & 0xc0 ) >> 6 );
+        char_array_4[3] = char_array_3[2] & 0x3f;
+        
+        for ( j = 0; ( j < i + 1 ); j++ )
+        { ret += base64_chars[char_array_4[j]]; }
+        
+        while ( ( i++ < 3 ) )
+        { ret += '='; }
+    }
+    
+    return ret;
+}
+
+std::string base64_decode ( std::string const& encoded_string ) {
+    int in_len = encoded_string.size();
+    int i = 0;
+    int j = 0;
+    int in_ = 0;
+    unsigned char char_array_4[4], char_array_3[3];
+    std::string ret;
+    
+    while ( in_len-- && ( encoded_string[in_] != '=' ) && is_base64 ( encoded_string[in_] ) ) {
+        char_array_4[i++] = encoded_string[in_]; in_++;
+        
+        if ( i == 4 ) {
+            for ( i = 0; i < 4; i++ )
+            { char_array_4[i] = base64_chars.find ( char_array_4[i] ); }
+            
+            char_array_3[0] = ( char_array_4[0] << 2 ) + ( ( char_array_4[1] & 0x30 ) >> 4 );
+            char_array_3[1] = ( ( char_array_4[1] & 0xf ) << 4 ) + ( ( char_array_4[2] & 0x3c ) >> 2 );
+            char_array_3[2] = ( ( char_array_4[2] & 0x3 ) << 6 ) + char_array_4[3];
+            
+            for ( i = 0; ( i < 3 ); i++ )
+            { ret += char_array_3[i]; }
+            
+            i = 0;
+        }
+    }
+    
+    if ( i ) {
+        for ( j = i; j < 4; j++ )
+        { char_array_4[j] = 0; }
+        
+        for ( j = 0; j < 4; j++ )
+        { char_array_4[j] = base64_chars.find ( char_array_4[j] ); }
+        
+        char_array_3[0] = ( char_array_4[0] << 2 ) + ( ( char_array_4[1] & 0x30 ) >> 4 );
+        char_array_3[1] = ( ( char_array_4[1] & 0xf ) << 4 ) + ( ( char_array_4[2] & 0x3c ) >> 2 );
+        char_array_3[2] = ( ( char_array_4[2] & 0x3 ) << 6 ) + char_array_4[3];
+        
+        for ( j = 0; ( j < i - 1 ); j++ ) { ret += char_array_3[j]; }
+    }
+    
+    return ret;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/base64.h
----------------------------------------------------------------------
diff --git a/odbc/Common/base64.h b/odbc/Common/base64.h
new file mode 100644
index 0000000..b10860f
--- /dev/null
+++ b/odbc/Common/base64.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <string>
+
+std::string base64_encode ( unsigned char const*, unsigned int len );
+std::string base64_decode ( std::string const& s );
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Common/x64/Release/.gitignore
----------------------------------------------------------------------
diff --git a/odbc/Common/x64/Release/.gitignore b/odbc/Common/x64/Release/.gitignore
new file mode 100644
index 0000000..7fa2b99
--- /dev/null
+++ b/odbc/Common/x64/Release/.gitignore
@@ -0,0 +1 @@
+*.lastbuildstate

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Driver/.gitignore
----------------------------------------------------------------------
diff --git a/odbc/Driver/.gitignore b/odbc/Driver/.gitignore
new file mode 100644
index 0000000..6e84b00
--- /dev/null
+++ b/odbc/Driver/.gitignore
@@ -0,0 +1,2 @@
+*.lib
+*.exp

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Driver/GODBC.RC
----------------------------------------------------------------------
diff --git a/odbc/Driver/GODBC.RC b/odbc/Driver/GODBC.RC
new file mode 100644
index 0000000..da9a478
--- /dev/null
+++ b/odbc/Driver/GODBC.RC
@@ -0,0 +1,177 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+"resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+"#include ""afxres.h""\r\n"
+"\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+"\r\n"
+"\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION 1, 0, 0, 1
+PRODUCTVERSION 1, 0, 0, 1
+FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+FILEFLAGS 0x1L
+#else
+FILEFLAGS 0x0L
+#endif
+FILEOS 0x40004L
+FILETYPE 0x2L
+FILESUBTYPE 0x0L
+BEGIN
+BLOCK "StringFileInfo"
+BEGIN
+BLOCK "040904b0"
+BEGIN
+VALUE "CompanyName", "kylinolap"
+VALUE "FileDescription", "Kylin ODBC Driver"
+VALUE "FileVersion", "1, 0, 0, 1"
+VALUE "InternalName", "KylinODBC"
+VALUE "LegalCopyright", "Copyright ?2014"
+VALUE "OriginalFilename", "driver.dll"
+VALUE "ProductName", "Kylin ODBC Driver"
+VALUE "ProductVersion", "1, 0, 0, 1"
+END
+END
+BLOCK "VarFileInfo"
+BEGIN
+VALUE "Translation", 0x409, 1200
+END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DSN_CFG1 DIALOGEX 0, 0, 263, 162
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
+CAPTION "Kylin Driver Connect Dialog"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+PUSHBUTTON      "Cancel", IDCANCEL, 152, 138, 50, 14
+LTEXT           "Server Host", IDC_STATIC, 49, 16, 38, 8
+LTEXT           "Port", IDC_STATIC, 69, 32, 14, 8
+EDITTEXT        IDC_SERVER, 92, 14, 110, 12, ES_AUTOHSCROLL
+EDITTEXT        IDC_PORT, 92, 31, 30, 12, ES_AUTOHSCROLL
+LTEXT           "Username", IDC_STATIC, 52, 60, 33, 8
+LTEXT           "Password", IDC_STATIC, 54, 79, 32, 8
+EDITTEXT        IDC_UID, 92, 59, 111, 12, ES_AUTOHSCROLL
+EDITTEXT        IDC_PWD, 92, 76, 111, 13, ES_PASSWORD | ES_AUTOHSCROLL
+DEFPUSHBUTTON   "Done", IDOK, 91, 138, 50, 14, WS_DISABLED
+LTEXT           "(only https service permitted)", IDC_STATIC, 93, 45, 90, 8
+COMBOBOX        IDC_COMBO1, 92, 117, 112, 30, CBS_DROPDOWN | CBS_SORT | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+PUSHBUTTON      "Connect", IDC_CONNECT, 91, 95, 111, 14
+LTEXT           "Project", IDC_STATIC, 61, 119, 23, 8
+END
+
+IDD_DSN_CFG2 DIALOGEX 0, 0, 263, 204
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
+CAPTION "Kylin DSN Configuration Dialog"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+PUSHBUTTON      "Cancel", IDCANCEL, 145, 167, 50, 14
+LTEXT           "Server Host", IDC_STATIC, 48, 35, 38, 8
+LTEXT           "Port", IDC_STATIC, 72, 52, 14, 8
+EDITTEXT        IDC_SERVER, 93, 33, 102, 12, ES_AUTOHSCROLL
+EDITTEXT        IDC_PORT, 93, 50, 30, 12, ES_AUTOHSCROLL
+LTEXT           "Username", IDC_STATIC, 53, 82, 33, 8
+LTEXT           "Password", IDC_STATIC, 55, 102, 32, 8
+EDITTEXT        IDC_UID, 93, 79, 102, 12, ES_AUTOHSCROLL
+EDITTEXT        IDC_PWD, 93, 97, 102, 13, ES_PASSWORD | ES_AUTOHSCROLL
+DEFPUSHBUTTON   "Done", IDOK, 84, 167, 50, 14, WS_DISABLED
+LTEXT           "&DSN Name", IDC_STATIC, 49, 17, 37, 8
+EDITTEXT        IDC_DSNNAME, 93, 14, 102, 12, ES_AUTOHSCROLL
+LTEXT           "(only https service permitted)", IDC_STATIC, 94, 66, 90, 8
+PUSHBUTTON      "Test", IDC_BTEST, 94, 117, 102, 14
+LTEXT           "Project", IDC_STATIC, 63, 145, 23, 8
+COMBOBOX        IDC_COMBO1, 94, 143, 101, 30, CBS_DROPDOWN | CBS_SORT | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+IDD_DSN_CFG1, DIALOG
+BEGIN
+LEFTMARGIN, 7
+RIGHTMARGIN, 256
+TOPMARGIN, 7
+BOTTOMMARGIN, 155
+END
+
+IDD_DSN_CFG2, DIALOG
+BEGIN
+LEFTMARGIN, 7
+RIGHTMARGIN, 256
+TOPMARGIN, 7
+BOTTOMMARGIN, 197
+END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Driver/KO_ALLOC.CPP
----------------------------------------------------------------------
diff --git a/odbc/Driver/KO_ALLOC.CPP b/odbc/Driver/KO_ALLOC.CPP
new file mode 100644
index 0000000..6176e5c
--- /dev/null
+++ b/odbc/Driver/KO_ALLOC.CPP
@@ -0,0 +1,608 @@
+
+// ----------------------------------------------------------------------------
+//
+// File:    KO_ALLOC.CPP
+//
+// Notes:   Contains function for managing allocation and release
+//          of the three structures/handles - Environment,
+//          Connection and Statement. Statements r
+//          encapsulated inside connection while all connections
+//          inside environment
+//
+// Exported functions:
+//                       SQLAllocEnv
+//                       SQLAllocConnect
+//                       SQLAllocConnect
+//                       SQLAllocStmt
+//                       SQLAllocHandle
+//                       SQLFreeStmt
+//                       SQLDisconnect
+//                       SQLFreeConnect
+//                       SQLFreeHandle
+//                       SQLFreeEnv
+// ----------------------------------------------------------------------------
+
+#include "stdafx.h"
+
+// --------------------------- local functions --------------------------------
+static eGoodBad         _SQLAttachStmt ( pODBCConn pConn, pODBCStmt pStmt );
+static eGoodBad         _SQLDetachStmt ( pODBCConn pConn, pODBCStmt pStmt );
+
+static RETCODE SQL_API _SQLFreeStmtResult ( pODBCStmt pHandle );
+static RETCODE SQL_API _SQLFreeStmtCols ( pODBCStmt pHandle );
+static RETCODE SQL_API _SQLFreeStmtParams ( pODBCStmt pHandle );
+static RETCODE SQL_API _SQLFreeStmtAll ( pODBCStmt pHandle );
+static RETCODE SQL_API _SQLFreeStmts ( pODBCStmt pHandle );
+
+static eGoodBad         _SQLAttachConn ( pODBCEnv pEnv, pODBCConn pConn );
+static eGoodBad         _SQLDetachConn ( pODBCEnv pEnv, pODBCConn pConn );
+
+
+static RETCODE SQL_API _SQLFreeConnect ( pODBCConn pHandle );
+static RETCODE SQL_API _SQLFreeConnects ( pODBCConn pHandle );
+
+static RETCODE SQL_API _SQLFreeEnv ( pODBCEnv pHandle );
+
+
+// -----------------------------------------------------------------------
+// to allocate a environment
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLAllocEnv ( HENV* pOutputHandlePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLAllocEnv called" ) );
+    pODBCEnv     env = NULL;
+    
+    // precaution
+    if ( pOutputHandlePtr == 0 ) {
+        __ODBCPOPMSG ( _ODBCPopMsg ( "SQLAllocEnv - bad params" ) );
+        return SQL_ERROR;
+    }
+    
+    // initializations
+    *pOutputHandlePtr = 0;
+    // allocate an env
+    env = new ODBCEnv;
+    // clear the env attributes
+    memset ( env, 0, sizeof ( ODBCEnv ) );
+    // set the handle signature
+    ( ( pODBCEnv ) env )->Sign = SQL_HANDLE_ENV;
+    // default values
+    ( ( pODBCEnv ) env )->AttrODBCVersion =
+        SQL_OV_ODBC3;                        // SQL_ATTR_ODBC_VERSION                200
+    ( ( pODBCEnv ) env )->AttrConnPooling =
+        SQL_CP_OFF;                          // SQL_ATTR_CONNECTION_POOLING          201
+    ( ( pODBCEnv ) env )->AttrCPMatch     =
+        SQL_CP_STRICT_MATCH;                 // SQL_ATTR_CP_MATCH                    202
+    ( ( pODBCEnv ) env )->AttrOutputNTS   = SQL_TRUE;                            // SQL_ATTR_OUTPUT_NTS
+    // pass back to caller
+    *pOutputHandlePtr = ( HENV ) env;
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to allocate a connection
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLAllocConnect ( HENV pEnvHandle, HDBC* pOutputHandlePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLAllocConnect called" ) );
+    pODBCConn    conn;
+    __CHK_HANDLE ( pEnvHandle, SQL_HANDLE_ENV, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGENV ( pEnvHandle ) );
+    
+    // precaution
+    if ( pOutputHandlePtr == 0 ) {
+        __ODBCPOPMSG ( _ODBCPopMsg ( "SQLAllocConnect - bad params" ) );
+        return SQL_ERROR;
+    }
+    
+    // initializations
+    *pOutputHandlePtr = 0;
+    // allocate a conn
+    conn = new ODBCConn;
+    // clear the conn attributes
+    memset ( conn, 0, sizeof ( ODBCConn ) );
+    // set the handle signature
+    ( ( pODBCConn ) conn )->Sign = SQL_HANDLE_DBC;
+    // default values
+    ( ( pODBCConn ) conn )->AccessMode      = SQL_MODE_READ_ONLY;
+    ( ( pODBCConn ) conn )->AutoIPD         = SQL_FALSE;
+    ( ( pODBCConn ) conn )->AsyncEnable     = SQL_ASYNC_ENABLE_OFF;
+    ( ( pODBCConn ) conn )->AutoCommit      = SQL_AUTOCOMMIT_ON;
+    ( ( pODBCConn ) conn )->TimeOut         = 0;
+    ( ( pODBCConn ) conn )->LoginTimeOut    = 0;
+    ( ( pODBCConn ) conn )->MetaDataID      = SQL_FALSE;
+    ( ( pODBCConn ) conn )->ODBCCursors     = SQL_CUR_USE_DRIVER;
+    ( ( pODBCConn ) conn )->Window          = NULL;
+    ( ( pODBCConn ) conn )->TxnIsolation    = 0;
+    ( ( pODBCConn ) conn )->MaxRows         = 0;
+    ( ( pODBCConn ) conn )->QueryTimeout    = 0;
+    // attach it to link list
+    _SQLAttachConn ( ( pODBCEnv ) pEnvHandle, conn );
+    // pass back conn to caller
+    *pOutputHandlePtr = ( HDBC ) conn;
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to allocate a statement
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLAllocStmt ( HDBC pConnHandle, HSTMT* pOutputHandlePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLAllocStmt called" ) );
+    pODBCStmt    stmt = NULL;
+    __CHK_HANDLE ( pConnHandle, SQL_HANDLE_DBC, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGCONN ( pConnHandle ) );
+    
+    // precaution
+    if ( pOutputHandlePtr == 0 ) {
+        __ODBCPOPMSG ( _ODBCPopMsg ( "SQLAllocStmt - bad params" ) );
+        return SQL_ERROR;
+    }
+    
+    // initializations
+    *pOutputHandlePtr = 0;
+    // allocate a stmt
+    stmt = new ODBCStmt;
+    // clear the stmt attributes
+    memset ( stmt, 0, sizeof ( ODBCStmt ) );
+    // set the handle signature
+    ( ( pODBCStmt ) stmt )->Sign = SQL_HANDLE_STMT;
+    // default values
+    ( ( pODBCStmt ) stmt )->AsyncEnable         = SQL_ASYNC_ENABLE_OFF;
+    ( ( pODBCStmt ) stmt )->Concurrency         = SQL_CONCUR_READ_ONLY;
+    ( ( pODBCStmt ) stmt )->CursorScroll        = SQL_NONSCROLLABLE;
+    ( ( pODBCStmt ) stmt )->CursorSensitivity   = SQL_UNSPECIFIED;
+    ( ( pODBCStmt ) stmt )->CursorType          = SQL_CURSOR_FORWARD_ONLY;
+    ( ( pODBCStmt ) stmt )->AutoIPD             = SQL_FALSE;
+    ( ( pODBCStmt ) stmt )->KeysetSize          = 0;
+    ( ( pODBCStmt ) stmt )->MetaDataID          = SQL_FALSE;
+    ( ( pODBCStmt ) stmt )->NoScan              = SQL_NOSCAN_OFF;
+    ( ( pODBCStmt ) stmt )->QryTimeout          = 0;
+    ( ( pODBCStmt ) stmt )->RetrieveData        = SQL_RD_DEFAULT;
+    // set descriptor defaults
+    _SQLSetARDFieldsDefault ( & ( ( ( pODBCStmt ) stmt )->ARD ), ( pODBCStmt ) stmt );
+    _SQLSetAPDFieldsDefault ( & ( ( ( pODBCStmt ) stmt )->APD ), ( pODBCStmt ) stmt );
+    _SQLSetIRDFieldsDefault ( & ( ( ( pODBCStmt ) stmt )->IRD ), ( pODBCStmt ) stmt );
+    _SQLSetIPDFieldsDefault ( & ( ( ( pODBCStmt ) stmt )->IPD ), ( pODBCStmt ) stmt );
+    // attach it to link list
+    _SQLAttachStmt ( ( pODBCConn ) pConnHandle, stmt );
+    // pass back to caller
+    *pOutputHandlePtr = ( HSTMT ) stmt;
+    // ???? debug log message
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "New stmt: %d", stmt ) );
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to allocate a handle for env, conn or stmt
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLAllocHandle ( SQLSMALLINT pHandleType, SQLHANDLE pInputHandle, SQLHANDLE*  pOutputHandlePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLAllocHandle called" ) );
+    
+    switch ( pHandleType ) {
+        case SQL_HANDLE_ENV:
+            return SQLAllocEnv ( pOutputHandlePtr );                        // allocate environment
+            
+        case SQL_HANDLE_DBC:
+            return SQLAllocConnect ( pInputHandle, pOutputHandlePtr );      // allocate connection
+            
+        case SQL_HANDLE_STMT:
+            return SQLAllocStmt ( pInputHandle, pOutputHandlePtr );         // allocate statement
+            
+        case SQL_HANDLE_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLAllocHandle - Explicit descriptor requested - not supported" ) );
+            return SQL_ERROR;                                             // allocate a descriptor
+    }
+    
+    return SQL_ERROR;
+}
+
+
+// -----------------------------------------------------------------------
+// to free an existing statement handle
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLFreeStmt ( SQLHSTMT pStmt, SQLUSMALLINT pOption ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "SQLFreeStmt called, %d with option %d", pStmt, pOption ) );
+    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
+    
+    // check the operation to perform
+    switch ( pOption ) {
+        case SQL_UNBIND:
+            __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLFreeStmt called for Col bindings" ) );
+            return _SQLFreeStmtCols ( ( pODBCStmt ) pStmt );
+            
+        case SQL_RESET_PARAMS:
+            __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLFreeStmt called for params" ) );
+            return _SQLFreeStmtParams ( ( pODBCStmt ) pStmt );
+            
+        default:            // include SQL_CLOSE:
+            __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLFreeStmt called for Result" ) );
+            return _SQLFreeStmtResult ( ( pODBCStmt ) pStmt );
+    }
+}
+
+
+// -----------------------------------------------------------------------
+// to disconnect from sever is a state is maintained on a connection
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLDisconnect ( HDBC pHandle ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "SQLDisconnect called" ) );
+    __CHK_HANDLE ( pHandle, SQL_HANDLE_DBC, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGCONN ( pHandle ) );
+    // free the connection
+    RETCODE code =  _SQLDisconnect ( ( pODBCConn ) pHandle );
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLDisconnect exited" ) );
+    return code;
+}
+
+// -----------------------------------------------------------------------
+// to free an existing connection handle
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLFreeConnect ( HDBC pHandle ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "SQLFreeConnect called" ) );
+    __CHK_HANDLE ( pHandle, SQL_HANDLE_DBC, SQL_ERROR );
+    // free the connection
+    RETCODE code =  _SQLFreeConnect ( ( pODBCConn ) pHandle );
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLFreeConnect Exited" ) );
+    return code;
+}
+
+
+// -----------------------------------------------------------------------
+// to free an existing environment handle
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLFreeEnv ( HENV pHandle ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "SQLFreeEnv called" ) );
+    __CHK_HANDLE ( pHandle, SQL_HANDLE_ENV, SQL_ERROR );
+    // free the env
+    return _SQLFreeEnv ( ( pODBCEnv ) pHandle );
+}
+
+// -----------------------------------------------------------------------
+// to free an environment, connection or stmt
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLFreeHandle ( SQLSMALLINT pHandleType, SQLHANDLE pHandle ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_INFO, "SQLFreeHandle called, Handle Type: %d, Handle: %d", pHandleType,
+                              ( Long ) pHandle ) );
+    __CHK_HANDLE ( pHandle, pHandleType, SQL_ERROR );
+    
+    // as per the handle type
+    switch ( pHandleType ) {
+        case SQL_HANDLE_ENV:
+            return _SQLFreeEnv ( ( pODBCEnv ) pHandle );                 // free environment
+            
+        case SQL_HANDLE_DBC:
+            return _SQLFreeConnect ( ( pODBCConn ) pHandle );            // free conenction
+            
+        case SQL_HANDLE_STMT:
+            return _SQLFreeStmtAll ( ( pODBCStmt ) pHandle );            // free statement
+            
+        case SQL_HANDLE_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLFreeHandle called for descriptor" ) );
+            return SQL_ERROR;                             // free descriptor
+    }
+    
+    return SQL_ERROR;
+}
+
+
+// -----------------------------------------------------------------------
+// to attach a new stmt to STMT link list in CONN
+// -----------------------------------------------------------------------
+
+static eGoodBad _SQLAttachStmt ( pODBCConn pConn, pODBCStmt pStmt ) {
+    pODBCStmt     l;
+    
+    // precaution
+    if ( pConn == NULL || pStmt == NULL )
+    { return BAD; }
+    
+    // set conn as stmt container
+    pStmt->Conn = pConn;
+    
+    // check if this is the first item
+    if ( pConn->Stmts == NULL ) {
+        // set as first and only item
+        pConn->Stmts  = pStmt;
+        pStmt->Prev   = NULL;
+        pStmt->Next   = NULL;
+        return GOOD;
+    }
+    
+    // move to tail item
+    for ( l = pConn->Stmts; l->Next != NULL; l = l->Next );
+    
+    // attach to tail
+    l->Next         = pStmt;
+    pStmt->Prev     = l;
+    pStmt->Next     = NULL;
+    return GOOD;
+}
+
+// -----------------------------------------------------------------------
+// to detach an existing stmt from link list
+// -----------------------------------------------------------------------
+
+static eGoodBad _SQLDetachStmt ( pODBCConn pConn, pODBCStmt pStmt ) {
+    // precaution
+    if ( pConn == NULL || pStmt == NULL )
+    { return BAD; }
+    
+    if ( pStmt->Prev )
+    { ( pStmt->Prev )->Next = pStmt->Next; }        // attach prev to next
+    
+    else
+    { pConn->Stmts = pStmt->Next; }                 // set head to next if any
+    
+    if ( pStmt->Next )
+    { ( pStmt->Next )->Prev = pStmt->Prev; }        // set next to prev if any
+    
+    return GOOD;
+}
+
+
+// -----------------------------------------------------------------------
+// free the cursor/results associated with the specified stmt
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeStmtResult ( pODBCStmt pHandle ) {
+    // note
+    // assumes handle already checked
+    
+    // basic stmt
+    if ( pHandle->Stmt ) {
+        delete[] pHandle->Stmt;
+        pHandle->Stmt = NULL;
+    }
+    
+    // basic stmt
+    pHandle->StmtLen    = 0;
+    pHandle->Prepared   = FALSE;
+    pHandle->CurRowsetStartRow      = NULL;                         // start of current rowset
+    pHandle->CurRowsetStartRowPos   = 0;                            // absolute position
+    pHandle->CurRowsetEndRow        = NULL;                         // end of current rowset
+    pHandle->CurRowsetEndRowPos     = 0;                            // absolute position
+    pHandle->RowCount       = 0;
+    _SQLFreeIRDContent ( & ( pHandle->IRD ) );
+    return SQL_SUCCESS;
+}
+
+// -----------------------------------------------------------------------
+// free all the cols bound to a specified stmt
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeStmtCols ( pODBCStmt pHandle ) {
+    // note
+    // assumes handle already checked
+    return _SQLFreeARDContent ( & ( pHandle->ARD ) );
+}
+
+
+// -----------------------------------------------------------------------
+// free all the params bound to a particular stmt
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeStmtParams ( pODBCStmt pHandle ) {
+    // note always called as a sub-function so no diag reset
+    // to be implemented along with
+    // other details of parms
+    return _SQLFreeAPDContent ( & ( pHandle->APD ) );
+}
+
+
+// -----------------------------------------------------------------------
+// to free the stmt itself  & others associated items like ARD, APD etc
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeStmtAll ( pODBCStmt pHandle ) {
+    _SQLFreeDiag ( _DIAGSTMT ( pHandle ) );
+    // note always called as a sub-function so no diag reset
+    pODBCConn    conn;
+    // extract the container connection
+    conn = pHandle->Conn;
+    
+    // check if valid
+    if ( conn == NULL )
+    { return SQL_ERROR; }
+    
+    // pluck from link-list
+    _SQLDetachStmt ( conn, pHandle );
+    // clear/free results
+    _SQLFreeStmtResult ( pHandle );
+    // clear/free col bindings
+    _SQLFreeStmtCols ( pHandle );
+    // clear/free parms bindings
+    _SQLFreeStmtParams ( pHandle );
+    // now free the structure itself
+    delete pHandle;
+    return SQL_SUCCESS;
+}
+
+// -----------------------------------------------------------------------
+// to all the stmts starting from the specified stmt
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeStmts ( pODBCStmt pHandle ) {
+    pODBCStmt    t, n;
+    
+    // loop to iterate the list
+    for ( n = pHandle; n != NULL; ) {
+        t = n;
+        n = n->Next;
+        _SQLFreeStmtAll ( t );
+    }
+    
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to attach a new conn to CONN link list in ENV
+// -----------------------------------------------------------------------
+
+static eGoodBad _SQLAttachConn ( pODBCEnv pEnv, pODBCConn pConn ) {
+    pODBCConn     l;
+    
+    // precaution
+    if ( pEnv == NULL || pConn == NULL )
+    { return BAD; }
+    
+    // set env as container for conn
+    pConn->Env = pEnv;
+    
+    // check if this is the first item
+    if ( pEnv->Conns == NULL ) {
+        // set as first and only item
+        pEnv->Conns   = pConn;
+        pConn->Prev   = NULL;
+        pConn->Next   = NULL;
+        return GOOD;
+    }
+    
+    // move to tail item
+    for ( l = pEnv->Conns; l->Next != NULL; l = l->Next );
+    
+    // attach to tail
+    l->Next         = pConn;
+    pConn->Prev     = l;
+    pConn->Next     = NULL;
+    return GOOD;
+}
+
+// -----------------------------------------------------------------------
+// to detach an existing item from ARD link-list
+// -----------------------------------------------------------------------
+
+static eGoodBad _SQLDetachConn ( pODBCEnv pEnv, pODBCConn pConn ) {
+    // precaution
+    if ( pEnv == NULL || pConn == NULL )
+    { return BAD; }
+    
+    if ( pConn->Prev )
+    { ( pConn->Prev )->Next = pConn->Next; }        // attach prev to next
+    
+    else
+    { pEnv->Conns = pConn->Next; }                 // set head to next if any
+    
+    if ( pConn->Next )
+    { ( pConn->Next )->Prev = pConn->Prev; }        // set next to prev if any
+    
+    return GOOD;
+}
+
+// -----------------------------------------------------------------------
+// to free all info associated with a connection but not the conenction itself
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API _SQLDisconnect ( pODBCConn pHandle ) {
+    pHandle->IsConnected = FALSE;
+    
+    if ( pHandle->ConnectStr ) {
+        delete[] pHandle->ConnectStr;
+        pHandle->ConnectStr = NULL;
+    }
+    
+    if ( pHandle->Server ) {
+        delete[] pHandle->Server;
+        pHandle->Server = NULL;
+    }
+    
+    if ( pHandle->Project ) {
+        delete[] pHandle->Project;
+        pHandle->Project = NULL;
+    }
+    
+    if ( pHandle->UserName ) {
+        delete[] pHandle->UserName;
+        pHandle->UserName = NULL;
+    }
+    
+    if ( pHandle->Password ) {
+        delete[] pHandle->Password;
+        pHandle->Password = NULL;
+    }
+    
+    // free all associated statements
+    if ( pHandle->Stmts ) {                                 // all stmts within connection
+        _SQLFreeStmts ( pHandle->Stmts );
+        pHandle->Stmts = NULL;
+    }
+    
+    //free meta
+    if ( pHandle->meta ) {
+        pHandle->meta = NULL;
+    }
+    
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to free a specifed connection, plucks from parent/list AND FREEs it
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeConnect ( pODBCConn pHandle ) {
+    _SQLFreeDiag ( _DIAGCONN ( pHandle ) );
+    pODBCEnv     env;
+    // disconnect
+    _SQLDisconnect ( pHandle );
+    // extract the container environment
+    env = pHandle->Env;
+    
+    // check if valid
+    if ( env == NULL ) { return SQL_ERROR; }
+    
+    // detach from link list
+    _SQLDetachConn ( env, pHandle );
+    // now free the structure itself
+    delete pHandle;
+    // reset
+    pHandle = NULL;
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to all the connections starting from the specified connection
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeConnects ( pODBCConn pHandle ) {
+    pODBCConn    t, n;
+    
+    // loop to iterate the list of connections
+    for ( n = pHandle; n != NULL; ) {
+        t = n;                      // save
+        n = n->Next;                // get next
+        _SQLFreeConnect ( t );      // free saved
+    }
+    
+    return SQL_SUCCESS;
+}
+
+// -----------------------------------------------------------------------
+// to free the specified env
+// -----------------------------------------------------------------------
+
+static RETCODE SQL_API _SQLFreeEnv ( pODBCEnv pHandle ) {
+    // free diags if any
+    _SQLFreeDiag ( _DIAGENV ( pHandle ) );
+    
+    // check if any connections are allocated
+    if ( pHandle->Conns ) {
+        //_SQLFreeConnects ( pHandle->Conns );                    // relase all connections
+    }
+    
+    delete pHandle;
+    return SQL_SUCCESS;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/d1dcfd15/odbc/Driver/KO_ATTR.CPP
----------------------------------------------------------------------
diff --git a/odbc/Driver/KO_ATTR.CPP b/odbc/Driver/KO_ATTR.CPP
new file mode 100644
index 0000000..e9016b4
--- /dev/null
+++ b/odbc/Driver/KO_ATTR.CPP
@@ -0,0 +1,897 @@
+// ----------------------------------------------------------------------------
+//
+// File:    KO_ATTR.CPP
+//
+// Notes:   Contains the attribute/option set/get functions
+//          for environment, connection and statement
+//          also contains some other functions like setting of
+//          cursor name etc.
+//
+// Exported functions:
+//                       SQLSetEnvAttr
+//                       SQLGetEnvAttr
+//                       SQLSetConnectAttr
+//                       SQLGetConnectAttr
+//                       SQLSetStmtAttr
+//                       SQLGetStmtAttr
+//                       SQLGetCursorName
+//                       SQLSetCursorName
+// ----------------------------------------------------------------------------
+
+#include "stdafx.h"
+
+
+// -----------------------------------------------------------------------
+// to set environment specific attributes
+// -----------------------------------------------------------------------
+
+
+RETCODE SQL_API SQLSetEnvAttr ( SQLHENV pEnv, SQLINTEGER pAttr, SQLPOINTER pDataPtr, SQLINTEGER pDataSize ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetEnvAttr called" ) );
+    __CHK_HANDLE ( pEnv, SQL_HANDLE_ENV, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGENV ( pEnv ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_ODBC_VERSION:
+            ( ( pODBCEnv ) pEnv )->AttrODBCVersion = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CONNECTION_POOLING:
+            ( ( pODBCEnv ) pEnv )->AttrConnPooling = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CP_MATCH:
+            ( ( pODBCEnv ) pEnv )->AttrCPMatch = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_OUTPUT_NTS:
+            ( ( pODBCEnv ) pEnv )->AttrOutputNTS = ( ULong ) pDataPtr;
+            break;
+            
+        default:
+            return SQL_ERROR;                   // unknown attribute
+    }
+    
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to get current value of specified env attribute
+// -----------------------------------------------------------------------
+
+RETCODE SQL_API SQLGetEnvAttr ( SQLHENV     pEnv,
+                                SQLINTEGER  pAttr,
+                                SQLPOINTER  pDataPtr,
+                                SQLINTEGER  pDataSize,
+                                SQLINTEGER* pDataSizePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetEnvAttr called" ) );
+    __CHK_HANDLE ( pEnv, SQL_HANDLE_ENV, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGENV ( pEnv ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_ODBC_VERSION:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCEnv ) pEnv )->AttrODBCVersion;
+            break;
+            
+        case SQL_ATTR_CONNECTION_POOLING:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCEnv ) pEnv )->AttrConnPooling;
+            break;
+            
+        case SQL_ATTR_CP_MATCH:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCEnv ) pEnv )->AttrCPMatch;
+            break;
+            
+        case SQL_ATTR_OUTPUT_NTS:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCEnv ) pEnv )->AttrOutputNTS;
+            break;
+            
+        default:
+            return SQL_ERROR;                   // unknown attribute
+    }
+    
+    return SQL_SUCCESS;
+}
+
+// --------------------------------------------------------------------
+// to set attributes specific to a connection
+// --------------------------------------------------------------------
+RETCODE SQL_API SQLSetConnectAttrW ( SQLHDBC            hdbc,
+                                     SQLINTEGER         fAttribute,
+                                     SQLPOINTER         rgbValue,
+                                     SQLINTEGER         cbValue ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetConnectAttrW, Attr: %d, DataPtr: %d, DataSize: %d", fAttribute,
+                              rgbValue, cbValue ) );
+    RETCODE code = SQLSetConnectAttr ( hdbc, fAttribute, rgbValue, cbValue );
+    return code;
+}
+
+
+RETCODE SQL_API SQLSetConnectAttr ( SQLHDBC pConn, SQLINTEGER pAttr, SQLPOINTER pDataPtr, SQLINTEGER pDataSize ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetConnectAttr, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    __CHK_HANDLE ( pConn, SQL_HANDLE_DBC, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGCONN ( pConn ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_ANSI_APP:
+            return  SQL_ERROR;
+            
+        case SQL_ATTR_ACCESS_MODE:
+            ( ( pODBCConn ) pConn )->AccessMode = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_ASYNC_ENABLE:
+            ( ( pODBCConn ) pConn )->AsyncEnable = ( ULong ) pDataPtr;
+            break;
+            
+        //case SQL_ATTR_AUTO_IPD:  read-only
+        
+        case SQL_ATTR_AUTOCOMMIT:
+            ( ( pODBCConn ) pConn )->AutoCommit = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CONNECTION_DEAD:
+            // (( pODBCConn )pConn)->AutoCommit = ( ULong )pDataPtr;
+            break;
+            
+        case SQL_ATTR_CONNECTION_TIMEOUT:
+            //(( pODBCConn )pConn)->TimeOut = *(( ULong* )pDataPtr );
+            break;
+            
+        case SQL_ATTR_CURRENT_CATALOG:          // current database
+            // assumes that current database is what it should be
+            // return _SQLCopyCharData ( _DIAGCONN(pConn), (( pODBCConn )pConn)->CurrDB, 32, NULL, 16, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_LOGIN_TIMEOUT:
+            // (( pODBCConn )pConn)->LoginTimeOut = *(( ULong* )pDataPtr );
+            break;
+            
+        case SQL_ATTR_METADATA_ID:
+            ( ( pODBCConn ) pConn )->MetaDataID = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_ODBC_CURSORS:
+            ( ( pODBCConn ) pConn )->ODBCCursors = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_PACKET_SIZE:
+            // not a typical option
+            return SQL_ERROR;
+            
+        case SQL_ATTR_QUIET_MODE:
+            ( ( pODBCConn ) pConn )->Window = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_TRACE:
+            // only for driver manager
+            break;
+            
+        case SQL_ATTR_TRACEFILE:
+            // only for driver manager
+            break;
+            
+        case SQL_ATTR_TRANSLATE_LIB:
+            // translation still not implemented
+            break;
+            
+        case SQL_ATTR_TRANSLATE_OPTION:
+            // translation still not implemented
+            break;
+            
+        case SQL_ATTR_TXN_ISOLATION:
+            ( ( pODBCConn ) pConn )->TxnIsolation = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_MAX_ROWS:
+            ( ( pODBCConn ) pConn )->MaxRows = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_QUERY_TIMEOUT:
+            ( ( pODBCConn ) pConn )->QueryTimeout = ( ULong ) pDataPtr;
+            break;
+            
+        default:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLSetConnectAttr is not recognized, Attr: %d, DataPtr: %d, DataSize: %d", pAttr,
+                                         pDataPtr, pDataSize ) );
+            return SQL_SUCCESS;
+    }
+    
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetConnectAttr, Attr: %d, DataPtr: %d, DataSize: %d is done!", pAttr,
+                              pDataPtr, pDataSize ) );
+    return SQL_SUCCESS;
+}
+
+
+// -----------------------------------------------------------------------
+// to get current value of specified conn attribute
+// -----------------------------------------------------------------------
+RETCODE SQL_API SQLGetConnectAttrW ( SQLHDBC     pConn,
+                                     SQLINTEGER  pAttr,
+                                     SQLPOINTER  pDataPtr,
+                                     SQLINTEGER  pDataSize,
+                                     SQLINTEGER* pDataSizePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetConnectAttrW, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    __CHK_HANDLE ( pConn, SQL_HANDLE_DBC, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGCONN ( pConn ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_ACCESS_MODE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AccessMode;
+            break;
+            
+        case SQL_ATTR_ASYNC_ENABLE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AsyncEnable;
+            break;
+            
+        case SQL_ATTR_AUTO_IPD:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AutoIPD;
+            break;
+            
+        case SQL_ATTR_AUTOCOMMIT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AutoCommit;
+            break;
+            
+        case SQL_ATTR_CONNECTION_DEAD:
+            * ( ( ULong* ) pDataPtr ) = SQL_CD_TRUE;
+            break;
+            
+        case SQL_ATTR_CONNECTION_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->TimeOut;
+            break;
+            
+        case SQL_ATTR_CURRENT_CATALOG:          // current database
+            return _SQLCopyWCharData ( _DIAGCONN ( pConn ), pDataPtr, pDataSize, pDataSizePtr, 32, "default", -1 );
+            
+        case SQL_ATTR_LOGIN_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->LoginTimeOut;
+            break;
+            
+        case SQL_ATTR_METADATA_ID:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->MetaDataID;
+            break;
+            
+        case SQL_ATTR_ODBC_CURSORS:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->ODBCCursors;
+            break;
+            
+        case SQL_ATTR_PACKET_SIZE:
+            return SQL_ERROR;                       // not a typical option
+            
+        case SQL_ATTR_QUIET_MODE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->Window;
+            break;
+            
+        case SQL_ATTR_TRACE:
+            // basically for driver manager
+            break;
+            
+        case SQL_ATTR_TRACEFILE:
+            // basically for driver manager
+            break;
+            
+        case SQL_ATTR_TRANSLATE_LIB:
+            // not implemented
+            break;
+            
+        case SQL_ATTR_TRANSLATE_OPTION:
+            // not implemented
+            break;
+            
+        case SQL_ATTR_TXN_ISOLATION:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->TxnIsolation;
+            break;
+            
+        case SQL_ATTR_MAX_ROWS:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->MaxRows;
+            break;
+            
+        case SQL_ATTR_QUERY_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->QueryTimeout;
+            break;
+            
+        default:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLGetConnectAttrW, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr, pDataSize ) );
+            return SQL_SUCCESS;
+    }
+    
+    return SQL_SUCCESS;
+}
+
+RETCODE SQL_API SQLGetConnectAttr ( SQLHDBC     pConn,
+                                    SQLINTEGER  pAttr,
+                                    SQLPOINTER  pDataPtr,
+                                    SQLINTEGER  pDataSize,
+                                    SQLINTEGER* pDataSizePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetConnectAttr, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    __CHK_HANDLE ( pConn, SQL_HANDLE_DBC, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGCONN ( pConn ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_ACCESS_MODE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AccessMode;
+            break;
+            
+        case SQL_ATTR_ASYNC_ENABLE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AsyncEnable;
+            break;
+            
+        case SQL_ATTR_AUTO_IPD:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AutoIPD;
+            break;
+            
+        case SQL_ATTR_AUTOCOMMIT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->AutoCommit;
+            break;
+            
+        case SQL_ATTR_CONNECTION_DEAD:
+            * ( ( ULong* ) pDataPtr ) = SQL_CD_TRUE;
+            break;
+            
+        case SQL_ATTR_CONNECTION_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->TimeOut;
+            break;
+            
+        case SQL_ATTR_CURRENT_CATALOG:          // current database
+            return _SQLCopyCharData ( _DIAGCONN ( pConn ), pDataPtr, pDataSize, pDataSizePtr, 32, "default", -1 );
+            
+        case SQL_ATTR_LOGIN_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->LoginTimeOut;
+            break;
+            
+        case SQL_ATTR_METADATA_ID:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->MetaDataID;
+            break;
+            
+        case SQL_ATTR_ODBC_CURSORS:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->ODBCCursors;
+            break;
+            
+        case SQL_ATTR_PACKET_SIZE:
+            return SQL_ERROR;                       // not a typical option
+            
+        case SQL_ATTR_QUIET_MODE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->Window;
+            break;
+            
+        case SQL_ATTR_TRACE:
+            // basically for driver manager
+            break;
+            
+        case SQL_ATTR_TRACEFILE:
+            // basically for driver manager
+            break;
+            
+        case SQL_ATTR_TRANSLATE_LIB:
+            // not implemented
+            break;
+            
+        case SQL_ATTR_TRANSLATE_OPTION:
+            // not implemented
+            break;
+            
+        case SQL_ATTR_TXN_ISOLATION:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->TxnIsolation;
+            break;
+            
+        case SQL_ATTR_MAX_ROWS:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->MaxRows;
+            break;
+            
+        case SQL_ATTR_QUERY_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCConn ) pConn )->QueryTimeout;
+            break;
+            
+        default:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLGetConnectAttr not recognized, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                                         pDataSize ) );
+            return SQL_SUCCESS;
+    }
+    
+    return SQL_SUCCESS;
+}
+
+
+// --------------------------------------------------------------------
+// to set attributes specific to a statement
+// --------------------------------------------------------------------
+
+
+RETCODE SQL_API SQLSetStmtAttrW ( SQLHSTMT       pStmt,
+                                  SQLINTEGER     pAttr,
+                                  SQLPOINTER     pDataPtr,
+                                  SQLINTEGER     pDataSize )
+
+{
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetStmtAttrW, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_APP_PARAM_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_APP_PARAM_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_APP_ROW_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_APP_ROW_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_ASYNC_ENABLE:
+            ( ( pODBCStmt ) pStmt )->AsyncEnable = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CONCURRENCY:
+            ( ( pODBCStmt ) pStmt )->Concurrency = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CURSOR_SCROLLABLE:
+            ( ( pODBCStmt ) pStmt )->CursorScroll = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CURSOR_SENSITIVITY:
+            ( ( pODBCStmt ) pStmt )->CursorSensitivity = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CURSOR_TYPE:
+            ( ( pODBCStmt ) pStmt )->CursorType = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_ENABLE_AUTO_IPD:
+            ( ( pODBCStmt ) pStmt )->AutoIPD = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_FETCH_BOOKMARK_PTR:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_FETCH_BOOKMARK_PTR - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_IMP_PARAM_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_IMP_PARAM_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_IMP_ROW_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_IMP_ROW_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_KEYSET_SIZE:
+            ( ( pODBCStmt ) pStmt )->KeysetSize = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_MAX_LENGTH:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_MAX_LENGTH - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_MAX_ROWS:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_MAX_ROWS - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_METADATA_ID:
+            ( ( pODBCStmt ) pStmt )->MetaDataID = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_NOSCAN:
+            ( ( pODBCStmt ) pStmt )->NoScan = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_PARAM_BIND_TYPE:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_BIND_TYPE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_BIND_OFFSET_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAM_OPERATION_PTR:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAM_STATUS_PTR:
+            _SQLSetIPDField ( & ( ( ( pODBCStmt ) pStmt )->IPD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAMS_PROCESSED_PTR:
+            // ???? note there is an error in MSDN on SQLSetDescField which says ARD/APD instead of IRD/IPD for this option
+            _SQLSetIPDField ( & ( ( ( pODBCStmt ) pStmt )->IPD ), SQL_DESC_ROWS_PROCESSED_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAMSET_SIZE:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ARRAY_SIZE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_QUERY_TIMEOUT:
+            if ( pDataPtr != NULL )
+            { ( ( pODBCStmt ) pStmt )->QryTimeout = ( ( ULong ) pDataPtr ); }
+            
+            break;
+            
+        case SQL_ATTR_RETRIEVE_DATA:
+            ( ( pODBCStmt ) pStmt )->RetrieveData = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ROWSET_SIZE:
+        case SQL_ATTR_ROW_ARRAY_SIZE:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_ARRAY_SIZE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_BIND_OFFSET_PTR:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_BIND_OFFSET_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_BIND_TYPE:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_BIND_TYPE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_OPERATION_PTR:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_STATUS_PTR:
+            _SQLSetIRDField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROWS_FETCHED_PTR:
+            _SQLSetIRDField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), SQL_DESC_ROWS_PROCESSED_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_SIMULATE_CURSOR:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_SIMULATE_CURSOR - option not implemented" ) );
+            return SQL_ERROR;
+            
+        default:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLSetStmtAttrW : Stmt attr - unknown %d", pAttr ) );
+            return SQL_ERROR;
+    }
+    
+    return SQL_SUCCESS;
+}
+
+RETCODE SQL_API SQLSetStmtAttr ( SQLHSTMT       pStmt,
+                                 SQLINTEGER     pAttr,
+                                 SQLPOINTER     pDataPtr,
+                                 SQLINTEGER     pDataSize )
+
+{
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLSetStmtAttr, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_APP_PARAM_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_APP_PARAM_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_APP_ROW_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_APP_ROW_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_ASYNC_ENABLE:
+            ( ( pODBCStmt ) pStmt )->AsyncEnable = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CONCURRENCY:
+            ( ( pODBCStmt ) pStmt )->Concurrency = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CURSOR_SCROLLABLE:
+            ( ( pODBCStmt ) pStmt )->CursorScroll = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CURSOR_SENSITIVITY:
+            ( ( pODBCStmt ) pStmt )->CursorSensitivity = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_CURSOR_TYPE:
+            ( ( pODBCStmt ) pStmt )->CursorType = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_ENABLE_AUTO_IPD:
+            ( ( pODBCStmt ) pStmt )->AutoIPD = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_FETCH_BOOKMARK_PTR:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_FETCH_BOOKMARK_PTR - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_IMP_PARAM_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_IMP_PARAM_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_IMP_ROW_DESC:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_IMP_ROW_DESC - Cannot set descriptor" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_KEYSET_SIZE:
+            ( ( pODBCStmt ) pStmt )->KeysetSize = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_MAX_LENGTH:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_MAX_LENGTH - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_MAX_ROWS:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_MAX_ROWS - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_METADATA_ID:
+            ( ( pODBCStmt ) pStmt )->MetaDataID = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_NOSCAN:
+            ( ( pODBCStmt ) pStmt )->NoScan = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ATTR_PARAM_BIND_TYPE:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_BIND_TYPE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_BIND_OFFSET_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAM_OPERATION_PTR:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAM_STATUS_PTR:
+            _SQLSetIPDField ( & ( ( ( pODBCStmt ) pStmt )->IPD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAMS_PROCESSED_PTR:
+            // ???? note there is an error in MSDN on SQLSetDescField which says ARD/APD instead of IRD/IPD for this option
+            _SQLSetIPDField ( & ( ( ( pODBCStmt ) pStmt )->IPD ), SQL_DESC_ROWS_PROCESSED_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_PARAMSET_SIZE:
+            _SQLSetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ARRAY_SIZE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_QUERY_TIMEOUT:
+            if ( pDataPtr != NULL )
+            { ( ( pODBCStmt ) pStmt )->QryTimeout = * ( ( ULong* ) pDataPtr ); }
+            
+            break;
+            
+        case SQL_ATTR_RETRIEVE_DATA:
+            ( ( pODBCStmt ) pStmt )->RetrieveData = ( ULong ) pDataPtr;
+            break;
+            
+        case SQL_ROWSET_SIZE:
+        case SQL_ATTR_ROW_ARRAY_SIZE:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_ARRAY_SIZE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_BIND_OFFSET_PTR:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_BIND_OFFSET_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_BIND_TYPE:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_BIND_TYPE, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_OPERATION_PTR:
+            _SQLSetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROW_STATUS_PTR:
+            _SQLSetIRDField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_ROWS_FETCHED_PTR:
+            _SQLSetIRDField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), SQL_DESC_ROWS_PROCESSED_PTR, pDataPtr, pDataSize );
+            break;
+            
+        case SQL_ATTR_SIMULATE_CURSOR:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_SIMULATE_CURSOR - option not implemented" ) );
+            return SQL_ERROR;
+            
+        default:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLSetStmtAttr: Stmt attr - unknown %d", pAttr ) );
+            return SQL_ERROR;
+    }
+    
+    return SQL_SUCCESS;
+}
+
+
+
+RETCODE SQL_API SQLGetStmtAttrW ( SQLHSTMT    pStmt,
+                                  SQLINTEGER  pAttr,
+                                  SQLPOINTER  pDataPtr,
+                                  SQLINTEGER  pDataSize,
+                                  SQLINTEGER* pDataSizePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetStmtAttrW, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    return SQLGetStmtAttr ( pStmt, pAttr, pDataPtr, pDataSize, pDataSizePtr );
+}
+
+
+// --------------------------------------------------------------------
+// to get attributes specific to a statement
+// --------------------------------------------------------------------
+
+RETCODE SQL_API SQLGetStmtAttr ( SQLHSTMT    pStmt,
+                                 SQLINTEGER  pAttr,
+                                 SQLPOINTER  pDataPtr,
+                                 SQLINTEGER  pDataSize,
+                                 SQLINTEGER* pDataSizePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetStmtAttr, Attr: %d, DataPtr: %d, DataSize: %d", pAttr, pDataPtr,
+                              pDataSize ) );
+    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
+    
+    switch ( pAttr ) {
+        case SQL_ATTR_APP_PARAM_DESC:
+            * ( ( Long* ) pDataPtr ) = ( Long ) & ( ( ( pODBCStmt ) pStmt )->APD );
+            break;
+            
+        case SQL_ATTR_APP_ROW_DESC:
+            * ( ( Long* ) pDataPtr ) = ( Long ) & ( ( ( pODBCStmt ) pStmt )->ARD );
+            break;
+            
+        case SQL_ATTR_ASYNC_ENABLE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->AsyncEnable;
+            break;
+            
+        case SQL_ATTR_CONCURRENCY:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->Concurrency;
+            break;
+            
+        case SQL_ATTR_CURSOR_SCROLLABLE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->CursorScroll;
+            break;
+            
+        case SQL_ATTR_CURSOR_SENSITIVITY:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->CursorSensitivity;
+            break;
+            
+        case SQL_ATTR_CURSOR_TYPE:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->CursorType;
+            break;
+            
+        case SQL_ATTR_ENABLE_AUTO_IPD:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->AutoIPD;
+            break;
+            
+        case SQL_ATTR_FETCH_BOOKMARK_PTR:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_FETCH_BOOKMARK_PTR - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_IMP_PARAM_DESC:
+            * ( ( Long* ) pDataPtr ) = ( Long ) & ( ( ( pODBCStmt ) pStmt )->IPD );
+            break;
+            
+        case SQL_ATTR_IMP_ROW_DESC:
+            * ( ( Long* ) pDataPtr ) = ( Long ) & ( ( ( pODBCStmt ) pStmt )->IRD );
+            break;
+            
+        case SQL_ATTR_KEYSET_SIZE:
+            * ( ( Long* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->KeysetSize;
+            break;
+            
+        case SQL_ATTR_MAX_LENGTH:
+            * ( ( ULong* ) pDataPtr ) = 0;
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_MAX_LENGTH - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_MAX_ROWS:
+            * ( ( ULong* ) pDataPtr ) = 0;
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_MAX_ROWS - option not implemented" ) );
+            return SQL_ERROR;
+            
+        case SQL_ATTR_METADATA_ID:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->MetaDataID;
+            break;
+            
+        case SQL_ATTR_NOSCAN:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->NoScan;
+            break;
+            
+        case SQL_ATTR_PARAM_BIND_TYPE:
+            _SQLGetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_BIND_TYPE, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
+            _SQLGetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_BIND_OFFSET_PTR, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_PARAM_OPERATION_PTR:
+            _SQLGetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_PARAM_STATUS_PTR:
+            _SQLGetIPDField ( & ( ( ( pODBCStmt ) pStmt )->IPD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_PARAMS_PROCESSED_PTR:
+            // ???? note there is an error in MSDN on SQLSetDescField which says ARD/APD instead of IRD/IPD for this option
+            _SQLGetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ROWS_PROCESSED_PTR, pDataPtr, pDataSize,
+                              pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_PARAMSET_SIZE:
+            _SQLGetAPDField ( & ( ( ( pODBCStmt ) pStmt )->APD ), SQL_DESC_ARRAY_SIZE, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_QUERY_TIMEOUT:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->QryTimeout;
+            break;
+            
+        case SQL_ATTR_RETRIEVE_DATA:
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->RetrieveData;
+            break;
+            
+        case SQL_ROWSET_SIZE:
+        case SQL_ATTR_ROW_ARRAY_SIZE:
+            _SQLGetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_ARRAY_SIZE, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_ROW_BIND_OFFSET_PTR:
+            _SQLGetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_BIND_OFFSET_PTR, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_ROW_BIND_TYPE:
+            _SQLGetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_BIND_TYPE, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_ROW_NUMBER:
+            // ??? in case of rowset being > 1, start row is being returned
+            * ( ( ULong* ) pDataPtr ) = ( ( pODBCStmt ) pStmt )->CurRowsetStartRowPos;
+            break;
+            
+        case SQL_ATTR_ROW_OPERATION_PTR:
+            _SQLGetARDField ( & ( ( ( pODBCStmt ) pStmt )->ARD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_ROW_STATUS_PTR:
+            _SQLGetIRDField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), SQL_DESC_ARRAY_STATUS_PTR, pDataPtr, pDataSize, pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_ROWS_FETCHED_PTR:
+            _SQLGetIRDField ( & ( ( ( pODBCStmt ) pStmt )->IRD ), SQL_DESC_ROWS_PROCESSED_PTR, pDataPtr, pDataSize,
+                              pDataSizePtr );
+            break;
+            
+        case SQL_ATTR_SIMULATE_CURSOR:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQL_ATTR_SIMULATE_CURSOR - option not implemented" ) );
+            return SQL_ERROR;
+            
+        default:
+            __ODBCPOPMSG ( _ODBCPopMsg ( "SQLGetStmtAttr: Stmt attr - unknown %d", pAttr ) );
+            return SQL_ERROR;
+    }
+    
+    return SQL_SUCCESS;
+}
+
+// --------------------------------------------------------------------
+// to get the name of the current cursor
+// --------------------------------------------------------------------
+
+RETCODE SQL_API SQLGetCursorName ( SQLHSTMT        pStmt,
+                                   SQLCHAR*        pDataPtr,
+                                   SQLSMALLINT     pDataSize,
+                                   SQLSMALLINT*    pDataSizePtr ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetCursorName called" ) );
+    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
+    _SQLCopyCharData ( _DIAGSTMT ( pStmt ), pDataPtr, pDataSize, pDataSizePtr, 32, "default", -1 );
+    return SQL_SUCCESS;
+}
+
+// --------------------------------------------------------------------
+// to set the name of the current cursor
+// --------------------------------------------------------------------
+
+RETCODE SQL_API SQLSetCursorName ( SQLHSTMT    pStmt,
+                                   SQLCHAR*    pDataPtr,
+                                   SQLSMALLINT pDataSize ) {
+    __ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "SQLGetCursorName called" ) );
+    __CHK_HANDLE ( pStmt, SQL_HANDLE_STMT, SQL_ERROR );
+    _SQLFreeDiag ( _DIAGSTMT ( pStmt ) );
+    return SQL_SUCCESS;
+}
+