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:
parent
99425f272f
commit
f45a7b04a6
|
@ -229,6 +229,8 @@ static const MSIVIEWOPS alter_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ALTER_execute,
|
||||
ALTER_close,
|
||||
ALTER_get_dimensions,
|
||||
|
|
|
@ -130,6 +130,8 @@ static const MSIVIEWOPS create_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
CREATE_execute,
|
||||
CREATE_close,
|
||||
CREATE_get_dimensions,
|
||||
|
|
|
@ -172,6 +172,8 @@ static const MSIVIEWOPS delete_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DELETE_execute,
|
||||
DELETE_close,
|
||||
DELETE_get_dimensions,
|
||||
|
|
|
@ -255,6 +255,8 @@ static const MSIVIEWOPS distinct_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DISTINCT_execute,
|
||||
DISTINCT_close,
|
||||
DISTINCT_get_dimensions,
|
||||
|
|
|
@ -100,6 +100,8 @@ static const MSIVIEWOPS drop_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DROP_execute,
|
||||
DROP_close,
|
||||
DROP_get_dimensions,
|
||||
|
|
|
@ -326,6 +326,8 @@ static const MSIVIEWOPS insert_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
INSERT_execute,
|
||||
INSERT_close,
|
||||
INSERT_get_dimensions,
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -203,6 +203,8 @@ static const MSIVIEWOPS update_ops =
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
UPDATE_execute,
|
||||
UPDATE_close,
|
||||
UPDATE_get_dimensions,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue