msi: Set table values directly in msi_select_update().

In order to avoid the need to create a temporary record and copy values back
and forth.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-01-26 16:58:58 -06:00 committed by Alexandre Julliard
parent 99425f272f
commit f45a7b04a6
13 changed files with 164 additions and 19 deletions

View File

@ -229,6 +229,8 @@ static const MSIVIEWOPS alter_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
ALTER_execute,
ALTER_close,
ALTER_get_dimensions,

View File

@ -130,6 +130,8 @@ static const MSIVIEWOPS create_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
CREATE_execute,
CREATE_close,
CREATE_get_dimensions,

View File

@ -172,6 +172,8 @@ static const MSIVIEWOPS delete_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
DELETE_execute,
DELETE_close,
DELETE_get_dimensions,

View File

@ -255,6 +255,8 @@ static const MSIVIEWOPS distinct_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
DISTINCT_execute,
DISTINCT_close,
DISTINCT_get_dimensions,

View File

@ -100,6 +100,8 @@ static const MSIVIEWOPS drop_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
DROP_execute,
DROP_close,
DROP_get_dimensions,

View File

@ -326,6 +326,8 @@ static const MSIVIEWOPS insert_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
INSERT_execute,
INSERT_close,
INSERT_get_dimensions,

View File

@ -248,6 +248,20 @@ typedef struct tagMSIVIEWOPS
*/
UINT (*get_row)( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec );
/*
* set_int - set the integer value at {row, col}
* This function has undefined behaviour if the column does not contain
* integers.
*/
UINT (*set_int)( struct tagMSIVIEW *view, UINT row, UINT col, int val );
/*
* set_string - set the string value at {row, col}
* This function has undefined behaviour if the column does not contain
* strings.
*/
UINT (*set_string)( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len );
/*
* set_row - sets values in a row as specified by mask
*

View File

@ -247,16 +247,11 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
UINT r, i, num_columns, col, type, val;
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, &mod);
if (r != ERROR_SUCCESS)
return r;
for (i = 0; i < num_columns; i++)
{
col = sv->cols[i];
@ -265,39 +260,34 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
if (r != ERROR_SUCCESS)
{
ERR("Failed to get column information: %d\n", r);
goto done;
return r;
}
if (MSITYPE_IS_BINARY(type))
{
ERR("Cannot modify binary data!\n");
r = ERROR_FUNCTION_FAILED;
goto done;
return ERROR_FUNCTION_FAILED;
}
else if (type & MSITYPE_STRING)
{
int len;
str = msi_record_get_string( rec, i + 1, &len );
r = msi_record_set_string( mod, col, str, len );
str = msi_record_get_string(rec, i + 1, &len);
r = sv->table->ops->set_string(sv->table, row, col, str, len);
}
else
{
val = MSI_RecordGetInteger(rec, i + 1);
r = MSI_RecordSetInteger(mod, col, val);
r = sv->table->ops->set_int(sv->table, row, col, val);
}
if (r != ERROR_SUCCESS)
{
ERR("Failed to modify record: %d\n", r);
goto done;
return r;
}
}
r = sv->table->ops->modify(sv->table, MSIMODIFY_UPDATE, mod, row);
done:
msiobj_release(&mod->hdr);
return r;
return ERROR_SUCCESS;
}
static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
@ -336,6 +326,8 @@ static const MSIVIEWOPS select_ops =
SELECT_fetch_int,
SELECT_fetch_stream,
SELECT_get_row,
NULL,
NULL,
SELECT_set_row,
SELECT_insert_row,
NULL,

View File

@ -124,6 +124,12 @@ static UINT STORAGES_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec
return ERROR_CALL_NOT_IMPLEMENTED;
}
static UINT STORAGES_set_string( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len )
{
ERR("Cannot modify primary key.\n");
return ERROR_FUNCTION_FAILED;
}
static HRESULT stream_to_storage(IStream *stm, IStorage **stg)
{
ILockBytes *lockbytes = NULL;
@ -420,6 +426,8 @@ static const MSIVIEWOPS storages_ops =
STORAGES_fetch_int,
STORAGES_fetch_stream,
STORAGES_get_row,
NULL,
STORAGES_set_string,
STORAGES_set_row,
STORAGES_insert_row,
STORAGES_delete_row,

View File

@ -104,6 +104,12 @@ static UINT STREAMS_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IS
return ERROR_SUCCESS;
}
static UINT STREAMS_set_string( struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len )
{
ERR("Cannot modify primary key.\n");
return ERROR_FUNCTION_FAILED;
}
static UINT STREAMS_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
@ -342,6 +348,8 @@ static const MSIVIEWOPS streams_ops =
STREAMS_fetch_int,
STREAMS_fetch_stream,
STREAMS_get_row,
NULL,
STREAMS_set_string,
STREAMS_set_row,
STREAMS_insert_row,
STREAMS_delete_row,

View File

@ -1164,7 +1164,8 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
return r;
}
static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
/* Set a table value, i.e. preadjusted integer or string ID. */
static UINT table_set_bytes( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
{
UINT offset, n, i;
@ -1221,6 +1222,70 @@ static UINT int_to_table_storage( const MSITABLEVIEW *tv, UINT col, int val, UIN
return ERROR_SUCCESS;
}
static UINT TABLE_set_int( MSIVIEW *view, UINT row, UINT col, int val )
{
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
UINT r, table_int;
TRACE("row %u, col %u, val %d.\n", row, col, val);
if ((r = int_to_table_storage( tv, col, val, &table_int )))
return r;
if (tv->columns[col-1].type & MSITYPE_KEY)
{
UINT key;
if ((r = TABLE_fetch_int( view, row, col, &key )))
return r;
if (key != table_int)
{
ERR("Cannot modify primary key %s.%s.\n",
debugstr_w(tv->table->name), debugstr_w(tv->columns[col-1].colname));
return ERROR_FUNCTION_FAILED;
}
}
return table_set_bytes( tv, row, col, table_int );
}
static UINT TABLE_set_string( MSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len )
{
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
BOOL persistent;
UINT id, r;
TRACE("row %u, col %u, val %s.\n", row, col, debugstr_wn(val, len));
persistent = (tv->table->persistent != MSICONDITION_FALSE)
&& tv->table->data_persistent[row];
if (val)
{
r = msi_string2id( tv->db->strings, val, len, &id );
if (r != ERROR_SUCCESS)
id = msi_add_string( tv->db->strings, val, len, persistent );
}
else
id = 0;
if (tv->columns[col-1].type & MSITYPE_KEY)
{
UINT key;
if ((r = TABLE_fetch_int( view, row, col, &key )))
return r;
if (key != id)
{
ERR("Cannot modify primary key %s.%s.\n",
debugstr_w(tv->table->name), debugstr_w(tv->columns[col-1].colname));
return ERROR_FUNCTION_FAILED;
}
}
return table_set_bytes( tv, row, col, id );
}
static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
@ -1402,7 +1467,7 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI
}
}
r = TABLE_set_int( tv, row, i+1, val );
r = table_set_bytes( tv, row, i+1, val );
if ( r != ERROR_SUCCESS )
break;
}
@ -2060,6 +2125,8 @@ static const MSIVIEWOPS table_ops =
TABLE_fetch_int,
TABLE_fetch_stream,
TABLE_get_row,
TABLE_set_int,
TABLE_set_string,
TABLE_set_row,
TABLE_insert_row,
TABLE_delete_row,

