Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
14ec5260
Commit
14ec5260
authored
Mar 16, 2004
by
Mike McCormack
Committed by
Alexandre Julliard
Mar 16, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extend the parser to deal with the CREATE TABLE query. The query
doesn't do anything as yet.
parent
821f4775
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
392 additions
and
18 deletions
+392
-18
Makefile.in
dlls/msi/Makefile.in
+1
-0
create.c
dlls/msi/create.c
+169
-0
msi.c
dlls/msi/msi.c
+39
-1
msipriv.h
dlls/msi/msipriv.h
+1
-0
query.h
dlls/msi/query.h
+9
-0
sql.y
dlls/msi/sql.y
+165
-17
tokenize.c
dlls/msi/tokenize.c
+8
-0
No files found.
dlls/msi/Makefile.in
View file @
14ec5260
...
...
@@ -7,6 +7,7 @@ IMPORTS = ole32 user32 advapi32 kernel32
EXTRALIBS
=
-luuid
$(LIBUNICODE)
C_SRCS
=
\
create.c
\
distinct.c
\
handle.c
\
msi.c
\
...
...
dlls/msi/create.c
0 → 100644
View file @
14ec5260
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2002 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
);
/* below is the query interface to a table */
typedef
struct
tagMSICREATEVIEW
{
MSIVIEW
view
;
MSIDATABASE
*
db
;
LPWSTR
name
;
BOOL
bIsTemp
;
create_col_info
*
col_info
;
}
MSICREATEVIEW
;
static
UINT
CREATE_fetch_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
*
val
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
TRACE
(
"%p %d %d %p
\n
"
,
cv
,
row
,
col
,
val
);
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
CREATE_execute
(
struct
tagMSIVIEW
*
view
,
MSIHANDLE
record
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
create_col_info
*
c
;
FIXME
(
"%p %ld
\n
"
,
cv
,
record
);
FIXME
(
"Table %s (%s)
\n
"
,
debugstr_w
(
cv
->
name
),
cv
->
bIsTemp
?
"temporary"
:
"permanent"
);
for
(
c
=
cv
->
col_info
;
c
;
c
=
c
->
next
)
{
FIXME
(
"Column %s type %04x
\n
"
,
debugstr_w
(
c
->
colname
),
c
->
type
);
}
return
ERROR_SUCCESS
;
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
CREATE_close
(
struct
tagMSIVIEW
*
view
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
FIXME
(
"%p
\n
"
,
cv
);
return
ERROR_SUCCESS
;
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
CREATE_get_dimensions
(
struct
tagMSIVIEW
*
view
,
UINT
*
rows
,
UINT
*
cols
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
TRACE
(
"%p %p %p
\n
"
,
cv
,
rows
,
cols
);
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
CREATE_get_column_info
(
struct
tagMSIVIEW
*
view
,
UINT
n
,
LPWSTR
*
name
,
UINT
*
type
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
TRACE
(
"%p %d %p %p
\n
"
,
cv
,
n
,
name
,
type
);
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
CREATE_modify
(
struct
tagMSIVIEW
*
view
,
MSIMODIFY
eModifyMode
,
MSIHANDLE
hrec
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
TRACE
(
"%p %d %ld
\n
"
,
cv
,
eModifyMode
,
hrec
);
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
CREATE_delete
(
struct
tagMSIVIEW
*
view
)
{
MSICREATEVIEW
*
cv
=
(
MSICREATEVIEW
*
)
view
;
create_col_info
*
col
;
TRACE
(
"%p
\n
"
,
cv
);
col
=
cv
->
col_info
;
while
(
col
)
{
create_col_info
*
t
=
col
;
col
=
col
->
next
;
HeapFree
(
GetProcessHeap
(),
0
,
t
->
colname
);
HeapFree
(
GetProcessHeap
(),
0
,
t
);
}
HeapFree
(
GetProcessHeap
(),
0
,
cv
->
name
);
HeapFree
(
GetProcessHeap
(),
0
,
cv
);
return
ERROR_SUCCESS
;
}
MSIVIEWOPS
create_ops
=
{
CREATE_fetch_int
,
CREATE_execute
,
CREATE_close
,
CREATE_get_dimensions
,
CREATE_get_column_info
,
CREATE_modify
,
CREATE_delete
};
UINT
CREATE_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPWSTR
table
,
create_col_info
*
col_info
,
BOOL
temp
)
{
MSICREATEVIEW
*
cv
=
NULL
;
TRACE
(
"%p
\n
"
,
cv
);
cv
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
*
cv
);
if
(
!
cv
)
return
ERROR_FUNCTION_FAILED
;
/* fill the structure */
cv
->
view
.
ops
=
&
create_ops
;
cv
->
db
=
db
;
cv
->
name
=
table
;
/* FIXME: strdupW it? */
cv
->
col_info
=
col_info
;
cv
->
bIsTemp
=
temp
;
*
view
=
(
MSIVIEW
*
)
cv
;
return
ERROR_SUCCESS
;
}
dlls/msi/msi.c
View file @
14ec5260
...
...
@@ -36,6 +36,14 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
msi
);
/*
* The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
* which is a problem because LPCTSTR isn't defined when compiling wine.
* To work around this problem, we need to define LPCTSTR as LPCWSTR here,
* and make sure to only use it in W functions.
*/
#define LPCTSTR LPCWSTR
const
WCHAR
szInstaller
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
'\\'
,
...
...
@@ -179,13 +187,42 @@ UINT WINAPI MsiOpenDatabaseW(
MSIHANDLE
handle
;
MSIDATABASE
*
db
;
UINT
ret
;
LPWSTR
szMode
;
TRACE
(
"%s %s %p
\n
"
,
debugstr_w
(
szDBPath
),
debugstr_w
(
szPersist
),
phDB
);
if
(
!
phDB
)
return
ERROR_INVALID_PARAMETER
;
r
=
StgOpenStorage
(
szDBPath
,
NULL
,
STGM_DIRECT
|
STGM_READ
|
STGM_SHARE_DENY_WRITE
,
NULL
,
0
,
&
stg
);
szMode
=
(
LPWSTR
)
szPersist
;
if
(
HIWORD
(
szPersist
)
)
{
/* UINT len = lstrlenW( szPerist ) + 1; */
FIXME
(
"don't support persist files yet
\b
"
);
return
ERROR_INVALID_PARAMETER
;
/* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
}
else
if
(
szPersist
==
MSIDBOPEN_READONLY
)
{
r
=
StgOpenStorage
(
szDBPath
,
NULL
,
STGM_DIRECT
|
STGM_READ
|
STGM_SHARE_DENY_WRITE
,
NULL
,
0
,
&
stg
);
}
else
if
(
szPersist
==
MSIDBOPEN_CREATE
)
{
r
=
StgCreateDocfile
(
szDBPath
,
STGM_DIRECT
|
STGM_READWRITE
|
STGM_SHARE_EXCLUSIVE
,
0
,
&
stg
);
}
else
if
(
szPersist
==
MSIDBOPEN_TRANSACT
)
{
r
=
StgOpenStorage
(
szDBPath
,
NULL
,
STGM_DIRECT
|
STGM_READWRITE
|
STGM_SHARE_EXCLUSIVE
,
NULL
,
0
,
&
stg
);
}
else
{
ERR
(
"unknown flag %p
\n
"
,
szPersist
);
return
ERROR_INVALID_PARAMETER
;
}
if
(
FAILED
(
r
)
)
{
FIXME
(
"open failed r = %08lx!
\n
"
,
r
);
...
...
@@ -208,6 +245,7 @@ UINT WINAPI MsiOpenDatabaseW(
goto
end
;
}
db
->
storage
=
stg
;
db
->
mode
=
szMode
;
ret
=
load_string_table
(
db
,
&
db
->
strings
);
if
(
ret
!=
ERROR_SUCCESS
)
goto
end
;
...
...
dlls/msi/msipriv.h
View file @
14ec5260
...
...
@@ -60,6 +60,7 @@ typedef struct tagMSIDATABASE
{
IStorage
*
storage
;
string_table
strings
;
LPWSTR
mode
;
MSITABLE
*
first_table
,
*
last_table
;
}
MSIDATABASE
;
...
...
dlls/msi/query.h
View file @
14ec5260
...
...
@@ -70,6 +70,12 @@ struct expr
}
u
;
};
typedef
struct
_create_col_info
{
LPWSTR
colname
;
UINT
type
;
struct
_create_col_info
*
next
;
}
create_col_info
;
UINT
MSI_ParseSQL
(
MSIDATABASE
*
db
,
LPCWSTR
command
,
MSIVIEW
**
phView
);
...
...
@@ -86,6 +92,9 @@ UINT ORDER_AddColumn( MSIVIEW *group, LPWSTR name );
UINT
WHERE_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
);
UINT
WHERE_AddCondition
(
MSIVIEW
*
view
,
struct
expr
*
condition
);
UINT
CREATE_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPWSTR
table
,
create_col_info
*
col_info
,
BOOL
temp
);
int
sqliteGetToken
(
const
WCHAR
*
z
,
int
*
tokenType
);
#endif
/* __WINE_MSI_QUERY_H */
dlls/msi/sql.y
View file @
14ec5260
...
...
@@ -63,6 +63,9 @@ static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in,
static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in,
struct string_list *columns );
static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
struct string_list *keys);
static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
static struct expr * EXPR_column( LPWSTR column );
static struct expr * EXPR_ival( INT ival );
...
...
@@ -76,34 +79,36 @@ static struct expr * EXPR_sval( LPWSTR string );
{
LPWSTR string;
struct string_list *column_list;
MSIVIEW *
table
;
MSIVIEW *
query
;
struct expr *expr;
USHORT column_type;
create_col_info *column_info;
}
%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL 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_CH
ECK TK_CLUSTER TK_COLLATE TK_COLUMN TK_COMMA
%token TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT
%token TK_CASCADE TK_CASE TK_CH
AR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN
%token TK_COMM
A TK_COMM
ENT 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_GE TK_GLOB TK_GROUP TK_GT
%token TK_HAVING
%token TK_HAVING
TK_HOLD
%token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY
%token <string> TK_ID
%token TK_INSERT TK_INSTEAD TK_INTEGER TK_INTERSECT TK_INTO TK_IS TK_ISNULL
%token TK_INSERT TK_INSTEAD TK_INT
TK_INT
EGER TK_INTERSECT TK_INTO TK_IS TK_ISNULL
%token TK_JOIN TK_JOIN_KW
%token TK_KEY
%token TK_LE TK_LIKE TK_LIMIT TK_LP TK_LSHIFT TK_LT
%token TK_LE TK_LIKE TK_LIMIT TK_L
ONG TK_LONGCHAR TK_L
P TK_LSHIFT TK_LT
%token TK_MATCH TK_MINUS
%token TK_NE TK_NOT TK_NOTNULL TK_NULL
%token TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
%token TK_O
BJECT TK_O
F TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
%token TK_PLUS TK_PRAGMA TK_PRIMARY
%token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK
%token TK_ROW TK_RP TK_RSHIFT
%token TK_SELECT TK_SEMI TK_SET TK_SLASH TK_SPACE TK_STAR TK_STATEMENT
%token TK_SELECT TK_SEMI TK_SET TK_S
HORT TK_S
LASH TK_SPACE TK_STAR TK_STATEMENT
%token <string> TK_STRING
%token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER
%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
...
...
@@ -120,14 +125,139 @@ static struct expr * EXPR_sval( LPWSTR string );
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
COLUMN AGG_FUNCTION.
%type <query> oneselect
%type <string> column table string_or_id
%type <column_list> selcollist
%type <
table> from unorderedsel
%type <
query> from unorderedsel oneselect onequery onecreate
%type <expr> expr val column_val
%type <column_type> column_type data_type data_count
%type <column_info> column_def table_def
%%
onequery:
oneselect
{
SQL_input* sql = (SQL_input*) info;
*sql->view = $1;
}
| onecreate
{
SQL_input* sql = (SQL_input*) info;
*sql->view = $1;
}
;
onecreate:
TK_CREATE TK_TABLE table TK_LP table_def TK_RP
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *create;
if( !$5 )
YYABORT;
CREATE_CreateView( sql->db, &create, $3, $5, FALSE );
$$ = create;
}
| TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *create;
if( !$5 )
YYABORT;
CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
$$ = create;
}
;
table_def:
column_def TK_PRIMARY TK_KEY selcollist
{
if( SQL_MarkPrimaryKeys( $1, $4 ) )
$$ = $1;
else
$$ = NULL;
}
;
column_def:
column_def TK_COMMA column column_type
{
$$ = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );
if( $$ )
{
$$->colname = $3;
$$->type = $4;
$$->next = $1;
}
else if( $1 )
HeapFree( GetProcessHeap(), 0, $1 );
}
| column column_type
{
$$ = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );
if( $$ )
{
$$->colname = $1;
$$->type = $2;
$$->next = NULL;
}
}
;
column_type:
data_type
{
$$ |= MSITYPE_NULLABLE;
}
| data_type TK_NOT TK_NULL
{
$$ = $1;
}
;
data_type:
TK_CHAR
{
$$ = MSITYPE_STRING | 1;
}
| TK_CHAR TK_LP data_count TK_RP
{
$$ = MSITYPE_STRING | $3;
}
| TK_LONGCHAR
{
$$ = 2;
}
| TK_SHORT
{
$$ = 2;
}
| TK_INT
{
$$ = 2;
}
| TK_LONG
{
$$ = 4;
}
| TK_OBJECT
{
$$ = 0;
}
;
data_count:
TK_INTEGER
{
SQL_input* sql = (SQL_input*) info;
int val = SQL_getint(sql);
if( ( val > 255 ) || ( val < 0 ) )
YYABORT;
$$ = val;
}
;
oneselect:
unorderedsel TK_ORDER TK_BY selcollist
{
...
...
@@ -136,16 +266,11 @@ oneselect:
if( !$1 )
YYABORT;
if( $4 )
*sql->view
= do_order_by( sql->db, $1, $4 );
$$
= do_order_by( sql->db, $1, $4 );
else
*sql->view
= $1;
$$
= $1;
}
| unorderedsel
{
SQL_input* sql = (SQL_input*) info;
*sql->view = $1;
}
;
unorderedsel:
...
...
@@ -491,6 +616,29 @@ static struct expr * EXPR_sval( LPWSTR string )
return e;
}
static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
struct string_list *keys )
{
struct string_list *k;
BOOL found = TRUE;
for( k = keys; k && found; k = k->next )
{
create_col_info *c;
found = FALSE;
for( c = cols; c && !found; c = c->next )
{
if( lstrcmpW( k->string, c->colname ) )
continue;
c->type |= MSITYPE_KEY;
found = TRUE;
}
}
return found;
}
UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
{
SQL_input sql;
...
...
dlls/msi/tokenize.c
View file @
14ec5260
...
...
@@ -55,6 +55,8 @@ static const Keyword aKeywordTable[] = {
{
"BY"
,
TK_BY
},
{
"CASCADE"
,
TK_CASCADE
},
{
"CASE"
,
TK_CASE
},
{
"CHAR"
,
TK_CHAR
},
{
"CHARACTER"
,
TK_CHAR
},
{
"CHECK"
,
TK_CHECK
},
{
"CLUSTER"
,
TK_CLUSTER
},
{
"COLLATE"
,
TK_COLLATE
},
...
...
@@ -85,6 +87,7 @@ static const Keyword aKeywordTable[] = {
{
"GLOB"
,
TK_GLOB
},
{
"GROUP"
,
TK_GROUP
},
{
"HAVING"
,
TK_HAVING
},
{
"HOLD"
,
TK_HOLD
},
{
"IGNORE"
,
TK_IGNORE
},
{
"IMMEDIATE"
,
TK_IMMEDIATE
},
{
"IN"
,
TK_IN
},
...
...
@@ -93,6 +96,7 @@ static const Keyword aKeywordTable[] = {
{
"INNER"
,
TK_JOIN_KW
},
{
"INSERT"
,
TK_INSERT
},
{
"INSTEAD"
,
TK_INSTEAD
},
{
"INT"
,
TK_INT
},
{
"INTERSECT"
,
TK_INTERSECT
},
{
"INTO"
,
TK_INTO
},
{
"IS"
,
TK_IS
},
...
...
@@ -102,11 +106,14 @@ static const Keyword aKeywordTable[] = {
{
"LEFT"
,
TK_JOIN_KW
},
{
"LIKE"
,
TK_LIKE
},
{
"LIMIT"
,
TK_LIMIT
},
{
"LONG"
,
TK_LONG
},
{
"LONGCHAR"
,
TK_LONGCHAR
},
{
"MATCH"
,
TK_MATCH
},
{
"NATURAL"
,
TK_JOIN_KW
},
{
"NOT"
,
TK_NOT
},
{
"NOTNULL"
,
TK_NOTNULL
},
{
"NULL"
,
TK_NULL
},
{
"OBJECT"
,
TK_OBJECT
},
{
"OF"
,
TK_OF
},
{
"OFFSET"
,
TK_OFFSET
},
{
"ON"
,
TK_ON
},
...
...
@@ -124,6 +131,7 @@ static const Keyword aKeywordTable[] = {
{
"ROW"
,
TK_ROW
},
{
"SELECT"
,
TK_SELECT
},
{
"SET"
,
TK_SET
},
{
"SHORT"
,
TK_SHORT
},
{
"STATEMENT"
,
TK_STATEMENT
},
{
"TABLE"
,
TK_TABLE
},
{
"TEMP"
,
TK_TEMP
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment