Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
0fd49432
Commit
0fd49432
authored
Oct 20, 2011
by
Bernhard Loos
Committed by
Alexandre Julliard
Oct 20, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Get rid of JOINVIEW.
parent
4383aafa
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
12 additions
and
508 deletions
+12
-508
Makefile.in
dlls/msi/Makefile.in
+0
-1
join.c
dlls/msi/join.c
+0
-493
query.h
dlls/msi/query.h
+0
-2
sql.y
dlls/msi/sql.y
+12
-12
No files found.
dlls/msi/Makefile.in
View file @
0fd49432
...
...
@@ -24,7 +24,6 @@ C_SRCS = \
handle.c
\
insert.c
\
install.c
\
join.c
\
media.c
\
msi.c
\
msi_main.c
\
...
...
dlls/msi/join.c
deleted
100644 → 0
View file @
4383aafa
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
#include "objidl.h"
#include "msipriv.h"
#include "query.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
msidb
);
typedef
struct
tagJOINTABLE
{
struct
list
entry
;
MSIVIEW
*
view
;
UINT
columns
;
UINT
rows
;
UINT
next_rows
;
}
JOINTABLE
;
typedef
struct
tagMSIJOINVIEW
{
MSIVIEW
view
;
MSIDATABASE
*
db
;
struct
list
tables
;
UINT
columns
;
UINT
rows
;
}
MSIJOINVIEW
;
static
UINT
JOIN_fetch_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
*
val
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
UINT
cols
=
0
;
UINT
prev_rows
=
1
;
if
(
col
==
0
||
col
>
jv
->
columns
)
return
ERROR_FUNCTION_FAILED
;
if
(
row
>=
jv
->
rows
)
return
ERROR_FUNCTION_FAILED
;
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
if
(
col
<=
cols
+
table
->
columns
)
{
row
=
(
row
%
(
jv
->
rows
/
table
->
next_rows
))
/
prev_rows
;
col
-=
cols
;
break
;
}
prev_rows
*=
table
->
rows
;
cols
+=
table
->
columns
;
}
return
table
->
view
->
ops
->
fetch_int
(
table
->
view
,
row
,
col
,
val
);
}
static
UINT
JOIN_fetch_stream
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
IStream
**
stm
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
UINT
cols
=
0
;
UINT
prev_rows
=
1
;
TRACE
(
"%p %d %d %p
\n
"
,
jv
,
row
,
col
,
stm
);
if
(
col
==
0
||
col
>
jv
->
columns
)
return
ERROR_FUNCTION_FAILED
;
if
(
row
>=
jv
->
rows
)
return
ERROR_FUNCTION_FAILED
;
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
if
(
col
<=
cols
+
table
->
columns
)
{
row
=
(
row
%
(
jv
->
rows
/
table
->
next_rows
))
/
prev_rows
;
col
-=
cols
;
break
;
}
prev_rows
*=
table
->
rows
;
cols
+=
table
->
columns
;
}
return
table
->
view
->
ops
->
fetch_stream
(
table
->
view
,
row
,
col
,
stm
);
}
static
UINT
JOIN_get_row
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
MSIRECORD
**
rec
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
TRACE
(
"%p %d %p
\n
"
,
jv
,
row
,
rec
);
return
msi_view_get_row
(
jv
->
db
,
view
,
row
,
rec
);
}
static
UINT
JOIN_execute
(
struct
tagMSIVIEW
*
view
,
MSIRECORD
*
record
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
UINT
r
,
rows
;
TRACE
(
"%p %p
\n
"
,
jv
,
record
);
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
table
->
view
->
ops
->
execute
(
table
->
view
,
NULL
);
r
=
table
->
view
->
ops
->
get_dimensions
(
table
->
view
,
&
table
->
rows
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"failed to get table dimensions
\n
"
);
return
r
;
}
/* each table must have at least one row */
if
(
table
->
rows
==
0
)
{
jv
->
rows
=
0
;
return
ERROR_SUCCESS
;
}
if
(
jv
->
rows
==
0
)
jv
->
rows
=
table
->
rows
;
else
jv
->
rows
*=
table
->
rows
;
}
rows
=
jv
->
rows
;
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
rows
/=
table
->
rows
;
table
->
next_rows
=
rows
;
}
return
ERROR_SUCCESS
;
}
static
UINT
JOIN_close
(
struct
tagMSIVIEW
*
view
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
TRACE
(
"%p
\n
"
,
jv
);
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
table
->
view
->
ops
->
close
(
table
->
view
);
}
return
ERROR_SUCCESS
;
}
static
UINT
JOIN_get_dimensions
(
struct
tagMSIVIEW
*
view
,
UINT
*
rows
,
UINT
*
cols
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
TRACE
(
"%p %p %p
\n
"
,
jv
,
rows
,
cols
);
if
(
cols
)
*
cols
=
jv
->
columns
;
if
(
rows
)
*
rows
=
jv
->
rows
;
return
ERROR_SUCCESS
;
}
static
UINT
JOIN_get_column_info
(
struct
tagMSIVIEW
*
view
,
UINT
n
,
LPCWSTR
*
name
,
UINT
*
type
,
BOOL
*
temporary
,
LPCWSTR
*
table_name
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
UINT
cols
=
0
;
TRACE
(
"%p %d %p %p %p %p
\n
"
,
jv
,
n
,
name
,
type
,
temporary
,
table_name
);
if
(
n
==
0
||
n
>
jv
->
columns
)
return
ERROR_FUNCTION_FAILED
;
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
if
(
n
<=
cols
+
table
->
columns
)
return
table
->
view
->
ops
->
get_column_info
(
table
->
view
,
n
-
cols
,
name
,
type
,
temporary
,
table_name
);
cols
+=
table
->
columns
;
}
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
join_find_row
(
MSIJOINVIEW
*
jv
,
MSIRECORD
*
rec
,
UINT
*
row
)
{
LPCWSTR
str
;
UINT
r
,
i
,
id
,
data
;
str
=
MSI_RecordGetString
(
rec
,
1
);
r
=
msi_string2idW
(
jv
->
db
->
strings
,
str
,
&
id
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
for
(
i
=
0
;
i
<
jv
->
rows
;
i
++
)
{
JOIN_fetch_int
(
&
jv
->
view
,
i
,
1
,
&
data
);
if
(
data
==
id
)
{
*
row
=
i
;
return
ERROR_SUCCESS
;
}
}
return
ERROR_FUNCTION_FAILED
;
}
static
UINT
JOIN_set_row
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
MSIRECORD
*
rec
,
UINT
mask
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
UINT
i
,
reduced_mask
=
0
,
r
=
ERROR_SUCCESS
,
offset
=
0
,
col_count
;
MSIRECORD
*
reduced
;
TRACE
(
"%p %d %p %u %08x
\n
"
,
jv
,
row
,
rec
,
rec
->
count
,
mask
);
if
(
mask
>=
1
<<
jv
->
columns
)
return
ERROR_INVALID_PARAMETER
;
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
r
=
table
->
view
->
ops
->
get_dimensions
(
table
->
view
,
NULL
,
&
col_count
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
reduced
=
MSI_CreateRecord
(
col_count
);
if
(
!
reduced
)
return
ERROR_FUNCTION_FAILED
;
for
(
i
=
0
;
i
<
col_count
;
i
++
)
{
r
=
MSI_RecordCopyField
(
rec
,
i
+
offset
+
1
,
reduced
,
i
+
1
);
if
(
r
!=
ERROR_SUCCESS
)
break
;
}
offset
+=
col_count
;
reduced_mask
=
mask
>>
(
jv
->
columns
-
offset
)
&
((
1
<<
col_count
)
-
1
);
if
(
r
==
ERROR_SUCCESS
)
r
=
table
->
view
->
ops
->
set_row
(
table
->
view
,
row
,
reduced
,
reduced_mask
);
msiobj_release
(
&
reduced
->
hdr
);
}
return
r
;
}
static
UINT
join_modify_update
(
struct
tagMSIVIEW
*
view
,
MSIRECORD
*
rec
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
UINT
r
,
row
;
r
=
join_find_row
(
jv
,
rec
,
&
row
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
return
JOIN_set_row
(
view
,
row
,
rec
,
(
1
<<
jv
->
columns
)
-
1
);
}
static
UINT
JOIN_modify
(
struct
tagMSIVIEW
*
view
,
MSIMODIFY
mode
,
MSIRECORD
*
rec
,
UINT
row
)
{
UINT
r
;
TRACE
(
"%p %d %p %u
\n
"
,
view
,
mode
,
rec
,
row
);
switch
(
mode
)
{
case
MSIMODIFY_UPDATE
:
return
join_modify_update
(
view
,
rec
);
case
MSIMODIFY_ASSIGN
:
case
MSIMODIFY_DELETE
:
case
MSIMODIFY_INSERT
:
case
MSIMODIFY_INSERT_TEMPORARY
:
case
MSIMODIFY_MERGE
:
case
MSIMODIFY_REPLACE
:
case
MSIMODIFY_SEEK
:
case
MSIMODIFY_VALIDATE
:
case
MSIMODIFY_VALIDATE_DELETE
:
case
MSIMODIFY_VALIDATE_FIELD
:
case
MSIMODIFY_VALIDATE_NEW
:
r
=
ERROR_FUNCTION_FAILED
;
break
;
case
MSIMODIFY_REFRESH
:
r
=
ERROR_CALL_NOT_IMPLEMENTED
;
break
;
default:
WARN
(
"%p %d %p %u - unknown mode
\n
"
,
view
,
mode
,
rec
,
row
);
r
=
ERROR_INVALID_PARAMETER
;
break
;
}
return
r
;
}
static
UINT
JOIN_delete
(
struct
tagMSIVIEW
*
view
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
struct
list
*
item
,
*
cursor
;
TRACE
(
"%p
\n
"
,
jv
);
LIST_FOR_EACH_SAFE
(
item
,
cursor
,
&
jv
->
tables
)
{
JOINTABLE
*
table
=
LIST_ENTRY
(
item
,
JOINTABLE
,
entry
);
list_remove
(
&
table
->
entry
);
table
->
view
->
ops
->
delete
(
table
->
view
);
table
->
view
=
NULL
;
msi_free
(
table
);
}
msi_free
(
jv
);
return
ERROR_SUCCESS
;
}
static
UINT
JOIN_find_matching_rows
(
struct
tagMSIVIEW
*
view
,
UINT
col
,
UINT
val
,
UINT
*
row
,
MSIITERHANDLE
*
handle
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
UINT
i
,
row_value
;
TRACE
(
"%p, %d, %u, %p
\n
"
,
view
,
col
,
val
,
*
handle
);
if
(
col
==
0
||
col
>
jv
->
columns
)
return
ERROR_INVALID_PARAMETER
;
for
(
i
=
PtrToUlong
(
*
handle
);
i
<
jv
->
rows
;
i
++
)
{
if
(
view
->
ops
->
fetch_int
(
view
,
i
,
col
,
&
row_value
)
!=
ERROR_SUCCESS
)
continue
;
if
(
row_value
==
val
)
{
*
row
=
i
;
(
*
(
UINT
*
)
handle
)
=
i
+
1
;
return
ERROR_SUCCESS
;
}
}
return
ERROR_NO_MORE_ITEMS
;
}
static
UINT
JOIN_sort
(
struct
tagMSIVIEW
*
view
,
column_info
*
columns
)
{
MSIJOINVIEW
*
jv
=
(
MSIJOINVIEW
*
)
view
;
JOINTABLE
*
table
;
UINT
r
;
TRACE
(
"%p %p
\n
"
,
view
,
columns
);
LIST_FOR_EACH_ENTRY
(
table
,
&
jv
->
tables
,
JOINTABLE
,
entry
)
{
r
=
table
->
view
->
ops
->
sort
(
table
->
view
,
columns
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
}
return
ERROR_SUCCESS
;
}
static
const
MSIVIEWOPS
join_ops
=
{
JOIN_fetch_int
,
JOIN_fetch_stream
,
JOIN_get_row
,
NULL
,
NULL
,
NULL
,
JOIN_execute
,
JOIN_close
,
JOIN_get_dimensions
,
JOIN_get_column_info
,
JOIN_modify
,
JOIN_delete
,
JOIN_find_matching_rows
,
NULL
,
NULL
,
NULL
,
NULL
,
JOIN_sort
,
NULL
,
};
UINT
JOIN_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPWSTR
tables
)
{
MSIJOINVIEW
*
jv
=
NULL
;
UINT
r
=
ERROR_SUCCESS
;
JOINTABLE
*
table
;
LPWSTR
ptr
;
TRACE
(
"%p (%s)
\n
"
,
jv
,
debugstr_w
(
tables
)
);
jv
=
msi_alloc_zero
(
sizeof
*
jv
);
if
(
!
jv
)
return
ERROR_FUNCTION_FAILED
;
/* fill the structure */
jv
->
view
.
ops
=
&
join_ops
;
jv
->
db
=
db
;
jv
->
columns
=
0
;
jv
->
rows
=
0
;
list_init
(
&
jv
->
tables
);
while
(
*
tables
)
{
if
((
ptr
=
strchrW
(
tables
,
' '
)))
*
ptr
=
'\0'
;
table
=
msi_alloc
(
sizeof
(
JOINTABLE
));
if
(
!
table
)
{
r
=
ERROR_OUTOFMEMORY
;
goto
end
;
}
r
=
TABLE_CreateView
(
db
,
tables
,
&
table
->
view
);
if
(
r
!=
ERROR_SUCCESS
)
{
WARN
(
"can't create table: %s
\n
"
,
debugstr_w
(
tables
));
msi_free
(
table
);
r
=
ERROR_BAD_QUERY_SYNTAX
;
goto
end
;
}
r
=
table
->
view
->
ops
->
get_dimensions
(
table
->
view
,
NULL
,
&
table
->
columns
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"can't get table dimensions
\n
"
);
goto
end
;
}
jv
->
columns
+=
table
->
columns
;
list_add_head
(
&
jv
->
tables
,
&
table
->
entry
);
if
(
!
ptr
)
break
;
tables
=
ptr
+
1
;
}
*
view
=
&
jv
->
view
;
return
ERROR_SUCCESS
;
end:
jv
->
view
.
ops
->
delete
(
&
jv
->
view
);
return
r
;
}
dlls/msi/query.h
View file @
0fd49432
...
...
@@ -123,8 +123,6 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
UINT
DELETE_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
)
DECLSPEC_HIDDEN
;
UINT
JOIN_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPWSTR
tables
)
DECLSPEC_HIDDEN
;
UINT
ALTER_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPCWSTR
name
,
column_info
*
colinfo
,
int
hold
)
DECLSPEC_HIDDEN
;
UINT
STREAMS_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
)
DECLSPEC_HIDDEN
;
...
...
dlls/msi/sql.y
View file @
0fd49432
...
...
@@ -490,6 +490,18 @@ from:
PARSER_BUBBLE_UP_VIEW( sql, $$, where );
}
| TK_FROM tablelist
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* where = NULL;
UINT r;
r = WHERE_CreateView( sql->db, &where, $2, NULL );
if( r != ERROR_SUCCESS )
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, $$, where );
}
;
fromtable:
...
...
@@ -505,18 +517,6 @@ fromtable:
PARSER_BUBBLE_UP_VIEW( sql, $$, table );
}
| TK_FROM tablelist
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* join = NULL;
UINT r;
r = JOIN_CreateView( sql->db, &join, $2 );
if( r != ERROR_SUCCESS )
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, $$, join );
}
;
tablelist:
...
...
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