mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:31:39 +00:00
odbc32: Support SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE).
This commit is contained in:
parent
d37bb6188f
commit
f6d7bcaa63
|
@ -47,6 +47,16 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
|||
|
||||
#define ODBC_CALL( func, params ) WINE_UNIX_CALL( unix_ ## func, params )
|
||||
|
||||
static BOOL is_wow64;
|
||||
|
||||
static struct handle *alloc_handle( void )
|
||||
{
|
||||
struct handle *ret;
|
||||
if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
|
||||
ret->row_count = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SQLAllocConnect [ODBC32.001]
|
||||
*/
|
||||
|
@ -59,7 +69,7 @@ SQLRETURN WINAPI SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionH
|
|||
TRACE("(EnvironmentHandle %p, ConnectionHandle %p)\n", EnvironmentHandle, ConnectionHandle);
|
||||
|
||||
*ConnectionHandle = 0;
|
||||
if (!(con = calloc( 1, sizeof(*con) ))) return SQL_ERROR;
|
||||
if (!(con = alloc_handle())) return SQL_ERROR;
|
||||
|
||||
params.EnvironmentHandle = env->unix_handle;
|
||||
if (SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms ))))
|
||||
|
@ -85,7 +95,7 @@ SQLRETURN WINAPI SQLAllocEnv(SQLHENV *EnvironmentHandle)
|
|||
TRACE("(EnvironmentHandle %p)\n", EnvironmentHandle);
|
||||
|
||||
*EnvironmentHandle = 0;
|
||||
if (!(env = calloc( 1, sizeof(*env) ))) return SQL_ERROR;
|
||||
if (!(env = alloc_handle())) return SQL_ERROR;
|
||||
|
||||
if (SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms ))))
|
||||
{
|
||||
|
@ -110,7 +120,7 @@ SQLRETURN WINAPI SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, S
|
|||
TRACE("(HandleType %d, InputHandle %p, OutputHandle %p)\n", HandleType, InputHandle, OutputHandle);
|
||||
|
||||
*OutputHandle = 0;
|
||||
if (!(output = calloc( 1, sizeof(*output) ))) return SQL_ERROR;
|
||||
if (!(output = alloc_handle())) return SQL_ERROR;
|
||||
|
||||
params.HandleType = HandleType;
|
||||
params.InputHandle = input ? input->unix_handle : 0;
|
||||
|
@ -137,7 +147,7 @@ SQLRETURN WINAPI SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandl
|
|||
TRACE("(ConnectionHandle %p, StatementHandle %p)\n", ConnectionHandle, StatementHandle);
|
||||
|
||||
*StatementHandle = 0;
|
||||
if (!(stmt = calloc( 1, sizeof(*stmt) ))) return SQL_ERROR;
|
||||
if (!(stmt = alloc_handle())) return SQL_ERROR;
|
||||
|
||||
params.ConnectionHandle = con->unix_handle;
|
||||
if (SUCCESS((ret = ODBC_CALL( SQLAllocStmt, ¶ms ))))
|
||||
|
@ -163,7 +173,7 @@ SQLRETURN WINAPI SQLAllocHandleStd(SQLSMALLINT HandleType, SQLHANDLE InputHandle
|
|||
TRACE("(HandleType %d, InputHandle %p, OutputHandle %p)\n", HandleType, InputHandle, OutputHandle);
|
||||
|
||||
*OutputHandle = 0;
|
||||
if (!(output = calloc( 1, sizeof(*output) ))) return SQL_ERROR;
|
||||
if (!(output = alloc_handle())) return SQL_ERROR;
|
||||
|
||||
params.HandleType = HandleType;
|
||||
params.InputHandle = input ? input->unix_handle : 0;
|
||||
|
@ -188,15 +198,17 @@ static const char *debugstr_sqllen( SQLLEN len )
|
|||
}
|
||||
|
||||
#define MAX_BINDING_PARAMS 1024
|
||||
static BOOL alloc_binding( struct param_binding *binding, UINT32 count )
|
||||
static BOOL alloc_binding( struct param_binding *binding, UINT column, UINT row_count )
|
||||
{
|
||||
if (count > MAX_BINDING_PARAMS)
|
||||
if (column > MAX_BINDING_PARAMS)
|
||||
{
|
||||
FIXME( "increase maximum number of parameters\n" );
|
||||
return FALSE;
|
||||
}
|
||||
binding->count = count;
|
||||
if (binding->param || (binding->param = calloc( MAX_BINDING_PARAMS, sizeof(*binding->param)))) return TRUE;
|
||||
if (!binding->param && !(binding->param = calloc( MAX_BINDING_PARAMS, sizeof(*binding->param)))) return FALSE;
|
||||
|
||||
if (!(binding->param[column - 1].len = calloc( row_count, sizeof(UINT64) ))) return FALSE;
|
||||
binding->count = column;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -220,9 +232,10 @@ SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber,
|
|||
FIXME( "column 0 not handled\n" );
|
||||
return SQL_ERROR;
|
||||
}
|
||||
if (!alloc_binding( &handle->bind_col, ColumnNumber )) return SQL_ERROR;
|
||||
if (!alloc_binding( &handle->bind_col, ColumnNumber, handle->row_count )) return SQL_ERROR;
|
||||
params.StatementHandle = handle->unix_handle;
|
||||
params.StrLen_or_Ind = &handle->bind_col.param[i].len;
|
||||
params.StrLen_or_Ind = handle->bind_col.param[i].len;
|
||||
*(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind;
|
||||
if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, ¶ms )))) handle->bind_col.param[i].ptr = StrLen_or_Ind;
|
||||
TRACE ("Returning %d\n", ret);
|
||||
return ret;
|
||||
|
@ -260,10 +273,11 @@ SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNu
|
|||
FIXME( "parameter 0 not handled\n" );
|
||||
return SQL_ERROR;
|
||||
}
|
||||
if (!alloc_binding( &handle->bind_param, ParameterNumber )) return SQL_ERROR;
|
||||
if (!alloc_binding( &handle->bind_param, ParameterNumber, handle->row_count )) return SQL_ERROR;
|
||||
|
||||
params.StatementHandle = handle->unix_handle;
|
||||
params.StrLen_or_Ind = &handle->bind_param.param[i].len;
|
||||
params.StrLen_or_Ind = handle->bind_param.param[i].len;
|
||||
*(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind;
|
||||
if (SUCCESS(( ret = ODBC_CALL( SQLBindParam, ¶ms )))) handle->bind_param.param[i].ptr = StrLen_or_Ind;
|
||||
TRACE ("Returning %d\n", ret);
|
||||
return ret;
|
||||
|
@ -593,22 +607,39 @@ SQLRETURN WINAPI SQLExecute(SQLHSTMT StatementHandle)
|
|||
|
||||
static void update_result_lengths( struct handle *handle )
|
||||
{
|
||||
UINT i;
|
||||
UINT i, j, width = sizeof(void *) == 8 ? 8 : is_wow64 ? 8 : 4;
|
||||
|
||||
for (i = 0; i < handle->bind_col.count; i++)
|
||||
{
|
||||
if (handle->bind_col.param[i].ptr)
|
||||
*(SQLLEN *)handle->bind_col.param[i].ptr = handle->bind_col.param[i].len;
|
||||
SQLLEN *ptr = handle->bind_col.param[i].ptr;
|
||||
if (ptr)
|
||||
{
|
||||
for (j = 0; j < handle->row_count; j++)
|
||||
{
|
||||
*ptr++ = *(SQLLEN *)(handle->bind_col.param[i].len + j * width);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < handle->bind_param.count; i++)
|
||||
{
|
||||
if (handle->bind_param.param[i].ptr)
|
||||
*(SQLLEN *)handle->bind_param.param[i].ptr = handle->bind_param.param[i].len;
|
||||
SQLLEN *ptr = handle->bind_param.param[i].ptr;
|
||||
if (ptr)
|
||||
{
|
||||
for (j = 0; j < handle->row_count; j++)
|
||||
{
|
||||
*ptr++ = *(SQLLEN *)(handle->bind_param.param[i].len + j * width);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < handle->bind_parameter.count; i++)
|
||||
{
|
||||
if (handle->bind_parameter.param[i].ptr)
|
||||
SQLLEN *ptr = handle->bind_parameter.param[i].ptr;
|
||||
if (ptr)
|
||||
{
|
||||
*(SQLLEN *)handle->bind_parameter.param[i].ptr = handle->bind_parameter.param[i].len;
|
||||
for (j = 0; j < handle->row_count; j++)
|
||||
{
|
||||
*ptr++ = *(SQLLEN *)(handle->bind_parameter.param[i].len + j * width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -694,9 +725,21 @@ SQLRETURN WINAPI SQLFreeEnv(SQLHENV EnvironmentHandle)
|
|||
|
||||
static void free_bindings( struct handle *handle )
|
||||
{
|
||||
free( handle->bind_col.param );
|
||||
free( handle->bind_param.param );
|
||||
free( handle->bind_parameter.param );
|
||||
if (handle->bind_col.param)
|
||||
{
|
||||
free( handle->bind_col.param->len );
|
||||
free( handle->bind_col.param );
|
||||
}
|
||||
if (handle->bind_param.param)
|
||||
{
|
||||
free( handle->bind_param.param->len );
|
||||
free( handle->bind_param.param );
|
||||
}
|
||||
if (handle->bind_parameter.param)
|
||||
{
|
||||
free( handle->bind_parameter.param->len );
|
||||
free( handle->bind_parameter.param );
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1306,6 +1349,30 @@ SQLRETURN WINAPI SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNum
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL resize_result_lengths( struct handle *handle, UINT size )
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < handle->bind_col.count; i++)
|
||||
{
|
||||
UINT8 *tmp = realloc( handle->bind_col.param[i].len, size * sizeof(UINT64) );
|
||||
if (!tmp) return FALSE;
|
||||
handle->bind_col.param[i].len = tmp;
|
||||
}
|
||||
for (i = 0; i < handle->bind_param.count; i++)
|
||||
{
|
||||
UINT8 *tmp = realloc( handle->bind_param.param[i].len, size * sizeof(UINT64) );
|
||||
if (!tmp) return FALSE;
|
||||
handle->bind_param.param[i].len = tmp;
|
||||
}
|
||||
for (i = 0; i < handle->bind_parameter.count; i++)
|
||||
{
|
||||
UINT8 *tmp = realloc( handle->bind_parameter.param[i].len, size * sizeof(UINT64) );
|
||||
if (!tmp) return FALSE;
|
||||
handle->bind_parameter.param[i].len = tmp;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SQLSetStmtAttr [ODBC32.076]
|
||||
*/
|
||||
|
@ -1322,7 +1389,16 @@ SQLRETURN WINAPI SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute,
|
|||
if (!handle) return SQL_INVALID_HANDLE;
|
||||
|
||||
params.StatementHandle = handle->unix_handle;
|
||||
ret = ODBC_CALL( SQLSetStmtAttr, ¶ms );
|
||||
if (SUCCESS((ret = ODBC_CALL( SQLSetStmtAttr, ¶ms ))))
|
||||
{
|
||||
SQLULEN row_count = (SQLULEN)Value;
|
||||
if (Attribute == SQL_ATTR_ROW_ARRAY_SIZE && row_count != handle->row_count)
|
||||
{
|
||||
TRACE( "resizing result length array\n" );
|
||||
if (!resize_result_lengths( handle, row_count )) ret = SQL_ERROR;
|
||||
else handle->row_count = row_count;
|
||||
}
|
||||
}
|
||||
TRACE("Returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1885,10 +1961,11 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet
|
|||
FIXME( "parameter 0 not handled\n" );
|
||||
return SQL_ERROR;
|
||||
}
|
||||
if (!alloc_binding( &handle->bind_parameter, ParameterNumber )) return SQL_ERROR;
|
||||
if (!alloc_binding( &handle->bind_parameter, ParameterNumber, handle->row_count )) return SQL_ERROR;
|
||||
|
||||
params.StatementHandle = handle->unix_handle;
|
||||
params.StrLen_or_Ind = &handle->bind_parameter.param[i].len;
|
||||
params.StrLen_or_Ind = handle->bind_parameter.param[i].len;
|
||||
*(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind;
|
||||
if (SUCCESS((ret = ODBC_CALL( SQLBindParameter, ¶ms )))) handle->bind_parameter.param[i].ptr = StrLen_or_Ind;
|
||||
TRACE("Returning %d\n", ret);
|
||||
return ret;
|
||||
|
@ -2887,11 +2964,15 @@ SQLRETURN WINAPI SQLSetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute,
|
|||
if (!handle) return SQL_INVALID_HANDLE;
|
||||
|
||||
params.StatementHandle = handle->unix_handle;
|
||||
ret = ODBC_CALL( SQLSetStmtAttrW, ¶ms );
|
||||
if (ret == SQL_ERROR && (Attribute == SQL_ROWSET_SIZE || Attribute == SQL_ATTR_ROW_ARRAY_SIZE))
|
||||
if (SUCCESS((ret = ODBC_CALL( SQLSetStmtAttrW, ¶ms ))))
|
||||
{
|
||||
TRACE("CHEAT: returning SQL_SUCCESS to ADO\n");
|
||||
return SQL_SUCCESS;
|
||||
SQLULEN row_count = (SQLULEN)Value;
|
||||
if (Attribute == SQL_ATTR_ROW_ARRAY_SIZE && row_count != handle->row_count)
|
||||
{
|
||||
TRACE( "resizing result length array\n" );
|
||||
if (!resize_result_lengths( handle, row_count )) ret = SQL_ERROR;
|
||||
else handle->row_count = row_count;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Returning %d\n", ret);
|
||||
|
@ -2924,6 +3005,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
|
|||
{
|
||||
if (WINE_UNIX_CALL( process_attach, NULL )) __wine_unixlib_handle = 0;
|
||||
}
|
||||
IsWow64Process( GetCurrentProcess(), &is_wow64 );
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
|
|
@ -368,7 +368,7 @@ static NTSTATUS wrap_SQLBindCol( void *args )
|
|||
{
|
||||
struct SQLBindCol_params *params = args;
|
||||
return SQLBindCol( (SQLHSTMT)(ULONG_PTR)params->StatementHandle, params->ColumnNumber, params->TargetType,
|
||||
params->TargetValue, params->BufferLength, (SQLLEN *)(ULONG_PTR)params->StrLen_or_Ind );
|
||||
params->TargetValue, params->BufferLength, params->StrLen_or_Ind );
|
||||
}
|
||||
|
||||
static NTSTATUS wrap_SQLBindParam( void *args )
|
||||
|
@ -376,7 +376,7 @@ static NTSTATUS wrap_SQLBindParam( void *args )
|
|||
struct SQLBindParam_params *params = args;
|
||||
return SQLBindParam( (SQLHSTMT)(ULONG_PTR)params->StatementHandle, params->ParameterNumber, params->ValueType,
|
||||
params->ParameterType, params->LengthPrecision, params->ParameterScale,
|
||||
params->ParameterValue, (SQLLEN *)(ULONG_PTR)params->StrLen_or_Ind );
|
||||
params->ParameterValue, params->StrLen_or_Ind );
|
||||
}
|
||||
|
||||
static NTSTATUS wrap_SQLBindParameter( void *args )
|
||||
|
@ -385,7 +385,7 @@ static NTSTATUS wrap_SQLBindParameter( void *args )
|
|||
return SQLBindParameter( (SQLHSTMT)(ULONG_PTR)params->StatementHandle, params->ParameterNumber,
|
||||
params->InputOutputType, params->ValueType, params->ParameterType, params->ColumnSize,
|
||||
params->DecimalDigits, params->ParameterValue, params->BufferLength,
|
||||
(SQLLEN *)(ULONG_PTR)params->StrLen_or_Ind );
|
||||
params->StrLen_or_Ind );
|
||||
}
|
||||
|
||||
static NTSTATUS wrap_SQLBrowseConnect( void *args )
|
||||
|
|
|
@ -154,8 +154,8 @@ enum sql_funcs
|
|||
|
||||
struct param
|
||||
{
|
||||
INT64 len; /* result length stored in Unix lib */
|
||||
void *ptr; /* result length ptr passed by client */
|
||||
UINT8 *len; /* result length array stored in Unix lib */
|
||||
void *ptr; /* result length ptr passed by client */
|
||||
};
|
||||
|
||||
struct param_binding
|
||||
|
@ -170,6 +170,7 @@ struct handle
|
|||
struct param_binding bind_col;
|
||||
struct param_binding bind_param;
|
||||
struct param_binding bind_parameter;
|
||||
UINT32 row_count; /* number of rows returned by SQLFetch() */
|
||||
};
|
||||
|
||||
struct SQLAllocConnect_params
|
||||
|
@ -210,7 +211,7 @@ struct SQLBindCol_params
|
|||
INT16 TargetType;
|
||||
void *TargetValue;
|
||||
INT64 BufferLength;
|
||||
INT64 *StrLen_or_Ind;
|
||||
void *StrLen_or_Ind;
|
||||
};
|
||||
|
||||
struct SQLBindParam_params
|
||||
|
@ -222,7 +223,7 @@ struct SQLBindParam_params
|
|||
UINT64 LengthPrecision;
|
||||
INT16 ParameterScale;
|
||||
void *ParameterValue;
|
||||
INT64 *StrLen_or_Ind;
|
||||
void *StrLen_or_Ind;
|
||||
};
|
||||
|
||||
struct SQLBindParameter_params
|
||||
|
@ -236,7 +237,7 @@ struct SQLBindParameter_params
|
|||
INT16 DecimalDigits;
|
||||
void *ParameterValue;
|
||||
INT64 BufferLength;
|
||||
INT64 *StrLen_or_Ind;
|
||||
void *StrLen_or_Ind;
|
||||
};
|
||||
|
||||
struct SQLBrowseConnect_params
|
||||
|
|
Loading…
Reference in a new issue