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_legnth(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
);
908 FIXME("%p, %lu, %p, %p, %p\n", rowset
, count
, propertyidsets
, out_count
, propertysets
);
912 static HRESULT WINAPI
rowset_info_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL ordinal
,
913 REFIID riid
, IUnknown
**unk
)
915 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
916 FIXME("%p, %Id, %s, %p\n", rowset
, ordinal
, debugstr_guid(riid
), unk
);
920 static HRESULT WINAPI
rowset_info_GetSpecification(IRowsetInfo
*iface
, REFIID riid
,
921 IUnknown
**specification
)
923 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
925 TRACE("%p, %s, %p\n", rowset
, debugstr_guid(riid
), specification
);
933 return IUnknown_QueryInterface(rowset
->caller
, riid
, (void**)specification
);
936 struct IRowsetInfoVtbl rowset_info_vtbl
=
938 rowset_info_QueryInterface
,
941 rowset_info_GetProperties
,
942 rowset_info_GetReferencedRowset
,
943 rowset_info_GetSpecification
946 static HRESULT WINAPI
rowset_colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
948 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
949 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
952 static ULONG WINAPI
rowset_colsinfo_AddRef(IColumnsInfo
*iface
)
954 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
955 return IRowset_AddRef(&rowset
->IRowset_iface
);
958 static ULONG WINAPI
rowset_colsinfo_Release(IColumnsInfo
*iface
)
960 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
961 return IRowset_Release(&rowset
->IRowset_iface
);
964 static HRESULT WINAPI
rowset_colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
965 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
967 #define MAX_COLUMN_LEN 128
969 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
970 DBCOLUMNINFO
*dbcolumn
;
976 TRACE("%p, %p, %p, %p\n", rowset
, columns
, colinfo
, stringsbuffer
);
978 if (!columns
|| !colinfo
|| !stringsbuffer
)
981 SQLNumResultCols(rowset
->hstmt
, &colcnt
);
982 TRACE("SQLNumResultCols %d\n", colcnt
);
986 ptr
= *stringsbuffer
= CoTaskMemAlloc(colcnt
* MAX_COLUMN_LEN
* sizeof(WCHAR
));
988 return E_OUTOFMEMORY
;
990 dbcolumn
= CoTaskMemAlloc(colcnt
* sizeof(DBCOLUMNINFO
));
994 return E_OUTOFMEMORY
;
997 for (i
= 0; i
< colcnt
; i
++)
999 SQLWCHAR columnname
[MAX_COLUMN_LEN
];
1000 SQLSMALLINT ColumnNameLen
;
1001 SQLSMALLINT ColumnDataType
;
1002 SQLULEN ColumnDataSize
;
1003 SQLSMALLINT ColumnDataDigits
;
1004 SQLSMALLINT ColumnDataNullable
;
1006 ret
= SQLDescribeColW(rowset
->hstmt
, i
+1, columnname
, MAX_COLUMN_LEN
, &ColumnNameLen
, &ColumnDataType
,
1007 &ColumnDataSize
, &ColumnDataDigits
, &ColumnDataNullable
);
1008 if (SQL_SUCCEEDED(ret
))
1012 TRACE("%d: Column Name : %s, Column Name Len : %i, SQL Data Type : %i, Data Size : %i, DecimalDigits : %i, Nullable %i\n",
1013 i
, debugstr_w(columnname
), (int)ColumnNameLen
, (int)ColumnDataType
, (int)ColumnDataSize
, (int)ColumnDataDigits
,
1014 (int)ColumnDataNullable
);
1015 lstrcpyW(ptr
, columnname
);
1017 dbcolumn
[i
].pwszName
= ptr
;
1018 dbcolumn
[i
].pTypeInfo
= NULL
;
1019 dbcolumn
[i
].iOrdinal
= i
+1;
1021 ret
= SQLColAttribute(rowset
->hstmt
, i
+1, SQL_DESC_UNSIGNED
, NULL
, 0, NULL
, &length
);
1022 if (!SQL_SUCCEEDED(ret
))
1025 CoTaskMemFree(dbcolumn
);
1026 ERR("Failed to get column %d attribute\n", i
+1);
1030 dbcolumn
[i
].wType
= sqltype_to_bindtype(ColumnDataType
, length
== SQL_FALSE
);
1031 TRACE("SQLType %s -> %s\n", debugstr_sqltype(ColumnDataType
), debugstr_dbtype(dbcolumn
[i
].wType
));
1033 dbcolumn
[i
].dwFlags
= DBCOLUMNFLAGS_WRITE
;
1035 ret
= SQLColAttribute(rowset
->hstmt
, i
+1, SQL_DESC_LENGTH
, NULL
, 0, NULL
, &length
);
1036 if (!SQL_SUCCEEDED(ret
))
1039 CoTaskMemFree(dbcolumn
);
1040 ERR("Failed to get column %d length (%d)\n", i
+1, ret
);
1043 dbcolumn
[i
].ulColumnSize
= length
;
1045 if (dbcolumn
[i
].ulColumnSize
> 1024 && is_variable_length(ColumnDataType
))
1046 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_MAYDEFER
| DBCOLUMNFLAGS_ISLONG
;
1048 if (ColumnDataNullable
)
1049 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_ISNULLABLE
| DBCOLUMNFLAGS_MAYBENULL
;
1051 if (is_fixed_legnth(ColumnDataType
))
1052 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_ISFIXEDLENGTH
;
1054 ret
= SQLColAttribute(rowset
->hstmt
, i
+1, SQL_DESC_SCALE
, NULL
, 0, NULL
, &length
);
1055 if (!SQL_SUCCEEDED(ret
))
1058 CoTaskMemFree(dbcolumn
);
1059 ERR("Failed to get column %d scale (%d)\n", i
+1, ret
);
1064 dbcolumn
[i
].bScale
= length
;
1066 ret
= SQLColAttribute(rowset
->hstmt
, i
+1, SQL_DESC_PRECISION
, NULL
, 0, NULL
, &length
);
1067 if (!SQL_SUCCEEDED(ret
))
1070 CoTaskMemFree(dbcolumn
);
1071 ERR("Failed to get column %d precision (%d)\n", i
+1, ret
);
1076 dbcolumn
[i
].bPrecision
= length
;
1078 dbcolumn
[i
].columnid
.eKind
= DBKIND_NAME
;
1079 dbcolumn
[i
].columnid
.uName
.pwszName
= ptr
;
1081 ptr
+= ColumnNameLen
+ 1;
1086 CoTaskMemFree(dbcolumn
);
1087 ERR("Failed to get column %d description (%d)\n", i
+1, ret
);
1092 *colinfo
= dbcolumn
;
1093 #undef MAX_COLUMN_LEN
1097 static HRESULT WINAPI
rowset_colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1098 const DBID
*dbids
, DBORDINAL
*columns
)
1100 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
1101 FIXME("%p, %Id, %p, %p\n", rowset
, column_ids
, dbids
, columns
);
1105 static struct IColumnsInfoVtbl rowset_columninfo_vtbll
=
1107 rowset_colsinfo_QueryInterface
,
1108 rowset_colsinfo_AddRef
,
1109 rowset_colsinfo_Release
,
1110 rowset_colsinfo_GetColumnInfo
,
1111 rowset_colsinfo_MapColumnIDs
1114 static HRESULT WINAPI
rowset_accessor_QueryInterface(IAccessor
*iface
, REFIID riid
, void **out
)
1116 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1117 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
1120 static ULONG WINAPI
rowset_accessor_AddRef(IAccessor
*iface
)
1122 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1123 return IRowset_AddRef(&rowset
->IRowset_iface
);
1126 static ULONG WINAPI
rowset_accessor_Release(IAccessor
*iface
)
1128 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1129 return IRowset_Release(&rowset
->IRowset_iface
);
1132 static HRESULT WINAPI
rowset_accessor_AddRefAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
1134 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1135 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
1139 static HRESULT WINAPI
rowset_accessor_CreateAccessor(IAccessor
*iface
, DBACCESSORFLAGS flags
,
1140 DBCOUNTITEM count
, const DBBINDING bindings
[], DBLENGTH row_size
, HACCESSOR
*accessor
,
1141 DBBINDSTATUS status
[])
1143 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1144 FIXME("%p, 0x%08lx, %Id, %p, %Id, %p, %p\n", rowset
, flags
, count
, bindings
, row_size
, accessor
, status
);
1148 static HRESULT WINAPI
rowset_accessor_GetBindings(IAccessor
*iface
, HACCESSOR accessor
,
1149 DBACCESSORFLAGS
*flags
, DBCOUNTITEM
*count
, DBBINDING
**bindings
)
1151 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1152 FIXME("%p, %Id, %p, %p, %p\n", rowset
, accessor
, flags
, count
, bindings
);
1156 static HRESULT WINAPI
rowset_accessor_ReleaseAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
1158 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1159 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
1163 struct IAccessorVtbl accessor_vtbl
=
1165 rowset_accessor_QueryInterface
,
1166 rowset_accessor_AddRef
,
1167 rowset_accessor_Release
,
1168 rowset_accessor_AddRefAccessor
,
1169 rowset_accessor_CreateAccessor
,
1170 rowset_accessor_GetBindings
,
1171 rowset_accessor_ReleaseAccessor
1174 static HRESULT WINAPI
column_rs_QueryInterface(IColumnsRowset
*iface
, REFIID riid
, void **out
)
1176 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1177 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
1180 static ULONG WINAPI
column_rs_AddRef(IColumnsRowset
*iface
)
1182 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1183 return IRowset_AddRef(&rowset
->IRowset_iface
);
1186 static ULONG WINAPI
column_rs_Release(IColumnsRowset
*iface
)
1188 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1189 return IRowset_Release(&rowset
->IRowset_iface
);
1192 static HRESULT WINAPI
column_rs_GetAvailableColumns(IColumnsRowset
*iface
, DBORDINAL
*count
, DBID
**columns
)
1194 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1196 TRACE("%p, %p, %p\n", rowset
, count
, columns
);
1198 if (!count
|| !columns
)
1199 return E_INVALIDARG
;
1207 static HRESULT WINAPI
column_rs_GetColumnsRowset(IColumnsRowset
*iface
, IUnknown
*outer
, DBORDINAL count
,
1208 const DBID columns
[], REFIID riid
, ULONG property_cnt
, DBPROPSET property_sets
[], IUnknown
**unk_rs
)
1210 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1211 FIXME("(%p)->(%p, %Id, %p, %s, %lu, %p, %p): stub\n", rowset
, outer
, count
, columns
, debugstr_guid(riid
),
1212 property_cnt
, property_sets
, unk_rs
);
1216 struct IColumnsRowsetVtbl columnrs_rs_vtbl
=
1218 column_rs_QueryInterface
,
1221 column_rs_GetAvailableColumns
,
1222 column_rs_GetColumnsRowset
1225 static HRESULT WINAPI
command_Execute(ICommandText
*iface
, IUnknown
*outer
, REFIID riid
,
1226 DBPARAMS
*params
, DBROWCOUNT
*affected
, IUnknown
**rowset
)
1228 struct command
*command
= impl_from_ICommandText( iface
);
1229 struct msdasql_rowset
*msrowset
;
1232 SQLHSTMT hstmt
= command
->hstmt
;
1233 SQLLEN results
= -1;
1235 TRACE("%p, %p, %s, %p %p %p\n", command
, outer
, debugstr_guid(riid
), params
, affected
, rowset
);
1238 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &hstmt
);
1240 ret
= SQLExecDirectW(hstmt
, command
->query
, SQL_NTS
);
1241 if (ret
!= SQL_SUCCESS
)
1243 dump_sql_diag_records(SQL_HANDLE_STMT
, hstmt
);
1247 ret
= SQLRowCount(hstmt
, &results
);
1248 if (ret
!= SQL_SUCCESS
)
1249 ERR("SQLRowCount failed (%d)\n", ret
);
1252 *affected
= results
;
1255 if (!wcsnicmp( command
->query
, L
"select ", 7 ))
1257 msrowset
= heap_alloc(sizeof(*msrowset
));
1259 return E_OUTOFMEMORY
;
1261 command
->hstmt
= NULL
;
1263 msrowset
->IRowset_iface
.lpVtbl
= &msdasql_rowset_vtbl
;
1264 msrowset
->IRowsetInfo_iface
.lpVtbl
= &rowset_info_vtbl
;
1265 msrowset
->IColumnsInfo_iface
.lpVtbl
= &rowset_columninfo_vtbll
;
1266 msrowset
->IAccessor_iface
.lpVtbl
= &accessor_vtbl
;
1267 msrowset
->IColumnsRowset_iface
.lpVtbl
= &columnrs_rs_vtbl
;
1269 ICommandText_QueryInterface(iface
, &IID_IUnknown
, (void**)&msrowset
->caller
);
1270 msrowset
->hstmt
= hstmt
;
1272 hr
= IRowset_QueryInterface(&msrowset
->IRowset_iface
, riid
, (void**)rowset
);
1273 IRowset_Release(&msrowset
->IRowset_iface
);
1276 SQLFreeStmt(hstmt
, SQL_CLOSE
);
1281 static HRESULT WINAPI
command_GetDBSession(ICommandText
*iface
, REFIID riid
, IUnknown
**session
)
1283 struct command
*command
= impl_from_ICommandText( iface
);
1285 TRACE("%p, %s, %p\n", command
, debugstr_guid(riid
), session
);
1288 return E_INVALIDARG
;
1292 if (!command
->session
)
1295 return IUnknown_QueryInterface(command
->session
, riid
, (void**)session
);
1298 static HRESULT WINAPI
command_GetCommandText(ICommandText
*iface
, GUID
*dialect
, LPOLESTR
*commandstr
)
1300 struct command
*command
= impl_from_ICommandText( iface
);
1302 TRACE("%p, %p, %p\n", command
, dialect
, commandstr
);
1304 if (!command
->query
)
1305 return DB_E_NOCOMMAND
;
1307 if (dialect
&& !IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1309 *dialect
= DBGUID_DEFAULT
;
1310 hr
= DB_S_DIALECTIGNORED
;
1313 *commandstr
= heap_alloc((lstrlenW(command
->query
)+1)*sizeof(WCHAR
));
1314 wcscpy(*commandstr
, command
->query
);
1318 static HRESULT WINAPI
command_SetCommandText(ICommandText
*iface
, REFGUID dialect
, LPCOLESTR commandstr
)
1320 struct command
*command
= impl_from_ICommandText( iface
);
1321 TRACE("%p, %s, %s\n", command
, debugstr_guid(dialect
), debugstr_w(commandstr
));
1323 if (!IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1324 FIXME("Currently non Default Dialect isn't supported\n");
1326 heap_free(command
->query
);
1330 command
->query
= heap_alloc((lstrlenW(commandstr
)+1)*sizeof(WCHAR
));
1331 if (!command
->query
)
1332 return E_OUTOFMEMORY
;
1334 wcscpy(command
->query
, commandstr
);
1337 command
->query
= NULL
;
1341 static const ICommandTextVtbl commandVtbl
=
1343 command_QueryInterface
,
1348 command_GetDBSession
,
1349 command_GetCommandText
,
1350 command_SetCommandText
1353 static HRESULT WINAPI
command_prop_QueryInterface(ICommandProperties
*iface
, REFIID riid
, void **out
)
1355 struct command
*command
= impl_from_ICommandProperties( iface
);
1356 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1359 static ULONG WINAPI
command_prop_AddRef(ICommandProperties
*iface
)
1361 struct command
*command
= impl_from_ICommandProperties( iface
);
1362 return ICommandText_AddRef(&command
->ICommandText_iface
);
1365 static ULONG WINAPI
command_prop_Release(ICommandProperties
*iface
)
1367 struct command
*command
= impl_from_ICommandProperties( iface
);
1368 return ICommandText_Release(&command
->ICommandText_iface
);
1371 static ULONG
get_property_count(DWORD flag
, struct msdasql_prop
*properties
, int prop_count
)
1375 for(i
=0; i
< prop_count
; i
++)
1377 if (properties
[i
].flags
& flag
)
1384 static HRESULT WINAPI
command_prop_GetProperties(ICommandProperties
*iface
, ULONG count
,
1385 const DBPROPIDSET propertyidsets
[], ULONG
*sets_cnt
, DBPROPSET
**propertyset
)
1387 struct command
*command
= impl_from_ICommandProperties( iface
);
1388 DBPROPSET
*propset
= NULL
;
1391 TRACE("%p %ld %p %p %p\n", command
, count
, propertyidsets
, sets_cnt
, propertyset
);
1393 /* All Properties */
1397 propset
= CoTaskMemAlloc(2 * sizeof(DBPROPSET
));
1399 return E_OUTOFMEMORY
;
1401 propset
[0].guidPropertySet
= DBPROPSET_ROWSET
;
1402 propset
[0].cProperties
= get_property_count(DBPROPFLAGS_ROWSET
, command
->properties
, command
->prop_count
);
1403 propset
[0].rgProperties
= CoTaskMemAlloc(propset
[0].cProperties
* sizeof(DBPROP
));
1404 if (!propset
[0].rgProperties
)
1406 CoTaskMemFree(propset
);
1407 return E_OUTOFMEMORY
;
1411 for (j
=0; j
< command
->prop_count
; j
++)
1413 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_ROWSET
))
1415 propset
[0].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1417 V_VT(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1418 if (command
->properties
[j
].vartype
== VT_BOOL
)
1420 V_BOOL(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1422 else if (command
->properties
[j
].vartype
== VT_I4
)
1424 V_I4(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1427 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1432 propset
[1].guidPropertySet
= DBPROPSET_PROVIDERROWSET
;
1433 propset
[1].cProperties
= get_property_count(DBPROPFLAGS_DATASOURCEINFO
, command
->properties
, command
->prop_count
);
1434 propset
[1].rgProperties
= CoTaskMemAlloc(propset
[1].cProperties
* sizeof(DBPROP
));
1435 if (!propset
[1].rgProperties
)
1437 CoTaskMemFree(propset
[0].rgProperties
);
1438 CoTaskMemFree(propset
);
1439 return E_OUTOFMEMORY
;
1443 for (j
=0; j
< command
->prop_count
; j
++)
1445 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_DATASOURCEINFO
))
1447 propset
[1].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1449 V_VT(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1450 if (command
->properties
[j
].vartype
== VT_BOOL
)
1452 V_BOOL(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1454 else if (command
->properties
[j
].vartype
== VT_I4
)
1456 V_I4(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1459 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1468 propset
= CoTaskMemAlloc(count
* sizeof(DBPROPSET
));
1470 return E_OUTOFMEMORY
;
1472 for (i
=0; i
< count
; i
++)
1474 TRACE("Property id %d (count %ld, set %s)\n", i
, propertyidsets
[i
].cPropertyIDs
,
1475 debugstr_guid(&propertyidsets
[i
].guidPropertySet
));
1477 propset
[i
].cProperties
= propertyidsets
[i
].cPropertyIDs
;
1478 propset
[i
].rgProperties
= CoTaskMemAlloc(propset
[i
].cProperties
* sizeof(DBPROP
));
1480 for (j
=0; j
< propset
[i
].cProperties
; j
++)
1482 propset
[i
].rgProperties
[j
].dwPropertyID
= propertyidsets
[i
].rgPropertyIDs
[j
];
1484 for(k
= 0; k
< command
->prop_count
; k
++)
1486 if (command
->properties
[k
].property_id
== propertyidsets
[i
].rgPropertyIDs
[j
])
1488 V_VT(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].vartype
;
1489 if (command
->properties
[j
].vartype
== VT_BOOL
)
1491 V_BOOL(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1493 else if (command
->properties
[j
].vartype
== VT_I4
)
1495 V_I4(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1498 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1508 *propertyset
= propset
;
1513 static HRESULT WINAPI
command_prop_SetProperties(ICommandProperties
*iface
, ULONG count
,
1514 DBPROPSET propertyset
[])
1516 struct command
*command
= impl_from_ICommandProperties( iface
);
1519 TRACE("%p %lu, %p\n", command
, count
, propertyset
);
1521 for(i
=0; i
< count
; i
++)
1523 TRACE("set %s, count %ld\n", debugstr_guid(&propertyset
[i
].guidPropertySet
), propertyset
[i
].cProperties
);
1524 for(j
=0; j
< propertyset
[i
].cProperties
; j
++)
1526 for(k
=0; k
< command
->prop_count
; k
++)
1528 if (command
->properties
[k
].property_id
== propertyset
[i
].rgProperties
[j
].dwPropertyID
)
1530 TRACE("Found property 0x%08lx\n", command
->properties
[k
].property_id
);
1531 if (command
->properties
[k
].flags
& DBPROPFLAGS_WRITE
)
1533 if (command
->properties
[k
].vartype
== VT_BOOL
)
1535 command
->properties
[k
].value
= V_BOOL(&propertyset
[i
].rgProperties
[j
].vValue
);
1537 else if (command
->properties
[k
].vartype
== VT_I4
)
1539 command
->properties
[k
].value
= V_I4(&propertyset
[i
].rgProperties
[j
].vValue
);
1542 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1545 WARN("Attempting to set Readonly property\n");
1555 static const ICommandPropertiesVtbl commonpropsVtbl
=
1557 command_prop_QueryInterface
,
1558 command_prop_AddRef
,
1559 command_prop_Release
,
1560 command_prop_GetProperties
,
1561 command_prop_SetProperties
1564 static HRESULT WINAPI
colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
1566 struct command
*command
= impl_from_IColumnsInfo( iface
);
1567 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1570 static ULONG WINAPI
colsinfo_AddRef(IColumnsInfo
*iface
)
1572 struct command
*command
= impl_from_IColumnsInfo( iface
);
1573 return ICommandText_AddRef(&command
->ICommandText_iface
);
1576 static ULONG WINAPI
colsinfo_Release(IColumnsInfo
*iface
)
1578 struct command
*command
= impl_from_IColumnsInfo( iface
);
1579 return ICommandText_Release(&command
->ICommandText_iface
);
1582 static HRESULT WINAPI
colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
1583 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
1585 struct command
*command
= impl_from_IColumnsInfo( iface
);
1586 FIXME("%p, %p, %p, %p\n", command
, columns
, colinfo
, stringsbuffer
);
1590 static HRESULT WINAPI
colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1591 const DBID
*dbids
, DBORDINAL
*columns
)
1593 struct command
*command
= impl_from_IColumnsInfo( iface
);
1594 FIXME("%p, %Iu, %p, %p\n", command
, column_ids
, dbids
, columns
);
1598 static struct IColumnsInfoVtbl columninfoVtbl
=
1600 colsinfo_QueryInterface
,
1603 colsinfo_GetColumnInfo
,
1604 colsinfo_MapColumnIDs
1607 static HRESULT WINAPI
converttype_QueryInterface(IConvertType
*iface
, REFIID riid
, void **out
)
1609 struct command
*command
= impl_from_IConvertType( iface
);
1610 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1613 static ULONG WINAPI
converttype_AddRef(IConvertType
*iface
)
1615 struct command
*command
= impl_from_IConvertType( iface
);
1616 return ICommandText_AddRef(&command
->ICommandText_iface
);
1619 static ULONG WINAPI
converttype_Release(IConvertType
*iface
)
1621 struct command
*command
= impl_from_IConvertType( iface
);
1622 return ICommandText_Release(&command
->ICommandText_iface
);
1625 static HRESULT WINAPI
converttype_CanConvert(IConvertType
*iface
, DBTYPE from
, DBTYPE to
, DBCONVERTFLAGS flags
)
1627 struct command
*command
= impl_from_IConvertType( iface
);
1628 FIXME("%p, %u, %d, 0x%08lx\n", command
, from
, to
, flags
);
1632 static struct IConvertTypeVtbl converttypeVtbl
=
1634 converttype_QueryInterface
,
1636 converttype_Release
,
1637 converttype_CanConvert
1640 static HRESULT WINAPI
commandprepare_QueryInterface(ICommandPrepare
*iface
, REFIID riid
, void **out
)
1642 struct command
*command
= impl_from_ICommandPrepare( iface
);
1643 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1646 static ULONG WINAPI
commandprepare_AddRef(ICommandPrepare
*iface
)
1648 struct command
*command
= impl_from_ICommandPrepare( iface
);
1649 return ICommandText_AddRef(&command
->ICommandText_iface
);
1652 static ULONG WINAPI
commandprepare_Release(ICommandPrepare
*iface
)
1654 struct command
*command
= impl_from_ICommandPrepare( iface
);
1655 return ICommandText_Release(&command
->ICommandText_iface
);
1658 static HRESULT WINAPI
commandprepare_Prepare(ICommandPrepare
*iface
, ULONG runs
)
1660 struct command
*command
= impl_from_ICommandPrepare( iface
);
1663 TRACE("%p, %lu\n", command
, runs
);
1665 if (!command
->query
)
1666 return DB_E_NOCOMMAND
;
1669 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
1671 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &command
->hstmt
);
1673 ret
= SQLPrepareW(command
->hstmt
, command
->query
, SQL_NTS
);
1674 if (ret
!= SQL_SUCCESS
)
1676 dump_sql_diag_records(SQL_HANDLE_STMT
, command
->hstmt
);
1682 static HRESULT WINAPI
commandprepare_Unprepare(ICommandPrepare
*iface
)
1684 struct command
*command
= impl_from_ICommandPrepare( iface
);
1685 TRACE("%p\n", command
);
1689 struct ICommandPrepareVtbl commandprepareVtbl
=
1691 commandprepare_QueryInterface
,
1692 commandprepare_AddRef
,
1693 commandprepare_Release
,
1694 commandprepare_Prepare
,
1695 commandprepare_Unprepare
1698 static HRESULT WINAPI
cmd_with_params_QueryInterface(ICommandWithParameters
*iface
, REFIID riid
, void **out
)
1700 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1701 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1704 static ULONG WINAPI
cmd_with_params_AddRef(ICommandWithParameters
*iface
)
1706 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1707 return ICommandText_AddRef(&command
->ICommandText_iface
);
1710 static ULONG WINAPI
cmd_with_params_Release(ICommandWithParameters
*iface
)
1712 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1713 return ICommandText_Release(&command
->ICommandText_iface
);
1716 static HRESULT WINAPI
cmd_with_params_GetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS
*uparams
,
1717 DBPARAMINFO
**info
, OLECHAR
**buffer
)
1719 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1720 FIXME("%p, %p, %p, %p\n", command
, uparams
, info
, buffer
);
1724 static HRESULT WINAPI
cmd_with_params_MapParameterNames(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1725 LPCWSTR names
[], DB_LPARAMS ordinals
[])
1727 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1728 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, names
, ordinals
);
1732 static HRESULT WINAPI
cmd_with_params_SetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1733 const DB_UPARAMS ordinals
[], const DBPARAMBINDINFO bindinfo
[])
1735 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1736 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, ordinals
, bindinfo
);
1740 struct ICommandWithParametersVtbl command_with_params_vtbl
=
1742 cmd_with_params_QueryInterface
,
1743 cmd_with_params_AddRef
,
1744 cmd_with_params_Release
,
1745 cmd_with_params_GetParameterInfo
,
1746 cmd_with_params_MapParameterNames
,
1747 cmd_with_params_SetParameterInfo
1750 static HRESULT WINAPI
createcommand_CreateCommand(IDBCreateCommand
*iface
, IUnknown
*outer
, REFIID riid
,
1753 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
1754 struct command
*command
;
1757 TRACE("%p, %p, %s, %p\n", session
, outer
, debugstr_guid(riid
), out
);
1760 FIXME("Outer not currently supported\n");
1762 command
= heap_alloc(sizeof(*command
));
1764 return E_OUTOFMEMORY
;
1766 command
->ICommandText_iface
.lpVtbl
= &commandVtbl
;
1767 command
->ICommandProperties_iface
.lpVtbl
= &commonpropsVtbl
;
1768 command
->IColumnsInfo_iface
.lpVtbl
= &columninfoVtbl
;
1769 command
->IConvertType_iface
.lpVtbl
= &converttypeVtbl
;
1770 command
->ICommandPrepare_iface
.lpVtbl
= &commandprepareVtbl
;
1771 command
->ICommandWithParameters_iface
.lpVtbl
= &command_with_params_vtbl
;
1773 command
->query
= NULL
;
1774 command
->hdbc
= session
->hdbc
;
1775 command
->hstmt
= NULL
;
1777 command
->prop_count
= ARRAY_SIZE(msdasql_init_props
);
1778 command
->properties
= heap_alloc(sizeof(msdasql_init_props
));
1779 memcpy(command
->properties
, msdasql_init_props
, sizeof(msdasql_init_props
));
1781 IUnknown_QueryInterface(&session
->session_iface
, &IID_IUnknown
, (void**)&command
->session
);
1783 hr
= ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, (void**)out
);
1784 ICommandText_Release(&command
->ICommandText_iface
);
1788 static const IDBCreateCommandVtbl createcommandVtbl
=
1790 createcommand_QueryInterface
,
1791 createcommand_AddRef
,
1792 createcommand_Release
,
1793 createcommand_CreateCommand
1796 static HRESULT WINAPI
transjoin_QueryInterface(ITransactionJoin
*iface
, REFIID riid
, void **out
)
1798 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1799 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1802 static ULONG WINAPI
transjoin_AddRef(ITransactionJoin
*iface
)
1804 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1805 return IUnknown_AddRef(&session
->session_iface
);
1808 static ULONG WINAPI
transjoin_Release(ITransactionJoin
*iface
)
1810 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1811 return IUnknown_Release(&session
->session_iface
);
1814 static HRESULT WINAPI
transjoin_GetOptionsObject(ITransactionJoin
*iface
, ITransactionOptions
**options
)
1816 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1818 FIXME("%p, %p\n", session
, options
);
1823 static HRESULT WINAPI
transjoin_JoinTransaction(ITransactionJoin
*iface
, IUnknown
*unk
, ISOLEVEL level
,
1824 ULONG flags
, ITransactionOptions
*options
)
1826 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1828 FIXME("%p, %p, %lu, 0x%08lx, %p\n", session
, unk
, level
, flags
, options
);
1833 static const ITransactionJoinVtbl transactionjoinVtbl
=
1835 transjoin_QueryInterface
,
1838 transjoin_GetOptionsObject
,
1839 transjoin_JoinTransaction
1842 static HRESULT WINAPI
transaction_QueryInterface(ITransaction
*iface
, REFIID riid
, void **out
)
1844 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1845 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1848 static ULONG WINAPI
transaction_AddRef(ITransaction
*iface
)
1850 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1851 return IUnknown_AddRef(&session
->session_iface
);
1854 static ULONG WINAPI
transaction_Release(ITransaction
*iface
)
1856 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1857 return IUnknown_Release(&session
->session_iface
);
1860 static HRESULT WINAPI
transaction_Commit(ITransaction
*iface
, BOOL retaining
, DWORD tc
, DWORD rm
)
1862 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1864 FIXME("%p, %d, %ld, %ld\n", session
, retaining
, tc
, rm
);
1869 static HRESULT WINAPI
transaction_Abort(ITransaction
*iface
, BOID
*reason
, BOOL retaining
, BOOL async
)
1871 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1873 FIXME("%p, %p, %d, %d\n", session
, reason
, retaining
, async
);
1878 static HRESULT WINAPI
transaction_GetTransactionInfo(ITransaction
*iface
, XACTTRANSINFO
*info
)
1880 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1882 FIXME("%p, %p\n", session
, info
);
1887 static const ITransactionVtbl transactionVtbl
=
1889 transaction_QueryInterface
,
1891 transaction_Release
,
1894 transaction_GetTransactionInfo
1897 HRESULT
create_db_session(REFIID riid
, IUnknown
*datasource
, HDBC hdbc
, void **unk
)
1899 struct msdasql_session
*session
;
1902 session
= heap_alloc(sizeof(*session
));
1904 return E_OUTOFMEMORY
;
1906 session
->session_iface
.lpVtbl
= &unkfactoryVtbl
;
1907 session
->IGetDataSource_iface
.lpVtbl
= &datasourceVtbl
;
1908 session
->IOpenRowset_iface
.lpVtbl
= &openrowsetVtbl
;
1909 session
->ISessionProperties_iface
.lpVtbl
= &propertiesVtbl
;
1910 session
->IDBCreateCommand_iface
.lpVtbl
= &createcommandVtbl
;
1911 session
->ITransactionJoin_iface
.lpVtbl
= &transactionjoinVtbl
;
1912 session
->ITransaction_iface
.lpVtbl
= &transactionVtbl
;
1914 IUnknown_QueryInterface(datasource
, &IID_IUnknown
, (void**)&session
->datasource
);
1916 session
->hdbc
= hdbc
;
1918 hr
= IUnknown_QueryInterface(&session
->session_iface
, riid
, unk
);
1919 IUnknown_Release(&session
->session_iface
);