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
91c205e8
Commit
91c205e8
authored
Dec 17, 2007
by
James Hawkins
Committed by
Alexandre Julliard
Dec 18, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Sort each table of the join separately.
parent
f93ee6f4
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
258 additions
and
454 deletions
+258
-454
Makefile.in
dlls/msi/Makefile.in
+0
-1
alter.c
dlls/msi/alter.c
+1
-0
create.c
dlls/msi/create.c
+1
-0
distinct.c
dlls/msi/distinct.c
+9
-0
insert.c
dlls/msi/insert.c
+1
-0
join.c
dlls/msi/join.c
+19
-0
msipriv.h
dlls/msi/msipriv.h
+15
-0
order.c
dlls/msi/order.c
+0
-376
query.h
dlls/msi/query.h
+0
-10
select.c
dlls/msi/select.c
+9
-0
sql.y
dlls/msi/sql.y
+8
-7
streams.c
dlls/msi/streams.c
+1
-0
table.c
dlls/msi/table.c
+170
-0
db.c
dlls/msi/tests/db.c
+15
-60
where.c
dlls/msi/where.c
+9
-0
No files found.
dlls/msi/Makefile.in
View file @
91c205e8
...
@@ -32,7 +32,6 @@ C_SRCS = \
...
@@ -32,7 +32,6 @@ C_SRCS = \
msi.c
\
msi.c
\
msi_main.c
\
msi_main.c
\
msiquery.c
\
msiquery.c
\
order.c
\
package.c
\
package.c
\
preview.c
\
preview.c
\
record.c
\
record.c
\
...
...
dlls/msi/alter.c
View file @
91c205e8
...
@@ -241,6 +241,7 @@ static const MSIVIEWOPS alter_ops =
...
@@ -241,6 +241,7 @@ static const MSIVIEWOPS alter_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
};
};
UINT
ALTER_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPCWSTR
name
,
column_info
*
colinfo
,
int
hold
)
UINT
ALTER_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPCWSTR
name
,
column_info
*
colinfo
,
int
hold
)
...
...
dlls/msi/create.c
View file @
91c205e8
...
@@ -136,6 +136,7 @@ static const MSIVIEWOPS create_ops =
...
@@ -136,6 +136,7 @@ static const MSIVIEWOPS create_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
};
};
static
UINT
check_columns
(
column_info
*
col_info
)
static
UINT
check_columns
(
column_info
*
col_info
)
...
...
dlls/msi/distinct.c
View file @
91c205e8
...
@@ -267,6 +267,14 @@ static UINT DISTINCT_find_matching_rows( struct tagMSIVIEW *view, UINT col,
...
@@ -267,6 +267,14 @@ static UINT DISTINCT_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return
r
;
return
r
;
}
}
static
UINT
DISTINCT_sort
(
struct
tagMSIVIEW
*
view
,
column_info
*
columns
)
{
MSIDISTINCTVIEW
*
dv
=
(
MSIDISTINCTVIEW
*
)
view
;
TRACE
(
"%p %p
\n
"
,
view
,
columns
);
return
dv
->
table
->
ops
->
sort
(
dv
->
table
,
columns
);
}
static
const
MSIVIEWOPS
distinct_ops
=
static
const
MSIVIEWOPS
distinct_ops
=
{
{
...
@@ -287,6 +295,7 @@ static const MSIVIEWOPS distinct_ops =
...
@@ -287,6 +295,7 @@ static const MSIVIEWOPS distinct_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
DISTINCT_sort
,
};
};
UINT
DISTINCT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
)
UINT
DISTINCT_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
)
...
...
dlls/msi/insert.c
View file @
91c205e8
...
@@ -238,6 +238,7 @@ static const MSIVIEWOPS insert_ops =
...
@@ -238,6 +238,7 @@ static const MSIVIEWOPS insert_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
};
};
static
UINT
count_column_info
(
const
column_info
*
ci
)
static
UINT
count_column_info
(
const
column_info
*
ci
)
...
...
dlls/msi/join.c
View file @
91c205e8
...
@@ -268,6 +268,24 @@ static UINT JOIN_find_matching_rows( struct tagMSIVIEW *view, UINT col,
...
@@ -268,6 +268,24 @@ static UINT JOIN_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return
ERROR_NO_MORE_ITEMS
;
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
=
static
const
MSIVIEWOPS
join_ops
=
{
{
JOIN_fetch_int
,
JOIN_fetch_int
,
...
@@ -287,6 +305,7 @@ static const MSIVIEWOPS join_ops =
...
@@ -287,6 +305,7 @@ static const MSIVIEWOPS join_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
JOIN_sort
,
};
};
UINT
JOIN_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPWSTR
tables
)
UINT
JOIN_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
LPWSTR
tables
)
...
...
dlls/msi/msipriv.h
View file @
91c205e8
...
@@ -133,6 +133,16 @@ typedef struct tagMSIMEDIADISK
...
@@ -133,6 +133,16 @@ typedef struct tagMSIMEDIADISK
LPWSTR
disk_prompt
;
LPWSTR
disk_prompt
;
}
MSIMEDIADISK
;
}
MSIMEDIADISK
;
typedef
struct
_column_info
{
LPCWSTR
table
;
LPCWSTR
column
;
INT
type
;
BOOL
temporary
;
struct
expr
*
val
;
struct
_column_info
*
next
;
}
column_info
;
typedef
const
struct
tagMSICOLUMNHASHENTRY
*
MSIITERHANDLE
;
typedef
const
struct
tagMSICOLUMNHASHENTRY
*
MSIITERHANDLE
;
typedef
struct
tagMSIVIEWOPS
typedef
struct
tagMSIVIEWOPS
...
@@ -248,6 +258,11 @@ typedef struct tagMSIVIEWOPS
...
@@ -248,6 +258,11 @@ typedef struct tagMSIVIEWOPS
* remove_column - removes the column represented by table name and column number from the table
* remove_column - removes the column represented by table name and column number from the table
*/
*/
UINT
(
*
remove_column
)(
struct
tagMSIVIEW
*
view
,
LPCWSTR
table
,
UINT
number
);
UINT
(
*
remove_column
)(
struct
tagMSIVIEW
*
view
,
LPCWSTR
table
,
UINT
number
);
/*
* sort - orders the table by columns
*/
UINT
(
*
sort
)(
struct
tagMSIVIEW
*
view
,
column_info
*
columns
);
}
MSIVIEWOPS
;
}
MSIVIEWOPS
;
struct
tagMSIVIEW
struct
tagMSIVIEW
...
...
dlls/msi/order.c
deleted
100644 → 0
View file @
f93ee6f4
/*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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
(
msidb
);
/* below is the query interface to a table */
typedef
struct
tagMSIORDERVIEW
{
MSIVIEW
view
;
MSIDATABASE
*
db
;
MSIVIEW
*
table
;
UINT
*
reorder
;
UINT
num_cols
;
UINT
cols
[
1
];
}
MSIORDERVIEW
;
static
UINT
ORDER_compare
(
MSIORDERVIEW
*
ov
,
UINT
a
,
UINT
b
,
UINT
*
swap
)
{
UINT
r
,
i
,
a_val
=
0
,
b_val
=
0
;
*
swap
=
0
;
for
(
i
=
0
;
i
<
ov
->
num_cols
;
i
++
)
{
r
=
ov
->
table
->
ops
->
fetch_int
(
ov
->
table
,
a
,
ov
->
cols
[
i
],
&
a_val
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
ov
->
table
->
ops
->
fetch_int
(
ov
->
table
,
b
,
ov
->
cols
[
i
],
&
b_val
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
a_val
!=
b_val
)
{
if
(
a_val
>
b_val
)
*
swap
=
1
;
break
;
}
}
return
ERROR_SUCCESS
;
}
static
UINT
ORDER_mergesort
(
MSIORDERVIEW
*
ov
,
UINT
left
,
UINT
right
)
{
UINT
r
,
centre
=
(
left
+
right
)
/
2
,
temp
,
swap
=
0
,
i
,
j
;
UINT
*
array
=
ov
->
reorder
;
if
(
left
==
right
)
return
ERROR_SUCCESS
;
/* sort the left half */
r
=
ORDER_mergesort
(
ov
,
left
,
centre
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
/* sort the right half */
r
=
ORDER_mergesort
(
ov
,
centre
+
1
,
right
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
for
(
i
=
left
,
j
=
centre
+
1
;
(
i
<=
centre
)
&&
(
j
<=
right
);
i
++
)
{
r
=
ORDER_compare
(
ov
,
array
[
i
],
array
[
j
],
&
swap
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
swap
)
{
temp
=
array
[
j
];
memmove
(
&
array
[
i
+
1
],
&
array
[
i
],
(
j
-
i
)
*
sizeof
(
UINT
)
);
array
[
i
]
=
temp
;
j
++
;
centre
++
;
}
}
return
ERROR_SUCCESS
;
}
static
UINT
ORDER_verify
(
MSIORDERVIEW
*
ov
,
UINT
num_rows
)
{
UINT
i
,
swap
,
r
;
for
(
i
=
1
;
i
<
num_rows
;
i
++
)
{
r
=
ORDER_compare
(
ov
,
ov
->
reorder
[
i
-
1
],
ov
->
reorder
[
i
],
&
swap
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
!
swap
)
continue
;
ERR
(
"Bad order! %d
\n
"
,
i
);
return
ERROR_FUNCTION_FAILED
;
}
return
ERROR_SUCCESS
;
}
static
UINT
ORDER_fetch_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
*
val
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p %d %d %p
\n
"
,
ov
,
row
,
col
,
val
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
row
=
ov
->
reorder
[
row
];
return
ov
->
table
->
ops
->
fetch_int
(
ov
->
table
,
row
,
col
,
val
);
}
static
UINT
ORDER_get_row
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
MSIRECORD
**
rec
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p %d %p
\n
"
,
ov
,
row
,
rec
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
row
=
ov
->
reorder
[
row
];
return
ov
->
table
->
ops
->
get_row
(
ov
->
table
,
row
,
rec
);
}
static
UINT
ORDER_execute
(
struct
tagMSIVIEW
*
view
,
MSIRECORD
*
record
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
UINT
r
,
num_rows
=
0
,
i
;
TRACE
(
"%p %p
\n
"
,
ov
,
record
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
r
=
ov
->
table
->
ops
->
execute
(
ov
->
table
,
record
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
ov
->
table
->
ops
->
get_dimensions
(
ov
->
table
,
&
num_rows
,
NULL
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
ov
->
reorder
=
msi_alloc
(
num_rows
*
sizeof
(
UINT
)
);
if
(
!
ov
->
reorder
)
return
ERROR_FUNCTION_FAILED
;
for
(
i
=
0
;
i
<
num_rows
;
i
++
)
ov
->
reorder
[
i
]
=
i
;
r
=
ORDER_mergesort
(
ov
,
0
,
num_rows
-
1
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
ORDER_verify
(
ov
,
num_rows
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
return
ERROR_SUCCESS
;
}
static
UINT
ORDER_close
(
struct
tagMSIVIEW
*
view
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p
\n
"
,
ov
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
msi_free
(
ov
->
reorder
);
ov
->
reorder
=
NULL
;
return
ov
->
table
->
ops
->
close
(
ov
->
table
);
}
static
UINT
ORDER_get_dimensions
(
struct
tagMSIVIEW
*
view
,
UINT
*
rows
,
UINT
*
cols
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p %p %p
\n
"
,
ov
,
rows
,
cols
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
return
ov
->
table
->
ops
->
get_dimensions
(
ov
->
table
,
rows
,
cols
);
}
static
UINT
ORDER_get_column_info
(
struct
tagMSIVIEW
*
view
,
UINT
n
,
LPWSTR
*
name
,
UINT
*
type
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p %d %p %p
\n
"
,
ov
,
n
,
name
,
type
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
return
ov
->
table
->
ops
->
get_column_info
(
ov
->
table
,
n
,
name
,
type
);
}
static
UINT
ORDER_modify
(
struct
tagMSIVIEW
*
view
,
MSIMODIFY
eModifyMode
,
MSIRECORD
*
rec
,
UINT
row
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p %d %p
\n
"
,
ov
,
eModifyMode
,
rec
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
return
ov
->
table
->
ops
->
modify
(
ov
->
table
,
eModifyMode
,
rec
,
row
);
}
static
UINT
ORDER_delete
(
struct
tagMSIVIEW
*
view
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
TRACE
(
"%p
\n
"
,
ov
);
if
(
ov
->
table
)
ov
->
table
->
ops
->
delete
(
ov
->
table
);
msi_free
(
ov
->
reorder
);
ov
->
reorder
=
NULL
;
msiobj_release
(
&
ov
->
db
->
hdr
);
msi_free
(
ov
);
return
ERROR_SUCCESS
;
}
static
UINT
ORDER_find_matching_rows
(
struct
tagMSIVIEW
*
view
,
UINT
col
,
UINT
val
,
UINT
*
row
,
MSIITERHANDLE
*
handle
)
{
MSIORDERVIEW
*
ov
=
(
MSIORDERVIEW
*
)
view
;
UINT
r
;
TRACE
(
"%p, %d, %u, %p
\n
"
,
ov
,
col
,
val
,
*
handle
);
if
(
!
ov
->
table
)
return
ERROR_FUNCTION_FAILED
;
r
=
ov
->
table
->
ops
->
find_matching_rows
(
ov
->
table
,
col
,
val
,
row
,
handle
);
*
row
=
ov
->
reorder
[
*
row
];
return
r
;
}
static
const
MSIVIEWOPS
order_ops
=
{
ORDER_fetch_int
,
NULL
,
ORDER_get_row
,
NULL
,
NULL
,
NULL
,
ORDER_execute
,
ORDER_close
,
ORDER_get_dimensions
,
ORDER_get_column_info
,
ORDER_modify
,
ORDER_delete
,
ORDER_find_matching_rows
,
NULL
,
NULL
,
NULL
,
NULL
,
};
static
UINT
ORDER_AddColumn
(
MSIORDERVIEW
*
ov
,
LPCWSTR
name
)
{
UINT
n
,
count
,
r
;
MSIVIEW
*
table
;
TRACE
(
"%p adding %s
\n
"
,
ov
,
debugstr_w
(
name
)
);
if
(
ov
->
view
.
ops
!=
&
order_ops
)
return
ERROR_FUNCTION_FAILED
;
table
=
ov
->
table
;
if
(
!
table
)
return
ERROR_FUNCTION_FAILED
;
if
(
!
table
->
ops
->
get_dimensions
)
return
ERROR_FUNCTION_FAILED
;
if
(
!
table
->
ops
->
get_column_info
)
return
ERROR_FUNCTION_FAILED
;
r
=
table
->
ops
->
get_dimensions
(
table
,
NULL
,
&
count
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
ov
->
num_cols
>=
count
)
return
ERROR_FUNCTION_FAILED
;
r
=
VIEW_find_column
(
table
,
name
,
&
n
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
ov
->
cols
[
ov
->
num_cols
]
=
n
;
TRACE
(
"Ordering by column %s (%d)
\n
"
,
debugstr_w
(
name
),
n
);
ov
->
num_cols
++
;
return
ERROR_SUCCESS
;
}
UINT
ORDER_CreateView
(
MSIDATABASE
*
db
,
MSIVIEW
**
view
,
MSIVIEW
*
table
,
column_info
*
columns
)
{
MSIORDERVIEW
*
ov
=
NULL
;
UINT
count
=
0
,
r
;
column_info
*
x
;
TRACE
(
"%p
\n
"
,
ov
);
r
=
table
->
ops
->
get_dimensions
(
table
,
NULL
,
&
count
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"can't get table dimensions
\n
"
);
return
r
;
}
ov
=
msi_alloc_zero
(
sizeof
*
ov
+
sizeof
(
UINT
)
*
count
);
if
(
!
ov
)
return
ERROR_FUNCTION_FAILED
;
/* fill the structure */
ov
->
view
.
ops
=
&
order_ops
;
msiobj_addref
(
&
db
->
hdr
);
ov
->
db
=
db
;
ov
->
table
=
table
;
ov
->
reorder
=
NULL
;
ov
->
num_cols
=
0
;
*
view
=
(
MSIVIEW
*
)
ov
;
for
(
x
=
columns
;
x
;
x
=
x
->
next
)
ORDER_AddColumn
(
ov
,
x
->
column
);
return
ERROR_SUCCESS
;
}
dlls/msi/query.h
View file @
91c205e8
...
@@ -61,16 +61,6 @@ struct sql_str {
...
@@ -61,16 +61,6 @@ struct sql_str {
INT
len
;
INT
len
;
};
};
typedef
struct
_column_info
{
LPCWSTR
table
;
LPCWSTR
column
;
UINT
type
;
BOOL
temporary
;
struct
expr
*
val
;
struct
_column_info
*
next
;
}
column_info
;
struct
complex_expr
struct
complex_expr
{
{
UINT
op
;
UINT
op
;
...
...
dlls/msi/select.c
View file @
91c205e8
...
@@ -334,6 +334,14 @@ static UINT SELECT_find_matching_rows( struct tagMSIVIEW *view, UINT col,
...
@@ -334,6 +334,14 @@ static UINT SELECT_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return
sv
->
table
->
ops
->
find_matching_rows
(
sv
->
table
,
col
,
val
,
row
,
handle
);
return
sv
->
table
->
ops
->
find_matching_rows
(
sv
->
table
,
col
,
val
,
row
,
handle
);
}
}
static
UINT
SELECT_sort
(
struct
tagMSIVIEW
*
view
,
column_info
*
columns
)
{
MSISELECTVIEW
*
sv
=
(
MSISELECTVIEW
*
)
view
;
TRACE
(
"%p %p
\n
"
,
view
,
columns
);
return
sv
->
table
->
ops
->
sort
(
sv
->
table
,
columns
);
}
static
const
MSIVIEWOPS
select_ops
=
static
const
MSIVIEWOPS
select_ops
=
{
{
...
@@ -354,6 +362,7 @@ static const MSIVIEWOPS select_ops =
...
@@ -354,6 +362,7 @@ static const MSIVIEWOPS select_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
SELECT_sort
,
};
};
static
UINT
SELECT_AddColumn
(
MSISELECTVIEW
*
sv
,
LPCWSTR
name
)
static
UINT
SELECT_AddColumn
(
MSISELECTVIEW
*
sv
,
LPCWSTR
name
)
...
...
dlls/msi/sql.y
View file @
91c205e8
...
@@ -373,15 +373,16 @@ data_count:
...
@@ -373,15 +373,16 @@ data_count:
oneselect:
oneselect:
unorderedsel TK_ORDER TK_BY selcollist
unorderedsel TK_ORDER TK_BY selcollist
{
{
SQL_input* sql = (SQL_input*) info
;
UINT r
;
$$ = NULL;
if( $4 )
if( $4 )
ORDER_CreateView( sql->db, &$$, $1, $4 );
{
else
r = $1->ops->sort( $1, $4 );
$$ = $1;
if ( r != ERROR_SUCCESS)
if( !$$ )
YYABORT;
YYABORT;
}
$$ = $1;
}
}
| unorderedsel
| unorderedsel
;
;
...
...
dlls/msi/streams.c
View file @
91c205e8
...
@@ -379,6 +379,7 @@ static const MSIVIEWOPS streams_ops =
...
@@ -379,6 +379,7 @@ static const MSIVIEWOPS streams_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
};
};
static
UINT
add_streams_to_table
(
MSISTREAMSVIEW
*
sv
)
static
UINT
add_streams_to_table
(
MSISTREAMSVIEW
*
sv
)
...
...
dlls/msi/table.c
View file @
91c205e8
...
@@ -62,6 +62,13 @@ typedef struct tagMSICOLUMNINFO
...
@@ -62,6 +62,13 @@ typedef struct tagMSICOLUMNINFO
MSICOLUMNHASHENTRY
**
hash_table
;
MSICOLUMNHASHENTRY
**
hash_table
;
}
MSICOLUMNINFO
;
}
MSICOLUMNINFO
;
typedef
struct
tagMSIORDERINFO
{
UINT
*
reorder
;
UINT
num_cols
;
UINT
cols
[
1
];
}
MSIORDERINFO
;
struct
tagMSITABLE
struct
tagMSITABLE
{
{
BYTE
**
data
;
BYTE
**
data
;
...
@@ -1114,6 +1121,7 @@ typedef struct tagMSITABLEVIEW
...
@@ -1114,6 +1121,7 @@ typedef struct tagMSITABLEVIEW
MSIDATABASE
*
db
;
MSIDATABASE
*
db
;
MSITABLE
*
table
;
MSITABLE
*
table
;
MSICOLUMNINFO
*
columns
;
MSICOLUMNINFO
*
columns
;
MSIORDERINFO
*
order
;
UINT
num_cols
;
UINT
num_cols
;
UINT
row_size
;
UINT
row_size
;
WCHAR
name
[
1
];
WCHAR
name
[
1
];
...
@@ -1142,6 +1150,9 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
...
@@ -1142,6 +1150,9 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
return
ERROR_FUNCTION_FAILED
;
return
ERROR_FUNCTION_FAILED
;
}
}
if
(
tv
->
order
)
row
=
tv
->
order
->
reorder
[
row
];
if
(
row
>=
tv
->
table
->
row_count
)
if
(
row
>=
tv
->
table
->
row_count
)
{
{
row
-=
tv
->
table
->
row_count
;
row
-=
tv
->
table
->
row_count
;
...
@@ -1286,6 +1297,9 @@ static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
...
@@ -1286,6 +1297,9 @@ static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
if
(
!
tv
->
table
)
if
(
!
tv
->
table
)
return
ERROR_INVALID_PARAMETER
;
return
ERROR_INVALID_PARAMETER
;
if
(
tv
->
order
)
row
=
tv
->
order
->
reorder
[
row
];
return
msi_view_get_row
(
tv
->
db
,
view
,
row
,
rec
);
return
msi_view_get_row
(
tv
->
db
,
view
,
row
,
rec
);
}
}
...
@@ -1728,6 +1742,10 @@ static UINT TABLE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
...
@@ -1728,6 +1742,10 @@ static UINT TABLE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return
ERROR_NO_MORE_ITEMS
;
return
ERROR_NO_MORE_ITEMS
;
*
row
=
entry
->
row
;
*
row
=
entry
->
row
;
if
(
tv
->
order
)
*
row
=
tv
->
order
->
reorder
[
*
row
];
return
ERROR_SUCCESS
;
return
ERROR_SUCCESS
;
}
}
...
@@ -1860,6 +1878,157 @@ done:
...
@@ -1860,6 +1878,157 @@ done:
return
r
;
return
r
;
}
}
static
UINT
order_add_column
(
struct
tagMSIVIEW
*
view
,
MSIORDERINFO
*
order
,
LPCWSTR
name
)
{
UINT
n
,
r
,
count
;
r
=
TABLE_get_dimensions
(
view
,
NULL
,
&
count
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
order
->
num_cols
>=
count
)
return
ERROR_FUNCTION_FAILED
;
r
=
VIEW_find_column
(
view
,
name
,
&
n
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
order
->
cols
[
order
->
num_cols
]
=
n
;
TRACE
(
"Ordering by column %s (%d)
\n
"
,
debugstr_w
(
name
),
n
);
order
->
num_cols
++
;
return
ERROR_SUCCESS
;
}
static
UINT
order_compare
(
struct
tagMSIVIEW
*
view
,
MSIORDERINFO
*
order
,
UINT
a
,
UINT
b
,
UINT
*
swap
)
{
UINT
r
,
i
,
a_val
=
0
,
b_val
=
0
;
*
swap
=
0
;
for
(
i
=
0
;
i
<
order
->
num_cols
;
i
++
)
{
r
=
TABLE_fetch_int
(
view
,
a
,
order
->
cols
[
i
],
&
a_val
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
TABLE_fetch_int
(
view
,
b
,
order
->
cols
[
i
],
&
b_val
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
a_val
!=
b_val
)
{
if
(
a_val
>
b_val
)
*
swap
=
1
;
break
;
}
}
return
ERROR_SUCCESS
;
}
static
UINT
order_mergesort
(
struct
tagMSIVIEW
*
view
,
MSIORDERINFO
*
order
,
UINT
left
,
UINT
right
)
{
UINT
r
,
i
,
j
,
temp
;
UINT
swap
=
0
,
center
=
(
left
+
right
)
/
2
;
UINT
*
array
=
order
->
reorder
;
if
(
left
==
right
)
return
ERROR_SUCCESS
;
/* sort the left half */
r
=
order_mergesort
(
view
,
order
,
left
,
center
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
/* sort the right half */
r
=
order_mergesort
(
view
,
order
,
center
+
1
,
right
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
for
(
i
=
left
,
j
=
center
+
1
;
(
i
<=
center
)
&&
(
j
<=
right
);
i
++
)
{
r
=
order_compare
(
view
,
order
,
array
[
i
],
array
[
j
],
&
swap
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
swap
)
{
temp
=
array
[
j
];
memmove
(
&
array
[
i
+
1
],
&
array
[
i
],
(
j
-
i
)
*
sizeof
(
UINT
));
array
[
i
]
=
temp
;
j
++
;
center
++
;
}
}
return
ERROR_SUCCESS
;
}
static
UINT
order_verify
(
struct
tagMSIVIEW
*
view
,
MSIORDERINFO
*
order
,
UINT
num_rows
)
{
UINT
i
,
swap
,
r
;
for
(
i
=
1
;
i
<
num_rows
;
i
++
)
{
r
=
order_compare
(
view
,
order
,
order
->
reorder
[
i
-
1
],
order
->
reorder
[
i
],
&
swap
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
!
swap
)
continue
;
ERR
(
"Bad order! %d
\n
"
,
i
);
return
ERROR_FUNCTION_FAILED
;
}
return
ERROR_SUCCESS
;
}
static
UINT
TABLE_sort
(
struct
tagMSIVIEW
*
view
,
column_info
*
columns
)
{
MSITABLEVIEW
*
tv
=
(
MSITABLEVIEW
*
)
view
;
MSIORDERINFO
*
order
;
column_info
*
ptr
;
UINT
r
,
i
;
UINT
rows
,
cols
;
TRACE
(
"sorting table %s
\n
"
,
debugstr_w
(
tv
->
name
));
r
=
TABLE_get_dimensions
(
view
,
&
rows
,
&
cols
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
order
=
msi_alloc_zero
(
sizeof
(
MSIORDERINFO
)
+
sizeof
(
UINT
)
*
cols
);
if
(
!
order
)
return
ERROR_OUTOFMEMORY
;
for
(
ptr
=
columns
;
ptr
;
ptr
=
ptr
->
next
)
order_add_column
(
view
,
order
,
ptr
->
column
);
order
->
reorder
=
msi_alloc
(
rows
*
sizeof
(
UINT
));
if
(
!
order
->
reorder
)
return
ERROR_OUTOFMEMORY
;
for
(
i
=
0
;
i
<
rows
;
i
++
)
order
->
reorder
[
i
]
=
i
;
r
=
order_mergesort
(
view
,
order
,
0
,
rows
-
1
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
r
=
order_verify
(
view
,
order
,
rows
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
tv
->
order
=
order
;
return
ERROR_SUCCESS
;
}
static
const
MSIVIEWOPS
table_ops
=
static
const
MSIVIEWOPS
table_ops
=
{
{
TABLE_fetch_int
,
TABLE_fetch_int
,
...
@@ -1879,6 +2048,7 @@ static const MSIVIEWOPS table_ops =
...
@@ -1879,6 +2048,7 @@ static const MSIVIEWOPS table_ops =
TABLE_release
,
TABLE_release
,
TABLE_add_column
,
TABLE_add_column
,
TABLE_remove_column
,
TABLE_remove_column
,
TABLE_sort
,
};
};
UINT
TABLE_CreateView
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSIVIEW
**
view
)
UINT
TABLE_CreateView
(
MSIDATABASE
*
db
,
LPCWSTR
name
,
MSIVIEW
**
view
)
...
...
dlls/msi/tests/db.c
View file @
91c205e8
...
@@ -4610,16 +4610,10 @@ static void test_order(void)
...
@@ -4610,16 +4610,10 @@ static void test_order(void)
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
val
=
MsiRecordGetInteger
(
hrec
,
1
);
val
=
MsiRecordGetInteger
(
hrec
,
1
);
todo_wine
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
{
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
}
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
4
,
"Expected 3, got %d
\n
"
,
val
);
{
ok
(
val
==
4
,
"Expected 3, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4627,16 +4621,10 @@ static void test_order(void)
...
@@ -4627,16 +4621,10 @@ static void test_order(void)
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
val
=
MsiRecordGetInteger
(
hrec
,
1
);
val
=
MsiRecordGetInteger
(
hrec
,
1
);
todo_wine
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
{
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
}
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
6
,
"Expected 6, got %d
\n
"
,
val
);
{
ok
(
val
==
6
,
"Expected 6, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4644,16 +4632,10 @@ static void test_order(void)
...
@@ -4644,16 +4632,10 @@ static void test_order(void)
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
r
);
val
=
MsiRecordGetInteger
(
hrec
,
1
);
val
=
MsiRecordGetInteger
(
hrec
,
1
);
todo_wine
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
{
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
}
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
2
,
"Expected 2, got %d
\n
"
,
val
);
{
ok
(
val
==
2
,
"Expected 2, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4673,10 +4655,7 @@ static void test_order(void)
...
@@ -4673,10 +4655,7 @@ static void test_order(void)
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
12
,
"Expected 12, got %d
\n
"
,
val
);
{
ok
(
val
==
12
,
"Expected 12, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4687,10 +4666,7 @@ static void test_order(void)
...
@@ -4687,10 +4666,7 @@ static void test_order(void)
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
12
,
"Expected 12, got %d
\n
"
,
val
);
{
ok
(
val
==
12
,
"Expected 12, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4701,10 +4677,7 @@ static void test_order(void)
...
@@ -4701,10 +4677,7 @@ static void test_order(void)
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
12
,
"Expected 12, got %d
\n
"
,
val
);
{
ok
(
val
==
12
,
"Expected 12, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4715,10 +4688,7 @@ static void test_order(void)
...
@@ -4715,10 +4688,7 @@ static void test_order(void)
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
14
,
"Expected 14, got %d
\n
"
,
val
);
{
ok
(
val
==
14
,
"Expected 14, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4729,10 +4699,7 @@ static void test_order(void)
...
@@ -4729,10 +4699,7 @@ static void test_order(void)
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
14
,
"Expected 14, got %d
\n
"
,
val
);
{
ok
(
val
==
14
,
"Expected 14, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4743,10 +4710,7 @@ static void test_order(void)
...
@@ -4743,10 +4710,7 @@ static void test_order(void)
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
14
,
"Expected 14, got %d
\n
"
,
val
);
{
ok
(
val
==
14
,
"Expected 14, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4757,10 +4721,7 @@ static void test_order(void)
...
@@ -4757,10 +4721,7 @@ static void test_order(void)
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
ok
(
val
==
1
,
"Expected 1, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
10
,
"Expected 10, got %d
\n
"
,
val
);
{
ok
(
val
==
10
,
"Expected 10, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4771,10 +4732,7 @@ static void test_order(void)
...
@@ -4771,10 +4732,7 @@ static void test_order(void)
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
ok
(
val
==
3
,
"Expected 3, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
10
,
"Expected 10, got %d
\n
"
,
val
);
{
ok
(
val
==
10
,
"Expected 10, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
@@ -4785,10 +4743,7 @@ static void test_order(void)
...
@@ -4785,10 +4743,7 @@ static void test_order(void)
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
ok
(
val
==
5
,
"Expected 5, got %d
\n
"
,
val
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
val
=
MsiRecordGetInteger
(
hrec
,
2
);
todo_wine
ok
(
val
==
10
,
"Expected 10, got %d
\n
"
,
val
);
{
ok
(
val
==
10
,
"Expected 10, got %d
\n
"
,
val
);
}
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hrec
);
...
...
dlls/msi/where.c
View file @
91c205e8
...
@@ -532,6 +532,14 @@ static UINT WHERE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
...
@@ -532,6 +532,14 @@ static UINT WHERE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return
find_entry_in_hash
(
wv
->
reorder
,
*
row
,
row
);
return
find_entry_in_hash
(
wv
->
reorder
,
*
row
,
row
);
}
}
static
UINT
WHERE_sort
(
struct
tagMSIVIEW
*
view
,
column_info
*
columns
)
{
MSIWHEREVIEW
*
wv
=
(
MSIWHEREVIEW
*
)
view
;
TRACE
(
"%p %p
\n
"
,
view
,
columns
);
return
wv
->
table
->
ops
->
sort
(
wv
->
table
,
columns
);
}
static
const
MSIVIEWOPS
where_ops
=
static
const
MSIVIEWOPS
where_ops
=
{
{
...
@@ -552,6 +560,7 @@ static const MSIVIEWOPS where_ops =
...
@@ -552,6 +560,7 @@ static const MSIVIEWOPS where_ops =
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
WHERE_sort
,
};
};
static
UINT
WHERE_VerifyCondition
(
MSIDATABASE
*
db
,
MSIVIEW
*
table
,
struct
expr
*
cond
,
static
UINT
WHERE_VerifyCondition
(
MSIDATABASE
*
db
,
MSIVIEW
*
table
,
struct
expr
*
cond
,
...
...
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