1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
25 #include "mysqlc_connection.hxx"
26 #include "mysqlc_propertyids.hxx"
27 #include "mysqlc_resultset.hxx"
28 #include "mysqlc_statement.hxx"
29 #include "mysqlc_general.hxx"
31 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <com/sun/star/sdbc/FetchDirection.hpp>
33 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
34 #include <com/sun/star/sdbc/ResultSetType.hpp>
36 #include <cppconn/connection.h>
37 #include <cppconn/exception.h>
38 #include <cppconn/statement.h>
39 #include <cppuhelper/typeprovider.hxx>
40 #include <cppuhelper/queryinterface.hxx>
41 #include <osl/diagnose.h>
42 #include <osl/thread.h>
44 using namespace connectivity::mysqlc
;
46 using namespace com::sun::star::uno
;
47 using namespace com::sun::star::lang
;
48 using namespace com::sun::star::beans
;
49 using namespace com::sun::star::sdbc
;
50 using namespace com::sun::star::sdbcx
;
51 using namespace com::sun::star::container
;
52 using namespace com::sun::star::io
;
53 using namespace com::sun::star::util
;
54 using ::osl::MutexGuard
;
56 OCommonStatement::OCommonStatement(OConnection
* _pConnection
, sql::Statement
*_cppStatement
)
57 :OCommonStatement_IBase(m_aMutex
)
58 ,OPropertySetHelper(OCommonStatement_IBase::rBHelper
)
59 ,OStatement_CBase( (::cppu::OWeakObject
*)_pConnection
, this )
60 ,m_pConnection(_pConnection
)
61 ,cppStatement(_cppStatement
)
62 ,rBHelper(OCommonStatement_IBase::rBHelper
)
64 OSL_TRACE("OCommonStatement::OCommonStatement");
65 m_pConnection
->acquire();
68 OCommonStatement::~OCommonStatement()
70 OSL_TRACE("OCommonStatement::~OCommonStatement");
73 void OCommonStatement::disposeResultSet()
75 OSL_TRACE("OCommonStatement::disposeResultSet");
76 // free the cursor if alive
81 void OCommonStatement::disposing()
83 OSL_TRACE("OCommonStatement::disposing");
84 MutexGuard
aGuard(m_aMutex
);
89 m_pConnection
->release();
95 OCommonStatement_IBase::disposing();
98 Any SAL_CALL
OCommonStatement::queryInterface(const Type
& rType
)
99 throw(RuntimeException
, std::exception
)
101 OSL_TRACE("OCommonStatement::queryInterface");
102 Any aRet
= OCommonStatement_IBase::queryInterface(rType
);
103 if (!aRet
.hasValue()) {
104 aRet
= OPropertySetHelper::queryInterface(rType
);
109 Sequence
< Type
> SAL_CALL
OCommonStatement::getTypes()
110 throw(RuntimeException
, std::exception
)
112 OSL_TRACE("OCommonStatement::getTypes");
113 ::cppu::OTypeCollection
aTypes( cppu::UnoType
<XMultiPropertySet
>::get(),
114 cppu::UnoType
<XFastPropertySet
>::get(),
115 cppu::UnoType
<XPropertySet
>::get());
117 return concatSequences(aTypes
.getTypes(), OCommonStatement_IBase::getTypes());
120 void SAL_CALL
OCommonStatement::cancel()
121 throw(RuntimeException
, std::exception
)
123 OSL_TRACE("OCommonStatement::cancel");
124 MutexGuard
aGuard(m_aMutex
);
125 checkDisposed(rBHelper
.bDisposed
);
126 // cancel the current sql statement
129 void SAL_CALL
OCommonStatement::close()
130 throw(SQLException
, RuntimeException
, std::exception
)
132 OSL_TRACE("OCommonStatement::close");
134 We need a block for the checkDisposed call.
135 After the check we can call dispose() as we are not under lock ??
138 MutexGuard
aGuard(m_aMutex
);
139 checkDisposed(rBHelper
.bDisposed
);
144 void SAL_CALL
OStatement::clearBatch()
145 throw(SQLException
, RuntimeException
, std::exception
)
147 OSL_TRACE("OStatement::clearBatch");
148 // if you support batches clear it here
151 sal_Bool SAL_CALL
OCommonStatement::execute(const rtl::OUString
& sql
)
152 throw(SQLException
, RuntimeException
, std::exception
)
154 OSL_TRACE("OCommonStatement::execute");
155 MutexGuard
aGuard(m_aMutex
);
156 checkDisposed(rBHelper
.bDisposed
);
157 const rtl::OUString sSqlStatement
= m_pConnection
->transFormPreparedStatement( sql
);
159 bool success
= false;
161 success
= cppStatement
->execute(rtl::OUStringToOString(sSqlStatement
, m_pConnection
->getConnectionSettings().encoding
).getStr());
162 } catch (const sql::SQLException
&e
) {
163 mysqlc_sdbc_driver::translateAndThrow(e
, *this, m_pConnection
->getConnectionEncoding());
168 Reference
< XResultSet
> SAL_CALL
OCommonStatement::executeQuery(const rtl::OUString
& sql
)
169 throw(SQLException
, RuntimeException
, std::exception
)
171 OSL_TRACE("OCommonStatement::executeQuery");
173 MutexGuard
aGuard(m_aMutex
);
174 checkDisposed(rBHelper
.bDisposed
);
175 const rtl::OUString sSqlStatement
= m_pConnection
->transFormPreparedStatement(sql
);
177 Reference
< XResultSet
> xResultSet
;
179 std::unique_ptr
< sql::ResultSet
> rset(cppStatement
->executeQuery(rtl::OUStringToOString(sSqlStatement
, m_pConnection
->getConnectionEncoding()).getStr()));
180 xResultSet
= new OResultSet(this, rset
.get(), m_pConnection
->getConnectionEncoding());
182 } catch (const sql::SQLException
&e
) {
183 mysqlc_sdbc_driver::translateAndThrow(e
, *this, m_pConnection
->getConnectionEncoding());
188 Reference
< XConnection
> SAL_CALL
OCommonStatement::getConnection()
189 throw(SQLException
, RuntimeException
, std::exception
)
191 OSL_TRACE("OCommonStatement::getConnection");
192 MutexGuard
aGuard(m_aMutex
);
193 checkDisposed(rBHelper
.bDisposed
);
195 // just return our connection here
196 return m_pConnection
;
199 sal_Int32 SAL_CALL
OCommonStatement::getUpdateCount()
200 throw(SQLException
, RuntimeException
, std::exception
)
202 OSL_TRACE("OCommonStatement::getUpdateCount");
206 Any SAL_CALL
OStatement::queryInterface(const Type
& rType
)
207 throw(RuntimeException
, std::exception
)
209 OSL_TRACE("OStatement::queryInterface");
210 Any aRet
= ::cppu::queryInterface(rType
,static_cast< XBatchExecution
*> (this));
211 if (!aRet
.hasValue()) {
212 aRet
= OCommonStatement::queryInterface(rType
);
217 void SAL_CALL
OStatement::addBatch(const rtl::OUString
& sql
)
218 throw(SQLException
, RuntimeException
, std::exception
)
220 OSL_TRACE("OStatement::addBatch");
221 MutexGuard
aGuard(m_aMutex
);
222 checkDisposed(rBHelper
.bDisposed
);
224 m_aBatchList
.push_back(sql
);
227 Sequence
< sal_Int32
> SAL_CALL
OStatement::executeBatch()
228 throw(SQLException
, RuntimeException
, std::exception
)
230 OSL_TRACE("OStatement::executeBatch");
231 MutexGuard
aGuard(m_aMutex
);
232 checkDisposed(rBHelper
.bDisposed
);
234 Sequence
< sal_Int32
> aRet
= Sequence
< sal_Int32
>();
238 sal_Int32 SAL_CALL
OCommonStatement::executeUpdate(const rtl::OUString
& sql
)
239 throw(SQLException
, RuntimeException
, std::exception
)
241 OSL_TRACE("OCommonStatement::executeUpdate");
242 MutexGuard
aGuard(m_aMutex
);
243 checkDisposed(rBHelper
.bDisposed
);
244 const rtl::OUString sSqlStatement
= m_pConnection
->transFormPreparedStatement(sql
);
246 sal_Int32 affectedRows
= 0;
248 affectedRows
= cppStatement
->executeUpdate(rtl::OUStringToOString(sSqlStatement
, m_pConnection
->getConnectionEncoding()).getStr());
249 } catch (const sql::SQLException
&e
) {
250 mysqlc_sdbc_driver::translateAndThrow(e
, *this, m_pConnection
->getConnectionEncoding());
255 Reference
< XResultSet
> SAL_CALL
OCommonStatement::getResultSet()
256 throw(SQLException
, RuntimeException
, std::exception
)
258 OSL_TRACE("OCommonStatement::getResultSet");
259 MutexGuard
aGuard(m_aMutex
);
260 checkDisposed(rBHelper
.bDisposed
);
262 Reference
< XResultSet
> xResultSet
;
264 std::unique_ptr
< sql::ResultSet
> rset(cppStatement
->getResultSet());
265 xResultSet
= new OResultSet(this, rset
.get(), m_pConnection
->getConnectionEncoding());
267 } catch (const sql::SQLException
&e
) {
268 mysqlc_sdbc_driver::translateAndThrow(e
, *this, m_pConnection
->getConnectionEncoding());
273 sal_Bool SAL_CALL
OCommonStatement::getMoreResults()
274 throw(SQLException
, RuntimeException
, std::exception
)
276 OSL_TRACE("OCommonStatement::getMoreResults");
277 MutexGuard
aGuard(m_aMutex
);
278 checkDisposed(rBHelper
.bDisposed
);
280 // if your driver supports more than only one resultset
281 // and has one more at this moment return true
285 Any SAL_CALL
OCommonStatement::getWarnings()
286 throw(SQLException
, RuntimeException
, std::exception
)
288 OSL_TRACE("OCommonStatement::getWarnings");
289 MutexGuard
aGuard(m_aMutex
);
290 checkDisposed(rBHelper
.bDisposed
);
292 return makeAny(m_aLastWarning
);
295 void SAL_CALL
OCommonStatement::clearWarnings()
296 throw(SQLException
, RuntimeException
, std::exception
)
298 OSL_TRACE("OCommonStatement::clearWarnings");
299 MutexGuard
aGuard(m_aMutex
);
300 checkDisposed(rBHelper
.bDisposed
);
302 m_aLastWarning
= SQLWarning();
305 ::cppu::IPropertyArrayHelper
* OCommonStatement::createArrayHelper( ) const
307 OSL_TRACE("OCommonStatement::createArrayHelper");
308 // this properties are define by the service statement
309 // they must in alphabetic order
310 Sequence
< Property
> aProps(10);
311 Property
* pProperties
= aProps
.getArray();
313 pProperties
[nPos
++] = Property("CursorName", PROPERTY_ID_CURSORNAME
, cppu::UnoType
<rtl::OUString
>::get(), 0);
314 pProperties
[nPos
++] = Property("EscapeProcessing", PROPERTY_ID_ESCAPEPROCESSING
, cppu::UnoType
<bool>::get(), 0);
315 pProperties
[nPos
++] = Property("FetchDirection", PROPERTY_ID_FETCHDIRECTION
, cppu::UnoType
<sal_Int32
>::get(), 0);
316 pProperties
[nPos
++] = Property("FetchSize", PROPERTY_ID_FETCHSIZE
, cppu::UnoType
<sal_Int32
>::get(), 0);
317 pProperties
[nPos
++] = Property("MaxFieldSize", PROPERTY_ID_MAXFIELDSIZE
, cppu::UnoType
<sal_Int32
>::get(), 0);
318 pProperties
[nPos
++] = Property("MaxRows", PROPERTY_ID_MAXROWS
, cppu::UnoType
<sal_Int32
>::get(), 0);
319 pProperties
[nPos
++] = Property("QueryTimeOut", PROPERTY_ID_QUERYTIMEOUT
, cppu::UnoType
<sal_Int32
>::get(), 0);
320 pProperties
[nPos
++] = Property("ResultSetConcurrency", PROPERTY_ID_RESULTSETCONCURRENCY
, cppu::UnoType
<sal_Int32
>::get(), 0);
321 pProperties
[nPos
++] = Property("ResultSetType", PROPERTY_ID_RESULTSETTYPE
, cppu::UnoType
<sal_Int32
>::get(), 0);
322 pProperties
[nPos
++] = Property("UseBookmarks", PROPERTY_ID_USEBOOKMARKS
, cppu::UnoType
<bool>::get(), 0);
324 return new ::cppu::OPropertyArrayHelper(aProps
);
327 ::cppu::IPropertyArrayHelper
& OCommonStatement::getInfoHelper()
329 OSL_TRACE("OCommonStatement::getInfoHelper");
330 return *getArrayHelper();
333 sal_Bool
OCommonStatement::convertFastPropertyValue(
334 Any
& /* rConvertedValue */, Any
& /* rOldValue */,
335 sal_Int32
/* nHandle */, const Any
& /* rValue */)
336 throw (IllegalArgumentException
)
338 OSL_TRACE("OCommonStatement::convertFastPropertyValue");
339 bool bConverted
= false;
340 // here we have to try to convert
344 void OCommonStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle
, const Any
& /* rValue */)
345 throw (Exception
, std::exception
)
347 OSL_TRACE("OCommonStatement::setFastPropertyValue_NoBroadcast");
348 // set the value to what ever is necessary
350 case PROPERTY_ID_QUERYTIMEOUT
:
351 case PROPERTY_ID_MAXFIELDSIZE
:
352 case PROPERTY_ID_MAXROWS
:
353 case PROPERTY_ID_CURSORNAME
:
354 case PROPERTY_ID_RESULTSETCONCURRENCY
:
355 case PROPERTY_ID_RESULTSETTYPE
:
356 case PROPERTY_ID_FETCHDIRECTION
:
357 case PROPERTY_ID_FETCHSIZE
:
358 case PROPERTY_ID_ESCAPEPROCESSING
:
359 case PROPERTY_ID_USEBOOKMARKS
:
365 void OCommonStatement::getFastPropertyValue(Any
& _rValue
, sal_Int32 nHandle
) const
367 OSL_TRACE("OCommonStatement::getFastPropertyValue");
369 case PROPERTY_ID_QUERYTIMEOUT
:
370 case PROPERTY_ID_MAXFIELDSIZE
:
371 case PROPERTY_ID_MAXROWS
:
372 case PROPERTY_ID_CURSORNAME
:
373 case PROPERTY_ID_RESULTSETCONCURRENCY
:
374 case PROPERTY_ID_RESULTSETTYPE
:
375 case PROPERTY_ID_FETCHDIRECTION
:
376 case PROPERTY_ID_FETCHSIZE
:
377 case PROPERTY_ID_ESCAPEPROCESSING
:
379 case PROPERTY_ID_USEBOOKMARKS
:
380 _rValue
<<= sal_False
;
387 rtl::OUString
OStatement::getImplementationName() throw (css::uno::RuntimeException
, std::exception
)
389 return rtl::OUString("com.sun.star.sdbcx.OStatement");
392 css::uno::Sequence
<rtl::OUString
> OStatement::getSupportedServiceNames()
393 throw (css::uno::RuntimeException
, std::exception
)
395 css::uno::Sequence
<rtl::OUString
> s(1);
396 s
[0] = "com.sun.star.sdbc.Statement";
400 sal_Bool
OStatement::supportsService(rtl::OUString
const & ServiceName
)
401 throw (css::uno::RuntimeException
, std::exception
)
403 return cppu::supportsService(this, ServiceName
);
406 void SAL_CALL
OCommonStatement::acquire()
409 OSL_TRACE("OCommonStatement::acquire");
410 OCommonStatement_IBase::acquire();
413 void SAL_CALL
OCommonStatement::release()
416 OSL_TRACE("OCommonStatement::release");
420 void SAL_CALL
OStatement::acquire()
423 OSL_TRACE("OStatement::acquire");
424 OCommonStatement::acquire();
427 void SAL_CALL
OStatement::release()
430 OSL_TRACE("OStatement::release");
431 OCommonStatement::release();
434 Reference
< ::com::sun::star::beans::XPropertySetInfo
> SAL_CALL
OCommonStatement::getPropertySetInfo()
435 throw(RuntimeException
, std::exception
)
437 OSL_TRACE("OCommonStatement::getPropertySetInfo");
438 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
446 * vim600: noet sw=4 ts=4 fdm=marker
447 * vim<600: noet sw=4 ts=4
450 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */