From: Hans Leidekker Subject: [PATCH 4/5] msado15: Implement Field_get_Value and Field_put_Value. Message-Id: <20191212161225.20946-4-hans@codeweavers.com> Date: Thu, 12 Dec 2019 17:12:24 +0100 Signed-off-by: Hans Leidekker --- dlls/msado15/recordset.c | 67 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index b262243d89..b214f9d077 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -36,7 +36,12 @@ struct recordset { _Recordset Recordset_iface; LONG refs; + LONG state; struct fields *fields; + LONG count; + LONG allocated; + LONG index; + VARIANT *data; }; struct fields @@ -187,16 +192,51 @@ static HRESULT WINAPI field_get_Type( Field *iface, DataTypeEnum *type ) return S_OK; } +static LONG get_column_count( struct recordset *recordset ) +{ + return recordset->fields->count; +} + static HRESULT WINAPI field_get_Value( Field *iface, VARIANT *val ) { - FIXME( "%p, %p\n", iface, val ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + ULONG row = field->recordset->index, col = field->index, col_count; + VARIANT copy; + HRESULT hr; + + TRACE( "%p, %p\n", field, val ); + + if (field->recordset->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed ); + if (field->recordset->index < 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord ); + + col_count = get_column_count( field->recordset ); + + VariantInit( © ); + if ((hr = VariantCopy( ©, &field->recordset->data[row * col_count + col] )) != S_OK) return hr; + + *val = copy; + return S_OK; } static HRESULT WINAPI field_put_Value( Field *iface, VARIANT val ) { - FIXME( "%p, %s\n", iface, debugstr_variant(&val) ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + ULONG row = field->recordset->index, col = field->index, col_count; + VARIANT copy; + HRESULT hr; + + TRACE( "%p, %s\n", field, debugstr_variant(&val) ); + + if (field->recordset->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed ); + if (field->recordset->index < 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord ); + + col_count = get_column_count( field->recordset ); + + VariantInit( © ); + if ((hr = VariantCopy( ©, &val )) != S_OK) return hr; + + field->recordset->data[row * col_count + col] = copy; + return S_OK; } static HRESULT WINAPI field_get_Precision( Field *iface, unsigned char *precision ) @@ -614,6 +654,22 @@ static ULONG WINAPI recordset_AddRef( _Recordset *iface ) return refs; } +static void close_recordset( struct recordset *recordset ) +{ + ULONG row, col, col_count = get_column_count( recordset ); + + recordset->fields->recordset = NULL; + Fields_Release( &recordset->fields->Fields_iface ); + recordset->fields = NULL; + + for (row = 0; row < recordset->count; row++) + for (col = 0; col < col_count; col++) VariantClear( &recordset->data[row * col_count + col] ); + + recordset->count = recordset->allocated = recordset->index = 0; + heap_free( recordset->data ); + recordset->data = NULL; +} + static ULONG WINAPI recordset_Release( _Recordset *iface ) { struct recordset *recordset = impl_from_Recordset( iface ); @@ -622,7 +678,7 @@ static ULONG WINAPI recordset_Release( _Recordset *iface ) if (!refs) { TRACE( "destroying %p\n", recordset ); - recordset->fields->recordset = NULL; + close_recordset( recordset ); heap_free( recordset ); } return refs; @@ -1264,6 +1320,7 @@ HRESULT Recordset_create( void **obj ) if (!(recordset = heap_alloc_zero( sizeof(*recordset) ))) return E_OUTOFMEMORY; recordset->Recordset_iface.lpVtbl = &recordset_vtbl; recordset->refs = 1; + recordset->index = -1; *obj = &recordset->Recordset_iface; TRACE( "returning iface %p\n", *obj ); -- 2.20.1