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
= SQLColAttributesW (rowset
->hstmt
, i
+1, SQL_DESC_UNSIGNED
, NULL
, 0, NULL
, &length
);
1033 if (!SQL_SUCCEEDED(ret
))
1035 dump_sql_diag_records(SQL_HANDLE_STMT
, rowset
->hstmt
);
1037 CoTaskMemFree(dbcolumn
);
1038 ERR("Failed to get column %d attribute\n", i
+1);
1042 dbcolumn
[i
].wType
= sqltype_to_bindtype(ColumnDataType
, length
== SQL_FALSE
);
1043 TRACE("SQLType %s -> %s\n", debugstr_sqltype(ColumnDataType
), debugstr_dbtype(dbcolumn
[i
].wType
));
1045 dbcolumn
[i
].dwFlags
= DBCOLUMNFLAGS_WRITE
;
1047 ret
= SQLColAttributesW(rowset
->hstmt
, i
+1, SQL_DESC_LENGTH
, NULL
, 0, NULL
, &length
);
1048 if (!SQL_SUCCEEDED(ret
))
1051 CoTaskMemFree(dbcolumn
);
1052 ERR("Failed to get column %d length (%d)\n", i
+1, ret
);
1055 dbcolumn
[i
].ulColumnSize
= length
;
1057 if (dbcolumn
[i
].ulColumnSize
> 1024 && is_variable_length(ColumnDataType
))
1058 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_MAYDEFER
| DBCOLUMNFLAGS_ISLONG
;
1060 if (ColumnDataNullable
)
1061 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_ISNULLABLE
| DBCOLUMNFLAGS_MAYBENULL
;
1063 if (is_fixed_length(ColumnDataType
))
1064 dbcolumn
[i
].dwFlags
|= DBCOLUMNFLAGS_ISFIXEDLENGTH
;
1066 ret
= SQLColAttributesW(rowset
->hstmt
, i
+1, SQL_DESC_SCALE
, NULL
, 0, NULL
, &length
);
1067 if (!SQL_SUCCEEDED(ret
))
1070 CoTaskMemFree(dbcolumn
);
1071 ERR("Failed to get column %d scale (%d)\n", i
+1, ret
);
1076 dbcolumn
[i
].bScale
= length
;
1078 ret
= SQLColAttributesW(rowset
->hstmt
, i
+1, SQL_DESC_PRECISION
, NULL
, 0, NULL
, &length
);
1079 if (!SQL_SUCCEEDED(ret
))
1082 CoTaskMemFree(dbcolumn
);
1083 ERR("Failed to get column %d precision (%d)\n", i
+1, ret
);
1088 dbcolumn
[i
].bPrecision
= length
;
1090 dbcolumn
[i
].columnid
.eKind
= DBKIND_NAME
;
1091 dbcolumn
[i
].columnid
.uName
.pwszName
= ptr
;
1093 ptr
+= ColumnNameLen
+ 1;
1098 CoTaskMemFree(dbcolumn
);
1099 ERR("Failed to get column %d description (%d)\n", i
+1, ret
);
1104 *colinfo
= dbcolumn
;
1105 #undef MAX_COLUMN_LEN
1109 static HRESULT WINAPI
rowset_colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1110 const DBID
*dbids
, DBORDINAL
*columns
)
1112 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
1113 FIXME("%p, %Id, %p, %p\n", rowset
, column_ids
, dbids
, columns
);
1117 static struct IColumnsInfoVtbl rowset_columninfo_vtbll
=
1119 rowset_colsinfo_QueryInterface
,
1120 rowset_colsinfo_AddRef
,
1121 rowset_colsinfo_Release
,
1122 rowset_colsinfo_GetColumnInfo
,
1123 rowset_colsinfo_MapColumnIDs
1126 static HRESULT WINAPI
rowset_accessor_QueryInterface(IAccessor
*iface
, REFIID riid
, void **out
)
1128 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1129 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
1132 static ULONG WINAPI
rowset_accessor_AddRef(IAccessor
*iface
)
1134 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1135 return IRowset_AddRef(&rowset
->IRowset_iface
);
1138 static ULONG WINAPI
rowset_accessor_Release(IAccessor
*iface
)
1140 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1141 return IRowset_Release(&rowset
->IRowset_iface
);
1144 static HRESULT WINAPI
rowset_accessor_AddRefAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
1146 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1147 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
1151 static HRESULT WINAPI
rowset_accessor_CreateAccessor(IAccessor
*iface
, DBACCESSORFLAGS flags
,
1152 DBCOUNTITEM count
, const DBBINDING bindings
[], DBLENGTH row_size
, HACCESSOR
*accessor
,
1153 DBBINDSTATUS status
[])
1155 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1156 FIXME("%p, 0x%08lx, %Id, %p, %Id, %p, %p\n", rowset
, flags
, count
, bindings
, row_size
, accessor
, status
);
1160 static HRESULT WINAPI
rowset_accessor_GetBindings(IAccessor
*iface
, HACCESSOR accessor
,
1161 DBACCESSORFLAGS
*flags
, DBCOUNTITEM
*count
, DBBINDING
**bindings
)
1163 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1164 FIXME("%p, %Id, %p, %p, %p\n", rowset
, accessor
, flags
, count
, bindings
);
1168 static HRESULT WINAPI
rowset_accessor_ReleaseAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
1170 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
1171 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
1175 struct IAccessorVtbl accessor_vtbl
=
1177 rowset_accessor_QueryInterface
,
1178 rowset_accessor_AddRef
,
1179 rowset_accessor_Release
,
1180 rowset_accessor_AddRefAccessor
,
1181 rowset_accessor_CreateAccessor
,
1182 rowset_accessor_GetBindings
,
1183 rowset_accessor_ReleaseAccessor
1186 static HRESULT WINAPI
column_rs_QueryInterface(IColumnsRowset
*iface
, REFIID riid
, void **out
)
1188 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1189 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
1192 static ULONG WINAPI
column_rs_AddRef(IColumnsRowset
*iface
)
1194 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1195 return IRowset_AddRef(&rowset
->IRowset_iface
);
1198 static ULONG WINAPI
column_rs_Release(IColumnsRowset
*iface
)
1200 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1201 return IRowset_Release(&rowset
->IRowset_iface
);
1204 static HRESULT WINAPI
column_rs_GetAvailableColumns(IColumnsRowset
*iface
, DBORDINAL
*count
, DBID
**columns
)
1206 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1208 TRACE("%p, %p, %p\n", rowset
, count
, columns
);
1210 if (!count
|| !columns
)
1211 return E_INVALIDARG
;
1219 static HRESULT WINAPI
column_rs_GetColumnsRowset(IColumnsRowset
*iface
, IUnknown
*outer
, DBORDINAL count
,
1220 const DBID columns
[], REFIID riid
, ULONG property_cnt
, DBPROPSET property_sets
[], IUnknown
**unk_rs
)
1222 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
1223 FIXME("(%p)->(%p, %Id, %p, %s, %lu, %p, %p): stub\n", rowset
, outer
, count
, columns
, debugstr_guid(riid
),
1224 property_cnt
, property_sets
, unk_rs
);
1228 struct IColumnsRowsetVtbl columnrs_rs_vtbl
=
1230 column_rs_QueryInterface
,
1233 column_rs_GetAvailableColumns
,
1234 column_rs_GetColumnsRowset
1237 static HRESULT WINAPI
command_Execute(ICommandText
*iface
, IUnknown
*outer
, REFIID riid
,
1238 DBPARAMS
*params
, DBROWCOUNT
*affected
, IUnknown
**rowset
)
1240 struct command
*command
= impl_from_ICommandText( iface
);
1241 struct msdasql_rowset
*msrowset
;
1244 SQLHSTMT hstmt
= command
->hstmt
;
1245 SQLLEN results
= -1;
1246 BOOL free_hstmt
= TRUE
;
1248 TRACE("%p, %p, %s, %p %p %p\n", command
, outer
, debugstr_guid(riid
), params
, affected
, rowset
);
1251 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &hstmt
);
1253 ret
= SQLExecDirectW(hstmt
, command
->query
, SQL_NTS
);
1254 if (ret
!= SQL_SUCCESS
)
1256 dump_sql_diag_records(SQL_HANDLE_STMT
, hstmt
);
1261 if (!wcsnicmp( command
->query
, L
"select ", 7 ))
1263 msrowset
= heap_alloc(sizeof(*msrowset
));
1265 return E_OUTOFMEMORY
;
1267 command
->hstmt
= NULL
;
1269 msrowset
->IRowset_iface
.lpVtbl
= &msdasql_rowset_vtbl
;
1270 msrowset
->IRowsetInfo_iface
.lpVtbl
= &rowset_info_vtbl
;
1271 msrowset
->IColumnsInfo_iface
.lpVtbl
= &rowset_columninfo_vtbll
;
1272 msrowset
->IAccessor_iface
.lpVtbl
= &accessor_vtbl
;
1273 msrowset
->IColumnsRowset_iface
.lpVtbl
= &columnrs_rs_vtbl
;
1275 ICommandText_QueryInterface(iface
, &IID_IUnknown
, (void**)&msrowset
->caller
);
1276 msrowset
->hstmt
= hstmt
;
1279 hr
= IRowset_QueryInterface(&msrowset
->IRowset_iface
, riid
, (void**)rowset
);
1280 IRowset_Release(&msrowset
->IRowset_iface
);
1285 ret
= SQLRowCount(hstmt
, &results
);
1286 if (ret
!= SQL_SUCCESS
)
1287 ERR("SQLRowCount failed (%d)\n", ret
);
1289 *affected
= results
;
1293 SQLFreeStmt(hstmt
, SQL_CLOSE
);
1298 static HRESULT WINAPI
command_GetDBSession(ICommandText
*iface
, REFIID riid
, IUnknown
**session
)
1300 struct command
*command
= impl_from_ICommandText( iface
);
1302 TRACE("%p, %s, %p\n", command
, debugstr_guid(riid
), session
);
1305 return E_INVALIDARG
;
1309 if (!command
->session
)
1312 return IUnknown_QueryInterface(command
->session
, riid
, (void**)session
);
1315 static HRESULT WINAPI
command_GetCommandText(ICommandText
*iface
, GUID
*dialect
, LPOLESTR
*commandstr
)
1317 struct command
*command
= impl_from_ICommandText( iface
);
1319 TRACE("%p, %p, %p\n", command
, dialect
, commandstr
);
1321 if (!command
->query
)
1322 return DB_E_NOCOMMAND
;
1324 if (dialect
&& !IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1326 *dialect
= DBGUID_DEFAULT
;
1327 hr
= DB_S_DIALECTIGNORED
;
1330 *commandstr
= heap_alloc((lstrlenW(command
->query
)+1)*sizeof(WCHAR
));
1331 wcscpy(*commandstr
, command
->query
);
1335 static HRESULT WINAPI
command_SetCommandText(ICommandText
*iface
, REFGUID dialect
, LPCOLESTR commandstr
)
1337 struct command
*command
= impl_from_ICommandText( iface
);
1338 TRACE("%p, %s, %s\n", command
, debugstr_guid(dialect
), debugstr_w(commandstr
));
1340 if (!IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1341 FIXME("Currently non Default Dialect isn't supported\n");
1343 heap_free(command
->query
);
1347 command
->query
= heap_alloc((lstrlenW(commandstr
)+1)*sizeof(WCHAR
));
1348 if (!command
->query
)
1349 return E_OUTOFMEMORY
;
1351 wcscpy(command
->query
, commandstr
);
1354 command
->query
= NULL
;
1358 static const ICommandTextVtbl commandVtbl
=
1360 command_QueryInterface
,
1365 command_GetDBSession
,
1366 command_GetCommandText
,
1367 command_SetCommandText
1370 static HRESULT WINAPI
command_prop_QueryInterface(ICommandProperties
*iface
, REFIID riid
, void **out
)
1372 struct command
*command
= impl_from_ICommandProperties( iface
);
1373 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1376 static ULONG WINAPI
command_prop_AddRef(ICommandProperties
*iface
)
1378 struct command
*command
= impl_from_ICommandProperties( iface
);
1379 return ICommandText_AddRef(&command
->ICommandText_iface
);
1382 static ULONG WINAPI
command_prop_Release(ICommandProperties
*iface
)
1384 struct command
*command
= impl_from_ICommandProperties( iface
);
1385 return ICommandText_Release(&command
->ICommandText_iface
);
1388 static ULONG
get_property_count(DWORD flag
, struct msdasql_prop
*properties
, int prop_count
)
1392 for(i
=0; i
< prop_count
; i
++)
1394 if (properties
[i
].flags
& flag
)
1401 static HRESULT WINAPI
command_prop_GetProperties(ICommandProperties
*iface
, ULONG count
,
1402 const DBPROPIDSET propertyidsets
[], ULONG
*sets_cnt
, DBPROPSET
**propertyset
)
1404 struct command
*command
= impl_from_ICommandProperties( iface
);
1405 DBPROPSET
*propset
= NULL
;
1408 TRACE("%p %ld %p %p %p\n", command
, count
, propertyidsets
, sets_cnt
, propertyset
);
1410 /* All Properties */
1414 propset
= CoTaskMemAlloc(2 * sizeof(DBPROPSET
));
1416 return E_OUTOFMEMORY
;
1418 propset
[0].guidPropertySet
= DBPROPSET_ROWSET
;
1419 propset
[0].cProperties
= get_property_count(DBPROPFLAGS_ROWSET
, command
->properties
, command
->prop_count
);
1420 propset
[0].rgProperties
= CoTaskMemAlloc(propset
[0].cProperties
* sizeof(DBPROP
));
1421 if (!propset
[0].rgProperties
)
1423 CoTaskMemFree(propset
);
1424 return E_OUTOFMEMORY
;
1428 for (j
=0; j
< command
->prop_count
; j
++)
1430 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_ROWSET
))
1432 propset
[0].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1434 V_VT(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1435 if (command
->properties
[j
].vartype
== VT_BOOL
)
1437 V_BOOL(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1439 else if (command
->properties
[j
].vartype
== VT_I4
)
1441 V_I4(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1444 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1449 propset
[1].guidPropertySet
= DBPROPSET_PROVIDERROWSET
;
1450 propset
[1].cProperties
= get_property_count(DBPROPFLAGS_DATASOURCEINFO
, command
->properties
, command
->prop_count
);
1451 propset
[1].rgProperties
= CoTaskMemAlloc(propset
[1].cProperties
* sizeof(DBPROP
));
1452 if (!propset
[1].rgProperties
)
1454 CoTaskMemFree(propset
[0].rgProperties
);
1455 CoTaskMemFree(propset
);
1456 return E_OUTOFMEMORY
;
1460 for (j
=0; j
< command
->prop_count
; j
++)
1462 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_DATASOURCEINFO
))
1464 propset
[1].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1466 V_VT(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1467 if (command
->properties
[j
].vartype
== VT_BOOL
)
1469 V_BOOL(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1471 else if (command
->properties
[j
].vartype
== VT_I4
)
1473 V_I4(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1476 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1485 propset
= CoTaskMemAlloc(count
* sizeof(DBPROPSET
));
1487 return E_OUTOFMEMORY
;
1489 for (i
=0; i
< count
; i
++)
1491 TRACE("Property id %d (count %ld, set %s)\n", i
, propertyidsets
[i
].cPropertyIDs
,
1492 debugstr_guid(&propertyidsets
[i
].guidPropertySet
));
1494 propset
[i
].cProperties
= propertyidsets
[i
].cPropertyIDs
;
1495 propset
[i
].rgProperties
= CoTaskMemAlloc(propset
[i
].cProperties
* sizeof(DBPROP
));
1497 for (j
=0; j
< propset
[i
].cProperties
; j
++)
1499 propset
[i
].rgProperties
[j
].dwPropertyID
= propertyidsets
[i
].rgPropertyIDs
[j
];
1501 for(k
= 0; k
< command
->prop_count
; k
++)
1503 if (command
->properties
[k
].property_id
== propertyidsets
[i
].rgPropertyIDs
[j
])
1505 V_VT(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].vartype
;
1506 if (command
->properties
[j
].vartype
== VT_BOOL
)
1508 V_BOOL(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1510 else if (command
->properties
[j
].vartype
== VT_I4
)
1512 V_I4(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1515 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1525 *propertyset
= propset
;
1530 static HRESULT WINAPI
command_prop_SetProperties(ICommandProperties
*iface
, ULONG count
,
1531 DBPROPSET propertyset
[])
1533 struct command
*command
= impl_from_ICommandProperties( iface
);
1536 TRACE("%p %lu, %p\n", command
, count
, propertyset
);
1538 for(i
=0; i
< count
; i
++)
1540 TRACE("set %s, count %ld\n", debugstr_guid(&propertyset
[i
].guidPropertySet
), propertyset
[i
].cProperties
);
1541 for(j
=0; j
< propertyset
[i
].cProperties
; j
++)
1543 for(k
=0; k
< command
->prop_count
; k
++)
1545 if (command
->properties
[k
].property_id
== propertyset
[i
].rgProperties
[j
].dwPropertyID
)
1547 TRACE("Found property 0x%08lx\n", command
->properties
[k
].property_id
);
1548 if (command
->properties
[k
].flags
& DBPROPFLAGS_WRITE
)
1550 if (command
->properties
[k
].vartype
== VT_BOOL
)
1552 command
->properties
[k
].value
= V_BOOL(&propertyset
[i
].rgProperties
[j
].vValue
);
1554 else if (command
->properties
[k
].vartype
== VT_I4
)
1556 command
->properties
[k
].value
= V_I4(&propertyset
[i
].rgProperties
[j
].vValue
);
1559 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1562 WARN("Attempting to set Readonly property\n");
1572 static const ICommandPropertiesVtbl commonpropsVtbl
=
1574 command_prop_QueryInterface
,
1575 command_prop_AddRef
,
1576 command_prop_Release
,
1577 command_prop_GetProperties
,
1578 command_prop_SetProperties
1581 static HRESULT WINAPI
colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
1583 struct command
*command
= impl_from_IColumnsInfo( iface
);
1584 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1587 static ULONG WINAPI
colsinfo_AddRef(IColumnsInfo
*iface
)
1589 struct command
*command
= impl_from_IColumnsInfo( iface
);
1590 return ICommandText_AddRef(&command
->ICommandText_iface
);
1593 static ULONG WINAPI
colsinfo_Release(IColumnsInfo
*iface
)
1595 struct command
*command
= impl_from_IColumnsInfo( iface
);
1596 return ICommandText_Release(&command
->ICommandText_iface
);
1599 static HRESULT WINAPI
colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
1600 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
1602 struct command
*command
= impl_from_IColumnsInfo( iface
);
1603 FIXME("%p, %p, %p, %p\n", command
, columns
, colinfo
, stringsbuffer
);
1607 static HRESULT WINAPI
colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1608 const DBID
*dbids
, DBORDINAL
*columns
)
1610 struct command
*command
= impl_from_IColumnsInfo( iface
);
1611 FIXME("%p, %Iu, %p, %p\n", command
, column_ids
, dbids
, columns
);
1615 static struct IColumnsInfoVtbl columninfoVtbl
=
1617 colsinfo_QueryInterface
,
1620 colsinfo_GetColumnInfo
,
1621 colsinfo_MapColumnIDs
1624 static HRESULT WINAPI
converttype_QueryInterface(IConvertType
*iface
, REFIID riid
, void **out
)
1626 struct command
*command
= impl_from_IConvertType( iface
);
1627 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1630 static ULONG WINAPI
converttype_AddRef(IConvertType
*iface
)
1632 struct command
*command
= impl_from_IConvertType( iface
);
1633 return ICommandText_AddRef(&command
->ICommandText_iface
);
1636 static ULONG WINAPI
converttype_Release(IConvertType
*iface
)
1638 struct command
*command
= impl_from_IConvertType( iface
);
1639 return ICommandText_Release(&command
->ICommandText_iface
);
1642 static HRESULT WINAPI
converttype_CanConvert(IConvertType
*iface
, DBTYPE from
, DBTYPE to
, DBCONVERTFLAGS flags
)
1644 struct command
*command
= impl_from_IConvertType( iface
);
1645 FIXME("%p, %u, %d, 0x%08lx\n", command
, from
, to
, flags
);
1649 static struct IConvertTypeVtbl converttypeVtbl
=
1651 converttype_QueryInterface
,
1653 converttype_Release
,
1654 converttype_CanConvert
1657 static HRESULT WINAPI
commandprepare_QueryInterface(ICommandPrepare
*iface
, REFIID riid
, void **out
)
1659 struct command
*command
= impl_from_ICommandPrepare( iface
);
1660 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1663 static ULONG WINAPI
commandprepare_AddRef(ICommandPrepare
*iface
)
1665 struct command
*command
= impl_from_ICommandPrepare( iface
);
1666 return ICommandText_AddRef(&command
->ICommandText_iface
);
1669 static ULONG WINAPI
commandprepare_Release(ICommandPrepare
*iface
)
1671 struct command
*command
= impl_from_ICommandPrepare( iface
);
1672 return ICommandText_Release(&command
->ICommandText_iface
);
1675 static HRESULT WINAPI
commandprepare_Prepare(ICommandPrepare
*iface
, ULONG runs
)
1677 struct command
*command
= impl_from_ICommandPrepare( iface
);
1680 TRACE("%p, %lu\n", command
, runs
);
1682 if (!command
->query
)
1683 return DB_E_NOCOMMAND
;
1686 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
1688 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &command
->hstmt
);
1690 ret
= SQLPrepareW(command
->hstmt
, command
->query
, SQL_NTS
);
1691 if (ret
!= SQL_SUCCESS
)
1693 dump_sql_diag_records(SQL_HANDLE_STMT
, command
->hstmt
);
1699 static HRESULT WINAPI
commandprepare_Unprepare(ICommandPrepare
*iface
)
1701 struct command
*command
= impl_from_ICommandPrepare( iface
);
1702 TRACE("%p\n", command
);
1706 struct ICommandPrepareVtbl commandprepareVtbl
=
1708 commandprepare_QueryInterface
,
1709 commandprepare_AddRef
,
1710 commandprepare_Release
,
1711 commandprepare_Prepare
,
1712 commandprepare_Unprepare
1715 static HRESULT WINAPI
cmd_with_params_QueryInterface(ICommandWithParameters
*iface
, REFIID riid
, void **out
)
1717 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1718 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1721 static ULONG WINAPI
cmd_with_params_AddRef(ICommandWithParameters
*iface
)
1723 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1724 return ICommandText_AddRef(&command
->ICommandText_iface
);
1727 static ULONG WINAPI
cmd_with_params_Release(ICommandWithParameters
*iface
)
1729 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1730 return ICommandText_Release(&command
->ICommandText_iface
);
1733 static HRESULT WINAPI
cmd_with_params_GetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS
*uparams
,
1734 DBPARAMINFO
**info
, OLECHAR
**buffer
)
1736 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1737 FIXME("%p, %p, %p, %p\n", command
, uparams
, info
, buffer
);
1741 static HRESULT WINAPI
cmd_with_params_MapParameterNames(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1742 LPCWSTR names
[], DB_LPARAMS ordinals
[])
1744 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1745 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, names
, ordinals
);
1749 static HRESULT WINAPI
cmd_with_params_SetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1750 const DB_UPARAMS ordinals
[], const DBPARAMBINDINFO bindinfo
[])
1752 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1753 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, ordinals
, bindinfo
);
1757 struct ICommandWithParametersVtbl command_with_params_vtbl
=
1759 cmd_with_params_QueryInterface
,
1760 cmd_with_params_AddRef
,
1761 cmd_with_params_Release
,
1762 cmd_with_params_GetParameterInfo
,
1763 cmd_with_params_MapParameterNames
,
1764 cmd_with_params_SetParameterInfo
1767 static HRESULT WINAPI
createcommand_CreateCommand(IDBCreateCommand
*iface
, IUnknown
*outer
, REFIID riid
,
1770 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
1771 struct command
*command
;
1774 TRACE("%p, %p, %s, %p\n", session
, outer
, debugstr_guid(riid
), out
);
1777 FIXME("Outer not currently supported\n");
1779 command
= heap_alloc(sizeof(*command
));
1781 return E_OUTOFMEMORY
;
1783 command
->ICommandText_iface
.lpVtbl
= &commandVtbl
;
1784 command
->ICommandProperties_iface
.lpVtbl
= &commonpropsVtbl
;
1785 command
->IColumnsInfo_iface
.lpVtbl
= &columninfoVtbl
;
1786 command
->IConvertType_iface
.lpVtbl
= &converttypeVtbl
;
1787 command
->ICommandPrepare_iface
.lpVtbl
= &commandprepareVtbl
;
1788 command
->ICommandWithParameters_iface
.lpVtbl
= &command_with_params_vtbl
;
1790 command
->query
= NULL
;
1791 command
->hdbc
= session
->hdbc
;
1792 command
->hstmt
= NULL
;
1794 command
->prop_count
= ARRAY_SIZE(msdasql_init_props
);
1795 command
->properties
= heap_alloc(sizeof(msdasql_init_props
));
1796 memcpy(command
->properties
, msdasql_init_props
, sizeof(msdasql_init_props
));
1798 IUnknown_QueryInterface(&session
->session_iface
, &IID_IUnknown
, (void**)&command
->session
);
1800 hr
= ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, (void**)out
);
1801 ICommandText_Release(&command
->ICommandText_iface
);
1805 static const IDBCreateCommandVtbl createcommandVtbl
=
1807 createcommand_QueryInterface
,
1808 createcommand_AddRef
,
1809 createcommand_Release
,
1810 createcommand_CreateCommand
1813 static HRESULT WINAPI
transjoin_QueryInterface(ITransactionJoin
*iface
, REFIID riid
, void **out
)
1815 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1816 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1819 static ULONG WINAPI
transjoin_AddRef(ITransactionJoin
*iface
)
1821 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1822 return IUnknown_AddRef(&session
->session_iface
);
1825 static ULONG WINAPI
transjoin_Release(ITransactionJoin
*iface
)
1827 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1828 return IUnknown_Release(&session
->session_iface
);
1831 static HRESULT WINAPI
transjoin_GetOptionsObject(ITransactionJoin
*iface
, ITransactionOptions
**options
)
1833 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1835 FIXME("%p, %p\n", session
, options
);
1840 static HRESULT WINAPI
transjoin_JoinTransaction(ITransactionJoin
*iface
, IUnknown
*unk
, ISOLEVEL level
,
1841 ULONG flags
, ITransactionOptions
*options
)
1843 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1845 FIXME("%p, %p, %lu, 0x%08lx, %p\n", session
, unk
, level
, flags
, options
);
1850 static const ITransactionJoinVtbl transactionjoinVtbl
=
1852 transjoin_QueryInterface
,
1855 transjoin_GetOptionsObject
,
1856 transjoin_JoinTransaction
1859 static HRESULT WINAPI
transaction_QueryInterface(ITransaction
*iface
, REFIID riid
, void **out
)
1861 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1862 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1865 static ULONG WINAPI
transaction_AddRef(ITransaction
*iface
)
1867 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1868 return IUnknown_AddRef(&session
->session_iface
);
1871 static ULONG WINAPI
transaction_Release(ITransaction
*iface
)
1873 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1874 return IUnknown_Release(&session
->session_iface
);
1877 static HRESULT WINAPI
transaction_Commit(ITransaction
*iface
, BOOL retaining
, DWORD tc
, DWORD rm
)
1879 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1881 FIXME("%p, %d, %ld, %ld\n", session
, retaining
, tc
, rm
);
1886 static HRESULT WINAPI
transaction_Abort(ITransaction
*iface
, BOID
*reason
, BOOL retaining
, BOOL async
)
1888 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1890 FIXME("%p, %p, %d, %d\n", session
, reason
, retaining
, async
);
1895 static HRESULT WINAPI
transaction_GetTransactionInfo(ITransaction
*iface
, XACTTRANSINFO
*info
)
1897 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1899 FIXME("%p, %p\n", session
, info
);
1904 static const ITransactionVtbl transactionVtbl
=
1906 transaction_QueryInterface
,
1908 transaction_Release
,
1911 transaction_GetTransactionInfo
1914 HRESULT
create_db_session(REFIID riid
, IUnknown
*datasource
, HDBC hdbc
, void **unk
)
1916 struct msdasql_session
*session
;
1919 session
= heap_alloc(sizeof(*session
));
1921 return E_OUTOFMEMORY
;
1923 session
->session_iface
.lpVtbl
= &unkfactoryVtbl
;
1924 session
->IGetDataSource_iface
.lpVtbl
= &datasourceVtbl
;
1925 session
->IOpenRowset_iface
.lpVtbl
= &openrowsetVtbl
;
1926 session
->ISessionProperties_iface
.lpVtbl
= &propertiesVtbl
;
1927 session
->IDBCreateCommand_iface
.lpVtbl
= &createcommandVtbl
;
1928 session
->ITransactionJoin_iface
.lpVtbl
= &transactionjoinVtbl
;
1929 session
->ITransaction_iface
.lpVtbl
= &transactionVtbl
;
1931 IUnknown_QueryInterface(datasource
, &IID_IUnknown
, (void**)&session
->datasource
);
1933 session
->hdbc
= hdbc
;
1935 hr
= IUnknown_QueryInterface(&session
->session_iface
, riid
, unk
);
1936 IUnknown_Release(&session
->session_iface
);