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 if (command
->properties
)
697 heap_free(command
->properties
);
698 if (command
->session
)
699 IUnknown_Release(command
->session
);
702 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
704 heap_free( command
->query
);
705 heap_free( command
);
710 static HRESULT WINAPI
command_Cancel(ICommandText
*iface
)
712 struct command
*command
= impl_from_ICommandText( iface
);
713 FIXME("%p\n", command
);
717 struct msdasql_rowset
719 IRowset IRowset_iface
;
720 IRowsetInfo IRowsetInfo_iface
;
721 IColumnsInfo IColumnsInfo_iface
;
722 IAccessor IAccessor_iface
;
723 IColumnsRowset IColumnsRowset_iface
;
729 static inline struct msdasql_rowset
*impl_from_IRowset( IRowset
*iface
)
731 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IRowset_iface
);
734 static inline struct msdasql_rowset
*impl_from_IRowsetInfo( IRowsetInfo
*iface
)
736 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IRowsetInfo_iface
);
739 static inline struct msdasql_rowset
*rowset_impl_from_IColumnsInfo( IColumnsInfo
*iface
)
741 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IColumnsInfo_iface
);
744 static inline struct msdasql_rowset
*impl_from_IAccessor ( IAccessor
*iface
)
746 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IAccessor_iface
);
749 static inline struct msdasql_rowset
*impl_from_IColumnsRowset ( IColumnsRowset
*iface
)
751 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IColumnsRowset_iface
);
754 static HRESULT WINAPI
msdasql_rowset_QueryInterface(IRowset
*iface
, REFIID riid
, void **ppv
)
756 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
758 TRACE( "%p, %s, %p\n", rowset
, debugstr_guid(riid
), ppv
);
761 if(IsEqualGUID(&IID_IUnknown
, riid
) ||
762 IsEqualGUID(&IID_IRowset
, riid
))
764 *ppv
= &rowset
->IRowset_iface
;
766 else if (IsEqualGUID(&IID_IRowsetInfo
, riid
))
768 *ppv
= &rowset
->IRowsetInfo_iface
;
770 else if (IsEqualGUID(&IID_IColumnsInfo
, riid
))
772 *ppv
= &rowset
->IColumnsInfo_iface
;
774 else if(IsEqualGUID(&IID_IAccessor
, riid
))
776 *ppv
= &rowset
->IAccessor_iface
;
778 else if(IsEqualGUID(&IID_IColumnsRowset
, riid
))
780 *ppv
= &rowset
->IColumnsRowset_iface
;
782 else if (IsEqualGUID(&IID_IRowsetChange
, riid
))
784 TRACE("IID_IRowsetChange not supported\n");
785 return E_NOINTERFACE
;
787 else if (IsEqualGUID(&IID_IRowsetUpdate
, riid
))
789 TRACE("IID_IRowsetUpdate not supported\n");
790 return E_NOINTERFACE
;
792 else if (IsEqualGUID(&IID_IRowsetLocate
, riid
))
794 TRACE("IID_IRowsetLocate not supported\n");
795 return E_NOINTERFACE
;
800 IUnknown_AddRef((IUnknown
*)*ppv
);
804 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
805 return E_NOINTERFACE
;
808 static ULONG WINAPI
msdasql_rowset_AddRef(IRowset
*iface
)
810 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
811 LONG refs
= InterlockedIncrement( &rowset
->refs
);
812 TRACE( "%p new refcount %ld\n", rowset
, refs
);
816 static ULONG WINAPI
msdasql_rowset_Release(IRowset
*iface
)
818 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
819 LONG refs
= InterlockedDecrement( &rowset
->refs
);
820 TRACE( "%p new refcount %ld\n", rowset
, refs
);
823 TRACE( "destroying %p\n", rowset
);
825 SQLFreeHandle(SQL_HANDLE_STMT
, rowset
->hstmt
);
828 IUnknown_Release(rowset
->caller
);
835 static HRESULT WINAPI
msdasql_rowset_AddRefRows(IRowset
*iface
, DBCOUNTITEM count
,
836 const HROW rows
[], DBREFCOUNT ref_counts
[], DBROWSTATUS status
[])
838 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
839 FIXME("%p, %Id, %p, %p, %p\n", rowset
, count
, rows
, ref_counts
, status
);
843 static HRESULT WINAPI
msdasql_rowset_GetData(IRowset
*iface
, HROW row
, HACCESSOR accessor
, void *data
)
845 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
846 FIXME("%p, %Id, %Id, %p\n", rowset
, row
, accessor
, data
);
850 static HRESULT WINAPI
msdasql_rowset_GetNextRows(IRowset
*iface
, HCHAPTER reserved
, DBROWOFFSET offset
,
851 DBROWCOUNT count
, DBCOUNTITEM
*obtained
, HROW
**rows
)
853 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
854 FIXME("%p, %Id, %Id, %Id, %p, %p\n", rowset
, reserved
, offset
, count
, obtained
, rows
);
858 static HRESULT WINAPI
msdasql_rowset_ReleaseRows(IRowset
*iface
, DBCOUNTITEM count
,
859 const HROW rows
[], DBROWOPTIONS options
[], DBREFCOUNT ref_counts
[], DBROWSTATUS status
[])
861 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
863 FIXME("%p, %Id, %p, %p, %p, %p\n", rowset
, count
, rows
, options
, ref_counts
, status
);
867 static HRESULT WINAPI
msdasql_rowset_RestartPosition(IRowset
*iface
, HCHAPTER reserved
)
869 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
870 FIXME("%p, %Id\n", rowset
, reserved
);
874 static const struct IRowsetVtbl msdasql_rowset_vtbl
=
876 msdasql_rowset_QueryInterface
,
877 msdasql_rowset_AddRef
,
878 msdasql_rowset_Release
,
879 msdasql_rowset_AddRefRows
,
880 msdasql_rowset_GetData
,
881 msdasql_rowset_GetNextRows
,
882 msdasql_rowset_ReleaseRows
,
883 msdasql_rowset_RestartPosition
886 static HRESULT WINAPI
rowset_info_QueryInterface(IRowsetInfo
*iface
, REFIID riid
, void **ppv
)
888 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
889 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, ppv
);
892 static ULONG WINAPI
rowset_info_AddRef(IRowsetInfo
*iface
)
894 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
895 return IRowset_AddRef(&rowset
->IRowset_iface
);
898 static ULONG WINAPI
rowset_info_Release(IRowsetInfo
*iface
)
900 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
901 return IRowset_Release(&rowset
->IRowset_iface
);
904 static HRESULT WINAPI
rowset_info_GetProperties(IRowsetInfo
*iface
, const ULONG count
,
905 const DBPROPIDSET propertyidsets
[], ULONG
*out_count
, DBPROPSET
**propertysets
)
907 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
909 ICommandProperties
*props
;
911 TRACE("%p, %lu, %p, %p, %p\n", rowset
, count
, propertyidsets
, out_count
, propertysets
);
913 hr
= IUnknown_QueryInterface(rowset
->caller
, &IID_ICommandProperties
, (void**)&props
);
917 hr
= ICommandProperties_GetProperties(props
, count
, propertyidsets
, out_count
, propertysets
);
918 ICommandProperties_Release(props
);
923 static HRESULT WINAPI
rowset_info_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL ordinal
,
924 REFIID riid
, IUnknown
**unk
)
926 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
927 FIXME("%p, %Id, %s, %p\n", rowset
, ordinal
, debugstr_guid(riid
), unk
);
931 static HRESULT WINAPI
rowset_info_GetSpecification(IRowsetInfo
*iface
, REFIID riid
,
932 IUnknown
**specification
)
934 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
936 TRACE("%p, %s, %p\n", rowset
, debugstr_guid(riid
), specification
);
944 return IUnknown_QueryInterface(rowset
->caller
, riid
, (void**)specification
);
947 struct IRowsetInfoVtbl rowset_info_vtbl
=
949 rowset_info_QueryInterface
,
952 rowset_info_GetProperties
,
953 rowset_info_GetReferencedRowset
,
954 rowset_info_GetSpecification
957 static HRESULT WINAPI
rowset_colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
959 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
960 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
963 static ULONG WINAPI
rowset_colsinfo_AddRef(IColumnsInfo
*iface
)
965 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
966 return IRowset_AddRef(&rowset
->IRowset_iface
);
969 static ULONG WINAPI
rowset_colsinfo_Release(IColumnsInfo
*iface
)
971 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
972 return IRowset_Release(&rowset
->IRowset_iface
);
975 static HRESULT WINAPI
rowset_colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
976 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
978 #define MAX_COLUMN_LEN 128
980 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
981 DBCOLUMNINFO
*dbcolumn
;
987 TRACE("%p, %p, %p, %p\n", rowset
, columns
, colinfo
, stringsbuffer
);
989 if (!columns
|| !colinfo
|| !stringsbuffer
)
992 SQLNumResultCols(rowset
->hstmt
, &colcnt
);
993 TRACE("SQLNumResultCols %d\n", colcnt
);
997 ptr
= *stringsbuffer
= CoTaskMemAlloc(colcnt
* MAX_COLUMN_LEN
* sizeof(WCHAR
));
999 return E_OUTOFMEMORY
;
1001 dbcolumn
= CoTaskMemAlloc(colcnt
* sizeof(DBCOLUMNINFO
));
1005 return E_OUTOFMEMORY
;
1008 for (i
= 0; i
< colcnt
; i
++)
1010 SQLWCHAR columnname
[MAX_COLUMN_LEN
];
1011 SQLSMALLINT ColumnNameLen
;
1012 SQLSMALLINT ColumnDataType
;
1013 SQLULEN ColumnDataSize
;
1014 SQLSMALLINT ColumnDataDigits
;
1015 SQLSMALLINT ColumnDataNullable
;
1017 ret
= SQLDescribeColW(rowset
->hstmt
, i
+1, columnname
, MAX_COLUMN_LEN
, &ColumnNameLen
, &ColumnDataType
,
1018 &ColumnDataSize
, &ColumnDataDigits
, &ColumnDataNullable
);
1019 if (SQL_SUCCEEDED(ret
))
1023 TRACE("%d: Column Name : %s, Column Name Len : %i, SQL Data Type : %i, Data Size : %i, DecimalDigits : %i, Nullable %i\n",
1024 i
, debugstr_w(columnname
), (int)ColumnNameLen
, (int)ColumnDataType
, (int)ColumnDataSize
, (int)ColumnDataDigits
,
1025 (int)ColumnDataNullable
);
1026 lstrcpyW(ptr
, columnname
);
1028 dbcolumn
[i
].pwszName
= ptr
;
1029 dbcolumn
[i
].pTypeInfo
= NULL
;
1030 dbcolumn
[i
].iOrdinal
= i
+1;
1032 ret
= SQLColAttribute(rowset
->hstmt
, i
+1, SQL_DESC_UNSIGNED
, NULL
, 0, NULL
, &length
);
1033 if (!SQL_SUCCEEDED(ret
))
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
= SQLColAttribute(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
= SQLColAttribute(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
= SQLColAttribute(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;
1246 TRACE("%p, %p, %s, %p %p %p\n", command
, outer
, debugstr_guid(riid
), params
, affected
, rowset
);
1249 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &hstmt
);
1251 ret
= SQLExecDirectW(hstmt
, command
->query
, SQL_NTS
);
1252 if (ret
!= SQL_SUCCESS
)
1254 dump_sql_diag_records(SQL_HANDLE_STMT
, hstmt
);
1259 if (!wcsnicmp( command
->query
, L
"select ", 7 ))
1261 msrowset
= heap_alloc(sizeof(*msrowset
));
1263 return E_OUTOFMEMORY
;
1265 command
->hstmt
= NULL
;
1267 msrowset
->IRowset_iface
.lpVtbl
= &msdasql_rowset_vtbl
;
1268 msrowset
->IRowsetInfo_iface
.lpVtbl
= &rowset_info_vtbl
;
1269 msrowset
->IColumnsInfo_iface
.lpVtbl
= &rowset_columninfo_vtbll
;
1270 msrowset
->IAccessor_iface
.lpVtbl
= &accessor_vtbl
;
1271 msrowset
->IColumnsRowset_iface
.lpVtbl
= &columnrs_rs_vtbl
;
1273 ICommandText_QueryInterface(iface
, &IID_IUnknown
, (void**)&msrowset
->caller
);
1274 msrowset
->hstmt
= hstmt
;
1276 hr
= IRowset_QueryInterface(&msrowset
->IRowset_iface
, riid
, (void**)rowset
);
1277 IRowset_Release(&msrowset
->IRowset_iface
);
1281 ret
= SQLRowCount(hstmt
, &results
);
1282 if (ret
!= SQL_SUCCESS
)
1283 ERR("SQLRowCount failed (%d)\n", ret
);
1285 SQLFreeStmt(hstmt
, SQL_CLOSE
);
1289 *affected
= results
;
1294 static HRESULT WINAPI
command_GetDBSession(ICommandText
*iface
, REFIID riid
, IUnknown
**session
)
1296 struct command
*command
= impl_from_ICommandText( iface
);
1298 TRACE("%p, %s, %p\n", command
, debugstr_guid(riid
), session
);
1301 return E_INVALIDARG
;
1305 if (!command
->session
)
1308 return IUnknown_QueryInterface(command
->session
, riid
, (void**)session
);
1311 static HRESULT WINAPI
command_GetCommandText(ICommandText
*iface
, GUID
*dialect
, LPOLESTR
*commandstr
)
1313 struct command
*command
= impl_from_ICommandText( iface
);
1315 TRACE("%p, %p, %p\n", command
, dialect
, commandstr
);
1317 if (!command
->query
)
1318 return DB_E_NOCOMMAND
;
1320 if (dialect
&& !IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1322 *dialect
= DBGUID_DEFAULT
;
1323 hr
= DB_S_DIALECTIGNORED
;
1326 *commandstr
= heap_alloc((lstrlenW(command
->query
)+1)*sizeof(WCHAR
));
1327 wcscpy(*commandstr
, command
->query
);
1331 static HRESULT WINAPI
command_SetCommandText(ICommandText
*iface
, REFGUID dialect
, LPCOLESTR commandstr
)
1333 struct command
*command
= impl_from_ICommandText( iface
);
1334 TRACE("%p, %s, %s\n", command
, debugstr_guid(dialect
), debugstr_w(commandstr
));
1336 if (!IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1337 FIXME("Currently non Default Dialect isn't supported\n");
1339 heap_free(command
->query
);
1343 command
->query
= heap_alloc((lstrlenW(commandstr
)+1)*sizeof(WCHAR
));
1344 if (!command
->query
)
1345 return E_OUTOFMEMORY
;
1347 wcscpy(command
->query
, commandstr
);
1350 command
->query
= NULL
;
1354 static const ICommandTextVtbl commandVtbl
=
1356 command_QueryInterface
,
1361 command_GetDBSession
,
1362 command_GetCommandText
,
1363 command_SetCommandText
1366 static HRESULT WINAPI
command_prop_QueryInterface(ICommandProperties
*iface
, REFIID riid
, void **out
)
1368 struct command
*command
= impl_from_ICommandProperties( iface
);
1369 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1372 static ULONG WINAPI
command_prop_AddRef(ICommandProperties
*iface
)
1374 struct command
*command
= impl_from_ICommandProperties( iface
);
1375 return ICommandText_AddRef(&command
->ICommandText_iface
);
1378 static ULONG WINAPI
command_prop_Release(ICommandProperties
*iface
)
1380 struct command
*command
= impl_from_ICommandProperties( iface
);
1381 return ICommandText_Release(&command
->ICommandText_iface
);
1384 static ULONG
get_property_count(DWORD flag
, struct msdasql_prop
*properties
, int prop_count
)
1388 for(i
=0; i
< prop_count
; i
++)
1390 if (properties
[i
].flags
& flag
)
1397 static HRESULT WINAPI
command_prop_GetProperties(ICommandProperties
*iface
, ULONG count
,
1398 const DBPROPIDSET propertyidsets
[], ULONG
*sets_cnt
, DBPROPSET
**propertyset
)
1400 struct command
*command
= impl_from_ICommandProperties( iface
);
1401 DBPROPSET
*propset
= NULL
;
1404 TRACE("%p %ld %p %p %p\n", command
, count
, propertyidsets
, sets_cnt
, propertyset
);
1406 /* All Properties */
1410 propset
= CoTaskMemAlloc(2 * sizeof(DBPROPSET
));
1412 return E_OUTOFMEMORY
;
1414 propset
[0].guidPropertySet
= DBPROPSET_ROWSET
;
1415 propset
[0].cProperties
= get_property_count(DBPROPFLAGS_ROWSET
, command
->properties
, command
->prop_count
);
1416 propset
[0].rgProperties
= CoTaskMemAlloc(propset
[0].cProperties
* sizeof(DBPROP
));
1417 if (!propset
[0].rgProperties
)
1419 CoTaskMemFree(propset
);
1420 return E_OUTOFMEMORY
;
1424 for (j
=0; j
< command
->prop_count
; j
++)
1426 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_ROWSET
))
1428 propset
[0].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1430 V_VT(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1431 if (command
->properties
[j
].vartype
== VT_BOOL
)
1433 V_BOOL(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1435 else if (command
->properties
[j
].vartype
== VT_I4
)
1437 V_I4(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1440 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1445 propset
[1].guidPropertySet
= DBPROPSET_PROVIDERROWSET
;
1446 propset
[1].cProperties
= get_property_count(DBPROPFLAGS_DATASOURCEINFO
, command
->properties
, command
->prop_count
);
1447 propset
[1].rgProperties
= CoTaskMemAlloc(propset
[1].cProperties
* sizeof(DBPROP
));
1448 if (!propset
[1].rgProperties
)
1450 CoTaskMemFree(propset
[0].rgProperties
);
1451 CoTaskMemFree(propset
);
1452 return E_OUTOFMEMORY
;
1456 for (j
=0; j
< command
->prop_count
; j
++)
1458 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_DATASOURCEINFO
))
1460 propset
[1].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1462 V_VT(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1463 if (command
->properties
[j
].vartype
== VT_BOOL
)
1465 V_BOOL(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1467 else if (command
->properties
[j
].vartype
== VT_I4
)
1469 V_I4(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1472 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1481 propset
= CoTaskMemAlloc(count
* sizeof(DBPROPSET
));
1483 return E_OUTOFMEMORY
;
1485 for (i
=0; i
< count
; i
++)
1487 TRACE("Property id %d (count %ld, set %s)\n", i
, propertyidsets
[i
].cPropertyIDs
,
1488 debugstr_guid(&propertyidsets
[i
].guidPropertySet
));
1490 propset
[i
].cProperties
= propertyidsets
[i
].cPropertyIDs
;
1491 propset
[i
].rgProperties
= CoTaskMemAlloc(propset
[i
].cProperties
* sizeof(DBPROP
));
1493 for (j
=0; j
< propset
[i
].cProperties
; j
++)
1495 propset
[i
].rgProperties
[j
].dwPropertyID
= propertyidsets
[i
].rgPropertyIDs
[j
];
1497 for(k
= 0; k
< command
->prop_count
; k
++)
1499 if (command
->properties
[k
].property_id
== propertyidsets
[i
].rgPropertyIDs
[j
])
1501 V_VT(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].vartype
;
1502 if (command
->properties
[j
].vartype
== VT_BOOL
)
1504 V_BOOL(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1506 else if (command
->properties
[j
].vartype
== VT_I4
)
1508 V_I4(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1511 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1521 *propertyset
= propset
;
1526 static HRESULT WINAPI
command_prop_SetProperties(ICommandProperties
*iface
, ULONG count
,
1527 DBPROPSET propertyset
[])
1529 struct command
*command
= impl_from_ICommandProperties( iface
);
1532 TRACE("%p %lu, %p\n", command
, count
, propertyset
);
1534 for(i
=0; i
< count
; i
++)
1536 TRACE("set %s, count %ld\n", debugstr_guid(&propertyset
[i
].guidPropertySet
), propertyset
[i
].cProperties
);
1537 for(j
=0; j
< propertyset
[i
].cProperties
; j
++)
1539 for(k
=0; k
< command
->prop_count
; k
++)
1541 if (command
->properties
[k
].property_id
== propertyset
[i
].rgProperties
[j
].dwPropertyID
)
1543 TRACE("Found property 0x%08lx\n", command
->properties
[k
].property_id
);
1544 if (command
->properties
[k
].flags
& DBPROPFLAGS_WRITE
)
1546 if (command
->properties
[k
].vartype
== VT_BOOL
)
1548 command
->properties
[k
].value
= V_BOOL(&propertyset
[i
].rgProperties
[j
].vValue
);
1550 else if (command
->properties
[k
].vartype
== VT_I4
)
1552 command
->properties
[k
].value
= V_I4(&propertyset
[i
].rgProperties
[j
].vValue
);
1555 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1558 WARN("Attempting to set Readonly property\n");
1568 static const ICommandPropertiesVtbl commonpropsVtbl
=
1570 command_prop_QueryInterface
,
1571 command_prop_AddRef
,
1572 command_prop_Release
,
1573 command_prop_GetProperties
,
1574 command_prop_SetProperties
1577 static HRESULT WINAPI
colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
1579 struct command
*command
= impl_from_IColumnsInfo( iface
);
1580 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1583 static ULONG WINAPI
colsinfo_AddRef(IColumnsInfo
*iface
)
1585 struct command
*command
= impl_from_IColumnsInfo( iface
);
1586 return ICommandText_AddRef(&command
->ICommandText_iface
);
1589 static ULONG WINAPI
colsinfo_Release(IColumnsInfo
*iface
)
1591 struct command
*command
= impl_from_IColumnsInfo( iface
);
1592 return ICommandText_Release(&command
->ICommandText_iface
);
1595 static HRESULT WINAPI
colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
1596 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
1598 struct command
*command
= impl_from_IColumnsInfo( iface
);
1599 FIXME("%p, %p, %p, %p\n", command
, columns
, colinfo
, stringsbuffer
);
1603 static HRESULT WINAPI
colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1604 const DBID
*dbids
, DBORDINAL
*columns
)
1606 struct command
*command
= impl_from_IColumnsInfo( iface
);
1607 FIXME("%p, %Iu, %p, %p\n", command
, column_ids
, dbids
, columns
);
1611 static struct IColumnsInfoVtbl columninfoVtbl
=
1613 colsinfo_QueryInterface
,
1616 colsinfo_GetColumnInfo
,
1617 colsinfo_MapColumnIDs
1620 static HRESULT WINAPI
converttype_QueryInterface(IConvertType
*iface
, REFIID riid
, void **out
)
1622 struct command
*command
= impl_from_IConvertType( iface
);
1623 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1626 static ULONG WINAPI
converttype_AddRef(IConvertType
*iface
)
1628 struct command
*command
= impl_from_IConvertType( iface
);
1629 return ICommandText_AddRef(&command
->ICommandText_iface
);
1632 static ULONG WINAPI
converttype_Release(IConvertType
*iface
)
1634 struct command
*command
= impl_from_IConvertType( iface
);
1635 return ICommandText_Release(&command
->ICommandText_iface
);
1638 static HRESULT WINAPI
converttype_CanConvert(IConvertType
*iface
, DBTYPE from
, DBTYPE to
, DBCONVERTFLAGS flags
)
1640 struct command
*command
= impl_from_IConvertType( iface
);
1641 FIXME("%p, %u, %d, 0x%08lx\n", command
, from
, to
, flags
);
1645 static struct IConvertTypeVtbl converttypeVtbl
=
1647 converttype_QueryInterface
,
1649 converttype_Release
,
1650 converttype_CanConvert
1653 static HRESULT WINAPI
commandprepare_QueryInterface(ICommandPrepare
*iface
, REFIID riid
, void **out
)
1655 struct command
*command
= impl_from_ICommandPrepare( iface
);
1656 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1659 static ULONG WINAPI
commandprepare_AddRef(ICommandPrepare
*iface
)
1661 struct command
*command
= impl_from_ICommandPrepare( iface
);
1662 return ICommandText_AddRef(&command
->ICommandText_iface
);
1665 static ULONG WINAPI
commandprepare_Release(ICommandPrepare
*iface
)
1667 struct command
*command
= impl_from_ICommandPrepare( iface
);
1668 return ICommandText_Release(&command
->ICommandText_iface
);
1671 static HRESULT WINAPI
commandprepare_Prepare(ICommandPrepare
*iface
, ULONG runs
)
1673 struct command
*command
= impl_from_ICommandPrepare( iface
);
1676 TRACE("%p, %lu\n", command
, runs
);
1678 if (!command
->query
)
1679 return DB_E_NOCOMMAND
;
1682 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
1684 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &command
->hstmt
);
1686 ret
= SQLPrepareW(command
->hstmt
, command
->query
, SQL_NTS
);
1687 if (ret
!= SQL_SUCCESS
)
1689 dump_sql_diag_records(SQL_HANDLE_STMT
, command
->hstmt
);
1695 static HRESULT WINAPI
commandprepare_Unprepare(ICommandPrepare
*iface
)
1697 struct command
*command
= impl_from_ICommandPrepare( iface
);
1698 TRACE("%p\n", command
);
1702 struct ICommandPrepareVtbl commandprepareVtbl
=
1704 commandprepare_QueryInterface
,
1705 commandprepare_AddRef
,
1706 commandprepare_Release
,
1707 commandprepare_Prepare
,
1708 commandprepare_Unprepare
1711 static HRESULT WINAPI
cmd_with_params_QueryInterface(ICommandWithParameters
*iface
, REFIID riid
, void **out
)
1713 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1714 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1717 static ULONG WINAPI
cmd_with_params_AddRef(ICommandWithParameters
*iface
)
1719 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1720 return ICommandText_AddRef(&command
->ICommandText_iface
);
1723 static ULONG WINAPI
cmd_with_params_Release(ICommandWithParameters
*iface
)
1725 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1726 return ICommandText_Release(&command
->ICommandText_iface
);
1729 static HRESULT WINAPI
cmd_with_params_GetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS
*uparams
,
1730 DBPARAMINFO
**info
, OLECHAR
**buffer
)
1732 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1733 FIXME("%p, %p, %p, %p\n", command
, uparams
, info
, buffer
);
1737 static HRESULT WINAPI
cmd_with_params_MapParameterNames(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1738 LPCWSTR names
[], DB_LPARAMS ordinals
[])
1740 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1741 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, names
, ordinals
);
1745 static HRESULT WINAPI
cmd_with_params_SetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1746 const DB_UPARAMS ordinals
[], const DBPARAMBINDINFO bindinfo
[])
1748 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1749 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, ordinals
, bindinfo
);
1753 struct ICommandWithParametersVtbl command_with_params_vtbl
=
1755 cmd_with_params_QueryInterface
,
1756 cmd_with_params_AddRef
,
1757 cmd_with_params_Release
,
1758 cmd_with_params_GetParameterInfo
,
1759 cmd_with_params_MapParameterNames
,
1760 cmd_with_params_SetParameterInfo
1763 static HRESULT WINAPI
createcommand_CreateCommand(IDBCreateCommand
*iface
, IUnknown
*outer
, REFIID riid
,
1766 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
1767 struct command
*command
;
1770 TRACE("%p, %p, %s, %p\n", session
, outer
, debugstr_guid(riid
), out
);
1773 FIXME("Outer not currently supported\n");
1775 command
= heap_alloc(sizeof(*command
));
1777 return E_OUTOFMEMORY
;
1779 command
->ICommandText_iface
.lpVtbl
= &commandVtbl
;
1780 command
->ICommandProperties_iface
.lpVtbl
= &commonpropsVtbl
;
1781 command
->IColumnsInfo_iface
.lpVtbl
= &columninfoVtbl
;
1782 command
->IConvertType_iface
.lpVtbl
= &converttypeVtbl
;
1783 command
->ICommandPrepare_iface
.lpVtbl
= &commandprepareVtbl
;
1784 command
->ICommandWithParameters_iface
.lpVtbl
= &command_with_params_vtbl
;
1786 command
->query
= NULL
;
1787 command
->hdbc
= session
->hdbc
;
1788 command
->hstmt
= NULL
;
1790 command
->prop_count
= ARRAY_SIZE(msdasql_init_props
);
1791 command
->properties
= heap_alloc(sizeof(msdasql_init_props
));
1792 memcpy(command
->properties
, msdasql_init_props
, sizeof(msdasql_init_props
));
1794 IUnknown_QueryInterface(&session
->session_iface
, &IID_IUnknown
, (void**)&command
->session
);
1796 hr
= ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, (void**)out
);
1797 ICommandText_Release(&command
->ICommandText_iface
);
1801 static const IDBCreateCommandVtbl createcommandVtbl
=
1803 createcommand_QueryInterface
,
1804 createcommand_AddRef
,
1805 createcommand_Release
,
1806 createcommand_CreateCommand
1809 static HRESULT WINAPI
transjoin_QueryInterface(ITransactionJoin
*iface
, REFIID riid
, void **out
)
1811 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1812 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1815 static ULONG WINAPI
transjoin_AddRef(ITransactionJoin
*iface
)
1817 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1818 return IUnknown_AddRef(&session
->session_iface
);
1821 static ULONG WINAPI
transjoin_Release(ITransactionJoin
*iface
)
1823 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1824 return IUnknown_Release(&session
->session_iface
);
1827 static HRESULT WINAPI
transjoin_GetOptionsObject(ITransactionJoin
*iface
, ITransactionOptions
**options
)
1829 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1831 FIXME("%p, %p\n", session
, options
);
1836 static HRESULT WINAPI
transjoin_JoinTransaction(ITransactionJoin
*iface
, IUnknown
*unk
, ISOLEVEL level
,
1837 ULONG flags
, ITransactionOptions
*options
)
1839 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1841 FIXME("%p, %p, %lu, 0x%08lx, %p\n", session
, unk
, level
, flags
, options
);
1846 static const ITransactionJoinVtbl transactionjoinVtbl
=
1848 transjoin_QueryInterface
,
1851 transjoin_GetOptionsObject
,
1852 transjoin_JoinTransaction
1855 static HRESULT WINAPI
transaction_QueryInterface(ITransaction
*iface
, REFIID riid
, void **out
)
1857 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1858 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1861 static ULONG WINAPI
transaction_AddRef(ITransaction
*iface
)
1863 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1864 return IUnknown_AddRef(&session
->session_iface
);
1867 static ULONG WINAPI
transaction_Release(ITransaction
*iface
)
1869 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1870 return IUnknown_Release(&session
->session_iface
);
1873 static HRESULT WINAPI
transaction_Commit(ITransaction
*iface
, BOOL retaining
, DWORD tc
, DWORD rm
)
1875 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1877 FIXME("%p, %d, %ld, %ld\n", session
, retaining
, tc
, rm
);
1882 static HRESULT WINAPI
transaction_Abort(ITransaction
*iface
, BOID
*reason
, BOOL retaining
, BOOL async
)
1884 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1886 FIXME("%p, %p, %d, %d\n", session
, reason
, retaining
, async
);
1891 static HRESULT WINAPI
transaction_GetTransactionInfo(ITransaction
*iface
, XACTTRANSINFO
*info
)
1893 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1895 FIXME("%p, %p\n", session
, info
);
1900 static const ITransactionVtbl transactionVtbl
=
1902 transaction_QueryInterface
,
1904 transaction_Release
,
1907 transaction_GetTransactionInfo
1910 HRESULT
create_db_session(REFIID riid
, IUnknown
*datasource
, HDBC hdbc
, void **unk
)
1912 struct msdasql_session
*session
;
1915 session
= heap_alloc(sizeof(*session
));
1917 return E_OUTOFMEMORY
;
1919 session
->session_iface
.lpVtbl
= &unkfactoryVtbl
;
1920 session
->IGetDataSource_iface
.lpVtbl
= &datasourceVtbl
;
1921 session
->IOpenRowset_iface
.lpVtbl
= &openrowsetVtbl
;
1922 session
->ISessionProperties_iface
.lpVtbl
= &propertiesVtbl
;
1923 session
->IDBCreateCommand_iface
.lpVtbl
= &createcommandVtbl
;
1924 session
->ITransactionJoin_iface
.lpVtbl
= &transactionjoinVtbl
;
1925 session
->ITransaction_iface
.lpVtbl
= &transactionVtbl
;
1927 IUnknown_QueryInterface(datasource
, &IID_IUnknown
, (void**)&session
->datasource
);
1929 session
->hdbc
= hdbc
;
1931 hr
= IUnknown_QueryInterface(&session
->session_iface
, riid
, unk
);
1932 IUnknown_Release(&session
->session_iface
);