From: Piotr Caban <piotr@codeweavers.com> --- dlls/odbc32/tests/driver.c | 80 ++++++ dlls/odbc32/tests/driver.h | 20 ++ dlls/odbc32/tests/driver.spec | 14 + dlls/odbc32/tests/odbc32.c | 481 +++++++++++++++++++++++++++++++--- 4 files changed, 564 insertions(+), 31 deletions(-) diff --git a/dlls/odbc32/tests/driver.c b/dlls/odbc32/tests/driver.c index 518740a0760..0bcd5c39033 100644 --- a/dlls/odbc32/tests/driver.c +++ b/dlls/odbc32/tests/driver.c @@ -100,3 +100,83 @@ SQLRETURN WINAPI SQLDisconnect( SQLHDBC con ) { return driver_funcs->SQLDisconnect( con ); } + +SQLRETURN WINAPI SQLGetStmtAttr( SQLHSTMT stmt, SQLINTEGER attr, + SQLPOINTER val, SQLINTEGER max_len, SQLINTEGER *len ) +{ + return driver_funcs->SQLGetStmtAttr( stmt, attr, val, max_len, len ); +} + +SQLRETURN WINAPI SQLSetStmtAttr( SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len ) +{ + return driver_funcs->SQLSetStmtAttr( stmt, attr, val, len ); +} + +SQLRETURN WINAPI SQLGetDiagField( SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT rec, + SQLSMALLINT identifier, SQLPOINTER info, SQLSMALLINT max_len, SQLSMALLINT *len ) +{ + return driver_funcs->SQLGetDiagField( type, handle, rec, identifier, info, max_len, len ); +} + +SQLRETURN WINAPI SQLGetDiagRec( SQLSMALLINT type, SQLHANDLE handle, + SQLSMALLINT rec, SQLCHAR *state, SQLINTEGER *err, SQLCHAR *msg, + SQLSMALLINT max_len, SQLSMALLINT *len ) +{ + return driver_funcs->SQLGetDiagRec( type, handle, rec, state, err, msg, max_len, len ); +} + +SQLRETURN WINAPI SQLExecDirect( SQLHSTMT stmt, SQLCHAR *cmd, SQLINTEGER len ) +{ + return driver_funcs->SQLExecDirect( stmt, cmd, len ); +} + +SQLRETURN WINAPI SQLRowCount( SQLHSTMT stmt, SQLLEN *count ) +{ + return driver_funcs->SQLRowCount( stmt, count ); +} + +SQLRETURN WINAPI SQLFetch( SQLHSTMT stmt ) +{ + return driver_funcs->SQLFetch( stmt ); +} + +SQLRETURN WINAPI SQLGetData( SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, + SQLPOINTER val, SQLLEN max_len, SQLLEN *len ) +{ + return driver_funcs->SQLGetData( stmt, col, type, val, max_len, len ); +} + +SQLRETURN WINAPI SQLBindCol( SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type, + SQLPOINTER val, SQLLEN max_len, SQLLEN *len ) +{ + return driver_funcs->SQLBindCol( stmt, col, type, val, max_len, len ); +} + +SQLRETURN WINAPI SQLPrepare( SQLHSTMT stmt, SQLCHAR *cmd, SQLINTEGER len ) +{ + return driver_funcs->SQLPrepare( stmt, cmd, len ); +} + +SQLRETURN WINAPI SQLBindParameter( SQLHSTMT stmt, SQLUSMALLINT param, + SQLSMALLINT param_type, SQLSMALLINT ctype, SQLSMALLINT type, SQLULEN size, + SQLSMALLINT decimal_digits, SQLPOINTER val, SQLLEN max_len, SQLLEN *len ) +{ + return driver_funcs->SQLBindParameter( stmt, param, param_type, ctype, + type, size, decimal_digits, val, max_len, len ); +} + +SQLRETURN WINAPI SQLExecute( SQLHSTMT stmt ) +{ + return driver_funcs->SQLExecute( stmt ); +} + +SQLRETURN WINAPI SQLSetDescField( SQLHDESC desc, SQLSMALLINT rec, + SQLSMALLINT field, SQLPOINTER val, SQLINTEGER len ) +{ + return driver_funcs->SQLSetDescField( desc, rec, field, val, len ); +} + +SQLRETURN WINAPI SQLFreeStmt( SQLHSTMT stmt, SQLUSMALLINT option ) +{ + return driver_funcs->SQLFreeStmt( stmt, option ); +} diff --git a/dlls/odbc32/tests/driver.h b/dlls/odbc32/tests/driver.h index f10384fb1e3..1f04f464ace 100644 --- a/dlls/odbc32/tests/driver.h +++ b/dlls/odbc32/tests/driver.h @@ -33,4 +33,24 @@ struct driver_funcs SQLRETURN (WINAPI *SQLBrowseConnect)(SQLHDBC, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*); SQLRETURN (WINAPI *SQLDisconnect)(SQLHDBC); + SQLRETURN (WINAPI *SQLGetStmtAttr)(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER, SQLINTEGER*); + SQLRETURN (WINAPI *SQLSetStmtAttr)(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER); + SQLRETURN (WINAPI *SQLGetDiagField)(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, + SQLSMALLINT, SQLPOINTER, SQLSMALLINT, SQLSMALLINT*); + SQLRETURN (WINAPI *SQLGetDiagRec)(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, + SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*); + SQLRETURN (WINAPI *SQLExecDirect)(SQLHSTMT, SQLCHAR*, SQLINTEGER); + SQLRETURN (WINAPI *SQLRowCount)(SQLHSTMT, SQLLEN*); + SQLRETURN (WINAPI *SQLFetch)(SQLHSTMT); + SQLRETURN (WINAPI *SQLGetData)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, + SQLPOINTER, SQLLEN, SQLLEN*); + SQLRETURN (WINAPI *SQLBindCol)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, + SQLPOINTER, SQLLEN, SQLLEN*); + SQLRETURN (WINAPI *SQLPrepare)(SQLHSTMT, SQLCHAR*, SQLINTEGER); + SQLRETURN (WINAPI *SQLBindParameter)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLSMALLINT, + SQLSMALLINT, SQLULEN, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN*); + SQLRETURN (WINAPI *SQLExecute)(SQLHSTMT); + SQLRETURN (WINAPI *SQLSetDescField)(SQLHDESC, SQLSMALLINT, + SQLSMALLINT, SQLPOINTER, SQLINTEGER); + SQLRETURN (WINAPI *SQLFreeStmt)(SQLHSTMT, SQLUSMALLINT); }; diff --git a/dlls/odbc32/tests/driver.spec b/dlls/odbc32/tests/driver.spec index 63aa6458153..99359bf8ee8 100644 --- a/dlls/odbc32/tests/driver.spec +++ b/dlls/odbc32/tests/driver.spec @@ -1,13 +1,27 @@ @ stdcall init_funcs(ptr) @ stdcall SQLAllocHandle(long long ptr) +@ stdcall SQLBindCol(long long long ptr long ptr) +@ stdcall SQLBindParameter(long long long long long long long ptr long ptr) @ stdcall SQLBrowseConnect(long str long ptr long ptr) @ stdcall SQLConnect(long str long str long str long) @ stdcall SQLDisconnect(long) @ stdcall SQLDriverConnect(long long str long ptr long ptr long) +@ stdcall SQLExecDirect(long str long) +@ stdcall SQLExecute(long) +@ stdcall SQLFetch(long) @ stdcall SQLFreeHandle(long long) +@ stdcall SQLFreeStmt(long long ) @ stdcall SQLGetConnectAttr(long long ptr long ptr) +@ stdcall SQLGetData(long long long ptr long ptr) +@ stdcall SQLGetDiagField(long long long long ptr long ptr) +@ stdcall SQLGetDiagRec(long long long ptr ptr ptr long ptr) @ stdcall SQLGetEnvAttr(long long ptr long ptr) @ stdcall SQLGetInfo(long long ptr long ptr) +@ stdcall SQLGetStmtAttr(long long ptr long ptr) +@ stdcall SQLPrepare(long str long) +@ stdcall SQLRowCount(long ptr) @ stdcall SQLSetConnectAttr(long long ptr long) +@ stdcall SQLSetDescField(long long long ptr long) @ stdcall SQLSetEnvAttr(long long ptr long) +@ stdcall SQLSetStmtAttr(long long ptr long) diff --git a/dlls/odbc32/tests/odbc32.c b/dlls/odbc32/tests/odbc32.c index d7d6381437b..aca2585dd84 100644 --- a/dlls/odbc32/tests/odbc32.c +++ b/dlls/odbc32/tests/odbc32.c @@ -64,8 +64,10 @@ DEFINE_EXPECT( driver_SQLAllocHandle_env ); DEFINE_EXPECT( driver_SQLAllocHandle_con ); +DEFINE_EXPECT( driver_SQLAllocHandle_stmt ); DEFINE_EXPECT( driver_SQLFreeHandle_env ); DEFINE_EXPECT( driver_SQLFreeHandle_con ); +DEFINE_EXPECT( driver_SQLFreeHandle_stmt ); DEFINE_EXPECT( driver_SQLSetEnvAttr ); DEFINE_EXPECT( driver_SQLGetInfo ); DEFINE_EXPECT( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); @@ -74,12 +76,45 @@ DEFINE_EXPECT( driver_SQLGetConnectAttr ); DEFINE_EXPECT( driver_SQLDisconnect ); DEFINE_EXPECT( driver_SQLDriverConnect ); DEFINE_EXPECT( driver_SQLBrowseConnect ); +DEFINE_EXPECT( driver_SQLGetStmtAttr ); +DEFINE_EXPECT( driver_SQLSetStmtAttr ); +DEFINE_EXPECT( driver_SQLGetDiagRec ); +DEFINE_EXPECT( driver_SQLExecDirect ); +DEFINE_EXPECT( driver_SQLRowCount ); +DEFINE_EXPECT( driver_SQLFetch ); +DEFINE_EXPECT( driver_SQLGetData ); +DEFINE_EXPECT( driver_SQLBindCol ); +DEFINE_EXPECT( driver_SQLPrepare ); +DEFINE_EXPECT( driver_SQLBindParameter ); +DEFINE_EXPECT( driver_SQLExecute ); +DEFINE_EXPECT( driver_SQLSetDescField ); +DEFINE_EXPECT( driver_SQLFreeStmt ); + +static struct stmt_data +{ + BOOL created; + int rows_no; + int cur_row; + struct + { + int id; + char name[255]; + } rows[2]; + + int fetch_size; + SQLULEN *rows_fetched; + SQLINTEGER *id_buf; + SQLLEN *id_len; + SQLCHAR *name_buf; + SQLLEN *name_len; +} stmt_data; static SQLRETURN WINAPI driver_SQLAllocHandle( SQLSMALLINT type, SQLHANDLE input_handle, SQLHANDLE *out ) { if (type == SQL_HANDLE_ENV) CHECK_EXPECT( driver_SQLAllocHandle_env ); else if (type == SQL_HANDLE_DBC) CHECK_EXPECT( driver_SQLAllocHandle_con ); + else if (type == SQL_HANDLE_STMT) CHECK_EXPECT( driver_SQLAllocHandle_stmt ); else ok( 0, "SQLAllocHandle type = %d\n", type ); *out = (SQLHANDLE)(ULONG_PTR)type; @@ -90,6 +125,16 @@ static SQLRETURN WINAPI driver_SQLFreeHandle( SQLSMALLINT type, SQLHANDLE handle { if (type == SQL_HANDLE_ENV) CHECK_EXPECT( driver_SQLFreeHandle_env ); else if (type == SQL_HANDLE_DBC) CHECK_EXPECT( driver_SQLFreeHandle_con ); + else if (type == SQL_HANDLE_STMT) + { + CHECK_EXPECT( driver_SQLFreeHandle_stmt ); + stmt_data.fetch_size = 1; + stmt_data.rows_fetched = NULL; + stmt_data.id_buf = NULL; + stmt_data.id_len = NULL; + stmt_data.name_buf = NULL; + stmt_data.name_len = NULL; + } else ok( 0, "SQLFreeHandle type = %d\n", type ); ok( (ULONG_PTR)handle == type, "handle = %p\n", handle ); @@ -215,6 +260,276 @@ static SQLRETURN WINAPI driver_SQLDisconnect( SQLHDBC con ) return SQL_SUCCESS; } +static SQLRETURN WINAPI driver_SQLGetStmtAttr( SQLHSTMT stmt, SQLINTEGER attr, + SQLPOINTER val, SQLINTEGER max_len, SQLINTEGER *len ) +{ + CHECK_EXPECT2( driver_SQLGetStmtAttr ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( attr == SQL_ATTR_APP_ROW_DESC || attr == SQL_ATTR_APP_PARAM_DESC + || attr == SQL_ATTR_IMP_ROW_DESC || attr == SQL_ATTR_IMP_PARAM_DESC, "attr = %x\n", attr); + ok( val != NULL, "val = %p\n", val ); + + *(SQLHDESC *)val = (SQLHDESC)(ULONG_PTR)attr; + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLSetStmtAttr( SQLHSTMT stmt, SQLINTEGER attr, + SQLPOINTER val, SQLINTEGER len ) +{ + CHECK_EXPECT( driver_SQLSetStmtAttr ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + + switch (attr) + { + case SQL_ATTR_ROW_ARRAY_SIZE: + ok( (ULONG_PTR)val == 2, "val = %p\n", val ); + ok( !len, "len = %d\n", len ); + + stmt_data.fetch_size = (ULONG_PTR)val; + break; + case SQL_ATTR_ROWS_FETCHED_PTR: + ok( val != NULL, "val = %p\n", val ); + ok( !len, "len = %d\n", len ); + + stmt_data.rows_fetched = val; + break; + default: + todo_wine ok( 0, "unexpected attribute: %d\n", attr ); + return SQL_ERROR; + } + + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLGetDiagField( SQLSMALLINT type, + SQLHANDLE handle, SQLSMALLINT rec, SQLSMALLINT identifier, + SQLPOINTER info, SQLSMALLINT max_len, SQLSMALLINT *len ) +{ + ok( 0, "unexpected call\n" ); + return SQL_ERROR; +} + +static SQLRETURN WINAPI driver_SQLGetDiagRec( SQLSMALLINT type, SQLHANDLE handle, + SQLSMALLINT rec, SQLCHAR *state, SQLINTEGER *err, SQLCHAR *msg, + SQLSMALLINT max_len, SQLSMALLINT *len ) +{ + CHECK_EXPECT( driver_SQLGetDiagRec ); + ok( type == SQL_HANDLE_DBC, "type = %d\n", type ); + ok( (ULONG_PTR)handle == SQL_HANDLE_DBC, "handle = %p\n", handle ); + ok( rec == 1, "rec = %d\n", rec ); + ok( state != NULL, "state = %p\n", state ); + ok( !err, "err = %p\n", err ); + ok( !msg, "msg = %p\n", msg ); + ok( !max_len, "max_len = %d\n", max_len ); + ok( len != NULL, "len = %p\n", len ); + return SQL_NO_DATA; +} + +static SQLRETURN WINAPI driver_SQLExecDirect( SQLHSTMT stmt, SQLCHAR *cmd, SQLINTEGER len ) +{ + CHECK_EXPECT( driver_SQLExecDirect ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + + if (!strncmp( (char *)cmd, "CREATE TABLE winetest ( Id int, Name varchar(255) )", len )) + { + ok( !stmt_data.created, "winetest table is already created\n" ); + stmt_data.created = TRUE; + stmt_data.cur_row = -1; + stmt_data.fetch_size = 1; + return SQL_SUCCESS; + } + + if (!strncmp( (char *)cmd, "INSERT INTO winetest VALUES (0, 'John')", len )) + { + ok (!stmt_data.rows_no, "rows_no = %d\n", stmt_data.rows_no ); + stmt_data.rows[0].id = 0; + strcpy( stmt_data.rows[0].name, "John" ); + stmt_data.rows_no++; + return SQL_SUCCESS; + } + + if (!strncmp( (char *)cmd, "INSERT INTO winetest VALUES (1, 'Mary')", len )) + { + ok (stmt_data.rows_no == 1, "rows_no = %d\n", stmt_data.rows_no ); + stmt_data.rows[1].id = 1; + strcpy( stmt_data.rows[1].name, "Mary" ); + stmt_data.rows_no++; + return SQL_SUCCESS; + } + + if (!strncmp( (char *)cmd, "SELECT * FROM winetest", len )) + { + stmt_data.cur_row = 0; + return SQL_SUCCESS; + } + + if (!strncmp( (char *)cmd, "DROP TABLE winetest", len )) + { + memset( &stmt_data, 0, sizeof(stmt_data) ); + return SQL_SUCCESS; + } + + ok( 0, "unexpected statement: %s\n", wine_dbgstr_an((char *)cmd, len) ); + return SQL_ERROR; +} + +static SQLRETURN WINAPI driver_SQLRowCount( SQLHSTMT stmt, SQLLEN *count ) +{ + CHECK_EXPECT( driver_SQLRowCount ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( count != NULL, "count = %p\n", count ); + + *count = stmt_data.rows_no; + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLFetch( SQLHSTMT stmt ) +{ + int i, len, pos; + + CHECK_EXPECT( driver_SQLFetch ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( stmt_data.cur_row + stmt_data.fetch_size <= stmt_data.rows_no, + "unexpected fetch\n"); + + pos = 0; + for (i = 0; i < stmt_data.fetch_size; i++) + { + if (stmt_data.id_buf) + { + stmt_data.id_buf[i] = stmt_data.rows[stmt_data.cur_row + i].id; + stmt_data.id_len[i] = sizeof(stmt_data.id_buf[i]); + } + if (stmt_data.name_buf) + { + len = strlen( stmt_data.rows[stmt_data.cur_row + i].name ); + strcpy( (char *)stmt_data.name_buf + pos, + stmt_data.rows[stmt_data.cur_row + i].name ); + stmt_data.name_len[i] = len; + pos += len + 1; + } + } + + if (stmt_data.rows_fetched) + *stmt_data.rows_fetched = stmt_data.fetch_size; + stmt_data.cur_row += stmt_data.fetch_size; + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLGetData( SQLHSTMT stmt, SQLUSMALLINT col, + SQLSMALLINT type, SQLPOINTER val, SQLLEN max_len, SQLLEN *len ) +{ + CHECK_EXPECT( driver_SQLGetData ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( stmt_data.cur_row == 1, "cur_row = %d\n", stmt_data.cur_row ); + + ok( col == 1, "col = %d\n", col ); + ok( type == SQL_C_SLONG, "type = %d\n", type ); + ok( val != NULL, "val = %p\n", val ); + ok( max_len == sizeof(SLONG), "max_len = %Id\n", max_len ); + ok( len != NULL, "len = %p\n", len ); + + *(SLONG *)val = stmt_data.rows[stmt_data.cur_row - 1].id; + *len = sizeof(SLONG); + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLBindCol( SQLHSTMT stmt, SQLUSMALLINT col, + SQLSMALLINT type, SQLPOINTER val, SQLLEN max_len, SQLLEN *len ) +{ + CHECK_EXPECT( driver_SQLBindCol ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( val != NULL, "val = %p\n", val ); + ok( len != NULL, "len = %p\n", len ); + + if (col == 1) + { + ok( type == SQL_C_SLONG, "type = %d\n", type ); + ok( max_len == 2 * sizeof(int), "max_len = %Id\n", max_len ); + + stmt_data.id_buf = val; + stmt_data.id_len = len; + return SQL_SUCCESS; + } + + ok( col == 2, "col = %d\n", col ); + ok( type == SQL_C_CHAR, "type = %d\n", type ); + ok( max_len == sizeof(char[32]), "max_len = %Id\n", max_len ); + + stmt_data.name_buf = val; + stmt_data.name_len = len; + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLPrepare( SQLHSTMT stmt, SQLCHAR *cmd, SQLINTEGER len ) +{ + CHECK_EXPECT( driver_SQLPrepare ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( !strcmp((char *)cmd, "SELECT * FROM winetest WHERE Id = ? AND Name = ?"), + "cmd = %s\n", wine_dbgstr_an((char *)cmd, len) ); + ok( len == 48, "len = %d\n", len ); + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLBindParameter( SQLHSTMT stmt, SQLUSMALLINT param, + SQLSMALLINT param_type, SQLSMALLINT ctype, SQLSMALLINT type, SQLULEN size, + SQLSMALLINT decimal_digits, SQLPOINTER val, SQLLEN max_len, SQLLEN *len ) +{ + CHECK_EXPECT( driver_SQLBindParameter ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + ok( param_type == SQL_PARAM_INPUT, "param_type = %d\n", param_type ); + ok( !size, "size = %Id\n", size ); + ok( !decimal_digits, "decimal_digits = %d\n", decimal_digits ); + ok( val != NULL, "val = %p\n", val ); + ok( !max_len, "max_len = %Id\n", max_len ); + ok( len != NULL, "len = %p\n", len ); + + if (param == 1) + { + ok( ctype == SQL_C_LONG, "ctype = %d\n", ctype ); + ok( type == SQL_INTEGER, "type = %d\n", type ); + ok( *(int *)val == 1, "val = %d\n", *(int *)val ); + ok( *len == sizeof(int), "*len = %Id\n", *len ); + return SQL_SUCCESS; + } + + ok( param == 2, "param = %d\n", param ); + ok( ctype == SQL_C_CHAR, "ctype = %d\n", ctype ); + ok( type == SQL_VARCHAR, "type = %d\n", type ); + ok( !strcmp((char *)val, "Mary"), "val = %s\n", (char *)val); + ok( *len == strlen("Mary"), "*len = %Id\n", *len ); + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLExecute( SQLHSTMT stmt ) +{ + CHECK_EXPECT( driver_SQLExecute ); + stmt_data.cur_row = 1; + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLSetDescField( SQLHDESC desc, SQLSMALLINT rec, + SQLSMALLINT field, SQLPOINTER value, SQLINTEGER len ) +{ + CHECK_EXPECT( driver_SQLSetDescField ); + ok( (ULONG_PTR)desc == SQL_ATTR_APP_ROW_DESC, "desc = %p\n", desc ); + ok( rec == 1, "rec = %d\n", rec ); + ok( field == SQL_DESC_OCTET_LENGTH_PTR, "field = %d\n", field ); + ok( value != NULL, "value = %p\n", value ); + ok( !len, "len = %d\n", len ); + return SQL_SUCCESS; +} + +static SQLRETURN WINAPI driver_SQLFreeStmt( SQLHSTMT stmt, SQLUSMALLINT option ) +{ + CHECK_EXPECT( driver_SQLFreeStmt ); + ok( (ULONG_PTR)stmt == SQL_HANDLE_STMT, "stmt = %p\n", stmt ); + todo_wine_if( option == SQL_DROP ) ok( option == SQL_UNBIND, "option = %d\n", option ); + if (option == SQL_DROP) + return driver_SQLFreeHandle( SQL_HANDLE_STMT, stmt ); + return SQL_SUCCESS; +} + struct driver_funcs driver_funcs = { driver_SQLAllocHandle, @@ -228,6 +543,20 @@ struct driver_funcs driver_funcs = driver_SQLDriverConnect, driver_SQLBrowseConnect, driver_SQLDisconnect, + driver_SQLGetStmtAttr, + driver_SQLSetStmtAttr, + driver_SQLGetDiagField, + driver_SQLGetDiagRec, + driver_SQLExecDirect, + driver_SQLRowCount, + driver_SQLFetch, + driver_SQLGetData, + driver_SQLBindCol, + driver_SQLPrepare, + driver_SQLBindParameter, + driver_SQLExecute, + driver_SQLSetDescField, + driver_SQLFreeStmt, }; static void load_resource(const char *name, char *path) @@ -421,6 +750,7 @@ static void test_SQLConnect( void ) SET_EXPECT( driver_SQLAllocHandle_con ); SET_EXPECT( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); SET_EXPECT( driver_SQLConnect ); + SET_EXPECT( driver_SQLGetDiagRec ); SET_EXPECT( driver_SQLGetInfo ); ret = SQLConnect( con, (SQLCHAR *)"winetest_dsn", SQL_NTS, (SQLCHAR *)"winetest", SQL_NTS, (SQLCHAR *)"winetest", SQL_NTS ); @@ -429,6 +759,7 @@ static void test_SQLConnect( void ) CHECK_CALLED( driver_SQLAllocHandle_con ); CHECK_CALLED( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); CHECK_CALLED( driver_SQLConnect ); + todo_wine CHECK_CALLED( driver_SQLGetDiagRec ); todo_wine CHECK_CALLED( driver_SQLGetInfo ); ok (ret == SQL_SUCCESS, "got %d\n", ret ); if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); @@ -500,6 +831,7 @@ static void test_SQLDriverConnect( void ) SET_EXPECT( driver_SQLAllocHandle_con ); SET_EXPECT( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); SET_EXPECT( driver_SQLDriverConnect ); + SET_EXPECT( driver_SQLGetDiagRec ); SET_EXPECT( driver_SQLGetInfo ); ret = SQLDriverConnect( con, NULL, (SQLCHAR *)"dsn=winetest_dsn;UID=winetest", strlen("dsn=winetest_dsn;UID=winetest"), str, sizeof(str), &len, 0 ); @@ -508,6 +840,7 @@ static void test_SQLDriverConnect( void ) CHECK_CALLED( driver_SQLAllocHandle_con ); CHECK_CALLED( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); CHECK_CALLED( driver_SQLDriverConnect ); + todo_wine CHECK_CALLED( driver_SQLGetDiagRec ); todo_wine CHECK_CALLED( driver_SQLGetInfo ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); @@ -529,6 +862,7 @@ static void test_SQLDriverConnect( void ) SET_EXPECT( driver_SQLAllocHandle_con ); SET_EXPECT( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); SET_EXPECT( driver_SQLDriverConnect ); + SET_EXPECT( driver_SQLGetDiagRec ); SET_EXPECT( driver_SQLGetInfo ); ret = SQLDriverConnect( con, NULL, (SQLCHAR *)"DSN=winetest_dsn;er\\9.99", strlen("DSN=winetest_dsn;er\\9.99"), str, sizeof(str), &len, 0 ); @@ -537,6 +871,7 @@ static void test_SQLDriverConnect( void ) todo_wine CHECK_NOT_CALLED( driver_SQLAllocHandle_con ); todo_wine CHECK_NOT_CALLED( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); CHECK_CALLED( driver_SQLDriverConnect ); + todo_wine CHECK_CALLED( driver_SQLGetDiagRec ); todo_wine CHECK_CALLED( driver_SQLGetInfo ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); todo_wine { @@ -583,6 +918,7 @@ static void test_SQLBrowseConnect( void ) SET_EXPECT( driver_SQLAllocHandle_con ); SET_EXPECT( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); SET_EXPECT( driver_SQLBrowseConnect ); + SET_EXPECT( driver_SQLGetDiagRec ); SET_EXPECT( driver_SQLGetInfo ); ret = SQLBrowseConnect( con, (SQLCHAR *)"DSN=winetest_dsn", 16, str, sizeof(str), &len ); CHECK_CALLED( driver_SQLAllocHandle_env ); @@ -590,6 +926,7 @@ static void test_SQLBrowseConnect( void ) CHECK_CALLED( driver_SQLAllocHandle_con ); CHECK_CALLED( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); CHECK_CALLED( driver_SQLBrowseConnect ); + todo_wine CHECK_CALLED( driver_SQLGetDiagRec ); todo_wine CHECK_CALLED( driver_SQLGetInfo ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); @@ -707,18 +1044,29 @@ static void test_SQLExecDirect( void ) ret = SQLAllocConnect( env, &con ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - ret = SQLConnect( con, (SQLCHAR *)"winetest", 8, (SQLCHAR *)"winetest", 8, (SQLCHAR *)"winetest", 8 ); - if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); - if (ret != SQL_SUCCESS) - { - SQLFreeConnect( con ); - SQLFreeEnv( env ); - skip( "data source winetest not available\n" ); - return; - } + SET_EXPECT( driver_SQLAllocHandle_env ); + SET_EXPECT( driver_SQLSetEnvAttr ); + SET_EXPECT( driver_SQLAllocHandle_con ); + SET_EXPECT( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); + SET_EXPECT( driver_SQLConnect ); + SET_EXPECT( driver_SQLGetDiagRec ); + SET_EXPECT( driver_SQLGetInfo ); + ret = SQLConnect( con, (SQLCHAR *)"winetest_dsn", SQL_NTS, (SQLCHAR *)"winetest", SQL_NTS, (SQLCHAR *)"winetest", SQL_NTS ); + CHECK_CALLED( driver_SQLAllocHandle_env ); + CHECK_CALLED( driver_SQLSetEnvAttr ); + CHECK_CALLED( driver_SQLAllocHandle_con ); + CHECK_CALLED( driver_SQLGetInfo_SQL_DRIVER_ODBC_VER ); + CHECK_CALLED( driver_SQLConnect ); + todo_wine CHECK_CALLED( driver_SQLGetDiagRec ); + todo_wine CHECK_CALLED( driver_SQLGetInfo ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); + SET_EXPECT( driver_SQLAllocHandle_stmt ); + SET_EXPECT( driver_SQLGetStmtAttr ); ret = SQLAllocStmt( con, &stmt ); + CHECK_CALLED( driver_SQLAllocHandle_stmt ); + todo_wine CHECK_CALLED( driver_SQLGetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); ret = SQLError( NULL, NULL, NULL, state, &err, msg, sizeof(msg), &len ); @@ -733,78 +1081,104 @@ static void test_SQLExecDirect( void ) ret = SQLError( env, con, stmt, state, &err, msg, sizeof(msg), &len ); ok( ret == SQL_NO_DATA, "got %d\n", ret ); - SQLExecDirect( stmt, (SQLCHAR *)"USE winetest", ARRAYSIZE("USE winetest") - 1 ); - SQLExecDirect( stmt, (SQLCHAR *)"DROP TABLE winetest", ARRAYSIZE("DROP TABLE winetest") - 1 ); + SET_EXPECT( driver_SQLExecDirect ); ret = SQLExecDirect( stmt, (SQLCHAR *)"CREATE TABLE winetest ( Id int, Name varchar(255) )", ARRAYSIZE("CREATE TABLE winetest ( Id int, Name varchar(255) )") - 1 ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + CHECK_CALLED( driver_SQLExecDirect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + ok( stmt_data.created, "winetest table was not created\n" ); + SET_EXPECT( driver_SQLExecDirect ); ret = SQLExecDirect( stmt, (SQLCHAR *)"INSERT INTO winetest VALUES (0, 'John')", ARRAYSIZE("INSERT INTO winetest VALUES (0, 'John')") - 1 ); + CHECK_CALLED( driver_SQLExecDirect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + ok( stmt_data.rows_no == 1, "rows_no = %d\n", stmt_data.rows_no ); + SET_EXPECT( driver_SQLExecDirect ); ret = SQLExecDirect( stmt, (SQLCHAR *)"INSERT INTO winetest VALUES (1, 'Mary')", ARRAYSIZE("INSERT INTO winetest VALUES (1, 'Mary')") - 1 ); + CHECK_CALLED( driver_SQLExecDirect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + ok( stmt_data.rows_no == 2, "rows_no = %d\n", stmt_data.rows_no ); + SET_EXPECT( driver_SQLExecDirect ); ret = SQLExecDirect( stmt, (SQLCHAR *)"SELECT * FROM winetest", ARRAYSIZE("SELECT * FROM winetest") - 1 ); + CHECK_CALLED( driver_SQLExecDirect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + ok( !stmt_data.cur_row, "cur_row = %d\n", stmt_data.cur_row ); count = 0xdeadbeef; + SET_EXPECT( driver_SQLRowCount ); ret = SQLRowCount( stmt, &count ); + CHECK_CALLED( driver_SQLRowCount ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); ok( count == 2, "got %d\n", (int)count ); + SET_EXPECT( driver_SQLFetch ); ret = SQLFetch( stmt ); + CHECK_CALLED( driver_SQLFetch ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); id[0] = -1; len_id[0] = 0; + SET_EXPECT( driver_SQLGetData ); ret = SQLGetData( stmt, 1, SQL_C_SLONG, id, sizeof(id[0]), len_id ); + CHECK_CALLED( driver_SQLGetData ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); ok( !id[0], "id not set\n" ); ok( len_id[0] == sizeof(id[0]), "got %d\n", (int)len_id[0] ); + SET_EXPECT( driver_SQLFreeStmt ); + SET_EXPECT( driver_SQLFreeHandle_stmt ); ret = SQLFreeStmt( stmt, SQL_DROP ); + CHECK_CALLED( driver_SQLFreeHandle_stmt ); + todo_wine CHECK_NOT_CALLED( driver_SQLFreeStmt ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLAllocHandle_stmt ); + SET_EXPECT( driver_SQLGetStmtAttr ); ret = SQLAllocStmt( con, &stmt ); + CHECK_CALLED( driver_SQLAllocHandle_stmt ); + todo_wine CHECK_CALLED( driver_SQLGetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLExecDirect ); ret = SQLExecDirect( stmt, (SQLCHAR *)"SELECT * FROM winetest", ARRAYSIZE("SELECT * FROM winetest") - 1 ); + CHECK_CALLED( driver_SQLExecDirect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + SET_EXPECT( driver_SQLSetStmtAttr ); ret = SQLSetStmtAttr( stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)2, 0 ); + CHECK_CALLED( driver_SQLSetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); rows_fetched = 0xdeadbeef; + SET_EXPECT( driver_SQLSetStmtAttr ); ret = SQLSetStmtAttr( stmt, SQL_ATTR_ROWS_FETCHED_PTR, (SQLPOINTER)&rows_fetched, 0 ); + CHECK_CALLED( driver_SQLSetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); id[0] = -1; id[1] = -1; len_id[0] = 0; len_id[1] = 0; + SET_EXPECT( driver_SQLBindCol ); ret = SQLBindCol( stmt, 1, SQL_C_SLONG, id, sizeof(id), len_id ); + CHECK_CALLED( driver_SQLBindCol ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); memset( name, 0, sizeof(name) ); len_name[0] = 0; len_name[1] = 0; + SET_EXPECT( driver_SQLBindCol ); ret = SQLBindCol( stmt, 2, SQL_C_CHAR, name, sizeof(name), len_name ); + CHECK_CALLED( driver_SQLBindCol ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + SET_EXPECT( driver_SQLFetch ); ret = SQLFetch( stmt ); + CHECK_CALLED( driver_SQLFetch ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); ok( rows_fetched == 2, "got %d\n", (int)rows_fetched ); ok( id[0] == 0, "got %d\n", id[0] ); @@ -815,82 +1189,127 @@ static void test_SQLExecDirect( void ) ok( len_name[0] == sizeof("John") - 1, "got %d\n", (int)len_name[0] ); ok( len_name[1] == sizeof("Mary") - 1, "got %d\n", (int)len_name[1] ); + SET_EXPECT( driver_SQLFreeStmt ); + SET_EXPECT( driver_SQLFreeHandle_stmt ); ret = SQLFreeStmt( stmt, SQL_DROP ); + CHECK_CALLED( driver_SQLFreeHandle_stmt ); + todo_wine CHECK_NOT_CALLED( driver_SQLFreeStmt ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLAllocHandle_stmt ); + SET_EXPECT( driver_SQLGetStmtAttr ); ret = SQLAllocStmt( con, &stmt ); + CHECK_CALLED( driver_SQLAllocHandle_stmt ); + todo_wine CHECK_CALLED( driver_SQLGetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLPrepare ); ret = SQLPrepare( stmt, (SQLCHAR *)"SELECT * FROM winetest WHERE Id = ? AND Name = ?", ARRAYSIZE("SELECT * FROM winetest WHERE Id = ? AND Name = ?") - 1 ); + CHECK_CALLED( driver_SQLPrepare ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); id[0] = 1; len_id[0] = sizeof(id[0]); + SET_EXPECT( driver_SQLBindParameter ); ret = SQLBindParameter( stmt, 1, SQL_PARAM_INPUT, SQL_INTEGER, SQL_INTEGER, 0, 0, id, 0, len_id ); + CHECK_CALLED( driver_SQLBindParameter ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); memcpy( name, "Mary", sizeof("Mary") ); len_name[0] = sizeof( "Mary" ) - 1; + SET_EXPECT( driver_SQLBindParameter ); ret = SQLBindParameter( stmt, 2, SQL_PARAM_INPUT, SQL_CHAR, SQL_VARCHAR, 0, 0, name, 0, len_name ); + CHECK_CALLED( driver_SQLBindParameter ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + SET_EXPECT( driver_SQLExecute ); ret = SQLExecute( stmt ); + CHECK_CALLED( driver_SQLExecute ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + SET_EXPECT( driver_SQLFetch ); ret = SQLFetch( stmt ); + CHECK_CALLED( driver_SQLFetch ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); ok( id[0] == 1, "got %d\n", id[0] ); ok( len_id[0] == sizeof(id[0]), "got %d\n", (int)len_id[0] ); ok( !strcmp( (const char *)name, "Mary" ), "got %s\n", name ); ok( len_name[0] == sizeof("Mary") - 1, "got %d\n", (int)len_name[0] ); + SET_EXPECT( driver_SQLFreeStmt ); ret = SQLFreeStmt( stmt, SQL_UNBIND ); + CHECK_CALLED( driver_SQLFreeStmt ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLFreeStmt ); + SET_EXPECT( driver_SQLFreeHandle_stmt ); ret = SQLFreeStmt( stmt, SQL_DROP ); + CHECK_CALLED( driver_SQLFreeHandle_stmt ); + todo_wine CHECK_NOT_CALLED( driver_SQLFreeStmt ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLAllocHandle_stmt ); + SET_EXPECT( driver_SQLGetStmtAttr ); ret = SQLAllocStmt( con, &stmt ); + CHECK_CALLED( driver_SQLAllocHandle_stmt ); + todo_wine CHECK_CALLED( driver_SQLGetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLExecDirect ); ret = SQLExecDirect( stmt, (SQLCHAR *)"DROP TABLE winetest", ARRAYSIZE("DROP TABLE winetest") - 1 ); + CHECK_CALLED( driver_SQLExecDirect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); desc = (SQLHDESC)0xdeadbeef; size = 0xdeadbeef; + SET_EXPECT( driver_SQLGetStmtAttr ); ret = SQLGetStmtAttr( stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &size ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); + todo_wine CHECK_NOT_CALLED( driver_SQLGetStmtAttr ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); ok( desc != (SQLHDESC)0xdeadbeef, "desc not set\n" ); ok( size == 0xdeadbeef, "got %d\n", size ); + SET_EXPECT( driver_SQLSetDescField ); ret = SQLSetDescField( desc, 1, SQL_DESC_OCTET_LENGTH_PTR, &len_octet, 0 ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_DESC ); + CHECK_CALLED( driver_SQLSetDescField ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLSetStmtAttr ); ret = SQLSetStmtAttr( stmt, SQL_ATTR_APP_ROW_DESC, NULL, sizeof(desc) ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); + todo_wine CHECK_NOT_CALLED( driver_SQLSetStmtAttr ); + todo_wine ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLSetStmtAttr ); ret = SQLSetStmtAttr( stmt, SQL_ATTR_APP_ROW_DESC, desc, 0 ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); + todo_wine CHECK_NOT_CALLED( driver_SQLSetStmtAttr ); + todo_wine ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLSetStmtAttr ); ret = SQLSetStmtAttr( stmt, SQL_ATTR_IMP_ROW_DESC, NULL, sizeof(desc) ); + todo_wine CHECK_NOT_CALLED( driver_SQLSetStmtAttr ); ok( ret == SQL_ERROR, "got %d\n", ret ); + SET_EXPECT( driver_SQLFreeStmt ); + SET_EXPECT( driver_SQLFreeHandle_stmt ); ret = SQLFreeStmt( stmt, SQL_DROP ); + CHECK_CALLED( driver_SQLFreeHandle_stmt ); + todo_wine CHECK_NOT_CALLED( driver_SQLFreeStmt ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLDisconnect ); ret = SQLDisconnect( con ); + CHECK_CALLED( driver_SQLDisconnect ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLFreeHandle_con ); + SET_EXPECT( driver_SQLFreeHandle_env ); ret = SQLFreeConnect( con ); + CHECK_CALLED( driver_SQLFreeHandle_con ); + todo_wine CHECK_CALLED( driver_SQLFreeHandle_env ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); + SET_EXPECT( driver_SQLFreeHandle_env ); ret = SQLFreeEnv( env ); + todo_wine CHECK_NOT_CALLED( driver_SQLFreeHandle_env ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); } @@ -1011,6 +1430,7 @@ START_TEST(odbc32) test_SQLConnect(); test_SQLDriverConnect(); test_SQLBrowseConnect(); + test_SQLExecDirect(); cleanup_odbc_driver( driver_path ); } @@ -1018,7 +1438,6 @@ START_TEST(odbc32) test_SQLGetDiagRec(); test_SQLDataSources(); test_SQLDrivers(); - test_SQLExecDirect(); test_SQLSetEnvAttr(); test_SQLSetConnectAttr(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10624