MSI: implement SQL delete query
Mike McCormack
mike at codeweavers.com
Sun Feb 13 23:15:02 CST 2005
ChangeLog:
* implement SQL delete query
-------------- next part --------------
Index: dlls/msi/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/msi/Makefile.in,v
retrieving revision 1.23
diff -u -p -r1.23 Makefile.in
--- dlls/msi/Makefile.in 8 Feb 2005 12:12:29 -0000 1.23
+++ dlls/msi/Makefile.in 14 Feb 2005 05:13:18 -0000
@@ -11,6 +11,7 @@ C_SRCS = \
appsearch.c \
create.c \
custom.c \
+ delete.c \
dialog.c \
distinct.c \
format.c \
Index: dlls/msi/query.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/query.h,v
retrieving revision 1.12
diff -u -p -r1.12 query.h
--- dlls/msi/query.h 22 Dec 2004 15:22:12 -0000 1.12
+++ dlls/msi/query.h 14 Feb 2005 05:13:18 -0000
@@ -131,6 +131,8 @@ UINT INSERT_CreateView( MSIDATABASE *db,
UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **, LPWSTR table,
column_assignment *list, struct expr *expr );
+UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
+
void delete_expr( struct expr *e );
void delete_string_list( string_list *sl );
void delete_value_list( value_list *vl );
Index: dlls/msi/sql.y
===================================================================
RCS file: /home/wine/wine/dlls/msi/sql.y,v
retrieving revision 1.20
diff -u -p -r1.20 sql.y
--- dlls/msi/sql.y 20 Jan 2005 20:39:15 -0000 1.20
+++ dlls/msi/sql.y 14 Feb 2005 05:13:19 -0000
@@ -129,7 +129,8 @@ static struct expr * EXPR_wildcard();
%type <string> column table string_or_id
%type <column_list> selcollist
-%type <query> from unorderedsel oneselect onequery onecreate oneinsert oneupdate
+%type <query> from unorderedsel oneselect onequery onecreate oneinsert
+%type <query> oneupdate onedelete
%type <expr> expr val column_val const_val
%type <column_type> column_type data_type data_type_l data_count
%type <column_info> column_def table_def
@@ -159,6 +160,11 @@ onequery:
SQL_input* sql = (SQL_input*) info;
*sql->view = $1;
}
+ | onedelete
+ {
+ SQL_input* sql = (SQL_input*) info;
+ *sql->view = $1;
+ }
;
oneinsert:
@@ -211,6 +217,17 @@ oneupdate:
UPDATE_CreateView( sql->db, &update, $2, &$4, $6 );
$$ = update;
+ }
+ ;
+
+onedelete:
+ TK_DELETE from
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *delete = NULL;
+
+ DELETE_CreateView( sql->db, &delete, $2 );
+ $$ = delete;
}
;
--- /dev/null 2004-12-26 03:00:47.000000000 +0900
+++ dlls/msi/delete.c 2005-02-14 14:06:50.000000000 +0900
@@ -0,0 +1,218 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2005 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/*
+ * Code to delete rows from a table.
+ *
+ * We delete rows by blanking them out rather than trying to remove the row.
+ * This appears to be what the native MSI does (or tries to do). For the query:
+ *
+ * delete from Property
+ *
+ * some non-zero entries are left in the table by native MSI. I'm not sure if
+ * that's a bug in the way I'm running the query, or a just a bug.
+ */
+
+typedef struct tagMSIDELETEVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ MSIVIEW *table;
+} MSIDELETEVIEW;
+
+static UINT DELETE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %d %d %p\n", dv, row, col, val );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %d %d %p\n", dv, row, col, stm );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %d %d %04x\n", dv, row, col, val );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_insert_row( struct tagMSIVIEW *view, UINT *num )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %p\n", dv, num );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+ UINT r, i, j, rows = 0, cols = 0;
+
+ TRACE("%p %p\n", dv, record);
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ r = dv->table->ops->execute( dv->table, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = dv->table->ops->get_dimensions( dv->table, &rows, &cols );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ TRACE("blanking %d rows\n", rows);
+
+ /* blank out all the rows that match */
+ for( i=0; i<rows; i++ )
+ for( j=1; j<=cols; j++ )
+ dv->table->ops->set_int( dv->table, i, j, 0 );
+
+ return ERROR_SUCCESS;
+}
+
+static UINT DELETE_close( struct tagMSIVIEW *view )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p\n", dv );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return dv->table->ops->close( dv->table );
+}
+
+static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %p %p\n", dv, rows, cols );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ *rows = 0;
+
+ return dv->table->ops->get_dimensions( dv->table, NULL, cols );
+}
+
+static UINT DELETE_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %d %p %p\n", dv, n, name, type );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return dv->table->ops->get_column_info( dv->table, n, name, type );
+}
+
+static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
+ MSIRECORD *rec )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p %d %p\n", dv, eModifyMode, rec );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_delete( struct tagMSIVIEW *view )
+{
+ MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+ TRACE("%p\n", dv );
+
+ if( dv->table )
+ dv->table->ops->delete( dv->table );
+
+ HeapFree( GetProcessHeap(), 0, dv );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS delete_ops =
+{
+ DELETE_fetch_int,
+ DELETE_fetch_stream,
+ DELETE_set_int,
+ DELETE_insert_row,
+ DELETE_execute,
+ DELETE_close,
+ DELETE_get_dimensions,
+ DELETE_get_column_info,
+ DELETE_modify,
+ DELETE_delete
+};
+
+UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
+{
+ MSIDELETEVIEW *dv = NULL;
+
+ TRACE("%p\n", dv );
+
+ dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv );
+ if( !dv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ dv->view.ops = &delete_ops;
+ dv->db = db;
+ dv->table = table;
+
+ *view = &dv->view;
+
+ return ERROR_SUCCESS;
+}
More information about the wine-patches
mailing list