diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in index fe125865973..6bc9d01d010 100644 --- a/dlls/msi/Makefile.in +++ b/dlls/msi/Makefile.in @@ -9,6 +9,7 @@ EXTRALIBS = -luuid C_SRCS = \ action.c \ + alter.c \ appsearch.c \ classes.c \ create.c \ diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c new file mode 100644 index 00000000000..98a62431538 --- /dev/null +++ b/dlls/msi/alter.c @@ -0,0 +1,176 @@ +/* + * Implementation of the Microsoft Installer (msi.dll) + * + * Copyright 2006 Mike McCormack + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#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 "query.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msidb); + +typedef struct tagMSIALTERVIEW +{ + MSIVIEW view; + MSIDATABASE *db; +} MSIALTERVIEW; + +static UINT ALTER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %d %d %p\n", av, row, col, val ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %d %d %p\n", av, row, col, stm ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %d %d %04x\n", av, row, col, val ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_insert_row( struct tagMSIVIEW *view, MSIRECORD *record ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %p\n", av, record ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_execute( struct tagMSIVIEW *view, MSIRECORD *record ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + FIXME("%p %p\n", av, record); + + return ERROR_SUCCESS; +} + +static UINT ALTER_close( struct tagMSIVIEW *view ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p\n", av ); + + return ERROR_SUCCESS; +} + +static UINT ALTER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %p %p\n", av, rows, cols ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_get_column_info( struct tagMSIVIEW *view, + UINT n, LPWSTR *name, UINT *type ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %d %p %p\n", av, n, name, type ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, + MSIRECORD *rec ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p %d %p\n", av, eModifyMode, rec ); + + return ERROR_FUNCTION_FAILED; +} + +static UINT ALTER_delete( struct tagMSIVIEW *view ) +{ + MSIALTERVIEW *av = (MSIALTERVIEW*)view; + + TRACE("%p\n", av ); + + return ERROR_SUCCESS; +} + +static UINT ALTER_find_matching_rows( struct tagMSIVIEW *view, UINT col, + UINT val, UINT *row, MSIITERHANDLE *handle ) +{ + TRACE("%p, %d, %u, %p\n", view, col, val, *handle); + + return ERROR_FUNCTION_FAILED; +} + + +static const MSIVIEWOPS alter_ops = +{ + ALTER_fetch_int, + ALTER_fetch_stream, + ALTER_set_int, + ALTER_insert_row, + ALTER_execute, + ALTER_close, + ALTER_get_dimensions, + ALTER_get_column_info, + ALTER_modify, + ALTER_delete, + ALTER_find_matching_rows +}; + +UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold ) +{ + MSIALTERVIEW *av = NULL; + + TRACE("%p\n", av ); + + av = msi_alloc_zero( sizeof *av ); + if( !av ) + return ERROR_FUNCTION_FAILED; + + /* fill the structure */ + av->view.ops = &alter_ops; + av->db = db; + + *view = &av->view; + + return ERROR_SUCCESS; +} diff --git a/dlls/msi/query.h b/dlls/msi/query.h index c0de03ba449..16aeb66fa41 100644 --- a/dlls/msi/query.h +++ b/dlls/msi/query.h @@ -121,6 +121,8 @@ UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR left, LPCWSTR right, struct expr *cond ); +UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold ); + int sqliteGetToken(const WCHAR *z, int *tokenType); #endif /* __WINE_MSI_QUERY_H */ diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y index 76160caf97b..a4e0f7e4463 100644 --- a/dlls/msi/sql.y +++ b/dlls/msi/sql.y @@ -79,15 +79,15 @@ static struct expr * EXPR_wildcard( void *info ); int integer; } -%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC +%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_ALTER TK_AND TK_AS TK_ASC %token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY %token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN -%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT +%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT %token TK_CONSTRAINT TK_COPY TK_CREATE %token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC %token TK_DISTINCT TK_DOT TK_DROP TK_EACH %token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN -%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FROM TK_FUNCTION +%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FREE TK_FROM TK_FUNCTION %token TK_GE TK_GLOB TK_GROUP TK_GT %token TK_HAVING TK_HOLD %token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY @@ -127,10 +127,10 @@ static struct expr * EXPR_wildcard( void *info ); %type selcollist column column_and_type column_def table_def %type column_assignment update_assign_list constlist %type query multifrom from fromtable selectfrom unorderedsel -%type oneupdate onedelete oneselect onequery onecreate oneinsert +%type oneupdate onedelete oneselect onequery onecreate oneinsert onealter %type expr val column_val const_val %type column_type data_type data_type_l data_count -%type number +%type number alterop /* Reference: http://mates.ms.mff.cuni.cz/oracle/doc/ora815nt/server.815/a67779/operator.htm */ %left TK_OR @@ -156,6 +156,7 @@ onequery: | oneinsert | oneupdate | onedelete + | onealter ; oneinsert: @@ -235,6 +236,30 @@ onedelete: } ; +onealter: + TK_ALTER TK_TABLE table alterop + { + SQL_input* sql = (SQL_input*) info; + MSIVIEW *alter = NULL; + + ALTER_CreateView( sql->db, &alter, $3, $4 ); + if( !alter ) + YYABORT; + $$ = alter; + } + ; + +alterop: + TK_HOLD + { + $$ = 1; + } + | TK_FREE + { + $$ = -1; + } + ; + table_def: column_def TK_PRIMARY TK_KEY selcollist { diff --git a/dlls/msi/tokenize.c b/dlls/msi/tokenize.c index c8708c71b4a..fe139839daf 100644 --- a/dlls/msi/tokenize.c +++ b/dlls/msi/tokenize.c @@ -41,6 +41,7 @@ struct Keyword { static const WCHAR ABORT_W[] = { 'A','B','O','R','T',0 }; static const WCHAR AFTER_W[] = { 'A','F','T','E','R',0 }; +static const WCHAR ALTER_W[] = { 'A','L','T','E','R',0 }; static const WCHAR ALL_W[] = { 'A','L','L',0 }; static const WCHAR AND_W[] = { 'A','N','D',0 }; static const WCHAR AS_W[] = { 'A','S',0 }; @@ -78,6 +79,7 @@ static const WCHAR EXPLAIN_W[] = { 'E','X','P','L','A','I','N',0 }; static const WCHAR FAIL_W[] = { 'F','A','I','L',0 }; static const WCHAR FOR_W[] = { 'F','O','R',0 }; static const WCHAR FOREIGN_W[] = { 'F','O','R','E','I','G','N',0 }; +static const WCHAR FREE_W[] = { 'F','R','E','E',0 }; static const WCHAR FROM_W[] = { 'F','R','O','M',0 }; static const WCHAR FULL_W[] = { 'F','U','L','L',0 }; static const WCHAR GLOB_W[] = { 'G','L','O','B',0 }; @@ -152,6 +154,7 @@ static const WCHAR WHERE_W[] = { 'W','H','E','R','E',0 }; static const Keyword aKeywordTable[] = { { ABORT_W, TK_ABORT }, { AFTER_W, TK_AFTER }, + { ALTER_W, TK_ALTER }, { ALL_W, TK_ALL }, { AND_W, TK_AND }, { AS_W, TK_AS },