View File

@ -203,6 +203,8 @@ static const MSIVIEWOPS update_ops =
NULL,
NULL,
NULL,
NULL,
NULL,
UPDATE_execute,
UPDATE_close,
UPDATE_get_dimensions,

View File

@ -271,6 +271,46 @@ static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
return msi_view_get_row( wv->db, view, row, rec );
}
static UINT WHERE_set_int(struct tagMSIVIEW *view, UINT row, UINT col, int val)
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
JOINTABLE *table;
UINT *rows;
UINT r;
TRACE("view %p, row %u, col %u, val %d.\n", wv, row, col, val );
r = find_row(wv, row, &rows);
if (r != ERROR_SUCCESS)
return r;
table = find_table(wv, col, &col);
if (!table)
return ERROR_FUNCTION_FAILED;
return table->view->ops->set_int(table->view, rows[table->table_index], col, val);
}
static UINT WHERE_set_string(struct tagMSIVIEW *view, UINT row, UINT col, const WCHAR *val, int len)
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
JOINTABLE *table;
UINT *rows;
UINT r;
TRACE("view %p, row %u, col %u, val %s.\n", wv, row, col, debugstr_wn(val, len));
r = find_row(wv, row, &rows);
if (r != ERROR_SUCCESS)
return r;
table = find_table(wv, col, &col);
if (!table)
return ERROR_FUNCTION_FAILED;
return table->view->ops->set_string(table->view, rows[table->table_index], col, val, len);
}
static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
@ -1069,6 +1109,8 @@ static const MSIVIEWOPS where_ops =
WHERE_fetch_int,
WHERE_fetch_stream,
WHERE_get_row,
WHERE_set_int,
WHERE_set_string,
WHERE_set_row,
NULL,
WHERE_delete_row,