Commit b830fb0a authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Implement the MSIMODIFY_UPDATE command in the SELECT view.

parent fb45206e
...@@ -61,6 +61,15 @@ static UINT ALTER_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt ...@@ -61,6 +61,15 @@ static UINT ALTER_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
static UINT ALTER_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSIALTERVIEW *av = (MSIALTERVIEW*)view;
TRACE("%p %d %p\n", av, row, rec );
return av->table->ops->get_row(av->table, row, rec);
}
static UINT ITERATE_columns(MSIRECORD *row, LPVOID param) static UINT ITERATE_columns(MSIRECORD *row, LPVOID param)
{ {
(*(UINT *)param)++; (*(UINT *)param)++;
...@@ -179,7 +188,7 @@ static UINT ALTER_get_column_info( struct tagMSIVIEW *view, ...@@ -179,7 +188,7 @@ static UINT ALTER_get_column_info( struct tagMSIVIEW *view,
} }
static UINT ALTER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT ALTER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIALTERVIEW *av = (MSIALTERVIEW*)view; MSIALTERVIEW *av = (MSIALTERVIEW*)view;
...@@ -211,6 +220,7 @@ static const MSIVIEWOPS alter_ops = ...@@ -211,6 +220,7 @@ static const MSIVIEWOPS alter_ops =
{ {
ALTER_fetch_int, ALTER_fetch_int,
ALTER_fetch_stream, ALTER_fetch_stream,
ALTER_get_row,
NULL, NULL,
NULL, NULL,
NULL, NULL,
......
...@@ -96,7 +96,7 @@ static UINT CREATE_get_column_info( struct tagMSIVIEW *view, ...@@ -96,7 +96,7 @@ static UINT CREATE_get_column_info( struct tagMSIVIEW *view,
} }
static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec) MSIRECORD *rec, UINT row)
{ {
MSICREATEVIEW *cv = (MSICREATEVIEW*)view; MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
...@@ -124,6 +124,7 @@ static const MSIVIEWOPS create_ops = ...@@ -124,6 +124,7 @@ static const MSIVIEWOPS create_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
CREATE_execute, CREATE_execute,
CREATE_close, CREATE_close,
CREATE_get_dimensions, CREATE_get_dimensions,
......
...@@ -147,7 +147,7 @@ static UINT DELETE_get_column_info( struct tagMSIVIEW *view, ...@@ -147,7 +147,7 @@ static UINT DELETE_get_column_info( struct tagMSIVIEW *view,
} }
static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view; MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
...@@ -186,6 +186,7 @@ static const MSIVIEWOPS delete_ops = ...@@ -186,6 +186,7 @@ static const MSIVIEWOPS delete_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
DELETE_execute, DELETE_execute,
DELETE_close, DELETE_close,
DELETE_get_dimensions, DELETE_get_dimensions,
......
...@@ -218,7 +218,7 @@ static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view, ...@@ -218,7 +218,7 @@ static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view,
} }
static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view; MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
...@@ -227,7 +227,7 @@ static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, ...@@ -227,7 +227,7 @@ static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
if( !dv->table ) if( !dv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return dv->table->ops->modify( dv->table, eModifyMode, rec ); return dv->table->ops->modify( dv->table, eModifyMode, rec, row );
} }
static UINT DISTINCT_delete( struct tagMSIVIEW *view ) static UINT DISTINCT_delete( struct tagMSIVIEW *view )
...@@ -275,6 +275,7 @@ static const MSIVIEWOPS distinct_ops = ...@@ -275,6 +275,7 @@ static const MSIVIEWOPS distinct_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
DISTINCT_execute, DISTINCT_execute,
DISTINCT_close, DISTINCT_close,
DISTINCT_get_dimensions, DISTINCT_get_dimensions,
......
...@@ -185,7 +185,7 @@ static UINT INSERT_get_column_info( struct tagMSIVIEW *view, ...@@ -185,7 +185,7 @@ static UINT INSERT_get_column_info( struct tagMSIVIEW *view,
return sv->ops->get_column_info( sv, n, name, type ); return sv->ops->get_column_info( sv, n, name, type );
} }
static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec) static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
{ {
MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view; MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
...@@ -226,6 +226,7 @@ static const MSIVIEWOPS insert_ops = ...@@ -226,6 +226,7 @@ static const MSIVIEWOPS insert_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
INSERT_execute, INSERT_execute,
INSERT_close, INSERT_close,
INSERT_get_dimensions, INSERT_get_dimensions,
......
...@@ -104,6 +104,33 @@ static UINT JOIN_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStr ...@@ -104,6 +104,33 @@ static UINT JOIN_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStr
return table->ops->fetch_stream( table, row, col, stm ); return table->ops->fetch_stream( table, row, col, stm );
} }
static UINT JOIN_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
MSIVIEW *table;
TRACE("%p %d %p\n", jv, row, rec );
if( !jv->left || !jv->right )
return ERROR_FUNCTION_FAILED;
if( row >= jv->left_rows * jv->right_rows )
return ERROR_FUNCTION_FAILED;
if( row <= jv->left_count )
{
table = jv->left;
row = (row/jv->right_rows);
}
else
{
table = jv->right;
row = (row % jv->right_rows);
}
return table->ops->get_row(table, row, rec);
}
static UINT JOIN_execute( struct tagMSIVIEW *view, MSIRECORD *record ) static UINT JOIN_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIJOINVIEW *jv = (MSIJOINVIEW*)view; MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
...@@ -201,7 +228,7 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view, ...@@ -201,7 +228,7 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view,
} }
static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT JOIN_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIJOINVIEW *jv = (MSIJOINVIEW*)view; MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
...@@ -243,6 +270,7 @@ static const MSIVIEWOPS join_ops = ...@@ -243,6 +270,7 @@ static const MSIVIEWOPS join_ops =
{ {
JOIN_fetch_int, JOIN_fetch_int,
JOIN_fetch_stream, JOIN_fetch_stream,
JOIN_get_row,
NULL, NULL,
NULL, NULL,
NULL, NULL,
......
...@@ -157,6 +157,12 @@ typedef struct tagMSIVIEWOPS ...@@ -157,6 +157,12 @@ typedef struct tagMSIVIEWOPS
UINT (*fetch_stream)( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm ); UINT (*fetch_stream)( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm );
/* /*
* get_row - gets values from a row
*
*/
UINT (*get_row)( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec );
/*
* set_row - sets values in a row as specified by mask * set_row - sets values in a row as specified by mask
* *
* Similar semantics to fetch_int * Similar semantics to fetch_int
...@@ -203,7 +209,7 @@ typedef struct tagMSIVIEWOPS ...@@ -203,7 +209,7 @@ typedef struct tagMSIVIEWOPS
/* /*
* modify - not yet implemented properly * modify - not yet implemented properly
*/ */
UINT (*modify)( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *record ); UINT (*modify)( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *record, UINT row );
/* /*
* delete - destroys the structure completely * delete - destroys the structure completely
...@@ -690,7 +696,7 @@ extern UINT MSI_ViewClose( MSIQUERY* ); ...@@ -690,7 +696,7 @@ extern UINT MSI_ViewClose( MSIQUERY* );
extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **); extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **);
extern UINT MSI_ViewModify( MSIQUERY *, MSIMODIFY, MSIRECORD * ); extern UINT MSI_ViewModify( MSIQUERY *, MSIMODIFY, MSIRECORD * );
extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, UINT * ); extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, UINT * );
extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **);
/* install internals */ /* install internals */
extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ); extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel );
......
...@@ -265,88 +265,100 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, ...@@ -265,88 +265,100 @@ UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
return ret; return ret;
} }
UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec) UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
{ {
MSIVIEW *view;
MSIRECORD *rec;
UINT row_count = 0, col_count = 0, i, ival, ret, type; UINT row_count = 0, col_count = 0, i, ival, ret, type;
TRACE("%p %p\n", query, prec ); TRACE("%p %p %d %p\n", db, view, row, rec);
view = query->view; ret = view->ops->get_dimensions(view, &row_count, &col_count);
if( !view ) if (ret)
return ERROR_FUNCTION_FAILED;
ret = view->ops->get_dimensions( view, &row_count, &col_count );
if( ret )
return ret; return ret;
if( !col_count )
if (!col_count)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
if( query->row >= row_count ) if (row >= row_count)
return ERROR_NO_MORE_ITEMS; return ERROR_NO_MORE_ITEMS;
rec = MSI_CreateRecord( col_count ); *rec = MSI_CreateRecord(col_count);
if( !rec ) if (!*rec)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
for( i=1; i<=col_count; i++ ) for (i = 1; i <= col_count; i++)
{ {
ret = view->ops->get_column_info( view, i, NULL, &type ); ret = view->ops->get_column_info(view, i, NULL, &type);
if( ret ) if (ret)
{ {
ERR("Error getting column type for %d\n", i ); ERR("Error getting column type for %d\n", i);
continue; continue;
} }
if (!MSITYPE_IS_BINARY(type))
if (MSITYPE_IS_BINARY(type))
{
IStream *stm = NULL;
ret = view->ops->fetch_stream(view, row, i, &stm);
if ((ret == ERROR_SUCCESS) && stm)
{ {
ret = view->ops->fetch_int( view, query->row, i, &ival ); MSI_RecordSetIStream(*rec, i, stm);
if( ret ) IStream_Release(stm);
}
else
ERR("failed to get stream\n");
continue;
}
ret = view->ops->fetch_int(view, row, i, &ival);
if (ret)
{ {
ERR("Error fetching data for %d\n", i ); ERR("Error fetching data for %d\n", i);
continue; continue;
} }
if( ! (type & MSITYPE_VALID ) )
if (! (type & MSITYPE_VALID))
ERR("Invalid type!\n"); ERR("Invalid type!\n");
/* check if it's nul (0) - if so, don't set anything */ /* check if it's nul (0) - if so, don't set anything */
if( !ival ) if (!ival)
continue; continue;
if( type & MSITYPE_STRING ) if (type & MSITYPE_STRING)
{ {
LPCWSTR sval; LPCWSTR sval;
sval = msi_string_lookup_id( query->db->strings, ival ); sval = msi_string_lookup_id(db->strings, ival);
MSI_RecordSetStringW( rec, i, sval ); MSI_RecordSetStringW(*rec, i, sval);
} }
else else
{ {
if( (type & MSI_DATASIZEMASK) == 2 ) if ((type & MSI_DATASIZEMASK) == 2)
MSI_RecordSetInteger( rec, i, ival - (1<<15) ); MSI_RecordSetInteger(*rec, i, ival - (1<<15));
else else
MSI_RecordSetInteger( rec, i, ival - (1<<31) ); MSI_RecordSetInteger(*rec, i, ival - (1<<31));
} }
} }
else
{
IStream *stm = NULL;
ret = view->ops->fetch_stream( view, query->row, i, &stm ); return ERROR_SUCCESS;
if( ( ret == ERROR_SUCCESS ) && stm ) }
{
MSI_RecordSetIStream( rec, i, stm );
IStream_Release( stm );
}
else
ERR("failed to get stream\n");
}
}
query->row ++;
*prec = rec; UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
{
MSIVIEW *view;
UINT r;
return ERROR_SUCCESS; TRACE("%p %p\n", query, prec );
view = query->view;
if( !view )
return ERROR_FUNCTION_FAILED;
r = msi_view_get_row(query->db, view, query->row, prec);
if (r == ERROR_SUCCESS)
query->row ++;
return r;
} }
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record) UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
...@@ -563,7 +575,7 @@ UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec ) ...@@ -563,7 +575,7 @@ UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec )
if ( !view || !view->ops->modify) if ( !view || !view->ops->modify)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return view->ops->modify( view, mode, rec ); return view->ops->modify( view, mode, rec, query->row );
} }
UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode, UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode,
......
...@@ -142,6 +142,20 @@ static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * ...@@ -142,6 +142,20 @@ static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
return ov->table->ops->fetch_int( ov->table, row, col, val ); return ov->table->ops->fetch_int( ov->table, row, col, val );
} }
static UINT ORDER_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSIORDERVIEW *ov = (MSIORDERVIEW *)view;
TRACE("%p %d %p\n", ov, row, rec );
if (!ov->table)
return ERROR_FUNCTION_FAILED;
row = ov->reorder[row];
return ov->table->ops->get_row(ov->table, row, rec);
}
static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record ) static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{ {
MSIORDERVIEW *ov = (MSIORDERVIEW*)view; MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
...@@ -219,7 +233,7 @@ static UINT ORDER_get_column_info( struct tagMSIVIEW *view, ...@@ -219,7 +233,7 @@ static UINT ORDER_get_column_info( struct tagMSIVIEW *view,
} }
static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIORDERVIEW *ov = (MSIORDERVIEW*)view; MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
...@@ -228,7 +242,7 @@ static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, ...@@ -228,7 +242,7 @@ static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
if( !ov->table ) if( !ov->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return ov->table->ops->modify( ov->table, eModifyMode, rec ); return ov->table->ops->modify( ov->table, eModifyMode, rec, row );
} }
static UINT ORDER_delete( struct tagMSIVIEW *view ) static UINT ORDER_delete( struct tagMSIVIEW *view )
...@@ -272,6 +286,7 @@ static const MSIVIEWOPS order_ops = ...@@ -272,6 +286,7 @@ static const MSIVIEWOPS order_ops =
{ {
ORDER_fetch_int, ORDER_fetch_int,
NULL, NULL,
ORDER_get_row,
NULL, NULL,
NULL, NULL,
NULL, NULL,
......
...@@ -82,6 +82,18 @@ static UINT SELECT_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IS ...@@ -82,6 +82,18 @@ static UINT SELECT_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IS
return sv->table->ops->fetch_stream( sv->table, row, col, stm ); return sv->table->ops->fetch_stream( sv->table, row, col, stm );
} }
static UINT SELECT_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSISELECTVIEW *sv = (MSISELECTVIEW *)view;
TRACE("%p %d %p\n", sv, row, rec );
if( !sv->table )
return ERROR_FUNCTION_FAILED;
return msi_view_get_row(sv->db, view, row, rec);
}
static UINT SELECT_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask ) static UINT SELECT_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{ {
MSISELECTVIEW *sv = (MSISELECTVIEW*)view; MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
...@@ -214,17 +226,79 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view, ...@@ -214,17 +226,79 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
return sv->table->ops->get_column_info( sv->table, n, name, type ); return sv->table->ops->get_column_info( sv->table, n, name, type );
} }
static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
{
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
UINT r, i, num_columns, col, type, val;
LPWSTR name;
LPCWSTR str;
MSIRECORD *mod;
r = SELECT_get_dimensions(view, NULL, &num_columns);
if (r != ERROR_SUCCESS)
return r;
r = sv->table->ops->get_row(sv->table, row - 1, &mod);
if (r != ERROR_SUCCESS)
return r;
for (i = 0; i < num_columns; i++)
{
col = sv->cols[i];
r = SELECT_get_column_info(view, i + 1, &name, &type);
msi_free(name);
if (r != ERROR_SUCCESS)
{
ERR("Failed to get column information: %d\n", r);
goto done;
}
if (MSITYPE_IS_BINARY(type))
{
ERR("Cannot modify binary data!\n");
r = ERROR_FUNCTION_FAILED;
goto done;
}
else if (type & MSITYPE_STRING)
{
str = MSI_RecordGetString(rec, i + 1);
r = MSI_RecordSetStringW(mod, col, str);
}
else
{
val = MSI_RecordGetInteger(rec, i + 1);
r = MSI_RecordSetInteger(mod, col, val);
}
if (r != ERROR_SUCCESS)
{
ERR("Failed to modify record: %d\n", r);
goto done;
}
}
r = sv->table->ops->modify(sv->table, MSIMODIFY_UPDATE, mod, row);
done:
msiobj_release(&mod->hdr);
return r;
}
static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSISELECTVIEW *sv = (MSISELECTVIEW*)view; MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
TRACE("%p %d %p\n", sv, eModifyMode, rec ); TRACE("%p %d %p %d\n", sv, eModifyMode, rec, row );
if( !sv->table ) if( !sv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return sv->table->ops->modify( sv->table, eModifyMode, rec ); if (eModifyMode == MSIMODIFY_UPDATE)
return msi_select_update(view, rec, row);
return sv->table->ops->modify( sv->table, eModifyMode, rec, row );
} }
static UINT SELECT_delete( struct tagMSIVIEW *view ) static UINT SELECT_delete( struct tagMSIVIEW *view )
...@@ -265,6 +339,7 @@ static const MSIVIEWOPS select_ops = ...@@ -265,6 +339,7 @@ static const MSIVIEWOPS select_ops =
{ {
SELECT_fetch_int, SELECT_fetch_int,
SELECT_fetch_stream, SELECT_fetch_stream,
SELECT_get_row,
SELECT_set_row, SELECT_set_row,
SELECT_insert_row, SELECT_insert_row,
NULL, NULL,
......
...@@ -129,6 +129,15 @@ static UINT STREAMS_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IS ...@@ -129,6 +129,15 @@ static UINT STREAMS_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IS
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT STREAMS_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
FIXME("%p %d %p\n", sv, row, rec);
return ERROR_CALL_NOT_IMPLEMENTED;
}
static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask) static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
{ {
FIXME("(%p, %d, %p, %d): stub!\n", view, row, rec, mask); FIXME("(%p, %d, %p, %d): stub!\n", view, row, rec, mask);
...@@ -269,7 +278,7 @@ static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, ...@@ -269,7 +278,7 @@ static UINT STREAMS_get_column_info(struct tagMSIVIEW *view,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec) static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
{ {
FIXME("(%p, %d, %p): stub!\n", view, eModifyMode, rec); FIXME("(%p, %d, %p): stub!\n", view, eModifyMode, rec);
return ERROR_SUCCESS; return ERROR_SUCCESS;
...@@ -327,6 +336,7 @@ static const MSIVIEWOPS streams_ops = ...@@ -327,6 +336,7 @@ static const MSIVIEWOPS streams_ops =
{ {
STREAMS_fetch_int, STREAMS_fetch_int,
STREAMS_fetch_stream, STREAMS_fetch_stream,
STREAMS_get_row,
STREAMS_set_row, STREAMS_set_row,
STREAMS_insert_row, STREAMS_insert_row,
STREAMS_delete_row, STREAMS_delete_row,
......
...@@ -1277,6 +1277,16 @@ static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val ) ...@@ -1277,6 +1277,16 @@ static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
if (!tv->table)
return ERROR_INVALID_PARAMETER;
return msi_view_get_row(tv->db, view, row, rec);
}
static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask ) static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{ {
MSITABLEVIEW *tv = (MSITABLEVIEW*)view; MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
...@@ -1532,10 +1542,10 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) ...@@ -1532,10 +1542,10 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec) static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
{ {
MSITABLEVIEW *tv = (MSITABLEVIEW *)view; MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
UINT r, row; UINT r, new_row;
/* FIXME: MsiViewFetch should set rec index 0 to some ID that /* FIXME: MsiViewFetch should set rec index 0 to some ID that
* sets the fetched record apart from other records * sets the fetched record apart from other records
...@@ -1544,19 +1554,22 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec) ...@@ -1544,19 +1554,22 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec)
if (!tv->table) if (!tv->table)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
r = msi_table_find_row(tv, rec, &row); r = msi_table_find_row(tv, rec, &new_row);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{
ERR("can't find row to modify\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
}
/* the row cannot be changed */ /* the row cannot be changed */
if (row != 0) if (row != new_row + 1)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return TABLE_set_row(view, row, rec, (1 << tv->num_cols) - 1); return TABLE_set_row(view, new_row, rec, (1 << tv->num_cols) - 1);
} }
static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec) MSIRECORD *rec, UINT row)
{ {
MSITABLEVIEW *tv = (MSITABLEVIEW*)view; MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT r; UINT r;
...@@ -1577,7 +1590,7 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, ...@@ -1577,7 +1590,7 @@ static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
break; break;
case MSIMODIFY_UPDATE: case MSIMODIFY_UPDATE:
r = msi_table_update( view, rec ); r = msi_table_update( view, rec, row );
break; break;
case MSIMODIFY_REFRESH: case MSIMODIFY_REFRESH:
...@@ -1826,6 +1839,7 @@ static const MSIVIEWOPS table_ops = ...@@ -1826,6 +1839,7 @@ static const MSIVIEWOPS table_ops =
{ {
TABLE_fetch_int, TABLE_fetch_int,
TABLE_fetch_stream, TABLE_fetch_stream,
TABLE_get_row,
TABLE_set_row, TABLE_set_row,
TABLE_insert_row, TABLE_insert_row,
TABLE_delete_row, TABLE_delete_row,
......
...@@ -3841,10 +3841,7 @@ static void test_viewmodify_update(void) ...@@ -3841,10 +3841,7 @@ static void test_viewmodify_update(void)
r = MsiRecordGetInteger(hrec, 1); r = MsiRecordGetInteger(hrec, 1);
ok(r == 1, "Expected 1, got %d\n", r); ok(r == 1, "Expected 1, got %d\n", r);
r = MsiRecordGetInteger(hrec, 2); r = MsiRecordGetInteger(hrec, 2);
todo_wine
{
ok(r == 0, "Expected 0, got %d\n", r); ok(r == 0, "Expected 0, got %d\n", r);
}
r = MsiCloseHandle(hrec); r = MsiCloseHandle(hrec);
ok(r == ERROR_SUCCESS, "failed to close record\n"); ok(r == ERROR_SUCCESS, "failed to close record\n");
...@@ -3918,10 +3915,7 @@ static void test_viewmodify_update(void) ...@@ -3918,10 +3915,7 @@ static void test_viewmodify_update(void)
r = MsiRecordGetInteger(hrec, 1); r = MsiRecordGetInteger(hrec, 1);
ok(r == 1, "Expected 1, got %d\n", r); ok(r == 1, "Expected 1, got %d\n", r);
r = MsiRecordGetInteger(hrec, 2); r = MsiRecordGetInteger(hrec, 2);
todo_wine
{
ok(r == 0, "Expected 0, got %d\n", r); ok(r == 0, "Expected 0, got %d\n", r);
}
r = MsiCloseHandle(hrec); r = MsiCloseHandle(hrec);
ok(r == ERROR_SUCCESS, "failed to close record\n"); ok(r == ERROR_SUCCESS, "failed to close record\n");
...@@ -3932,10 +3926,7 @@ static void test_viewmodify_update(void) ...@@ -3932,10 +3926,7 @@ static void test_viewmodify_update(void)
r = MsiRecordGetInteger(hrec, 1); r = MsiRecordGetInteger(hrec, 1);
ok(r == 3, "Expected 3, got %d\n", r); ok(r == 3, "Expected 3, got %d\n", r);
r = MsiRecordGetInteger(hrec, 2); r = MsiRecordGetInteger(hrec, 2);
todo_wine
{
ok(r == 0, "Expected 0, got %d\n", r); ok(r == 0, "Expected 0, got %d\n", r);
}
r = MsiCloseHandle(hrec); r = MsiCloseHandle(hrec);
ok(r == ERROR_SUCCESS, "failed to close record\n"); ok(r == ERROR_SUCCESS, "failed to close record\n");
...@@ -3946,10 +3937,7 @@ static void test_viewmodify_update(void) ...@@ -3946,10 +3937,7 @@ static void test_viewmodify_update(void)
r = MsiRecordGetInteger(hrec, 1); r = MsiRecordGetInteger(hrec, 1);
ok(r == 5, "Expected 5, got %d\n", r); ok(r == 5, "Expected 5, got %d\n", r);
r = MsiRecordGetInteger(hrec, 2); r = MsiRecordGetInteger(hrec, 2);
todo_wine
{
ok(r == 0, "Expected 0, got %d\n", r); ok(r == 0, "Expected 0, got %d\n", r);
}
r = MsiCloseHandle(hrec); r = MsiCloseHandle(hrec);
ok(r == ERROR_SUCCESS, "failed to close record\n"); ok(r == ERROR_SUCCESS, "failed to close record\n");
......
...@@ -138,7 +138,7 @@ static UINT UPDATE_get_column_info( struct tagMSIVIEW *view, ...@@ -138,7 +138,7 @@ static UINT UPDATE_get_column_info( struct tagMSIVIEW *view,
} }
static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view; MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
...@@ -178,6 +178,7 @@ static const MSIVIEWOPS update_ops = ...@@ -178,6 +178,7 @@ static const MSIVIEWOPS update_ops =
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
UPDATE_execute, UPDATE_execute,
UPDATE_close, UPDATE_close,
UPDATE_get_dimensions, UPDATE_get_dimensions,
......
...@@ -82,6 +82,23 @@ static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt ...@@ -82,6 +82,23 @@ static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
return wv->table->ops->fetch_stream( wv->table, row, col, stm ); return wv->table->ops->fetch_stream( wv->table, row, col, stm );
} }
static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW *)view;
TRACE("%p %d %p\n", wv, row, rec );
if (!wv->table)
return ERROR_FUNCTION_FAILED;
if (row > wv->row_count)
return ERROR_NO_MORE_ITEMS;
row = wv->reorder[row];
return wv->table->ops->get_row(view, row, rec);
}
static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask ) static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{ {
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
...@@ -379,7 +396,7 @@ static UINT WHERE_get_column_info( struct tagMSIVIEW *view, ...@@ -379,7 +396,7 @@ static UINT WHERE_get_column_info( struct tagMSIVIEW *view,
} }
static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
MSIRECORD *rec ) MSIRECORD *rec, UINT row )
{ {
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
...@@ -388,7 +405,7 @@ static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, ...@@ -388,7 +405,7 @@ static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
if( !wv->table ) if( !wv->table )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return wv->table->ops->modify( wv->table, eModifyMode, rec ); return wv->table->ops->modify( wv->table, eModifyMode, rec, row );
} }
static UINT WHERE_delete( struct tagMSIVIEW *view ) static UINT WHERE_delete( struct tagMSIVIEW *view )
...@@ -437,6 +454,7 @@ static const MSIVIEWOPS where_ops = ...@@ -437,6 +454,7 @@ static const MSIVIEWOPS where_ops =
{ {
WHERE_fetch_int, WHERE_fetch_int,
WHERE_fetch_stream, WHERE_fetch_stream,
WHERE_get_row,
WHERE_set_row, WHERE_set_row,
NULL, NULL,
NULL, NULL,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment