tdf#150789 - FILEOPEN PPTX: fix text in SmartArt vertically off
[LibreOffice.git] / connectivity / source / drivers / firebird / StatementCommonBase.cxx
blob12ce9a8fd7bac2e8b51cc1d742d64b1e9bdd47de
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
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 "StatementCommonBase.hxx"
21 #include "Util.hxx"
22 #include "ResultSet.hxx"
24 #include <sal/log.hxx>
25 #include <comphelper/sequence.hxx>
26 #include <cppuhelper/typeprovider.hxx>
27 #include <propertyids.hxx>
28 #include <vcl/svapp.hxx>
29 #include <TConnection.hxx>
31 #include <com/sun/star/sdbc/SQLException.hpp>
33 using namespace ::connectivity::firebird;
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::lang;
38 using namespace ::com::sun::star::beans;
39 using namespace ::com::sun::star::sdbc;
40 using namespace ::com::sun::star::sdbcx;
41 using namespace ::com::sun::star::container;
42 using namespace ::com::sun::star::io;
43 using namespace ::com::sun::star::util;
45 using namespace ::comphelper;
46 using namespace ::osl;
48 OStatementCommonBase::OStatementCommonBase(Connection* _pConnection)
49 : OStatementCommonBase_Base(m_aMutex),
50 OPropertySetHelper(OStatementCommonBase_Base::rBHelper),
51 m_pConnection(_pConnection),
52 #if SAL_TYPES_SIZEOFPOINTER == 8
53 m_aStatementHandle(0)
54 #else
55 m_aStatementHandle(nullptr)
56 #endif
60 OStatementCommonBase::~OStatementCommonBase()
64 void OStatementCommonBase::disposeResultSet()
66 if (m_xResultSet.is())
67 m_xResultSet->dispose();
68 m_xResultSet.clear();
71 void OStatementCommonBase::freeStatementHandle()
73 if (m_aStatementHandle)
75 isc_dsql_free_statement(m_statusVector,
76 &m_aStatementHandle,
77 DSQL_drop);
78 evaluateStatusVector(m_statusVector,
79 u"isc_dsql_free_statement",
80 *this);
85 Any SAL_CALL OStatementCommonBase::queryInterface( const Type & rType )
87 Any aRet = OStatementCommonBase_Base::queryInterface(rType);
88 if(!aRet.hasValue())
89 aRet = OPropertySetHelper::queryInterface(rType);
90 return aRet;
93 Sequence< Type > SAL_CALL OStatementCommonBase::getTypes( )
95 ::cppu::OTypeCollection aTypes(
96 ::cppu::UnoType<XMultiPropertySet>::get(),
97 ::cppu::UnoType<XFastPropertySet>::get(),
98 ::cppu::UnoType<XPropertySet>::get());
100 return concatSequences(aTypes.getTypes(),OStatementCommonBase_Base::getTypes());
104 void SAL_CALL OStatementCommonBase::cancel( )
106 MutexGuard aGuard(m_aMutex);
107 checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
108 // cancel the current sql statement
111 void SAL_CALL OStatementCommonBase::close()
113 SAL_INFO("connectivity.firebird", "close");
116 MutexGuard aGuard(m_aMutex);
117 checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
118 disposeResultSet();
119 freeStatementHandle();
122 dispose();
125 void OStatementCommonBase::prepareAndDescribeStatement(std::u16string_view sql, XSQLDA*& pOutSqlda)
127 SolarMutexGuard g; // tdf#122129
129 freeStatementHandle();
131 if (!pOutSqlda)
133 pOutSqlda = static_cast<XSQLDA*>(calloc(1, XSQLDA_LENGTH(10)));
134 assert(pOutSqlda && "Don't handle OOM conditions");
135 pOutSqlda->version = SQLDA_VERSION1;
136 pOutSqlda->sqln = 10;
139 ISC_STATUS aErr = isc_dsql_allocate_statement(m_statusVector,
140 &m_pConnection->getDBHandle(),
141 &m_aStatementHandle);
143 if (aErr)
145 evaluateStatusVector(m_statusVector,
146 u"isc_dsql_allocate_statement",
147 *this);
149 else
151 aErr = isc_dsql_prepare(m_statusVector,
152 &m_pConnection->getTransaction(),
153 &m_aStatementHandle,
155 OUStringToOString(sql, RTL_TEXTENCODING_UTF8).getStr(),
156 SQL_DIALECT_CURRENT,
157 pOutSqlda);
159 if (aErr)
161 evaluateStatusVector(m_statusVector,
162 u"isc_dsql_prepare",
163 *this);
165 else
167 // Ensure we have enough space in pOutSqlda
168 if (pOutSqlda->sqld > pOutSqlda->sqln)
170 int n = pOutSqlda->sqld;
171 free(pOutSqlda);
172 pOutSqlda = static_cast<XSQLDA*>(calloc(1, XSQLDA_LENGTH(n)));
173 assert(pOutSqlda && "Don't handle OOM conditions");
174 pOutSqlda->version = SQLDA_VERSION1;
175 pOutSqlda->sqln = n;
176 aErr = isc_dsql_describe(m_statusVector,
177 &m_aStatementHandle,
179 pOutSqlda);
182 // Process each XSQLVAR parameter structure in the output XSQLDA
183 if (aErr)
185 evaluateStatusVector(m_statusVector,
186 u"isc_dsql_describe",
187 *this);
189 else
191 mallocSQLVAR(pOutSqlda);
194 if(aErr)
196 freeStatementHandle();
199 if(aErr)
201 free(pOutSqlda);
202 pOutSqlda = nullptr;
206 // ---- XMultipleResults - UNSUPPORTED ----------------------------------------
207 uno::Reference< XResultSet > SAL_CALL OStatementCommonBase::getResultSet()
209 // TODO: verify we really can't support this
210 // return uno::Reference< XResultSet >();
211 MutexGuard aGuard(m_aMutex);
212 checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
214 return m_xResultSet;
217 sal_Bool SAL_CALL OStatementCommonBase::getMoreResults()
219 // TODO: verify we really can't support this
220 return false;
221 // MutexGuard aGuard( m_aMutex );
222 // checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
225 sal_Int32 SAL_CALL OStatementCommonBase::getUpdateCount()
227 // TODO: verify we really can't support this
228 return -1;
232 // ---- XWarningsSupplier - UNSUPPORTED ----------------------------------------
233 Any SAL_CALL OStatementCommonBase::getWarnings()
235 return Any();
238 void SAL_CALL OStatementCommonBase::clearWarnings()
242 ::cppu::IPropertyArrayHelper* OStatementCommonBase::createArrayHelper( ) const
244 // this properties are define by the service statement
245 // they must in alphabetic order
246 return new ::cppu::OPropertyArrayHelper
250 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),
251 PROPERTY_ID_CURSORNAME,
252 cppu::UnoType<OUString>::get(),
256 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING),
257 PROPERTY_ID_ESCAPEPROCESSING,
258 cppu::UnoType<bool>::get(),
262 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
263 PROPERTY_ID_FETCHDIRECTION,
264 cppu::UnoType<sal_Int32>::get(),
268 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
269 PROPERTY_ID_FETCHSIZE,
270 cppu::UnoType<sal_Int32>::get(),
274 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE),
275 PROPERTY_ID_MAXFIELDSIZE,
276 cppu::UnoType<sal_Int32>::get(),
280 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS),
281 PROPERTY_ID_MAXROWS,
282 cppu::UnoType<sal_Int32>::get(),
286 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT),
287 PROPERTY_ID_QUERYTIMEOUT,
288 cppu::UnoType<sal_Int32>::get(),
292 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
293 PROPERTY_ID_RESULTSETCONCURRENCY,
294 cppu::UnoType<sal_Int32>::get(),
298 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
299 PROPERTY_ID_RESULTSETTYPE,
300 cppu::UnoType<sal_Int32>::get(),
304 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_USEBOOKMARKS),
305 PROPERTY_ID_USEBOOKMARKS,
306 cppu::UnoType<bool>::get(),
314 ::cppu::IPropertyArrayHelper & OStatementCommonBase::getInfoHelper()
316 return *getArrayHelper();
319 sal_Bool OStatementCommonBase::convertFastPropertyValue(
320 Any &,
321 Any &,
322 sal_Int32,
323 const Any& )
325 // here we have to try to convert
326 return false;
329 void OStatementCommonBase::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any&)
331 // set the value to whatever is necessary
332 switch(nHandle)
334 case PROPERTY_ID_QUERYTIMEOUT:
335 case PROPERTY_ID_MAXFIELDSIZE:
336 case PROPERTY_ID_MAXROWS:
337 case PROPERTY_ID_CURSORNAME:
338 case PROPERTY_ID_RESULTSETCONCURRENCY:
339 case PROPERTY_ID_RESULTSETTYPE:
340 case PROPERTY_ID_FETCHDIRECTION:
341 case PROPERTY_ID_FETCHSIZE:
342 case PROPERTY_ID_ESCAPEPROCESSING:
343 case PROPERTY_ID_USEBOOKMARKS:
344 default:
349 void OStatementCommonBase::getFastPropertyValue(Any&,sal_Int32 nHandle) const
351 switch(nHandle)
353 case PROPERTY_ID_QUERYTIMEOUT:
354 case PROPERTY_ID_MAXFIELDSIZE:
355 case PROPERTY_ID_MAXROWS:
356 case PROPERTY_ID_CURSORNAME:
357 case PROPERTY_ID_RESULTSETCONCURRENCY:
358 case PROPERTY_ID_RESULTSETTYPE:
359 case PROPERTY_ID_FETCHDIRECTION:
360 case PROPERTY_ID_FETCHSIZE:
361 case PROPERTY_ID_ESCAPEPROCESSING:
362 case PROPERTY_ID_USEBOOKMARKS:
363 default:
368 void SAL_CALL OStatementCommonBase::acquire() noexcept
370 OStatementCommonBase_Base::acquire();
373 void SAL_CALL OStatementCommonBase::release() noexcept
375 OStatementCommonBase_Base::release();
378 uno::Reference< css::beans::XPropertySetInfo > SAL_CALL OStatementCommonBase::getPropertySetInfo( )
380 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
383 short OStatementCommonBase::getSqlInfoItem(char aInfoItem)
385 ISC_STATUS_ARRAY aStatusVector;
386 ISC_STATUS aErr;
388 char aInfoItems[] = {aInfoItem};
389 char aResultsBuffer[8];
391 aErr = isc_dsql_sql_info(aStatusVector,
392 &m_aStatementHandle,
393 sizeof(aInfoItems),
394 aInfoItems,
395 sizeof(aResultsBuffer),
396 aResultsBuffer);
398 if (!aErr && aResultsBuffer[0] == aInfoItem)
400 const short aBytes = static_cast<short>(isc_vax_integer(aResultsBuffer+1, 2));
401 return static_cast<short>(isc_vax_integer(aResultsBuffer+3, aBytes));
404 evaluateStatusVector(aStatusVector,
405 u"isc_dsq_sql_info",
406 *this);
407 return 0;
410 bool OStatementCommonBase::isDDLStatement()
412 return getSqlInfoItem(isc_info_sql_stmt_type) == isc_info_sql_stmt_ddl;
415 sal_Int32 OStatementCommonBase::getStatementChangeCount()
417 const short aStatementType = getSqlInfoItem(isc_info_sql_stmt_type);
420 ISC_STATUS_ARRAY aStatusVector;
421 ISC_STATUS aErr;
423 // This is somewhat undocumented so I'm just guessing and hoping for the best.
424 char aInfoItems[] = {isc_info_sql_records};
425 char aResultsBuffer[1024];
427 aErr = isc_dsql_sql_info(aStatusVector,
428 &m_aStatementHandle,
429 sizeof(aInfoItems),
430 aInfoItems,
431 sizeof(aResultsBuffer),
432 aResultsBuffer);
434 if (aErr)
436 evaluateStatusVector(aStatusVector,
437 u"isc_dsq_sql_info",
438 *this);
439 return 0;
442 short aDesiredInfoType = 0;
443 switch (aStatementType)
445 case isc_info_sql_stmt_select:
446 aDesiredInfoType = isc_info_req_select_count;
447 break;
448 case isc_info_sql_stmt_insert:
449 aDesiredInfoType = isc_info_req_insert_count;
450 break;
451 case isc_info_sql_stmt_update:
452 aDesiredInfoType = isc_info_req_update_count;
453 break;
454 case isc_info_sql_stmt_delete:
455 aDesiredInfoType = isc_info_req_delete_count;
456 break;
457 case isc_info_sql_stmt_exec_procedure:
458 case isc_info_sql_stmt_ddl:
459 return 0; // cannot determine
460 default:
461 throw SQLException(); // TODO: better error message?
464 char* pResults = aResultsBuffer;
465 if (static_cast<short>(*pResults++) != isc_info_sql_records)
466 return 0;
468 // const short aTotalLength = (short) isc_vax_integer(pResults, 2);
469 pResults += 2;
471 // Seems to be of form TOKEN (1 byte), LENGTH (2 bytes), DATA (LENGTH bytes)
472 while (*pResults != isc_info_rsb_end)
474 const char aToken = *pResults;
475 const short aLength = static_cast<short>(isc_vax_integer(pResults+1, 2));
477 if (aToken == aDesiredInfoType)
479 return isc_vax_integer(pResults + 3, aLength);
482 pResults += (3 + aLength);
485 return 0;
488 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */