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;
82 TRACE("%p %p\n", dv
, record
);
85 return ERROR_FUNCTION_FAILED
;
87 r
= dv
->table
->ops
->execute( dv
->table
, record
);
88 if( r
!= ERROR_SUCCESS
)
91 r
= dv
->table
->ops
->get_dimensions( dv
->table
, &rows
, &cols
);
92 if( r
!= ERROR_SUCCESS
)
95 TRACE("blanking %d rows\n", rows
);
97 empty
= MSI_CreateRecord( cols
);
99 return ERROR_FUNCTION_FAILED
;
101 /* blank out all the rows that match */
102 for ( i
=0; i
<rows
; i
++ )
103 dv
->table
->ops
->set_row( dv
->table
, i
, empty
, (1<<cols
)-1 );
105 msiobj_release( &empty
->hdr
);
107 return ERROR_SUCCESS
;
110 static UINT
DELETE_close( struct tagMSIVIEW
*view
)
112 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
117 return ERROR_FUNCTION_FAILED
;
119 return dv
->table
->ops
->close( dv
->table
);
122 static UINT
DELETE_get_dimensions( struct tagMSIVIEW
*view
, UINT
*rows
, UINT
*cols
)
124 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
126 TRACE("%p %p %p\n", dv
, rows
, cols
);
129 return ERROR_FUNCTION_FAILED
;
133 return dv
->table
->ops
->get_dimensions( dv
->table
, NULL
, cols
);
136 static UINT
DELETE_get_column_info( struct tagMSIVIEW
*view
,
137 UINT n
, LPWSTR
*name
, UINT
*type
)
139 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
141 TRACE("%p %d %p %p\n", dv
, n
, name
, type
);
144 return ERROR_FUNCTION_FAILED
;
146 return dv
->table
->ops
->get_column_info( dv
->table
, n
, name
, type
);
149 static UINT
DELETE_modify( struct tagMSIVIEW
*view
, MSIMODIFY eModifyMode
,
152 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
154 TRACE("%p %d %p\n", dv
, eModifyMode
, rec
);
156 return ERROR_FUNCTION_FAILED
;
159 static UINT
DELETE_delete( struct tagMSIVIEW
*view
)
161 MSIDELETEVIEW
*dv
= (MSIDELETEVIEW
*)view
;
166 dv
->table
->ops
->delete( dv
->table
);
170 return ERROR_SUCCESS
;
173 static UINT
DELETE_find_matching_rows( struct tagMSIVIEW
*view
, UINT col
,
174 UINT val
, UINT
*row
, MSIITERHANDLE
*handle
)
176 TRACE("%p, %d, %u, %p\n", view
, col
, val
, *handle
);
178 return ERROR_FUNCTION_FAILED
;
182 static const MSIVIEWOPS delete_ops
=
191 DELETE_get_dimensions
,
192 DELETE_get_column_info
,
195 DELETE_find_matching_rows
198 UINT
DELETE_CreateView( MSIDATABASE
*db
, MSIVIEW
**view
, MSIVIEW
*table
)
200 MSIDELETEVIEW
*dv
= NULL
;
204 dv
= msi_alloc_zero( sizeof *dv
);
206 return ERROR_FUNCTION_FAILED
;
208 /* fill the structure */
209 dv
->view
.ops
= &delete_ops
;
215 return ERROR_SUCCESS
;