2 * Copyright 2020 Alistair Leslie-Hughes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/heap.h"
29 #include "wine/debug.h"
35 #include "msdasql_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msdasql
);
48 static struct msdasql_prop msdasql_init_props
[] =
50 { DBPROP_ABORTPRESERVE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_DATASOURCEINFO
, VT_BOOL
, VARIANT_FALSE
},
51 { DBPROP_BLOCKINGSTORAGEOBJECTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
52 { DBPROP_BOOKMARKS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
53 { DBPROP_BOOKMARKSKIPPED
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
54 { DBPROP_BOOKMARKTYPE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 1 },
55 { DBPROP_CANFETCHBACKWARDS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
56 { DBPROP_CANHOLDROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
57 { DBPROP_CANSCROLLBACKWARDS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
58 { DBPROP_COLUMNRESTRICT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
59 { DBPROP_COMMITPRESERVE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
60 { DBPROP_DELAYSTORAGEOBJECTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
61 { DBPROP_IMMOBILEROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
62 { DBPROP_LITERALBOOKMARKS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
63 { DBPROP_LITERALIDENTITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
64 { DBPROP_MAXOPENROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 0 },
65 { DBPROP_MAXPENDINGROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 0 },
66 { DBPROP_MAXROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 0 },
67 { DBPROP_NOTIFICATIONPHASES
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 31 },
68 { DBPROP_OTHERUPDATEDELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
69 { DBPROP_OWNINSERT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
70 { DBPROP_OWNUPDATEDELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
71 { DBPROP_QUICKRESTART
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
72 { DBPROP_REENTRANTEVENTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
73 { DBPROP_REMOVEDELETED
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
74 { DBPROP_REPORTMULTIPLECHANGES
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
75 { DBPROP_ROWRESTRICT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
76 { DBPROP_ROWTHREADMODEL
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 2 },
77 { DBPROP_TRANSACTEDOBJECT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
78 { DBPROP_UPDATABILITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 0 },
79 { DBPROP_STRONGIDENTITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
80 { DBPROP_IAccessor
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
81 { DBPROP_IColumnsInfo
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
82 { DBPROP_IColumnsRowset
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
83 { DBPROP_IConnectionPointContainer
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
84 { DBPROP_IRowset
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
85 { DBPROP_IRowsetChange
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
86 { DBPROP_IRowsetIdentity
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
87 { DBPROP_IRowsetInfo
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
88 { DBPROP_IRowsetLocate
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
89 { DBPROP_IRowsetResynch
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
90 { DBPROP_IRowsetUpdate
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
91 { DBPROP_ISupportErrorInfo
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
92 { DBPROP_ISequentialStream
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
93 { DBPROP_NOTIFYCOLUMNSET
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
94 { DBPROP_NOTIFYROWDELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
95 { DBPROP_NOTIFYROWFIRSTCHANGE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
96 { DBPROP_NOTIFYROWINSERT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
97 { DBPROP_NOTIFYROWRESYNCH
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
98 { DBPROP_NOTIFYROWSETRELEASE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
99 { DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
100 { DBPROP_NOTIFYROWUNDOCHANGE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
101 { DBPROP_NOTIFYROWUNDODELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
102 { DBPROP_NOTIFYROWUNDOINSERT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
103 { DBPROP_NOTIFYROWUPDATE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
104 { DBPROP_CHANGEINSERTEDROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
105 { DBPROP_RETURNPENDINGINSERTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
106 { DBPROP_IConvertType
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
107 { DBPROP_NOTIFICATIONGRANULARITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 1 },
108 { DBPROP_IMultipleResults
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
109 { DBPROP_ACCESSORDER
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 1 },
110 { DBPROP_BOOKMARKINFO
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 0 },
111 { DBPROP_UNIQUEROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
112 { DBPROP_IRowsetFind
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
113 { DBPROP_IRowsetScroll
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
114 { DBPROP_IRowsetRefresh
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
115 { DBPROP_FINDCOMPAREOPS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 27 },
116 { DBPROP_ORDEREDBOOKMARKS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
117 { DBPROP_CLIENTCURSOR
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
118 { DBPROP_ABORTPRESERVE
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
119 { DBPROP_ACTIVESESSIONS
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
120 { DBPROP_ASYNCTXNCOMMIT
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
121 { DBPROP_AUTH_CACHE_AUTHINFO
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
122 { DBPROP_AUTH_ENCRYPT_PASSWORD
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 0 },
123 { DBPROP_AUTH_INTEGRATED
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 14 },
124 { DBPROP_AUTH_MASK_PASSWORD
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
125 { DBPROP_AUTH_PASSWORD
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
126 { DBPROP_AUTH_PERSIST_ENCRYPTED
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
127 { DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
128 { DBPROP_AUTH_USERID
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
129 { DBPROP_BLOCKINGSTORAGEOBJECTS
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
132 #define SQLTYPE_TO_STR(x) case x: return #x
134 static const char *debugstr_sqltype(SQLSMALLINT type
)
138 SQLTYPE_TO_STR(SQL_DECIMAL
);
139 SQLTYPE_TO_STR(SQL_CHAR
);
140 SQLTYPE_TO_STR(SQL_VARCHAR
);
141 SQLTYPE_TO_STR(SQL_LONGVARCHAR
);
142 SQLTYPE_TO_STR(SQL_NUMERIC
);
143 SQLTYPE_TO_STR(SQL_GUID
);
144 SQLTYPE_TO_STR(SQL_TINYINT
);
145 SQLTYPE_TO_STR(SQL_SMALLINT
);
146 SQLTYPE_TO_STR(SQL_INTEGER
);
147 SQLTYPE_TO_STR(SQL_REAL
);
148 SQLTYPE_TO_STR(SQL_FLOAT
);
149 SQLTYPE_TO_STR(SQL_DOUBLE
);
150 SQLTYPE_TO_STR(SQL_BINARY
);
151 SQLTYPE_TO_STR(SQL_VARBINARY
);
152 SQLTYPE_TO_STR(SQL_LONGVARBINARY
);
153 SQLTYPE_TO_STR(SQL_TYPE_DATE
);
154 SQLTYPE_TO_STR(SQL_DATE
);
155 SQLTYPE_TO_STR(SQL_TIME
);
156 SQLTYPE_TO_STR(SQL_TYPE_TIMESTAMP
);
157 SQLTYPE_TO_STR(SQL_TIMESTAMP
);
158 SQLTYPE_TO_STR(SQL_TYPE_TIME
);
159 SQLTYPE_TO_STR(SQL_BIGINT
);
160 SQLTYPE_TO_STR(SQL_C_SBIGINT
);
161 SQLTYPE_TO_STR(SQL_C_SLONG
);
162 SQLTYPE_TO_STR(SQL_C_ULONG
);
163 SQLTYPE_TO_STR(SQL_WLONGVARCHAR
);
164 SQLTYPE_TO_STR(SQL_WCHAR
);
165 SQLTYPE_TO_STR(SQL_WVARCHAR
);
171 static const char *debugstr_dbtype(DBTYPE type
)
175 SQLTYPE_TO_STR(DBTYPE_NUMERIC
);
176 SQLTYPE_TO_STR(DBTYPE_STR
);
177 SQLTYPE_TO_STR(DBTYPE_GUID
);
178 SQLTYPE_TO_STR(DBTYPE_I1
);
179 SQLTYPE_TO_STR(DBTYPE_I2
);
180 SQLTYPE_TO_STR(DBTYPE_UI2
);
181 SQLTYPE_TO_STR(DBTYPE_I4
);
182 SQLTYPE_TO_STR(DBTYPE_I8
);
183 SQLTYPE_TO_STR(DBTYPE_UI4
);
184 SQLTYPE_TO_STR(DBTYPE_R4
);
185 SQLTYPE_TO_STR(DBTYPE_R8
);
186 SQLTYPE_TO_STR(DBTYPE_BYTES
);
187 SQLTYPE_TO_STR(DBTYPE_DBDATE
);
188 SQLTYPE_TO_STR(DBTYPE_DBTIME
);
189 SQLTYPE_TO_STR(DBTYPE_DATE
);
190 SQLTYPE_TO_STR(DBTYPE_DBTIMESTAMP
);
191 SQLTYPE_TO_STR(DBTYPE_WSTR
);
197 static SQLSMALLINT
sqltype_to_bindtype(SQLSMALLINT type
, BOOL sign
)
202 return DBTYPE_NUMERIC
;
205 case SQL_LONGVARCHAR
:
213 return sign
? DBTYPE_I2
: DBTYPE_UI2
;
215 return sign
? DBTYPE_I4
: DBTYPE_UI4
;
223 case SQL_LONGVARBINARY
:
226 return DBTYPE_DBDATE
;
228 return DBTYPE_DBTIME
;
231 case SQL_TYPE_TIMESTAMP
:
233 return DBTYPE_DBTIMESTAMP
;
235 return DBTYPE_DBTIME
;
243 case SQL_WLONGVARCHAR
:
248 FIXME("Unsupported type %i\n", type
);
254 static BOOL
is_variable_length(SQLSMALLINT type
)
258 case SQL_LONGVARCHAR
:
259 case SQL_WLONGVARCHAR
:
260 case SQL_LONGVARBINARY
:
266 static BOOL
is_fixed_length(SQLSMALLINT type
)
270 case SQL_LONGVARCHAR
:
271 case SQL_WLONGVARCHAR
:
273 case SQL_LONGVARBINARY
:
280 struct msdasql_session
282 IUnknown session_iface
;
283 IGetDataSource IGetDataSource_iface
;
284 IOpenRowset IOpenRowset_iface
;
285 ISessionProperties ISessionProperties_iface
;
286 IDBCreateCommand IDBCreateCommand_iface
;
287 ITransactionJoin ITransactionJoin_iface
;
288 ITransaction ITransaction_iface
;
291 IUnknown
*datasource
;
296 static inline struct msdasql_session
*impl_from_IUnknown( IUnknown
*iface
)
298 return CONTAINING_RECORD( iface
, struct msdasql_session
, session_iface
);
301 static inline struct msdasql_session
*impl_from_IGetDataSource( IGetDataSource
*iface
)
303 return CONTAINING_RECORD( iface
, struct msdasql_session
, IGetDataSource_iface
);
306 static inline struct msdasql_session
*impl_from_IOpenRowset( IOpenRowset
*iface
)
308 return CONTAINING_RECORD( iface
, struct msdasql_session
, IOpenRowset_iface
);
311 static inline struct msdasql_session
*impl_from_ISessionProperties( ISessionProperties
*iface
)
313 return CONTAINING_RECORD( iface
, struct msdasql_session
, ISessionProperties_iface
);
316 static inline struct msdasql_session
*impl_from_IDBCreateCommand( IDBCreateCommand
*iface
)
318 return CONTAINING_RECORD( iface
, struct msdasql_session
, IDBCreateCommand_iface
);
321 static inline struct msdasql_session
*impl_from_ITransactionJoin( ITransactionJoin
*iface
)
323 return CONTAINING_RECORD( iface
, struct msdasql_session
, ITransactionJoin_iface
);
326 static inline struct msdasql_session
*impl_from_ITransaction( ITransaction
*iface
)
328 return CONTAINING_RECORD( iface
, struct msdasql_session
, ITransaction_iface
);
331 static HRESULT WINAPI
session_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
333 struct msdasql_session
*session
= impl_from_IUnknown( iface
);
335 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), ppv
);
338 if(IsEqualGUID(&IID_IUnknown
, riid
))
340 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
341 *ppv
= &session
->session_iface
;
343 else if(IsEqualGUID(&IID_IGetDataSource
, riid
))
345 TRACE("(%p)->(IID_IGetDataSource %p)\n", iface
, ppv
);
346 *ppv
= &session
->IGetDataSource_iface
;
348 else if(IsEqualGUID(&IID_IOpenRowset
, riid
))
350 TRACE("(%p)->(IID_IOpenRowset %p)\n", iface
, ppv
);
351 *ppv
= &session
->IOpenRowset_iface
;
353 else if(IsEqualGUID(&IID_ISessionProperties
, riid
))
355 TRACE("(%p)->(IID_ISessionProperties %p)\n", iface
, ppv
);
356 *ppv
= &session
->ISessionProperties_iface
;
358 else if(IsEqualGUID(&IID_IDBCreateCommand
, riid
))
360 TRACE("(%p)->(IDBCreateCommand_iface %p)\n", iface
, ppv
);
361 *ppv
= &session
->IDBCreateCommand_iface
;
363 else if(IsEqualGUID(&IID_ITransactionJoin
, riid
))
365 TRACE("(%p)->(ITransactionJoin %p)\n", iface
, ppv
);
366 *ppv
= &session
->ITransactionJoin_iface
;
368 else if(IsEqualGUID(&IID_ITransaction
, riid
))
370 TRACE("(%p)->(ITransaction %p)\n", iface
, ppv
);
371 *ppv
= &session
->ITransaction_iface
;
373 else if(IsEqualGUID(&IID_IBindResource
, riid
))
375 TRACE("(%p)->(IID_IBindResource not support)\n", iface
);
376 return E_NOINTERFACE
;
378 else if(IsEqualGUID(&IID_ICreateRow
, riid
))
380 TRACE("(%p)->(IID_ICreateRow not support)\n", iface
);
381 return E_NOINTERFACE
;
386 IUnknown_AddRef((IUnknown
*)*ppv
);
390 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
391 return E_NOINTERFACE
;
394 static ULONG WINAPI
session_AddRef(IUnknown
*iface
)
396 struct msdasql_session
*session
= impl_from_IUnknown( iface
);
397 LONG refs
= InterlockedIncrement( &session
->refs
);
398 TRACE( "%p new refcount %ld\n", session
, refs
);
402 static ULONG WINAPI
session_Release(IUnknown
*iface
)
404 struct msdasql_session
*session
= impl_from_IUnknown( iface
);
405 LONG refs
= InterlockedDecrement( &session
->refs
);
406 TRACE( "%p new refcount %ld\n", session
, refs
);
409 TRACE( "destroying %p\n", session
);
411 IUnknown_Release(session
->datasource
);
412 heap_free( session
);
417 static const IUnknownVtbl unkfactoryVtbl
=
419 session_QueryInterface
,
425 HRESULT WINAPI
datasource_QueryInterface(IGetDataSource
*iface
, REFIID riid
, void **out
)
427 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
428 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
431 ULONG WINAPI
datasource_AddRef(IGetDataSource
*iface
)
433 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
434 return IUnknown_AddRef(&session
->session_iface
);
437 ULONG WINAPI
datasource_Release(IGetDataSource
*iface
)
439 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
440 return IUnknown_Release(&session
->session_iface
);
443 HRESULT WINAPI
datasource_GetDataSource(IGetDataSource
*iface
, REFIID riid
, IUnknown
**datasource
)
445 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
447 TRACE("%p, %s, %p stub\n", session
, debugstr_guid(riid
), datasource
);
452 return IUnknown_QueryInterface(session
->datasource
, riid
, (void**)datasource
);
455 static const IGetDataSourceVtbl datasourceVtbl
=
457 datasource_QueryInterface
,
460 datasource_GetDataSource
463 HRESULT WINAPI
openrowset_QueryInterface(IOpenRowset
*iface
, REFIID riid
, void **out
)
465 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
466 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
469 ULONG WINAPI
openrowset_AddRef(IOpenRowset
*iface
)
471 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
472 return IUnknown_AddRef(&session
->session_iface
);
475 ULONG WINAPI
openrowset_Release(IOpenRowset
*iface
)
477 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
478 return IUnknown_Release(&session
->session_iface
);
481 HRESULT WINAPI
openrowset_OpenRowset(IOpenRowset
*iface
, IUnknown
*pUnkOuter
, DBID
*table
,
482 DBID
*index
, REFIID riid
, ULONG count
, DBPROPSET propertysets
[], IUnknown
**rowset
)
484 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
485 FIXME("%p, %p, %p %p %s, %ld %p %p stub\n", session
, pUnkOuter
, table
, index
, debugstr_guid(riid
),
486 count
, propertysets
, rowset
);
491 static const IOpenRowsetVtbl openrowsetVtbl
=
493 openrowset_QueryInterface
,
496 openrowset_OpenRowset
499 static HRESULT WINAPI
properties_QueryInterface(ISessionProperties
*iface
, REFIID riid
, void **out
)
501 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
502 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
505 static ULONG WINAPI
properties_AddRef(ISessionProperties
*iface
)
507 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
508 return IUnknown_AddRef(&session
->session_iface
);
511 static ULONG WINAPI
properties_Release(ISessionProperties
*iface
)
513 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
514 return IUnknown_Release(&session
->session_iface
);
518 static HRESULT WINAPI
properties_GetProperties(ISessionProperties
*iface
, ULONG set_count
,
519 const DBPROPIDSET id_sets
[], ULONG
*count
, DBPROPSET
**sets
)
521 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
522 FIXME("%p %lu %p %p %p\n", session
, set_count
, id_sets
, count
, sets
);
527 static HRESULT WINAPI
properties_SetProperties(ISessionProperties
*iface
, ULONG count
,
530 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
531 FIXME("%p %lu %p\n", session
, count
, sets
);
536 static const ISessionPropertiesVtbl propertiesVtbl
=
538 properties_QueryInterface
,
541 properties_GetProperties
,
542 properties_SetProperties
545 static HRESULT WINAPI
createcommand_QueryInterface(IDBCreateCommand
*iface
, REFIID riid
, void **out
)
547 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
548 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
551 static ULONG WINAPI
createcommand_AddRef(IDBCreateCommand
*iface
)
553 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
554 return IUnknown_AddRef(&session
->session_iface
);
557 static ULONG WINAPI
createcommand_Release(IDBCreateCommand
*iface
)
559 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
560 return IUnknown_Release(&session
->session_iface
);
565 ICommandText ICommandText_iface
;
566 ICommandProperties ICommandProperties_iface
;
567 IColumnsInfo IColumnsInfo_iface
;
568 IConvertType IConvertType_iface
;
569 ICommandPrepare ICommandPrepare_iface
;
570 ICommandWithParameters ICommandWithParameters_iface
;
577 struct msdasql_prop
*properties
;
581 static inline struct command
*impl_from_ICommandText( ICommandText
*iface
)
583 return CONTAINING_RECORD( iface
, struct command
, ICommandText_iface
);
586 static inline struct command
*impl_from_ICommandProperties( ICommandProperties
*iface
)
588 return CONTAINING_RECORD( iface
, struct command
, ICommandProperties_iface
);
591 static inline struct command
*impl_from_IColumnsInfo( IColumnsInfo
*iface
)
593 return CONTAINING_RECORD( iface
, struct command
, IColumnsInfo_iface
);
596 static inline struct command
*impl_from_IConvertType( IConvertType
*iface
)
598 return CONTAINING_RECORD( iface
, struct command
, IConvertType_iface
);
601 static inline struct command
*impl_from_ICommandPrepare( ICommandPrepare
*iface
)
603 return CONTAINING_RECORD( iface
, struct command
, ICommandPrepare_iface
);
606 static inline struct command
*impl_from_ICommandWithParameters( ICommandWithParameters
*iface
)
608 return CONTAINING_RECORD( iface
, struct command
, ICommandWithParameters_iface
);
611 static HRESULT WINAPI
command_QueryInterface(ICommandText
*iface
, REFIID riid
, void **ppv
)
613 struct command
*command
= impl_from_ICommandText( iface
);
615 TRACE( "%p, %s, %p\n", command
, debugstr_guid(riid
), ppv
);
618 if(IsEqualGUID(&IID_IUnknown
, riid
) ||
619 IsEqualGUID(&IID_ICommand
, riid
) ||
620 IsEqualGUID(&IID_ICommandText
, riid
))
622 *ppv
= &command
->ICommandText_iface
;
624 else if(IsEqualGUID(&IID_ICommandProperties
, riid
))
626 *ppv
= &command
->ICommandProperties_iface
;
628 else if(IsEqualGUID(&IID_IColumnsInfo
, riid
))
630 *ppv
= &command
->IColumnsInfo_iface
;
632 else if(IsEqualGUID(&IID_IConvertType
, riid
))
634 *ppv
= &command
->IConvertType_iface
;
636 else if(IsEqualGUID(&IID_ICommandPrepare
, riid
))
638 *ppv
= &command
->ICommandPrepare_iface
;
640 else if(IsEqualGUID(&IID_ICommandWithParameters
, riid
))
642 *ppv
= &command
->ICommandWithParameters_iface
;
647 IUnknown_AddRef((IUnknown
*)*ppv
);
650 else if (IsEqualGUID(&IID_IMultipleResults
, riid
))
652 TRACE("IID_IMultipleResults not supported\n");
653 return E_NOINTERFACE
;
655 else if(IsEqualGUID(&IID_ICommandStream
, riid
))
657 TRACE("ICommandStream not support\n");
658 return E_NOINTERFACE
;
660 else if (IsEqualGUID(&IID_IRowsetChange
, riid
))
662 TRACE("IID_IRowsetChange not supported\n");
663 return E_NOINTERFACE
;
665 else if (IsEqualGUID(&IID_IRowsetUpdate
, riid
))
667 TRACE("IID_IRowsetUpdate not supported\n");
668 return E_NOINTERFACE
;
670 else if (IsEqualGUID(&IID_IRowsetLocate
, riid
))
672 TRACE("IID_IRowsetLocate not supported\n");
673 return E_NOINTERFACE
;
676 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
677 return E_NOINTERFACE
;
680 static ULONG WINAPI
command_AddRef(ICommandText
*iface
)
682 struct command
*command
= impl_from_ICommandText( iface
);
683 LONG refs
= InterlockedIncrement( &command
->refs
);
684 TRACE( "%p new refcount %ld\n", command
, refs
);
688 static ULONG WINAPI
command_Release(ICommandText
*iface
)
690 struct command
*command
= impl_from_ICommandText( iface
);
691 LONG refs
= InterlockedDecrement( &command
->refs
);
692 TRACE( "%p new refcount %ld\n", command
, refs
);
695 TRACE( "destroying %p\n", command
);
696 heap_free(command
->properties
);
697 if (command
->session
)
698 IUnknown_Release(command
->session
);
701 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
703 heap_free( command
->query
);
704 heap_free( command
);
709 static HRESULT WINAPI
command_Cancel(ICommandText
*iface
)
711 struct command
*command
= impl_from_ICommandText( iface
);
712 FIXME("%p\n", command
);
716 struct msdasql_rowset
718 IRowset IRowset_iface
;
719 IRowsetInfo IRowsetInfo_iface
;
720 IColumnsInfo IColumnsInfo_iface
;
721 IAccessor IAccessor_iface
;
722 IColumnsRowset IColumnsRowset_iface
;
728 static inline struct msdasql_rowset
*impl_from_IRowset( IRowset
*iface
)
730 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IRowset_iface
);
733 static inline struct msdasql_rowset
*impl_from_IRowsetInfo( IRowsetInfo
*iface
)
735 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IRowsetInfo_iface
);
738 static inline struct msdasql_rowset
*rowset_impl_from_IColumnsInfo( IColumnsInfo
*iface
)
740 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IColumnsInfo_iface
);
743 static inline struct msdasql_rowset
*impl_from_IAccessor ( IAccessor
*iface
)
745 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IAccessor_iface
);
748 static inline struct msdasql_rowset
*impl_from_IColumnsRowset ( IColumnsRowset
*iface
)
750 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IColumnsRowset_iface
);
753 static HRESULT WINAPI
msdasql_rowset_QueryInterface(IRowset
*iface
, REFIID riid
, void **ppv
)
755 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
757 TRACE( "%p, %s, %p\n", rowset
, debugstr_guid(riid
), ppv
);
760 if(IsEqualGUID(&IID_IUnknown
, riid
) ||
761 IsEqualGUID(&IID_IRowset
, riid
))
763 *ppv
= &rowset
->IRowset_iface
;
765 else if (IsEqualGUID(&IID_IRowsetInfo
, riid
))
767 *ppv
= &rowset
->IRowsetInfo_iface
;
769 else if (IsEqualGUID(&IID_IColumnsInfo
, riid
))
771 *ppv
= &rowset
->IColumnsInfo_iface
;
773 else if(IsEqualGUID(&IID_IAccessor
, riid
))
775 *ppv
= &rowset
->IAccessor_iface
;
777 else if(IsEqualGUID(&IID_IColumnsRowset
, riid
))
779 *ppv
= &rowset
->IColumnsRowset_iface
;
781 else if (IsEqualGUID(&IID_IRowsetChange
, riid
))
783 TRACE("IID_IRowsetChange not supported\n");
784 return E_NOINTERFACE
;
786 else if (IsEqualGUID(&IID_IRowsetUpdate
, riid
))
788 TRACE("IID_IRowsetUpdate not supported\n");
789 return E_NOINTERFACE
;
791 else if (IsEqualGUID(&IID_IRowsetLocate
, riid
))
793 TRACE("IID_IRowsetLocate not supported\n");
794 return E_NOINTERFACE
;
799 IUnknown_AddRef((IUnknown
*)*ppv
);
803 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
804 return E_NOINTERFACE
;
807 static ULONG WINAPI
msdasql_rowset_AddRef(IRowset
*iface
)
809 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
810 LONG refs
= InterlockedIncrement( &rowset
->refs
);
811 TRACE( "%p new refcount %ld\n", rowset
, refs
);
815 static ULONG WINAPI
msdasql_rowset_Release(IRowset
*iface
)
817 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
818 LONG refs
= InterlockedDecrement( &rowset
->refs
);
819 TRACE( "%p new refcount %ld\n", rowset
, refs
);
822 TRACE( "destroying %p\n", rowset
);
824 SQLFreeHandle(SQL_HANDLE_STMT
, rowset
->hstmt
);
827 IUnknown_Release(rowset
->caller
);
834 static HRESULT WINAPI
msdasql_rowset_AddRefRows(IRowset
*iface
, DBCOUNTITEM count
,
835 const HROW rows
[], DBREFCOUNT ref_counts
[], DBROWSTATUS status
[])
837 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
838 FIXME("%p, %Id, %p, %p, %p\n", rowset
, count
, rows
, ref_counts
, status
);
842 static HRESULT WINAPI
msdasql_rowset_GetData(IRowset
*iface
, HROW row
, HACCESSOR accessor
, void *data
)
844 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
845 FIXME("%p, %Id, %Id, %p\n", rowset
, row
, accessor
, data
);
849 static HRESULT WINAPI
msdasql_rowset_GetNextRows(IRowset
*iface
, HCHAPTER reserved
, DBROWOFFSET offset
,
850 DBROWCOUNT count
, DBCOUNTITEM
*obtained
, HROW
**rows
)
852 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
853 FIXME("%p, %Id, %Id, %Id, %p, %p\n", rowset
, reserved
, offset
, count
, obtained
, rows
);
857 static HRESULT WINAPI
msdasql_rowset_ReleaseRows(IRowset
*iface
, DBCOUNTITEM count
,
858 const HROW rows
[], DBROWOPTIONS options
[], DBREFCOUNT ref_counts
[], DBROWSTATUS status
[])
860 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
862 FIXME("%p, %Id, %p, %p, %p, %p\n", rowset
, count
, rows
, options
, ref_counts
, status
);
866 static HRESULT WINAPI
msdasql_rowset_RestartPosition(IRowset
*iface
, HCHAPTER reserved
)
868 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
869 FIXME("%p, %Id\n", rowset
, reserved
);
873 static const struct IRowsetVtbl msdasql_rowset_vtbl
=
875 msdasql_rowset_QueryInterface
,
876 msdasql_rowset_AddRef
,
877 msdasql_rowset_Release
,
878 msdasql_rowset_AddRefRows
,
879 msdasql_rowset_GetData
,
880 msdasql_rowset_GetNextRows
,
881 msdasql_rowset_ReleaseRows
,
882 msdasql_rowset_RestartPosition
885 static HRESULT WINAPI
rowset_info_QueryInterface(IRowsetInfo
*iface
, REFIID riid
, void **ppv
)
887 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
888 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, ppv
);
891 static ULONG WINAPI
rowset_info_AddRef(IRowsetInfo
*iface
)
893 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
894 return IRowset_AddRef(&rowset
->IRowset_iface
);
897 static ULONG WINAPI
rowset_info_Release(IRowsetInfo
*iface
)
899 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
900 return IRowset_Release(&rowset
->IRowset_iface
);
903 static HRESULT WINAPI
rowset_info_GetProperties(IRowsetInfo
*iface
, const ULONG count
,
904 const DBPROPIDSET propertyidsets
[], ULONG
*out_count
, DBPROPSET
**propertysets
)
906 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
908 ICommandProperties
*props
;
910 TRACE("%p, %lu, %p, %p, %p\n", rowset
, count
, propertyidsets
, out_count
, propertysets
);
912 hr
= IUnknown_QueryInterface(rowset
->caller
, &IID_ICommandProperties
, (void**)&props
);
916 hr
= ICommandProperties_GetProperties(props
, count
, propertyidsets
, out_count
, propertysets
);
917 ICommandProperties_Release(props
);
922 static HRESULT WINAPI
rowset_info_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL ordinal
,
923 REFIID riid
, IUnknown
**unk
)
925 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
926 FIXME("%p, %Id, %s, %p\n", rowset
, ordinal
, debugstr_guid(riid
), unk
);
930 static HRESULT WINAPI
rowset_info_GetSpecification(IRowsetInfo
*iface
, REFIID riid
,
931 IUnknown
**specification
)
933 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
935 TRACE("%p, %s, %p\n", rowset
, debugstr_guid(riid
), specification
);
943 return IUnknown_QueryInterface(rowset
->caller
, riid
, (void**)specification
);
946 struct IRowsetInfoVtbl rowset_info_vtbl
=
948 rowset_info_QueryInterface
,
951 rowset_info_GetProperties
,
952 rowset_info_GetReferencedRowset
,
953 rowset_info_GetSpecification
956 static HRESULT WINAPI
rowset_colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
958 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
959 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
962 static ULONG WINAPI
rowset_colsinfo_AddRef(IColumnsInfo
*iface
)
964 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
965 return IRowset_AddRef(&rowset
->IRowset_iface
);
968 static ULONG WINAPI
rowset_colsinfo_Release(IColumnsInfo
*iface
)
970 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
971 return IRowset_Release(&rowset
->IRowset_iface
);
974 static HRESULT WINAPI
rowset_colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
975 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
977 #define MAX_COLUMN_LEN 128
979 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
980 DBCOLUMNINFO
*dbcolumn
;
986 TRACE("%p, %p, %p, %p\n", rowset
, columns
, colinfo
, stringsbuffer
);
988 if (!columns
|| !colinfo
|| !stringsbuffer
)
991 SQLNumResultCols(rowset
->hstmt
, &colcnt
);
992 TRACE("SQLNumResultCols %d\n", colcnt
);
996 ptr
= *stringsbuffer
= CoTaskMemAlloc(colcnt
* MAX_COLUMN_LEN
* sizeof(WCHAR
));
998 return E_OUTOFMEMORY
;
1000 dbcolumn
= CoTaskMemAlloc(colcnt
* sizeof(DBCOLUMNINFO
));
1004 return E_OUTOFMEMORY
;
1007 for (i
= 0; i
< colcnt
; i
++)
1009 SQLWCHAR columnname
[MAX_COLUMN_LEN
];
1010 SQLSMALLINT ColumnNameLen
;
1011 SQLSMALLINT ColumnDataType
;
1012 SQLULEN ColumnDataSize
;
1013 SQLSMALLINT ColumnDataDigits
;
1014 SQLSMALLINT ColumnDataNullable
;
1016 ret
= SQLDescribeColW(rowset
->hstmt
, i
+1, columnname
, MAX_COLUMN_LEN
, &ColumnNameLen
, &ColumnDataType
,
1017 &ColumnDataSize
, &ColumnDataDigits
, &ColumnDataNullable
);
1018 if (SQL_SUCCEEDED(ret
))
1022 TRACE("%d: Column Name : %s, Column Name Len : %i, SQL Data Type : %i, Data Size : %i, DecimalDigits : %i, Nullable %i\n",
1023 i
, debugstr_w(columnname
), (int)ColumnNameLen
, (int)ColumnDataType
, (int)ColumnDataSize
, (int)ColumnDataDigits
,
1024 (int)ColumnDataNullable
);
1025 lstrcpyW(ptr
, columnname
);
1027 dbcolumn
[i
].pwszName
= ptr
;
1028 dbcolumn
[i
].pTypeInfo
= NULL
;
1029 dbcolumn
[i
].iOrdinal
= i
+1;
1031 ret
= SQLColAttributesW (rowset
->hstmt
, i
+1, SQL_DESC_UNSIGNED
, NULL
, 0, NULL
, &length
);
1032 if (!SQL_SUCCEEDED(ret
))
1034 dump_sql_diag_records(SQL_HANDLE_STMT
, rowset
->hstmt
);
1036 CoTaskMemFree(dbcolumn
);
1037 ERR("Failed to get column %d attribute\n", i
+1);
1041 dbcolumn
[i
].wType
= sqltype_to_bindtype(ColumnDataType
, length
== SQL_FALSE
);
1042 TRACE("SQLType %s -> %s\n", debugstr_sqltype(ColumnDataType
), debugstr_dbtype(dbcolumn
[i
].wType
));
1044 dbcolumn
[i
].dwFlags
= DBCOLUMNFLAGS_WRITE
;
1046 ret
= SQLColAttributesW(rowset
->hstmt
, i
+1, SQL_DESC_LENGTH
, NULL
, 0, NULL
, &length
);
1047 if (!SQL_SUCCEEDED(ret
))
1050 CoTaskMemFree(dbcolumn
);
1051 ERR("Failed to get column %d length (%d)\n", i
+1, ret
);
1054 dbcolumn
[i
].ulColumnSize
= length
;
1056 if (dbcolumn
[i
].ulColumnSize
> 1024 && is_variable_length(ColumnDataType
))
1057 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_MAYDEFER
| DBCOLUMNFLAGS_ISLONG
;
1059 if (ColumnDataNullable
)
1060 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_ISNULLABLE
| DBCOLUMNFLAGS_MAYBENULL
;
1062 if (is_fixed_length(ColumnDataType
))
1063 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_ISFIXEDLENGTH
;
1065 ret
= SQLColAttributesW(rowset
->hstmt
, i
+1, SQL_DESC_SCALE
, NULL
, 0, NULL
, &length
);
1066 if (!SQL_SUCCEEDED(ret
))
1069 CoTaskMemFree(dbcolumn
);
1070 ERR("Failed to get column %d scale (%d)\n", i
+1, ret
);
1075 dbcolumn
[i
].bScale
= length
;
1077 ret
= SQLColAttributesW(rowset
->hstmt
, i
+1, SQL_DESC_PRECISION
, NULL
, 0, NULL
, &length
);
1078 if (!SQL_SUCCEEDED(ret
))
1081 CoTaskMemFree(dbcolumn
);
1082 ERR("Failed to get column %d precision (%d)\n", i
+1, ret
);
1087 dbcolumn
[i
].bPrecision
= length
;
1089 dbcolumn
[i
].columnid
.eKind
= DBKIND_NAME
;
1090 dbcolumn
[i
].columnid
.uName
.pwszName
= ptr
;
1092 ptr
+= ColumnNameLen
+ 1;
1097 CoTaskMemFree(dbcolumn
);
1098 ERR("Failed to get column %d description (%d)\n", i
+1, ret
);
1103 *colinfo
= dbcolumn
;
1104 #undef MAX_COLUMN_LEN
1108 static HRESULT WINAPI
rowset_colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1109 const DBID
*dbids
, DBORDINAL
*columns
)
1111 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
1112 FIXME("%p, %Id, %p, %p\n", rowset
, column_ids
, dbids
, columns
);
1116 static struct IColumnsInfoVtbl rowset_columninfo_vtbll
=
1118 rowset_colsinfo_QueryInterface
,
1119 rowset_colsinfo_AddRef
,
1120 rowset_colsinfo_Release
,
1121 rowset_colsinfo_GetColumnInfo
,
1122 rowset_colsinfo_MapColumnIDs
1125 static HRESULT WINAPI
rowset_accessor_QueryInterface(IAccessor
*iface
, REFIID riid
, void **out
)
1127 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1128 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
1131 static ULONG WINAPI
rowset_accessor_AddRef(IAccessor
*iface
)
1133 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1134 return IRowset_AddRef(&rowset
->IRowset_iface
);
1137 static ULONG WINAPI
rowset_accessor_Release(IAccessor
*iface
)
1139 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1140 return IRowset_Release(&rowset
->IRowset_iface
);
1143 static HRESULT WINAPI
rowset_accessor_AddRefAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
1145 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1146 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
1150 static HRESULT WINAPI
rowset_accessor_CreateAccessor(IAccessor
*iface
, DBACCESSORFLAGS flags
,
1151 DBCOUNTITEM count
, const DBBINDING bindings
[], DBLENGTH row_size
, HACCESSOR
*accessor
,
1152 DBBINDSTATUS status
[])
1154 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1155 FIXME("%p, 0x%08lx, %Id, %p, %Id, %p, %p\n", rowset
, flags
, count
, bindings
, row_size
, accessor
, status
);
1159 static HRESULT WINAPI
rowset_accessor_GetBindings(IAccessor
*iface
, HACCESSOR accessor
,
1160 DBACCESSORFLAGS
*flags
, DBCOUNTITEM
*count
, DBBINDING
**bindings
)
1162 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1163 FIXME("%p, %Id, %p, %p, %p\n", rowset
, accessor
, flags
, count
, bindings
);
1167 static HRESULT WINAPI
rowset_accessor_ReleaseAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
1169 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1170 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
1174 struct IAccessorVtbl accessor_vtbl
=
1176 rowset_accessor_QueryInterface
,
1177 rowset_accessor_AddRef
,
1178 rowset_accessor_Release
,
1179 rowset_accessor_AddRefAccessor
,
1180 rowset_accessor_CreateAccessor
,
1181 rowset_accessor_GetBindings
,
1182 rowset_accessor_ReleaseAccessor
1185 static HRESULT WINAPI
column_rs_QueryInterface(IColumnsRowset
*iface
, REFIID riid
, void **out
)
1187 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1188 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
1191 static ULONG WINAPI
column_rs_AddRef(IColumnsRowset
*iface
)
1193 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1194 return IRowset_AddRef(&rowset
->IRowset_iface
);
1197 static ULONG WINAPI
column_rs_Release(IColumnsRowset
*iface
)
1199 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1200 return IRowset_Release(&rowset
->IRowset_iface
);
1203 static HRESULT WINAPI
column_rs_GetAvailableColumns(IColumnsRowset
*iface
, DBORDINAL
*count
, DBID
**columns
)
1205 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1207 TRACE("%p, %p, %p\n", rowset
, count
, columns
);
1209 if (!count
|| !columns
)
1210 return E_INVALIDARG
;
1218 static HRESULT WINAPI
column_rs_GetColumnsRowset(IColumnsRowset
*iface
, IUnknown
*outer
, DBORDINAL count
,
1219 const DBID columns
[], REFIID riid
, ULONG property_cnt
, DBPROPSET property_sets
[], IUnknown
**unk_rs
)
1221 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1222 FIXME("(%p)->(%p, %Id, %p, %s, %lu, %p, %p): stub\n", rowset
, outer
, count
, columns
, debugstr_guid(riid
),
1223 property_cnt
, property_sets
, unk_rs
);
1227 struct IColumnsRowsetVtbl columnrs_rs_vtbl
=
1229 column_rs_QueryInterface
,
1232 column_rs_GetAvailableColumns
,
1233 column_rs_GetColumnsRowset
1236 static HRESULT WINAPI
command_Execute(ICommandText
*iface
, IUnknown
*outer
, REFIID riid
,
1237 DBPARAMS
*params
, DBROWCOUNT
*affected
, IUnknown
**rowset
)
1239 struct command
*command
= impl_from_ICommandText( iface
);
1240 struct msdasql_rowset
*msrowset
;
1243 SQLHSTMT hstmt
= command
->hstmt
;
1244 SQLLEN results
= -1;
1245 BOOL free_hstmt
= TRUE
;
1247 TRACE("%p, %p, %s, %p %p %p\n", command
, outer
, debugstr_guid(riid
), params
, affected
, rowset
);
1250 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &hstmt
);
1252 ret
= SQLExecDirectW(hstmt
, command
->query
, SQL_NTS
);
1253 if (ret
!= SQL_SUCCESS
)
1255 dump_sql_diag_records(SQL_HANDLE_STMT
, hstmt
);
1260 if (!wcsnicmp( command
->query
, L
"select ", 7 ))
1262 msrowset
= heap_alloc(sizeof(*msrowset
));
1264 return E_OUTOFMEMORY
;
1266 command
->hstmt
= NULL
;
1268 msrowset
->IRowset_iface
.lpVtbl
= &msdasql_rowset_vtbl
;
1269 msrowset
->IRowsetInfo_iface
.lpVtbl
= &rowset_info_vtbl
;
1270 msrowset
->IColumnsInfo_iface
.lpVtbl
= &rowset_columninfo_vtbll
;
1271 msrowset
->IAccessor_iface
.lpVtbl
= &accessor_vtbl
;
1272 msrowset
->IColumnsRowset_iface
.lpVtbl
= &columnrs_rs_vtbl
;
1274 ICommandText_QueryInterface(iface
, &IID_IUnknown
, (void**)&msrowset
->caller
);
1275 msrowset
->hstmt
= hstmt
;
1278 hr
= IRowset_QueryInterface(&msrowset
->IRowset_iface
, riid
, (void**)rowset
);
1279 IRowset_Release(&msrowset
->IRowset_iface
);
1284 ret
= SQLRowCount(hstmt
, &results
);
1285 if (ret
!= SQL_SUCCESS
)
1286 ERR("SQLRowCount failed (%d)\n", ret
);
1288 *affected
= results
;
1292 SQLFreeStmt(hstmt
, SQL_CLOSE
);
1297 static HRESULT WINAPI
command_GetDBSession(ICommandText
*iface
, REFIID riid
, IUnknown
**session
)
1299 struct command
*command
= impl_from_ICommandText( iface
);
1301 TRACE("%p, %s, %p\n", command
, debugstr_guid(riid
), session
);
1304 return E_INVALIDARG
;
1308 if (!command
->session
)
1311 return IUnknown_QueryInterface(command
->session
, riid
, (void**)session
);
1314 static HRESULT WINAPI
command_GetCommandText(ICommandText
*iface
, GUID
*dialect
, LPOLESTR
*commandstr
)
1316 struct command
*command
= impl_from_ICommandText( iface
);
1318 TRACE("%p, %p, %p\n", command
, dialect
, commandstr
);
1320 if (!command
->query
)
1321 return DB_E_NOCOMMAND
;
1323 if (dialect
&& !IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1325 *dialect
= DBGUID_DEFAULT
;
1326 hr
= DB_S_DIALECTIGNORED
;
1329 *commandstr
= heap_alloc((lstrlenW(command
->query
)+1)*sizeof(WCHAR
));
1330 wcscpy(*commandstr
, command
->query
);
1334 static HRESULT WINAPI
command_SetCommandText(ICommandText
*iface
, REFGUID dialect
, LPCOLESTR commandstr
)
1336 struct command
*command
= impl_from_ICommandText( iface
);
1337 TRACE("%p, %s, %s\n", command
, debugstr_guid(dialect
), debugstr_w(commandstr
));
1339 if (!IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1340 FIXME("Currently non Default Dialect isn't supported\n");
1342 heap_free(command
->query
);
1346 command
->query
= heap_alloc((lstrlenW(commandstr
)+1)*sizeof(WCHAR
));
1347 if (!command
->query
)
1348 return E_OUTOFMEMORY
;
1350 wcscpy(command
->query
, commandstr
);
1353 command
->query
= NULL
;
1357 static const ICommandTextVtbl commandVtbl
=
1359 command_QueryInterface
,
1364 command_GetDBSession
,
1365 command_GetCommandText
,
1366 command_SetCommandText
1369 static HRESULT WINAPI
command_prop_QueryInterface(ICommandProperties
*iface
, REFIID riid
, void **out
)
1371 struct command
*command
= impl_from_ICommandProperties( iface
);
1372 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1375 static ULONG WINAPI
command_prop_AddRef(ICommandProperties
*iface
)
1377 struct command
*command
= impl_from_ICommandProperties( iface
);
1378 return ICommandText_AddRef(&command
->ICommandText_iface
);
1381 static ULONG WINAPI
command_prop_Release(ICommandProperties
*iface
)
1383 struct command
*command
= impl_from_ICommandProperties( iface
);
1384 return ICommandText_Release(&command
->ICommandText_iface
);
1387 static ULONG
get_property_count(DWORD flag
, struct msdasql_prop
*properties
, int prop_count
)
1391 for(i
=0; i
< prop_count
; i
++)
1393 if (properties
[i
].flags
& flag
)
1400 static HRESULT WINAPI
command_prop_GetProperties(ICommandProperties
*iface
, ULONG count
,
1401 const DBPROPIDSET propertyidsets
[], ULONG
*sets_cnt
, DBPROPSET
**propertyset
)
1403 struct command
*command
= impl_from_ICommandProperties( iface
);
1404 DBPROPSET
*propset
= NULL
;
1407 TRACE("%p %ld %p %p %p\n", command
, count
, propertyidsets
, sets_cnt
, propertyset
);
1409 /* All Properties */
1413 propset
= CoTaskMemAlloc(2 * sizeof(DBPROPSET
));
1415 return E_OUTOFMEMORY
;
1417 propset
[0].guidPropertySet
= DBPROPSET_ROWSET
;
1418 propset
[0].cProperties
= get_property_count(DBPROPFLAGS_ROWSET
, command
->properties
, command
->prop_count
);
1419 propset
[0].rgProperties
= CoTaskMemAlloc(propset
[0].cProperties
* sizeof(DBPROP
));
1420 if (!propset
[0].rgProperties
)
1422 CoTaskMemFree(propset
);
1423 return E_OUTOFMEMORY
;
1427 for (j
=0; j
< command
->prop_count
; j
++)
1429 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_ROWSET
))
1431 propset
[0].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1433 V_VT(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1434 if (command
->properties
[j
].vartype
== VT_BOOL
)
1436 V_BOOL(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1438 else if (command
->properties
[j
].vartype
== VT_I4
)
1440 V_I4(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1443 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1448 propset
[1].guidPropertySet
= DBPROPSET_PROVIDERROWSET
;
1449 propset
[1].cProperties
= get_property_count(DBPROPFLAGS_DATASOURCEINFO
, command
->properties
, command
->prop_count
);
1450 propset
[1].rgProperties
= CoTaskMemAlloc(propset
[1].cProperties
* sizeof(DBPROP
));
1451 if (!propset
[1].rgProperties
)
1453 CoTaskMemFree(propset
[0].rgProperties
);
1454 CoTaskMemFree(propset
);
1455 return E_OUTOFMEMORY
;
1459 for (j
=0; j
< command
->prop_count
; j
++)
1461 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_DATASOURCEINFO
))
1463 propset
[1].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1465 V_VT(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1466 if (command
->properties
[j
].vartype
== VT_BOOL
)
1468 V_BOOL(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1470 else if (command
->properties
[j
].vartype
== VT_I4
)
1472 V_I4(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1475 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1484 propset
= CoTaskMemAlloc(count
* sizeof(DBPROPSET
));
1486 return E_OUTOFMEMORY
;
1488 for (i
=0; i
< count
; i
++)
1490 TRACE("Property id %d (count %ld, set %s)\n", i
, propertyidsets
[i
].cPropertyIDs
,
1491 debugstr_guid(&propertyidsets
[i
].guidPropertySet
));
1493 propset
[i
].cProperties
= propertyidsets
[i
].cPropertyIDs
;
1494 propset
[i
].rgProperties
= CoTaskMemAlloc(propset
[i
].cProperties
* sizeof(DBPROP
));
1496 for (j
=0; j
< propset
[i
].cProperties
; j
++)
1498 propset
[i
].rgProperties
[j
].dwPropertyID
= propertyidsets
[i
].rgPropertyIDs
[j
];
1500 for(k
= 0; k
< command
->prop_count
; k
++)
1502 if (command
->properties
[k
].property_id
== propertyidsets
[i
].rgPropertyIDs
[j
])
1504 V_VT(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].vartype
;
1505 if (command
->properties
[j
].vartype
== VT_BOOL
)
1507 V_BOOL(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1509 else if (command
->properties
[j
].vartype
== VT_I4
)
1511 V_I4(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1514 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1524 *propertyset
= propset
;
1529 static HRESULT WINAPI
command_prop_SetProperties(ICommandProperties
*iface
, ULONG count
,
1530 DBPROPSET propertyset
[])
1532 struct command
*command
= impl_from_ICommandProperties( iface
);
1535 TRACE("%p %lu, %p\n", command
, count
, propertyset
);
1537 for(i
=0; i
< count
; i
++)
1539 TRACE("set %s, count %ld\n", debugstr_guid(&propertyset
[i
].guidPropertySet
), propertyset
[i
].cProperties
);
1540 for(j
=0; j
< propertyset
[i
].cProperties
; j
++)
1542 for(k
=0; k
< command
->prop_count
; k
++)
1544 if (command
->properties
[k
].property_id
== propertyset
[i
].rgProperties
[j
].dwPropertyID
)
1546 TRACE("Found property 0x%08lx\n", command
->properties
[k
].property_id
);
1547 if (command
->properties
[k
].flags
& DBPROPFLAGS_WRITE
)
1549 if (command
->properties
[k
].vartype
== VT_BOOL
)
1551 command
->properties
[k
].value
= V_BOOL(&propertyset
[i
].rgProperties
[j
].vValue
);
1553 else if (command
->properties
[k
].vartype
== VT_I4
)
1555 command
->properties
[k
].value
= V_I4(&propertyset
[i
].rgProperties
[j
].vValue
);
1558 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1561 WARN("Attempting to set Readonly property\n");
1571 static const ICommandPropertiesVtbl commonpropsVtbl
=
1573 command_prop_QueryInterface
,
1574 command_prop_AddRef
,
1575 command_prop_Release
,
1576 command_prop_GetProperties
,
1577 command_prop_SetProperties
1580 static HRESULT WINAPI
colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
1582 struct command
*command
= impl_from_IColumnsInfo( iface
);
1583 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1586 static ULONG WINAPI
colsinfo_AddRef(IColumnsInfo
*iface
)
1588 struct command
*command
= impl_from_IColumnsInfo( iface
);
1589 return ICommandText_AddRef(&command
->ICommandText_iface
);
1592 static ULONG WINAPI
colsinfo_Release(IColumnsInfo
*iface
)
1594 struct command
*command
= impl_from_IColumnsInfo( iface
);
1595 return ICommandText_Release(&command
->ICommandText_iface
);
1598 static HRESULT WINAPI
colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
1599 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
1601 struct command
*command
= impl_from_IColumnsInfo( iface
);
1602 FIXME("%p, %p, %p, %p\n", command
, columns
, colinfo
, stringsbuffer
);
1606 static HRESULT WINAPI
colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1607 const DBID
*dbids
, DBORDINAL
*columns
)
1609 struct command
*command
= impl_from_IColumnsInfo( iface
);
1610 FIXME("%p, %Iu, %p, %p\n", command
, column_ids
, dbids
, columns
);
1614 static struct IColumnsInfoVtbl columninfoVtbl
=
1616 colsinfo_QueryInterface
,
1619 colsinfo_GetColumnInfo
,
1620 colsinfo_MapColumnIDs
1623 static HRESULT WINAPI
converttype_QueryInterface(IConvertType
*iface
, REFIID riid
, void **out
)
1625 struct command
*command
= impl_from_IConvertType( iface
);
1626 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1629 static ULONG WINAPI
converttype_AddRef(IConvertType
*iface
)
1631 struct command
*command
= impl_from_IConvertType( iface
);
1632 return ICommandText_AddRef(&command
->ICommandText_iface
);
1635 static ULONG WINAPI
converttype_Release(IConvertType
*iface
)
1637 struct command
*command
= impl_from_IConvertType( iface
);
1638 return ICommandText_Release(&command
->ICommandText_iface
);
1641 static HRESULT WINAPI
converttype_CanConvert(IConvertType
*iface
, DBTYPE from
, DBTYPE to
, DBCONVERTFLAGS flags
)
1643 struct command
*command
= impl_from_IConvertType( iface
);
1644 FIXME("%p, %u, %d, 0x%08lx\n", command
, from
, to
, flags
);
1648 static struct IConvertTypeVtbl converttypeVtbl
=
1650 converttype_QueryInterface
,
1652 converttype_Release
,
1653 converttype_CanConvert
1656 static HRESULT WINAPI
commandprepare_QueryInterface(ICommandPrepare
*iface
, REFIID riid
, void **out
)
1658 struct command
*command
= impl_from_ICommandPrepare( iface
);
1659 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1662 static ULONG WINAPI
commandprepare_AddRef(ICommandPrepare
*iface
)
1664 struct command
*command
= impl_from_ICommandPrepare( iface
);
1665 return ICommandText_AddRef(&command
->ICommandText_iface
);
1668 static ULONG WINAPI
commandprepare_Release(ICommandPrepare
*iface
)
1670 struct command
*command
= impl_from_ICommandPrepare( iface
);
1671 return ICommandText_Release(&command
->ICommandText_iface
);
1674 static HRESULT WINAPI
commandprepare_Prepare(ICommandPrepare
*iface
, ULONG runs
)
1676 struct command
*command
= impl_from_ICommandPrepare( iface
);
1679 TRACE("%p, %lu\n", command
, runs
);
1681 if (!command
->query
)
1682 return DB_E_NOCOMMAND
;
1685 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
1687 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &command
->hstmt
);
1689 ret
= SQLPrepareW(command
->hstmt
, command
->query
, SQL_NTS
);
1690 if (ret
!= SQL_SUCCESS
)
1692 dump_sql_diag_records(SQL_HANDLE_STMT
, command
->hstmt
);
1698 static HRESULT WINAPI
commandprepare_Unprepare(ICommandPrepare
*iface
)
1700 struct command
*command
= impl_from_ICommandPrepare( iface
);
1701 TRACE("%p\n", command
);
1705 struct ICommandPrepareVtbl commandprepareVtbl
=
1707 commandprepare_QueryInterface
,
1708 commandprepare_AddRef
,
1709 commandprepare_Release
,
1710 commandprepare_Prepare
,
1711 commandprepare_Unprepare
1714 static HRESULT WINAPI
cmd_with_params_QueryInterface(ICommandWithParameters
*iface
, REFIID riid
, void **out
)
1716 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1717 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1720 static ULONG WINAPI
cmd_with_params_AddRef(ICommandWithParameters
*iface
)
1722 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1723 return ICommandText_AddRef(&command
->ICommandText_iface
);
1726 static ULONG WINAPI
cmd_with_params_Release(ICommandWithParameters
*iface
)
1728 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1729 return ICommandText_Release(&command
->ICommandText_iface
);
1732 static HRESULT WINAPI
cmd_with_params_GetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS
*uparams
,
1733 DBPARAMINFO
**info
, OLECHAR
**buffer
)
1735 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1736 FIXME("%p, %p, %p, %p\n", command
, uparams
, info
, buffer
);
1740 static HRESULT WINAPI
cmd_with_params_MapParameterNames(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1741 LPCWSTR names
[], DB_LPARAMS ordinals
[])
1743 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1744 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, names
, ordinals
);
1748 static HRESULT WINAPI
cmd_with_params_SetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1749 const DB_UPARAMS ordinals
[], const DBPARAMBINDINFO bindinfo
[])
1751 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1752 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, ordinals
, bindinfo
);
1756 struct ICommandWithParametersVtbl command_with_params_vtbl
=
1758 cmd_with_params_QueryInterface
,
1759 cmd_with_params_AddRef
,
1760 cmd_with_params_Release
,
1761 cmd_with_params_GetParameterInfo
,
1762 cmd_with_params_MapParameterNames
,
1763 cmd_with_params_SetParameterInfo
1766 static HRESULT WINAPI
createcommand_CreateCommand(IDBCreateCommand
*iface
, IUnknown
*outer
, REFIID riid
,
1769 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
1770 struct command
*command
;
1773 TRACE("%p, %p, %s, %p\n", session
, outer
, debugstr_guid(riid
), out
);
1776 FIXME("Outer not currently supported\n");
1778 command
= heap_alloc(sizeof(*command
));
1780 return E_OUTOFMEMORY
;
1782 command
->ICommandText_iface
.lpVtbl
= &commandVtbl
;
1783 command
->ICommandProperties_iface
.lpVtbl
= &commonpropsVtbl
;
1784 command
->IColumnsInfo_iface
.lpVtbl
= &columninfoVtbl
;
1785 command
->IConvertType_iface
.lpVtbl
= &converttypeVtbl
;
1786 command
->ICommandPrepare_iface
.lpVtbl
= &commandprepareVtbl
;
1787 command
->ICommandWithParameters_iface
.lpVtbl
= &command_with_params_vtbl
;
1789 command
->query
= NULL
;
1790 command
->hdbc
= session
->hdbc
;
1791 command
->hstmt
= NULL
;
1793 command
->prop_count
= ARRAY_SIZE(msdasql_init_props
);
1794 command
->properties
= heap_alloc(sizeof(msdasql_init_props
));
1795 memcpy(command
->properties
, msdasql_init_props
, sizeof(msdasql_init_props
));
1797 IUnknown_QueryInterface(&session
->session_iface
, &IID_IUnknown
, (void**)&command
->session
);
1799 hr
= ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, (void**)out
);
1800 ICommandText_Release(&command
->ICommandText_iface
);
1804 static const IDBCreateCommandVtbl createcommandVtbl
=
1806 createcommand_QueryInterface
,
1807 createcommand_AddRef
,
1808 createcommand_Release
,
1809 createcommand_CreateCommand
1812 static HRESULT WINAPI
transjoin_QueryInterface(ITransactionJoin
*iface
, REFIID riid
, void **out
)
1814 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1815 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1818 static ULONG WINAPI
transjoin_AddRef(ITransactionJoin
*iface
)
1820 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1821 return IUnknown_AddRef(&session
->session_iface
);
1824 static ULONG WINAPI
transjoin_Release(ITransactionJoin
*iface
)
1826 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1827 return IUnknown_Release(&session
->session_iface
);
1830 static HRESULT WINAPI
transjoin_GetOptionsObject(ITransactionJoin
*iface
, ITransactionOptions
**options
)
1832 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1834 FIXME("%p, %p\n", session
, options
);
1839 static HRESULT WINAPI
transjoin_JoinTransaction(ITransactionJoin
*iface
, IUnknown
*unk
, ISOLEVEL level
,
1840 ULONG flags
, ITransactionOptions
*options
)
1842 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1844 FIXME("%p, %p, %lu, 0x%08lx, %p\n", session
, unk
, level
, flags
, options
);
1849 static const ITransactionJoinVtbl transactionjoinVtbl
=
1851 transjoin_QueryInterface
,
1854 transjoin_GetOptionsObject
,
1855 transjoin_JoinTransaction
1858 static HRESULT WINAPI
transaction_QueryInterface(ITransaction
*iface
, REFIID riid
, void **out
)
1860 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1861 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1864 static ULONG WINAPI
transaction_AddRef(ITransaction
*iface
)
1866 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1867 return IUnknown_AddRef(&session
->session_iface
);
1870 static ULONG WINAPI
transaction_Release(ITransaction
*iface
)
1872 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1873 return IUnknown_Release(&session
->session_iface
);
1876 static HRESULT WINAPI
transaction_Commit(ITransaction
*iface
, BOOL retaining
, DWORD tc
, DWORD rm
)
1878 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1880 FIXME("%p, %d, %ld, %ld\n", session
, retaining
, tc
, rm
);
1885 static HRESULT WINAPI
transaction_Abort(ITransaction
*iface
, BOID
*reason
, BOOL retaining
, BOOL async
)
1887 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1889 FIXME("%p, %p, %d, %d\n", session
, reason
, retaining
, async
);
1894 static HRESULT WINAPI
transaction_GetTransactionInfo(ITransaction
*iface
, XACTTRANSINFO
*info
)
1896 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1898 FIXME("%p, %p\n", session
, info
);
1903 static const ITransactionVtbl transactionVtbl
=
1905 transaction_QueryInterface
,
1907 transaction_Release
,
1910 transaction_GetTransactionInfo
1913 HRESULT
create_db_session(REFIID riid
, IUnknown
*datasource
, HDBC hdbc
, void **unk
)
1915 struct msdasql_session
*session
;
1918 session
= heap_alloc(sizeof(*session
));
1920 return E_OUTOFMEMORY
;
1922 session
->session_iface
.lpVtbl
= &unkfactoryVtbl
;
1923 session
->IGetDataSource_iface
.lpVtbl
= &datasourceVtbl
;
1924 session
->IOpenRowset_iface
.lpVtbl
= &openrowsetVtbl
;
1925 session
->ISessionProperties_iface
.lpVtbl
= &propertiesVtbl
;
1926 session
->IDBCreateCommand_iface
.lpVtbl
= &createcommandVtbl
;
1927 session
->ITransactionJoin_iface
.lpVtbl
= &transactionjoinVtbl
;
1928 session
->ITransaction_iface
.lpVtbl
= &transactionVtbl
;
1930 IUnknown_QueryInterface(datasource
, &IID_IUnknown
, (void**)&session
->datasource
);
1932 session
->hdbc
= hdbc
;
1934 hr
= IUnknown_QueryInterface(&session
->session_iface
, riid
, unk
);
1935 IUnknown_Release(&session
->session_iface
);