2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002-2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msidb
);
40 * Code to delete rows from a table.
42 * We delete rows by blanking them out rather than trying to remove the row.
43 * This appears to be what the native MSI does (or tries to do). For the query:
45 * delete from Property
47 * some non-zero entries are left in the table by native MSI. I'm not sure if
48 * that's a bug in the way I'm running the query, or a just a bug.
51 typedef struct tagMSIDELETEVIEW
58 static UINT
DELETE_fetch_int( struct tagMSIVIEW
*view
, UINT row
, UINT col
, UINT
*val
)
60 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
62 TRACE("%p %d %d %p\n", dv
, row
, col
, val
);
64 return ERROR_FUNCTION_FAILED
;
67 static UINT
DELETE_fetch_stream( struct tagMSIVIEW
*view
, UINT row
, UINT col
, IStream
**stm
)
69 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
71 TRACE("%p %d %d %p\n", dv
, row
, col
, stm
);
73 return ERROR_FUNCTION_FAILED
;
76 static UINT
DELETE_execute( struct tagMSIVIEW
*view
, MSIRECORD
*record
)
78 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
79 UINT r
, i
, rows
= 0, cols
= 0;
81 TRACE("%p %p\n", dv
, record
);
84 return ERROR_FUNCTION_FAILED
;
86 r
= dv
->table
->ops
->execute( dv
->table
, record
);
87 if( r
!= ERROR_SUCCESS
)
90 r
= dv
->table
->ops
->get_dimensions( dv
->table
, &rows
, &cols
);
91 if( r
!= ERROR_SUCCESS
)
94 TRACE("deleting %d rows\n", rows
);
96 /* blank out all the rows that match */
97 for ( i
=0; i
<rows
; i
++ )
98 dv
->table
->ops
->delete_row( dv
->table
, i
);
100 return ERROR_SUCCESS
;
103 static UINT
DELETE_close( struct tagMSIVIEW
*view
)
105 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
110 return ERROR_FUNCTION_FAILED
;
112 return dv
->table
->ops
->close( dv
->table
);
115 static UINT
DELETE_get_dimensions( struct tagMSIVIEW
*view
, UINT
*rows
, UINT
*cols
)
117 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
119 TRACE("%p %p %p\n", dv
, rows
, cols
);
122 return ERROR_FUNCTION_FAILED
;
126 return dv
->table
->ops
->get_dimensions( dv
->table
, NULL
, cols
);
129 static UINT
DELETE_get_column_info( struct tagMSIVIEW
*view
, UINT n
, LPCWSTR
*name
,
130 UINT
*type
, BOOL
*temporary
, LPCWSTR
*table_name
)
132 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
134 TRACE("%p %d %p %p %p %p\n", dv
, n
, name
, type
, temporary
, table_name
);
137 return ERROR_FUNCTION_FAILED
;
139 return dv
->table
->ops
->get_column_info( dv
->table
, n
, name
,
140 type
, temporary
, table_name
);
143 static UINT
DELETE_modify( struct tagMSIVIEW
*view
, MSIMODIFY eModifyMode
,
144 MSIRECORD
*rec
, UINT row
)
146 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
148 TRACE("%p %d %p\n", dv
, eModifyMode
, rec
);
150 return ERROR_FUNCTION_FAILED
;
153 static UINT
DELETE_delete( struct tagMSIVIEW
*view
)
155 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
160 dv
->table
->ops
->delete( dv
->table
);
164 return ERROR_SUCCESS
;
167 static UINT
DELETE_find_matching_rows( struct tagMSIVIEW
*view
, UINT col
,
168 UINT val
, UINT
*row
, MSIITERHANDLE
*handle
)
170 TRACE("%p, %d, %u, %p\n", view
, col
, val
, *handle
);
172 return ERROR_FUNCTION_FAILED
;
176 static const MSIVIEWOPS delete_ops
=
186 DELETE_get_dimensions
,
187 DELETE_get_column_info
,
190 DELETE_find_matching_rows
,
199 UINT
DELETE_CreateView( MSIDATABASE
*db
, MSIVIEW
**view
, MSIVIEW
*table
)
201 MSIDELETEVIEW
*dv
= NULL
;
205 dv
= msi_alloc_zero( sizeof *dv
);
207 return ERROR_FUNCTION_FAILED
;
209 /* fill the structure */
210 dv
->view
.ops
= &delete_ops
;
216 return ERROR_SUCCESS
;