From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 6bd149b73a9..6ea7bbbb1f7 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -1687,6 +1687,8 @@ static HRESULT WINAPI recordset_MoveNext( _Recordset *iface )
TRACE( "%p\n", recordset );
+ if (recordset->index >= recordset->count) + return MAKE_ADO_HRESULT( adErrNoCurrentRecord ); if (recordset->index < recordset->count) recordset->index++; return S_OK; }
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 70 +++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 29 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 6ea7bbbb1f7..d5bf3201fef 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -1811,7 +1811,7 @@ static HRESULT create_bindings(IUnknown *rowset, struct recordset *recordset, DB hr = IColumnsInfo_GetColumnInfo(columninfo, &columns, &colinfo, &stringsbuffer); if (SUCCEEDED(hr)) { - ULONG i; + ULONG i, j; DBOBJECT *dbobj; offset = 1;
@@ -1824,7 +1824,7 @@ static HRESULT create_bindings(IUnknown *rowset, struct recordset *recordset, DB bindings = CoTaskMemAlloc( (sizeof(DBBINDING) + sizeof(DBOBJECT)) * columns); dbobj = (DBOBJECT *)((char*)bindings + (sizeof(DBBINDING) * columns));
- for (i=0; i < columns; i++) + for (i=0, j=0; i < columns; i++) { TRACE("Column %lu, pwszName: %s, pTypeInfo %p, iOrdinal %Iu, dwFlags 0x%08lx, " "ulColumnSize %Iu, wType %d, bPrecision %d, bScale %d\n", @@ -1832,58 +1832,70 @@ static HRESULT create_bindings(IUnknown *rowset, struct recordset *recordset, DB colinfo[i].dwFlags, colinfo[i].ulColumnSize, colinfo[i].wType, colinfo[i].bPrecision, colinfo[i].bScale);
- hr = append_field(&recordset->fields, colinfo[i].pwszName, colinfo[i].wType, colinfo[i].ulColumnSize, - colinfo[i].dwFlags, NULL); + if (!colinfo[i].pwszName) + { + FIXME("skipping implicit column\n"); + continue; + }
- bindings[i].iOrdinal = colinfo[i].iOrdinal; - bindings[i].obValue = offset; - bindings[i].pTypeInfo = NULL; + hr = append_field(&recordset->fields, colinfo[i].pwszName, colinfo[i].wType, + colinfo[i].ulColumnSize, colinfo[i].dwFlags, NULL); + if (FAILED(hr)) WARN("append_field failed: %lx\n", hr); + + bindings[j].iOrdinal = colinfo[i].iOrdinal; + bindings[j].obValue = offset; + bindings[j].pTypeInfo = NULL; /* Always assigned the pObject even if it's not used. */ - bindings[i].pObject = &dbobj[i]; - bindings[i].pObject->dwFlags = 0; - bindings[i].pObject->iid = IID_ISequentialStream; - bindings[i].pBindExt = NULL; - bindings[i].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS; - bindings[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED; - bindings[i].eParamIO = 0; - - recordset->columntypes[i] = colinfo[i].wType; + bindings[j].pObject = &dbobj[i]; + bindings[j].pObject->dwFlags = 0; + bindings[j].pObject->iid = IID_ISequentialStream; + bindings[j].pBindExt = NULL; + bindings[j].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS; + bindings[j].dwMemOwner = DBMEMOWNER_CLIENTOWNED; + bindings[j].eParamIO = 0; + + recordset->columntypes[j] = colinfo[i].wType; if (colinfo[i].dwFlags & DBCOLUMNFLAGS_ISLONG) { colinfo[i].wType = DBTYPE_IUNKNOWN;
- bindings[i].cbMaxLen = (colinfo[i].ulColumnSize + 1) * sizeof(WCHAR); + bindings[j].cbMaxLen = (colinfo[i].ulColumnSize + 1) * sizeof(WCHAR); offset += sizeof(ISequentialStream*); } else if(colinfo[i].wType == DBTYPE_WSTR) { /* ulColumnSize is the number of characters in the string not the actual buffer size */ - bindings[i].cbMaxLen = colinfo[i].ulColumnSize * sizeof(WCHAR); - offset += bindings[i].cbMaxLen; + bindings[j].cbMaxLen = colinfo[i].ulColumnSize * sizeof(WCHAR); + offset += bindings[j].cbMaxLen; } else { - bindings[i].cbMaxLen = colinfo[i].ulColumnSize; - offset += bindings[i].cbMaxLen; + bindings[j].cbMaxLen = colinfo[i].ulColumnSize; + offset += bindings[j].cbMaxLen; }
- bindings[i].dwFlags = 0; - bindings[i].wType = colinfo[i].wType; - bindings[i].bPrecision = colinfo[i].bPrecision; - bindings[i].bScale = colinfo[i].bScale; + bindings[j].dwFlags = 0; + bindings[j].wType = colinfo[i].wType; + bindings[j].bPrecision = colinfo[i].bPrecision; + bindings[j].bScale = colinfo[i].bScale; + j++; }
offset = ROUND_SIZE(offset); - for (i=0; i < columns; i++) + for (i=0, j=0; i < columns; i++) { - bindings[i].obLength = offset; - bindings[i].obStatus = offset + sizeof(DBBYTEOFFSET); + if (!colinfo[i].pwszName) + continue; + + bindings[j].obLength = offset; + bindings[j].obStatus = offset + sizeof(DBBYTEOFFSET);
offset += sizeof(DBBYTEOFFSET) + sizeof(DBBYTEOFFSET);
- hr = IAccessor_CreateAccessor(accessor, DBACCESSOR_ROWDATA, 1, &bindings[i], 0, &recordset->haccessors[i], NULL); + hr = IAccessor_CreateAccessor(accessor, DBACCESSOR_ROWDATA, 1, &bindings[j], 0, &recordset->haccessors[j], NULL); if (FAILED(hr)) FIXME("IAccessor_CreateAccessor Failed 0x%0lx\n", hr); + j++; }
*size = offset;
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index d5bf3201fef..d4e59008da5 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -2096,6 +2096,10 @@ static HRESULT load_all_recordset_data(struct recordset *recordset, IUnknown *ro V_DATE(v) = d; break; } + case DBTYPE_VARIANT: + VariantInit(v); + VariantCopy(v, (VARIANT*)(data + bindings[datacol].obValue)); + break; default: V_VT(v) = VT_I2; V_I2(v) = 0;
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index d4e59008da5..8647482f8ba 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -1025,17 +1025,16 @@ static BOOL resize_fields( struct fields *fields, ULONG count ) return TRUE; }
-static HRESULT append_field( struct fields *fields, BSTR name, DataTypeEnum type, LONG size, FieldAttributeEnum attr, - VARIANT *value ) +static HRESULT append_field( struct fields *fields, const DBCOLUMNINFO *info ) { Field *field; HRESULT hr;
- if ((hr = Field_create( name, fields->count, fields_get_recordset(fields), &field )) != S_OK) return hr; - Field_put_Type( field, type ); - Field_put_DefinedSize( field, size ); - if (attr != adFldUnspecified) Field_put_Attributes( field, attr ); - if (value) FIXME( "ignoring value %s\n", debugstr_variant(value) ); + hr = Field_create( info->pwszName, fields->count, fields_get_recordset(fields), &field ); + if (hr != S_OK) return hr; + Field_put_Type( field, info->wType ); + Field_put_DefinedSize( field, info->ulColumnSize ); + if (info->dwFlags != adFldUnspecified) Field_put_Attributes( field, info->dwFlags );
if (!(resize_fields( fields, fields->count + 1 ))) { @@ -1050,10 +1049,16 @@ static HRESULT append_field( struct fields *fields, BSTR name, DataTypeEnum type static HRESULT WINAPI fields__Append( Fields *iface, BSTR name, DataTypeEnum type, ADO_LONGPTR size, FieldAttributeEnum attr ) { struct fields *fields = impl_from_Fields( iface ); + DBCOLUMNINFO colinfo;
TRACE( "%p, %s, %u, %Id, %d\n", fields, debugstr_w(name), type, size, attr );
- return append_field( fields, name, type, size, attr, NULL ); + memset( &colinfo, 0, sizeof(colinfo) ); + colinfo.pwszName = name; + colinfo.wType = type; + colinfo.ulColumnSize = size; + colinfo.dwFlags = attr; + return append_field( fields, &colinfo ); }
static HRESULT WINAPI fields_Delete( Fields *iface, VARIANT index ) @@ -1065,11 +1070,8 @@ static HRESULT WINAPI fields_Delete( Fields *iface, VARIANT index ) static HRESULT WINAPI fields_Append( Fields *iface, BSTR name, DataTypeEnum type, ADO_LONGPTR size, FieldAttributeEnum attr, VARIANT value ) { - struct fields *fields = impl_from_Fields( iface ); - - TRACE( "%p, %s, %u, %Id, %d, %s\n", fields, debugstr_w(name), type, size, attr, debugstr_variant(&value) ); - - return append_field( fields, name, type, size, attr, &value ); + FIXME( "ignoring value %s\n", debugstr_variant(&value) ); + return Fields__Append( iface, name, type, size, attr ); }
static HRESULT WINAPI fields_Update( Fields *iface ) @@ -1173,8 +1175,7 @@ static void map_rowset_fields(struct recordset *recordset, struct fields *fields colinfo[i].dwFlags, colinfo[i].ulColumnSize, colinfo[i].wType, colinfo[i].bPrecision, colinfo[i].bScale);
- hr = append_field(fields, colinfo[i].pwszName, colinfo[i].wType, colinfo[i].ulColumnSize, - colinfo[i].dwFlags, NULL); + hr = append_field(fields, &colinfo[i]); if (FAILED(hr)) { ERR("Failed to add Field name - 0x%08lx\n", hr); @@ -1838,8 +1839,7 @@ static HRESULT create_bindings(IUnknown *rowset, struct recordset *recordset, DB continue; }
- hr = append_field(&recordset->fields, colinfo[i].pwszName, colinfo[i].wType, - colinfo[i].ulColumnSize, colinfo[i].dwFlags, NULL); + hr = append_field(&recordset->fields, &colinfo[i]); if (FAILED(hr)) WARN("append_field failed: %lx\n", hr);
bindings[j].iOrdinal = colinfo[i].iOrdinal;
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 8647482f8ba..4d49ce4f689 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -78,6 +78,7 @@ struct field LONG defined_size; LONG attrs; LONG index; + unsigned char prec; struct recordset *recordset;
/* Field Properties */ @@ -355,8 +356,14 @@ static HRESULT WINAPI field_putref_DataFormat( Field *iface, IUnknown *format )
static HRESULT WINAPI field_put_Precision( Field *iface, unsigned char precision ) { - FIXME( "%p, %c\n", iface, precision ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + + TRACE( "%p, %u\n", iface, precision ); + + if (field->recordset->state != adStateClosed) return MAKE_ADO_HRESULT( adErrObjectOpen ); + + field->prec = precision; + return S_OK; }
static HRESULT WINAPI field_put_NumericScale( Field *iface, unsigned char scale ) @@ -1035,6 +1042,7 @@ static HRESULT append_field( struct fields *fields, const DBCOLUMNINFO *info ) Field_put_Type( field, info->wType ); Field_put_DefinedSize( field, info->ulColumnSize ); if (info->dwFlags != adFldUnspecified) Field_put_Attributes( field, info->dwFlags ); + Field_put_Precision( field, info->bPrecision );
if (!(resize_fields( fields, fields->count + 1 ))) {
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 8 ++++++-- dlls/msado15/tests/msado15.c | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 4d49ce4f689..3ecb0cc8fc8 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -308,8 +308,12 @@ static HRESULT WINAPI field_put_Value( Field *iface, VARIANT val )
static HRESULT WINAPI field_get_Precision( Field *iface, unsigned char *precision ) { - FIXME( "%p, %p\n", iface, precision ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + + TRACE( "%p, %p\n", iface, precision ); + + *precision = field->prec; + return S_OK; }
static HRESULT WINAPI field_get_NumericScale( Field *iface, unsigned char *scale ) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 3219755916c..44b4c565aba 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -746,6 +746,7 @@ static void test_ADORecordsetConstruction(void) ok( count == 1, "got %ld\n", count ); if (count > 0) { + unsigned char prec; VARIANT index; ADO_LONGPTR size; DataTypeEnum type; @@ -754,6 +755,7 @@ static void test_ADORecordsetConstruction(void) V_BSTR( &index ) = SysAllocString( L"Column1" );
hr = Fields_get_Item( fields, index, &field ); + VariantClear(&index); ok( hr == S_OK, "got %08lx\n", hr );
hr = Field_get_Type( field, &type ); @@ -763,8 +765,9 @@ static void test_ADORecordsetConstruction(void) hr = Field_get_DefinedSize( field, &size ); ok( hr == S_OK, "got %08lx\n", hr ); ok( size == 5, "got %Id\n", size ); - - VariantClear(&index); + hr = Field_get_Precision( field, &prec ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( prec == 1, "got %u\n", prec );
Field_Release(field); } @@ -786,6 +789,7 @@ static void test_Fields(void) Fields *fields; Field *field, *field2; VARIANT val, index; + unsigned char prec; BSTR name; LONG count; ADO_LONGPTR size; @@ -837,6 +841,7 @@ static void test_Fields(void) V_VT( &index ) = VT_BSTR; V_BSTR( &index ) = name; hr = Fields_get_Item( fields, index, &field ); + ok( hr == S_OK, "got %08lx\n", hr );
/* calling get_Item again returns the same object and adds reference */ hr = Fields_get_Item( fields, index, &field2 ); @@ -868,6 +873,15 @@ static void test_Fields(void) hr = Field_get_Attributes( field, &attrs ); ok( hr == S_OK, "got %08lx\n", hr ); ok( !attrs, "got %ld\n", attrs ); + hr = Field_get_Precision( field, &prec ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( !prec, "got %u\n", prec ); + + hr = Field_put_Precision( field, 7 ); + ok( hr == S_OK, "got %08lx\n", hr ); + hr = Field_get_Precision( field, &prec ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( prec == 7, "got %u\n", prec );
Field_Release( field ); Fields_Release( fields );
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 3ecb0cc8fc8..091a6e7ba33 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -79,6 +79,7 @@ struct field LONG attrs; LONG index; unsigned char prec; + unsigned char scale; struct recordset *recordset;
/* Field Properties */ @@ -372,8 +373,14 @@ static HRESULT WINAPI field_put_Precision( Field *iface, unsigned char precision
static HRESULT WINAPI field_put_NumericScale( Field *iface, unsigned char scale ) { - FIXME( "%p, %c\n", iface, scale ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + + TRACE( "%p, %u\n", iface, scale ); + + if (field->recordset->state != adStateClosed) return MAKE_ADO_HRESULT( adErrObjectOpen ); + + field->scale = scale; + return S_OK; }
static HRESULT WINAPI field_put_Type( Field *iface, DataTypeEnum type ) @@ -1047,6 +1054,7 @@ static HRESULT append_field( struct fields *fields, const DBCOLUMNINFO *info ) Field_put_DefinedSize( field, info->ulColumnSize ); if (info->dwFlags != adFldUnspecified) Field_put_Attributes( field, info->dwFlags ); Field_put_Precision( field, info->bPrecision ); + Field_put_NumericScale( field, info->bScale );
if (!(resize_fields( fields, fields->count + 1 ))) {
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 8 ++++++-- dlls/msado15/tests/msado15.c | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 091a6e7ba33..326664d2ecb 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -319,8 +319,12 @@ static HRESULT WINAPI field_get_Precision( Field *iface, unsigned char *precisio
static HRESULT WINAPI field_get_NumericScale( Field *iface, unsigned char *scale ) { - FIXME( "%p, %p\n", iface, scale ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + + TRACE( "%p, %p\n", iface, scale ); + + *scale = field->scale; + return S_OK; }
static HRESULT WINAPI field_AppendChunk( Field *iface, VARIANT data ) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 44b4c565aba..95c73591c1f 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -746,7 +746,7 @@ static void test_ADORecordsetConstruction(void) ok( count == 1, "got %ld\n", count ); if (count > 0) { - unsigned char prec; + unsigned char prec, scale; VARIANT index; ADO_LONGPTR size; DataTypeEnum type; @@ -768,6 +768,9 @@ static void test_ADORecordsetConstruction(void) hr = Field_get_Precision( field, &prec ); ok( hr == S_OK, "got %08lx\n", hr ); ok( prec == 1, "got %u\n", prec ); + hr = Field_get_NumericScale( field, &scale ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( scale == 1, "got %u\n", scale );
Field_Release(field); } @@ -786,10 +789,10 @@ static void test_Fields(void) { _Recordset *recordset; ISupportErrorInfo *errorinfo; + unsigned char prec, scale; Fields *fields; Field *field, *field2; VARIANT val, index; - unsigned char prec; BSTR name; LONG count; ADO_LONGPTR size; @@ -876,6 +879,9 @@ static void test_Fields(void) hr = Field_get_Precision( field, &prec ); ok( hr == S_OK, "got %08lx\n", hr ); ok( !prec, "got %u\n", prec ); + hr = Field_get_NumericScale( field, &scale ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( !scale, "got %u\n", scale );
hr = Field_put_Precision( field, 7 ); ok( hr == S_OK, "got %08lx\n", hr ); @@ -883,6 +889,12 @@ static void test_Fields(void) ok( hr == S_OK, "got %08lx\n", hr ); ok( prec == 7, "got %u\n", prec );
+ hr = Field_put_NumericScale( field, 12 ); + ok( hr == S_OK, "got %08lx\n", hr ); + hr = Field_get_NumericScale( field, &scale ); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( scale == 12, "got %u\n", scale ); + Field_Release( field ); Fields_Release( fields ); ok( !_Recordset_Release( recordset ), "_Recordset not released\n" );