ReactOS 0.4.15-dev-7918-g2a2556c
distinct.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2002 Mike McCormack for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "winerror.h"
26#include "wine/debug.h"
27#include "msi.h"
28#include "msiquery.h"
29#include "objbase.h"
30#include "objidl.h"
31#include "msipriv.h"
32#include "winnls.h"
33
34#include "query.h"
35
37
38typedef struct tagDISTINCTSET
39{
46
47typedef struct tagMSIDISTINCTVIEW
48{
55
57{
58 /* horrible O(n) find */
59 while( *x )
60 {
61 if( (*x)->val == val )
62 {
63 (*x)->count++;
64 return x;
65 }
66 x = &(*x)->nextrow;
67 }
68
69 /* nothing found, so add one */
70 *x = msi_alloc( sizeof (DISTINCTSET) );
71 if( *x )
72 {
73 (*x)->val = val;
74 (*x)->count = 1;
75 (*x)->row = row;
76 (*x)->nextrow = NULL;
77 (*x)->nextcol = NULL;
78 }
79 return x;
80}
81
83{
84 while( x )
85 {
86 DISTINCTSET *next = x->nextrow;
87 distinct_free( x->nextcol );
88 msi_free( x );
89 x = next;
90 }
91}
92
94{
96
97 TRACE("%p %d %d %p\n", dv, row, col, val );
98
99 if( !dv->table )
101
102 if( row >= dv->row_count )
104
105 row = dv->translation[ row ];
106
107 return dv->table->ops->fetch_int( dv->table, row, col, val );
108}
109
111{
113 UINT r, i, j, r_count, c_count;
114 DISTINCTSET *rowset = NULL;
115
116 TRACE("%p %p\n", dv, record);
117
118 if( !dv->table )
120
121 r = dv->table->ops->execute( dv->table, record );
122 if( r != ERROR_SUCCESS )
123 return r;
124
125 r = dv->table->ops->get_dimensions( dv->table, &r_count, &c_count );
126 if( r != ERROR_SUCCESS )
127 return r;
128
129 dv->translation = msi_alloc( r_count*sizeof(UINT) );
130 if( !dv->translation )
132
133 /* build it */
134 for( i=0; i<r_count; i++ )
135 {
136 DISTINCTSET **x = &rowset;
137
138 for( j=1; j<=c_count; j++ )
139 {
140 UINT val = 0;
141 r = dv->table->ops->fetch_int( dv->table, i, j, &val );
142 if( r != ERROR_SUCCESS )
143 {
144 ERR("Failed to fetch int at %d %d\n", i, j );
145 distinct_free( rowset );
146 return r;
147 }
148 x = distinct_insert( x, val, i );
149 if( !*x )
150 {
151 ERR("Failed to insert at %d %d\n", i, j );
152 distinct_free( rowset );
154 }
155 if( j != c_count )
156 x = &(*x)->nextcol;
157 }
158
159 /* check if it was distinct and if so, include it */
160 if( (*x)->row == i )
161 {
162 TRACE("Row %d -> %d\n", dv->row_count, i);
163 dv->translation[dv->row_count++] = i;
164 }
165 }
166
167 distinct_free( rowset );
168
169 return ERROR_SUCCESS;
170}
171
173{
175
176 TRACE("%p\n", dv );
177
178 if( !dv->table )
180
181 msi_free( dv->translation );
182 dv->translation = NULL;
183 dv->row_count = 0;
184
185 return dv->table->ops->close( dv->table );
186}
187
188static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
189{
191
192 TRACE("%p %p %p\n", dv, rows, cols );
193
194 if( !dv->table )
196
197 if( rows )
198 {
199 if( !dv->translation )
201 *rows = dv->row_count;
202 }
203
204 return dv->table->ops->get_dimensions( dv->table, NULL, cols );
205}
206
208 UINT *type, BOOL *temporary, LPCWSTR *table_name )
209{
211
212 TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, table_name );
213
214 if( !dv->table )
216
217 return dv->table->ops->get_column_info( dv->table, n, name,
218 type, temporary, table_name );
219}
220
221static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
222 MSIRECORD *rec, UINT row )
223{
225
226 TRACE("%p %d %p\n", dv, eModifyMode, rec );
227
228 if( !dv->table )
230
231 return dv->table->ops->modify( dv->table, eModifyMode, rec, row );
232}
233
235{
237
238 TRACE("%p\n", dv );
239
240 if( dv->table )
241 dv->table->ops->delete( dv->table );
242
243 msi_free( dv->translation );
244 msiobj_release( &dv->db->hdr );
245 msi_free( dv );
246
247 return ERROR_SUCCESS;
248}
249
251{
253 NULL,
254 NULL,
255 NULL,
256 NULL,
257 NULL,
258 NULL,
259 NULL,
266 NULL,
267 NULL,
268 NULL,
269 NULL,
270 NULL,
271};
272
274{
275 MSIDISTINCTVIEW *dv = NULL;
276 UINT count = 0, r;
277
278 TRACE("%p\n", dv );
279
280 r = table->ops->get_dimensions( table, NULL, &count );
281 if( r != ERROR_SUCCESS )
282 {
283 ERR("can't get table dimensions\n");
284 return r;
285 }
286
287 dv = msi_alloc_zero( sizeof *dv );
288 if( !dv )
290
291 /* fill the structure */
292 dv->view.ops = &distinct_ops;
293 msiobj_addref( &db->hdr );
294 dv->db = db;
295 dv->table = table;
296 dv->translation = NULL;
297 dv->row_count = 0;
298 *view = (MSIVIEW*) dv;
299
300 return ERROR_SUCCESS;
301}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_SUCCESS
Definition: deptool.c:10
struct tagMSIDISTINCTVIEW MSIDISTINCTVIEW
static const MSIVIEWOPS distinct_ops
Definition: distinct.c:250
static UINT DISTINCT_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: distinct.c:110
UINT DISTINCT_CreateView(MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table)
Definition: distinct.c:273
struct tagDISTINCTSET DISTINCTSET
static UINT DISTINCT_close(struct tagMSIVIEW *view)
Definition: distinct.c:172
static UINT DISTINCT_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: distinct.c:93
static UINT DISTINCT_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: distinct.c:207
static UINT DISTINCT_delete(struct tagMSIVIEW *view)
Definition: distinct.c:234
static void distinct_free(DISTINCTSET *x)
Definition: distinct.c:82
static UINT DISTINCT_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
Definition: distinct.c:221
static DISTINCTSET ** distinct_insert(DISTINCTSET **x, UINT val, UINT row)
Definition: distinct.c:56
static UINT DISTINCT_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: distinct.c:188
#define NULL
Definition: types.h:112
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
static void msi_free(void *mem)
Definition: msipriv.h:1159
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
unsigned int UINT
Definition: ndis.h:50
static unsigned __int64 next
Definition: rand_nt.c:6
#define TRACE(s)
Definition: solgame.cpp:4
Definition: name.c:39
struct tagDISTINCTSET * nextcol
Definition: distinct.c:44
struct tagDISTINCTSET * nextrow
Definition: distinct.c:43
MSIOBJECTHDR hdr
Definition: msipriv.h:108
MSIVIEW * table
Definition: distinct.c:51
UINT * translation
Definition: distinct.c:53
MSIDATABASE * db
Definition: distinct.c:50
UINT(* fetch_int)(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: msipriv.h:242
UINT(* modify)(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *record, UINT row)
Definition: msipriv.h:319
UINT(* close)(struct tagMSIVIEW *view)
Definition: msipriv.h:298
UINT(* get_dimensions)(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: msipriv.h:306
UINT(* execute)(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: msipriv.h:293
UINT(* get_column_info)(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: msipriv.h:313
UINT(* delete)(struct tagMSIVIEW *)
Definition: msipriv.h:324
const MSIVIEWOPS * ops
Definition: msipriv.h:355
int MSIMODIFY
Definition: winemsi.idl:33
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185