ReactOS  0.4.15-dev-4872-g8a3db97
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 
38 typedef struct tagDISTINCTSET
39 {
45 } DISTINCTSET;
46 
47 typedef 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 
82 static void distinct_free( DISTINCTSET *x )
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 )
100  return ERROR_FUNCTION_FAILED;
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 )
119  return ERROR_FUNCTION_FAILED;
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 )
131  return ERROR_FUNCTION_FAILED;
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 );
153  return ERROR_FUNCTION_FAILED;
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 )
179  return ERROR_FUNCTION_FAILED;
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 
188 static 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 )
195  return ERROR_FUNCTION_FAILED;
196 
197  if( rows )
198  {
199  if( !dv->translation )
200  return ERROR_FUNCTION_FAILED;
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 )
215  return ERROR_FUNCTION_FAILED;
216 
217  return dv->table->ops->get_column_info( dv->table, n, name,
218  type, temporary, table_name );
219 }
220 
221 static 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 )
229  return ERROR_FUNCTION_FAILED;
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 
250 static const MSIVIEWOPS distinct_ops =
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 )
289  return ERROR_FUNCTION_FAILED;
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 }
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static UINT DISTINCT_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: distinct.c:188
static const MSIVIEWOPS distinct_ops
Definition: distinct.c:250
WINE_DEFAULT_DEBUG_CHANNEL(msidb)
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
UINT(* get_dimensions)(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
Definition: msipriv.h:306
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint GLuint GLsizei count
Definition: gl.h:1545
static UINT DISTINCT_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: distinct.c:93
GLdouble n
Definition: glext.h:7729
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static void msi_free(void *mem)
Definition: msipriv.h:1159
UINT(* execute)(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: msipriv.h:293
static UINT DISTINCT_close(struct tagMSIVIEW *view)
Definition: distinct.c:172
struct tagDISTINCTSET * nextrow
Definition: distinct.c:43
struct tagDISTINCTSET * nextcol
Definition: distinct.c:44
static void distinct_free(DISTINCTSET *x)
Definition: distinct.c:82
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
unsigned int BOOL
Definition: ntddk_ex.h:94
struct tagMSIDISTINCTVIEW MSIDISTINCTVIEW
static DISTINCTSET ** distinct_insert(DISTINCTSET **x, UINT val, UINT row)
Definition: distinct.c:56
int MSIMODIFY
Definition: winemsi.idl:33
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 GLint GLint j
Definition: glfuncs.h:250
MSIVIEW * table
Definition: distinct.c:51
#define TRACE(s)
Definition: solgame.cpp:4
static UINT DISTINCT_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
Definition: distinct.c:221
const MSIVIEWOPS * ops
Definition: msipriv.h:355
UINT(* close)(struct tagMSIVIEW *view)
Definition: msipriv.h:298
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
static UINT DISTINCT_get_column_info(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: distinct.c:207
UINT DISTINCT_CreateView(MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table)
Definition: distinct.c:273
static UINT DISTINCT_execute(struct tagMSIVIEW *view, MSIRECORD *record)
Definition: distinct.c:110
#define ERR(fmt,...)
Definition: debug.h:110
UINT(* delete)(struct tagMSIVIEW *)
Definition: msipriv.h:324
static unsigned __int64 next
Definition: rand_nt.c:6
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
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
UINT(* fetch_int)(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
Definition: msipriv.h:242
MSIDATABASE * db
Definition: distinct.c:50
struct tagDISTINCTSET DISTINCTSET
UINT(* get_column_info)(struct tagMSIVIEW *view, UINT n, LPCWSTR *name, UINT *type, BOOL *temporary, LPCWSTR *table_name)
Definition: msipriv.h:313
Definition: name.c:38
UINT(* modify)(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *record, UINT row)
Definition: msipriv.h:319
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
static UINT DISTINCT_delete(struct tagMSIVIEW *view)
Definition: distinct.c:234
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
MSIOBJECTHDR hdr
Definition: msipriv.h:108
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
UINT * translation
Definition: distinct.c:53