LibreOffice Module connectivity (master) 1
OStatement.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <osl/diagnose.h>
22#include <odbc/OStatement.hxx>
23#include <odbc/OConnection.hxx>
24#include <odbc/OResultSet.hxx>
26#include <odbc/OTools.hxx>
27#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
28#include <com/sun/star/sdbc/ResultSetType.hpp>
29#include <com/sun/star/sdbc/FetchDirection.hpp>
30#include <com/sun/star/lang/DisposedException.hpp>
34#include <comphelper/types.hxx>
35#include <rtl/strbuf.hxx>
36#include <algorithm>
37#include <strings.hrc>
39
40using namespace ::comphelper;
41
42#define THROW_SQL(x) \
43 OTools::ThrowException(m_pConnection.get(),x,m_aStatementHandle,SQL_HANDLE_STMT,*this)
44
45
46using namespace connectivity::odbc;
47
48using namespace com::sun::star::uno;
49using namespace com::sun::star::lang;
50using namespace com::sun::star::beans;
51using namespace com::sun::star::sdbc;
52using namespace com::sun::star::sdbcx;
53using namespace com::sun::star::container;
54using namespace com::sun::star::io;
55using namespace com::sun::star::util;
56
60 ,m_pConnection(_pConnection)
61 ,m_aStatementHandle(SQL_NULL_HANDLE)
62 ,m_pRowStatusArray(nullptr)
63{
64 osl_atomic_increment( &m_refCount );
65 m_aStatementHandle = m_pConnection->createStatementHandle();
66
67 //setMaxFieldSize(0);
68 // Don't do this. By ODBC spec, "0" is the default for the SQL_ATTR_MAX_LENGTH attribute. We once introduced
69 // this line since a PostgreSQL ODBC driver had a default other than 0. However, current drivers (at least 8.3
70 // and later) have a proper default of 0, so there should be no need anymore.
71 // On the other hand, the NotesSQL driver (IBM's ODBC driver for the Lotus Notes series) wrongly interprets
72 // "0" as "0", whereas the ODBC spec says it should in fact mean "unlimited".
73 // So, removing this line seems to be the best option for now.
74 // If we ever again encounter an ODBC driver which needs this option, then we should introduce a data source
75 // setting for it, instead of unconditionally doing it.
76
77 osl_atomic_decrement( &m_refCount );
78}
79
81{
82 OSL_ENSURE(!m_aStatementHandle,"Sohould ne null here!");
83}
84
86{
87 // free the cursor if alive
88 Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
89 if (xComp.is())
90 xComp->dispose();
91 m_xResultSet.clear();
92}
93
95{
96 ::osl::MutexGuard aGuard(m_aMutex);
97
99 ::comphelper::disposeComponent(m_xGeneratedStatement);
100
101 OSL_ENSURE(m_aStatementHandle,"OStatement_BASE2::disposing: StatementHandle is null!");
102 if (m_pConnection.is())
103 {
104 m_pConnection->freeStatementHandle(m_aStatementHandle);
105 m_pConnection.clear();
106 }
107 OSL_ENSURE(!m_aStatementHandle,"Sohould ne null here!");
108
109 OStatement_BASE::disposing();
110}
111
113{
114 ::osl::MutexGuard aGuard1(m_aMutex);
116}
117
118Any SAL_CALL OStatement_Base::queryInterface( const Type & rType )
119{
120 if ( m_pConnection.is() && !m_pConnection->isAutoRetrievingEnabled() && rType == cppu::UnoType<XGeneratedResultSet>::get())
121 return Any();
122 Any aRet = OStatement_BASE::queryInterface(rType);
123 return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
124}
125
127{
131 Sequence< Type > aOldTypes = OStatement_BASE::getTypes();
132 if ( m_pConnection.is() && !m_pConnection->isAutoRetrievingEnabled() )
133 {
134 auto [begin, end] = asNonConstRange(aOldTypes);
135 auto newEnd = std::remove(begin, end,
137 aOldTypes.realloc(std::distance(begin, newEnd));
138 }
139
140 return ::comphelper::concatSequences(aTypes.getTypes(),aOldTypes);
141}
142
144{
145 OSL_ENSURE( m_pConnection.is() && m_pConnection->isAutoRetrievingEnabled(),"Illegal call here. isAutoRetrievingEnabled is false!");
147 if ( m_pConnection.is() )
148 {
149 OUString sStmt = m_pConnection->getTransformedGeneratedStatement(m_sSqlStatement);
150 if ( !sStmt.isEmpty() )
151 {
152 ::comphelper::disposeComponent(m_xGeneratedStatement);
153 m_xGeneratedStatement = m_pConnection->createStatement();
154 xRes = m_xGeneratedStatement->executeQuery(sStmt);
155 }
156 }
157 return xRes;
158}
159
161{
162 ::osl::MutexGuard aGuard( m_aMutex );
163 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
164
165 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
167}
168
169
171{
172 {
173 ::osl::MutexGuard aGuard( m_aMutex );
174 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
175
176 }
177 dispose();
182{
183
184}
185
187{
188 ::osl::MutexGuard aGuard( m_aMutex );
189 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
190
191
192 clearWarnings ();
193
194 if (m_xResultSet.get().is())
195 {
197 }
199 {
201 }
202}
203
204// clearMyResultSet
205// If a ResultSet was created for this Statement, close it
207{
208 ::osl::MutexGuard aGuard( m_aMutex );
209 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
210
211 try
212 {
213 Reference<XCloseable> xCloseable(
214 m_xResultSet.get(), css::uno::UNO_QUERY);
215 if ( xCloseable.is() )
216 xCloseable->close();
217 }
218 catch( const DisposedException& ) { }
219
220 m_xResultSet.clear();
221}
222
224{
225 ::osl::MutexGuard aGuard( m_aMutex );
226 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
227
228
229 SQLLEN numRows = 0;
230
231 try {
233 }
234 catch (const SQLException&)
235 {
236 }
237 return numRows;
238}
239
240// lockIfNecessary
241// If the given SQL statement contains a 'FOR UPDATE' clause, change
242// the concurrency to lock so that the row can then be updated. Returns
243// true if the concurrency has been changed
245{
246 bool rc = false;
247
248 // First, convert the statement to upper case
249
250 OUString sqlStatement = sql.toAsciiUpperCase ();
251
252 // Now, look for the FOR UPDATE keywords. If there is any extra white
253 // space between the FOR and UPDATE, this will fail.
254
255 sal_Int32 index = sqlStatement.indexOf(" FOR UPDATE");
256
257 // We found it. Change our concurrency level to ensure that the
258 // row can be updated.
259
260 if (index > 0)
261 {
262 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
263 try
264 {
265 THROW_SQL((setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CONCURRENCY, SQL_CONCUR_LOCK)));
266 }
267 catch (const SQLWarning& warn)
268 {
269 // Catch any warnings and place on the warning stack
270 setWarning (warn);
271 }
272 rc = true;
273 }
274
275 return rc;
276}
277
278// setWarning
279// Sets the warning
280
281
282void OStatement_Base::setWarning (const SQLWarning &ex)
283{
284 ::osl::MutexGuard aGuard( m_aMutex );
285 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
286
287
289}
290
291
292// getColumnCount
293// Return the number of columns in the ResultSet
295{
296 ::osl::MutexGuard aGuard( m_aMutex );
297 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
298
299
300 sal_Int16 numCols = 0;
301 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
302
303 try {
305 }
306 catch (const SQLException&)
307 {
308 }
309 return numCols;
310}
311
312
313sal_Bool SAL_CALL OStatement_Base::execute( const OUString& sql )
314{
315 ::osl::MutexGuard aGuard( m_aMutex );
316 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
318
319
320 OString aSql(OUStringToOString(sql,getOwnConnection()->getTextEncoding()));
321
322 bool hasResultSet = false;
323
324 // Reset the statement handle and warning
325
326 reset();
327
328 // Check for a 'FOR UPDATE' statement. If present, change
329 // the concurrency to lock
330
332
333 // Call SQLExecDirect
334 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
335
336 try {
337 THROW_SQL(N3SQLExecDirect(m_aStatementHandle, reinterpret_cast<SDB_ODBC_CHAR *>(const_cast<char *>(aSql.getStr())), aSql.getLength()));
338 }
339 catch (const SQLWarning&) {
340
341 //TODO: Save pointer to warning and save with ResultSet
342 // object once it is created.
343 }
344
345 // Now determine if there is a result set associated with
346 // the SQL statement that was executed. Get the column
347 // count, and if it is not zero, there is a result set.
348
349 if (getColumnCount () > 0)
350 {
351 hasResultSet = true;
352 }
353
354 return hasResultSet;
355}
356
357// getResultSet
358// getResultSet returns the current result as a ResultSet. It
359// returns NULL if the current result is not a ResultSet.
360
362{
363 ::osl::MutexGuard aGuard( m_aMutex );
364 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
365
366
367 if (m_xResultSet.get().is()) // if resultset already retrieved,
368 {
369 // throw exception to avoid sequence error
371 }
372
374 sal_Int32 numCols = 1;
375
376 // If we already know we have result columns, checkCount
377 // is false. This is an optimization to prevent unneeded
378 // calls to getColumnCount
379
380 if (checkCount)
381 numCols = getColumnCount ();
382
383 // Only return a result set if there are result columns
384
385 if (numCols > 0)
386 {
387 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
388 pRs = createResultSet();
389 pRs->construct();
390
391 // Save a copy of our last result set
392 // Changed to save copy at getResultSet.
393 //m_xResultSet = rs;
394 }
395 else
397
398 return pRs;
399}
400
401// getStmtOption
402// Invoke SQLGetStmtOption with the given option.
403
404
405template < typename T, SQLINTEGER BufferLength > T OStatement_Base::getStmtOption (SQLINTEGER fOption) const
406{
407 T result (0);
408 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
409 N3SQLGetStmtAttr(m_aStatementHandle, fOption, &result, BufferLength, nullptr);
410 return result;
411}
412template < typename T, SQLINTEGER BufferLength > SQLRETURN OStatement_Base::setStmtOption (SQLINTEGER fOption, T value) const
413{
414 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
415 SQLPOINTER sv = reinterpret_cast<SQLPOINTER>(value);
416 return N3SQLSetStmtAttr(m_aStatementHandle, fOption, sv, BufferLength);
417}
418
419
421{
422 ::osl::MutexGuard aGuard( m_aMutex );
423 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
424
425
427
428 // Execute the statement. If execute returns true, a result
429 // set exists.
430
431 if (execute (sql))
432 {
433 xRS = getResultSet (false);
434 m_xResultSet = xRS;
435 }
436 else
437 {
438 // No ResultSet was produced. Raise an exception
439 m_pConnection->throwGenericSQLException(STR_NO_RESULTSET,*this);
440 }
441 return xRS;
442}
443
444
446{
447 ::osl::MutexGuard aGuard( m_aMutex );
448 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
449
450 return m_pConnection;
451}
452
453
454Any SAL_CALL OStatement::queryInterface( const Type & rType )
455{
456 Any aRet = ::cppu::queryInterface(rType,static_cast< XBatchExecution*> (this));
457 return aRet.hasValue() ? aRet : OStatement_Base::queryInterface(rType);
458}
459
460
461void SAL_CALL OStatement::addBatch( const OUString& sql )
462{
463 ::osl::MutexGuard aGuard( m_aMutex );
464 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
465
466
467 m_aBatchVector.push_back(sql);
468}
469
471{
472 ::osl::MutexGuard aGuard( m_aMutex );
473 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
474
475 OStringBuffer aBatchSql;
476 sal_Int32 nLen = m_aBatchVector.size();
477
478 for (auto const& elem : m_aBatchVector)
479 {
480 aBatchSql.append(OUStringToOString(elem,getOwnConnection()->getTextEncoding())
481 + ";");
482 }
483
484 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
485 auto s = aBatchSql.makeStringAndClear();
486 THROW_SQL(N3SQLExecDirect(m_aStatementHandle, reinterpret_cast<SDB_ODBC_CHAR *>(const_cast<char *>(s.getStr())), s.getLength()));
487
488 Sequence< sal_Int32 > aRet(nLen);
489 sal_Int32* pArray = aRet.getArray();
490 for(sal_Int32 j=0;j<nLen;++j)
491 {
492 SQLRETURN nError = N3SQLMoreResults(m_aStatementHandle);
493 if(nError == SQL_SUCCESS)
494 {
495 SQLLEN nRowCount=0;
497 pArray[j] = nRowCount;
498 }
499 }
500 return aRet;
501}
502
503
504sal_Int32 SAL_CALL OStatement_Base::executeUpdate( const OUString& sql )
505{
506 ::osl::MutexGuard aGuard( m_aMutex );
507 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
508
509
510 sal_Int32 numRows = -1;
511
512 // Execute the statement. If execute returns false, a
513 // row count exists.
514
515 if (!execute (sql)) {
516 numRows = getUpdateCount();
517 }
518 else {
519
520 // No update count was produced (a ResultSet was). Raise
521 // an exception
522
524 const OUString sError( aResources.getResourceString(STR_NO_ROWCOUNT));
525 throw SQLException (sError, *this,OUString(),0,Any());
526 }
527 return numRows;
528
529}
530
531
533{
534 ::osl::MutexGuard aGuard( m_aMutex );
535 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
536
537
539 return m_xResultSet;
540}
541
542
544{
545 ::osl::MutexGuard aGuard( m_aMutex );
546 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
547
548
549 sal_Int32 rowCount = -1;
550
551 // Only return a row count for SQL statements that did not
552 // return a result set.
553
554 if (getColumnCount () == 0)
555 rowCount = getRowCount ();
556
557 return rowCount;
558}
559
560
562{
563 ::osl::MutexGuard aGuard( m_aMutex );
564 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
565
566
567 SQLWarning warning;
568 bool hasResultSet = false;
569
570 // clear previous warnings
571
572 clearWarnings ();
573
574 // Call SQLMoreResults
575 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
576
577 try {
578 hasResultSet = N3SQLMoreResults(m_aStatementHandle) == SQL_SUCCESS;
579 }
580 catch (const SQLWarning &ex) {
581
582 // Save pointer to warning and save with ResultSet
583 // object once it is created.
584
585 warning = ex;
586 }
587
588 // There are more results (it may not be a result set, though)
589
590 if (hasResultSet)
591 {
592
593 // Now determine if there is a result set associated
594 // with the SQL statement that was executed. Get the
595 // column count, and if it is zero, there is not a
596 // result set.
597
598 if (getColumnCount () == 0)
599 hasResultSet = false;
600 }
601
602 // Set the warning for the statement, if one was generated
603
604 setWarning (warning);
605
606 // Return the result set indicator
607
608 return hasResultSet;
609}
610
611
613{
614 ::osl::MutexGuard aGuard( m_aMutex );
615 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
616
617
618 return Any(m_aLastWarning);
619}
620
621
623{
624 ::osl::MutexGuard aGuard( m_aMutex );
625 checkDisposed(OStatement_BASE::rBHelper.bDisposed);
626
627
628 m_aLastWarning = SQLWarning();
629}
630
631
633{
634 return getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_QUERY_TIMEOUT);
635}
636
638{
639 return getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_MAX_ROWS);
640}
641
643{
644 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
645 SQLULEN nValue (getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CONCURRENCY));
646 if(nValue == SQL_CONCUR_READ_ONLY)
647 nValue = ResultSetConcurrency::READ_ONLY;
648 else
649 nValue = ResultSetConcurrency::UPDATABLE;
650 return nValue;
651}
652
654{
655 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
656 SQLULEN nValue (getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE));
657 switch(nValue)
658 {
659 case SQL_CURSOR_FORWARD_ONLY:
660 nValue = ResultSetType::FORWARD_ONLY;
661 break;
662 case SQL_CURSOR_KEYSET_DRIVEN:
663 case SQL_CURSOR_STATIC:
664 nValue = ResultSetType::SCROLL_INSENSITIVE;
665 break;
666 case SQL_CURSOR_DYNAMIC:
667 nValue = ResultSetType::SCROLL_SENSITIVE;
668 break;
669 default:
670 OSL_FAIL("Unknown ODBC Cursor Type");
671 }
672
673 return nValue;
674}
675
677{
678 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
679 SQLULEN nValue (getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_SCROLLABLE));
680 switch(nValue)
681 {
682 case SQL_SCROLLABLE:
683 nValue = FetchDirection::REVERSE;
684 break;
685 default:
686 nValue = FetchDirection::FORWARD;
687 break;
688 }
689
690 return nValue;
691}
692
694{
695 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
696 return getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_ARRAY_SIZE);
697}
698
700{
701 return getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_MAX_LENGTH);
702}
703
705{
706 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
707 SQLCHAR pName[258];
708 SQLSMALLINT nRealLen = 0;
710 return OUString::createFromAscii(reinterpret_cast<char*>(pName));
711}
712
713void OStatement_Base::setQueryTimeOut(sal_Int64 seconds)
714{
715 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
716 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_QUERY_TIMEOUT,seconds);
717}
718
719void OStatement_Base::setMaxRows(sal_Int64 _par0)
720{
721 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
722 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_MAX_ROWS, _par0);
723}
724
726{
727 SQLULEN nSet;
728 if(_par0 == ResultSetConcurrency::READ_ONLY)
729 nSet = SQL_CONCUR_READ_ONLY;
730 else
731 nSet = SQL_CONCUR_VALUES;
732
733 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
734 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CONCURRENCY, nSet);
735}
736
738{
739
740 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
741 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN);
742
743 bool bUseBookmark = isUsingBookmarks();
744 SQLULEN nSet( SQL_UNSPECIFIED );
745 switch(_par0)
746 {
747 case ResultSetType::FORWARD_ONLY:
748 nSet = SQL_UNSPECIFIED;
749 break;
750 case ResultSetType::SCROLL_INSENSITIVE:
751 nSet = SQL_INSENSITIVE;
752 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_KEYSET_DRIVEN);
753 break;
754 case ResultSetType::SCROLL_SENSITIVE:
755 if(bUseBookmark)
756 {
757 SQLUINTEGER nCurProp = getCursorProperties(SQL_CURSOR_DYNAMIC,true);
758 if((nCurProp & SQL_CA1_BOOKMARK) != SQL_CA1_BOOKMARK) // check if bookmark for this type isn't supported
759 { // we have to test the next one
760 nCurProp = getCursorProperties(SQL_CURSOR_KEYSET_DRIVEN,true);
761 bool bNotBookmarks = ((nCurProp & SQL_CA1_BOOKMARK) != SQL_CA1_BOOKMARK);
762 nCurProp = getCursorProperties(SQL_CURSOR_KEYSET_DRIVEN,false);
763 nSet = SQL_CURSOR_KEYSET_DRIVEN;
764 if( bNotBookmarks ||
765 ((nCurProp & SQL_CA2_SENSITIVITY_DELETIONS) != SQL_CA2_SENSITIVITY_DELETIONS) ||
766 ((nCurProp & SQL_CA2_SENSITIVITY_ADDITIONS) != SQL_CA2_SENSITIVITY_ADDITIONS))
767 {
768 // bookmarks for keyset isn't supported so reset bookmark setting
769 setUsingBookmarks(false);
770 nSet = SQL_CURSOR_DYNAMIC;
771 }
772 }
773 else
774 nSet = SQL_CURSOR_DYNAMIC;
775 }
776 else
777 nSet = SQL_CURSOR_DYNAMIC;
778 if( setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE, nSet) != SQL_SUCCESS )
779 {
780 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_KEYSET_DRIVEN);
781 }
782 nSet = SQL_SENSITIVE;
783 break;
784 default:
785 OSL_FAIL( "OStatement_Base::setResultSetType: invalid result set type!" );
786 break;
787 }
788
789
790 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_SENSITIVITY, nSet);
791}
792
793void OStatement_Base::setEscapeProcessing( const bool _bEscapeProc )
794{
795 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
796 SQLULEN nEscapeProc( _bEscapeProc ? SQL_NOSCAN_OFF : SQL_NOSCAN_ON );
797 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_NOSCAN, nEscapeProc);
798}
799
800
802{
803 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
804 if(_par0 == FetchDirection::FORWARD)
805 {
806 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_SCROLLABLE, SQL_NONSCROLLABLE);
807 }
808 else if(_par0 == FetchDirection::REVERSE)
809 {
810 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_SCROLLABLE, SQL_SCROLLABLE);
811 }
812}
813
814void OStatement_Base::setFetchSize(sal_Int32 _par0)
815{
816 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
817 OSL_ENSURE(_par0>0,"Illegal fetch size!");
818 if ( _par0 > 0 )
819 {
820 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_ARRAY_SIZE, _par0);
821
822 delete[] m_pRowStatusArray;
823 m_pRowStatusArray = new SQLUSMALLINT[_par0];
824 setStmtOption<SQLUSMALLINT*, SQL_IS_POINTER>(SQL_ATTR_ROW_STATUS_PTR, m_pRowStatusArray);
825 }
826}
827
829{
830 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
831 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_MAX_LENGTH, _par0);
832}
833
834void OStatement_Base::setCursorName(std::u16string_view _par0)
835{
836 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
837 OString aName(OUStringToOString(_par0,getOwnConnection()->getTextEncoding()));
838 N3SQLSetCursorName(m_aStatementHandle, reinterpret_cast<SDB_ODBC_CHAR *>(const_cast<char *>(aName.getStr())), static_cast<SQLSMALLINT>(aName.getLength()));
839}
840
842{
843 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
844 return SQL_UB_OFF != getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS);
845}
846
848{
849 OSL_ENSURE( m_aStatementHandle, "StatementHandle is null!" );
850 return SQL_NOSCAN_OFF == getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS);
851}
852
854{
855 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
856 SQLULEN nValue = _bUseBookmark ? SQL_UB_VARIABLE : SQL_UB_OFF;
857 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, nValue);
858}
859
861{
862 return new ::cppu::OPropertyArrayHelper
863 {
864 {
865 {
869 0
870 },
871 {
875 0
876 },
877 {
881 0
882 },
883 {
887 0
888 },
889 {
893 0
894 },
895 {
899 0
900 },
901 {
905 0
906 },
907 {
911 0
912 },
913 {
917 0
918 },
919 {
923 0
924 }
925 }
926 };
927}
928
929
931{
932 return *getArrayHelper();
933}
934
936 Any & rConvertedValue,
937 Any & rOldValue,
938 sal_Int32 nHandle,
939 const Any& rValue )
940{
941 bool bConverted = false;
942 try
943 {
944 switch(nHandle)
945 {
947 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getQueryTimeOut());
948 break;
949
951 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxFieldSize());
952 break;
953
955 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxRows());
956 break;
957
959 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getCursorName());
960 break;
961
963 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetConcurrency());
964 break;
965
967 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetType());
968 break;
969
971 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
972 break;
973
975 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
976 break;
977
979 bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, isUsingBookmarks());
980 break;
981
983 bConverted = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, getEscapeProcessing() );
984 break;
985
986 }
987 }
988 catch(const SQLException&)
989 {
990 // throw Exception(e.Message,*this);
991 }
992 return bConverted;
993}
994
995void OStatement_Base::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)
996{
997 try
998 {
999 switch(nHandle)
1000 {
1003 break;
1006 break;
1009 break;
1012 break;
1015 break;
1018 break;
1021 break;
1024 break;
1027 break;
1029 setEscapeProcessing( ::comphelper::getBOOL( rValue ) );
1030 break;
1031 default:
1032 OSL_FAIL( "OStatement_Base::setFastPropertyValue_NoBroadcast: what property?" );
1033 break;
1034 }
1035 }
1036 catch(const SQLException& )
1037 {
1038 // throw Exception(e.Message,*this);
1039 }
1040}
1041
1042void OStatement_Base::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
1043{
1044 switch(nHandle)
1045 {
1047 rValue <<= getQueryTimeOut();
1048 break;
1050 rValue <<= getMaxFieldSize();
1051 break;
1053 rValue <<= getMaxRows();
1054 break;
1056 rValue <<= getCursorName();
1057 break;
1059 rValue <<= getResultSetConcurrency();
1060 break;
1062 rValue <<= getResultSetType();
1063 break;
1065 rValue <<= getFetchDirection();
1066 break;
1068 rValue <<= getFetchSize();
1069 break;
1071 rValue <<= isUsingBookmarks();
1072 break;
1074 rValue <<= getEscapeProcessing();
1075 break;
1076 default:
1077 OSL_FAIL( "OStatement_Base::getFastPropertyValue: what property?" );
1078 break;
1079 }
1080}
1081
1082IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.OStatement","com.sun.star.sdbc.Statement");
1083
1084void SAL_CALL OStatement_Base::acquire() noexcept
1085{
1086 OStatement_BASE::acquire();
1087}
1088
1089void SAL_CALL OStatement_Base::release() noexcept
1090{
1091 OStatement_BASE::release();
1092}
1093
1094void SAL_CALL OStatement::acquire() noexcept
1095{
1097}
1098
1099void SAL_CALL OStatement::release() noexcept
1100{
1102}
1103
1105{
1106 return new OResultSet(m_aStatementHandle,this);
1107}
1108
1110{
1111 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1112}
1113
1114SQLUINTEGER OStatement_Base::getCursorProperties(SQLINTEGER _nCursorType, bool bFirst)
1115{
1116 SQLUINTEGER nValueLen = 0;
1117 try
1118 {
1119 SQLUSMALLINT nAskFor = SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2;
1120 if(SQL_CURSOR_KEYSET_DRIVEN == _nCursorType)
1121 nAskFor = bFirst ? SQL_KEYSET_CURSOR_ATTRIBUTES1 : SQL_KEYSET_CURSOR_ATTRIBUTES2;
1122 else if(SQL_CURSOR_STATIC == _nCursorType)
1123 nAskFor = bFirst ? SQL_STATIC_CURSOR_ATTRIBUTES1 : SQL_STATIC_CURSOR_ATTRIBUTES2;
1124 else if(SQL_CURSOR_FORWARD_ONLY == _nCursorType)
1125 nAskFor = bFirst ? SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 : SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2;
1126 else if(SQL_CURSOR_DYNAMIC == _nCursorType)
1127 nAskFor = bFirst ? SQL_DYNAMIC_CURSOR_ATTRIBUTES1 : SQL_DYNAMIC_CURSOR_ATTRIBUTES2;
1128
1129
1130 OTools::GetInfo(getOwnConnection(),getConnectionHandle(),nAskFor,nValueLen,nullptr);
1131 }
1132 catch(const Exception&)
1133 { // we don't want our result destroy here
1134 nValueLen = 0;
1135 }
1136 return nValueLen;
1137}
1138
1139
1140/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define N3SQLRowCount(a, b)
Definition: OFunctions.hxx:274
#define N3SQLMoreResults(a)
Definition: OFunctions.hxx:345
#define N3SQLExecDirect(a, b, c)
Definition: OFunctions.hxx:243
#define N3SQLGetStmtAttr(a, b, c, d, e)
Definition: OFunctions.hxx:150
#define N3SQLSetCursorName(a, b, c)
Definition: OFunctions.hxx:232
#define N3SQLCancel(a)
Definition: OFunctions.hxx:501
#define N3SQLSetStmtAttr(a, b, c, d)
Definition: OFunctions.hxx:142
#define N3SQLNumResultCols(a, b)
Definition: OFunctions.hxx:279
#define N3SQLFreeStmt(a, b)
Definition: OFunctions.hxx:493
#define N3SQLGetCursorName(a, b, c, d)
Definition: OFunctions.hxx:524
#define THROW_SQL(x)
Definition: OStatement.cxx:42
IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.OStatement","com.sun.star.sdbc.Statement")
const char * pName
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
::dbtools::OPropertyMap & getPropMap()
Definition: TConnection.cxx:68
helper class for accessing resources shared by different libraries in the connectivity module
OUString getResourceString(TranslateId pResId) const
loads a string from the shared resource file
virtual void SAL_CALL disposing() override
Definition: OStatement.cxx:112
bool lockIfNecessary(const OUString &sql)
Definition: OStatement.cxx:244
virtual void SAL_CALL cancel() override
Definition: OStatement.cxx:160
void setUsingBookmarks(bool _bUseBookmark)
Definition: OStatement.cxx:853
SQLRETURN setStmtOption(SQLINTEGER fOption, T value) const
Definition: OStatement.cxx:412
sal_Int32 getResultSetConcurrency() const
Definition: OStatement.cxx:642
void setMaxFieldSize(sal_Int64 _par0)
Definition: OStatement.cxx:828
virtual void SAL_CALL acquire() noexcept override
void setCursorName(std::u16string_view _par0)
Definition: OStatement.cxx:834
virtual void SAL_CALL getFastPropertyValue(css::uno::Any &rValue, sal_Int32 nHandle) const override
void setResultSetType(sal_Int32 _par0)
Definition: OStatement.cxx:737
SQLUINTEGER getCursorProperties(SQLINTEGER _nCursorType, bool bFirst)
getCursorProperties return the properties for a specific cursor type
virtual css::uno::Reference< css::sdbc::XConnection > SAL_CALL getConnection() override
Definition: OStatement.cxx:445
void setQueryTimeOut(sal_Int64 _par0)
Definition: OStatement.cxx:713
virtual sal_Bool SAL_CALL execute(const OUString &sql) override
Definition: OStatement.cxx:313
virtual sal_Int32 SAL_CALL executeUpdate(const OUString &sql) override
Definition: OStatement.cxx:504
virtual sal_Int32 SAL_CALL getUpdateCount() override
Definition: OStatement.cxx:543
void setResultSetConcurrency(sal_Int32 _par0)
Definition: OStatement.cxx:725
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual void SAL_CALL close() override
Definition: OStatement.cxx:170
void setMaxRows(sal_Int64 _par0)
Definition: OStatement.cxx:719
virtual void SAL_CALL clearWarnings() override
Definition: OStatement.cxx:622
virtual css::uno::Any SAL_CALL getWarnings() override
Definition: OStatement.cxx:612
css::uno::WeakReference< css::sdbc::XResultSet > m_xResultSet
Definition: OStatement.hxx:64
void setWarning(const css::sdbc::SQLWarning &ex)
void setFetchDirection(sal_Int32 _par0)
Definition: OStatement.cxx:801
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: OStatement.cxx:126
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual rtl::Reference< OResultSet > createResultSet()
creates the driver specific resultset (factory)
virtual ::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
Definition: OStatement.cxx:930
css::uno::Reference< css::sdbc::XStatement > m_xGeneratedStatement
Definition: OStatement.hxx:65
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL getResultSet() override
Definition: OStatement.cxx:532
virtual sal_Bool SAL_CALL getMoreResults() override
Definition: OStatement.cxx:561
std::vector< OUString > m_aBatchVector
Definition: OStatement.hxx:68
virtual ~OStatement_Base() override
Definition: OStatement.cxx:80
virtual void SAL_CALL disposing() override
Definition: OStatement.cxx:94
rtl::Reference< OConnection > m_pConnection
Definition: OStatement.hxx:71
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL getGeneratedValues() override
Definition: OStatement.cxx:143
OConnection * getOwnConnection() const
Definition: OStatement.hxx:198
virtual ::cppu::IPropertyArrayHelper * createArrayHelper() const override
Definition: OStatement.cxx:860
void setEscapeProcessing(const bool _bEscapeProc)
Definition: OStatement.cxx:793
T getStmtOption(SQLINTEGER fOption) const
Definition: OStatement.cxx:405
virtual css::uno::Reference< css::sdbc::XResultSet > SAL_CALL executeQuery(const OUString &sql) override
Definition: OStatement.cxx:420
css::sdbc::SQLWarning m_aLastWarning
Definition: OStatement.hxx:62
void setFetchSize(sal_Int32 _par0)
Definition: OStatement.cxx:814
virtual void SAL_CALL release() noexcept override
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &rConvertedValue, css::uno::Any &rOldValue, sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual void SAL_CALL addBatch(const OUString &sql) override
Definition: OStatement.cxx:461
virtual void SAL_CALL release() noexcept override
virtual void SAL_CALL acquire() noexcept override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
virtual void SAL_CALL clearBatch() override
Definition: OStatement.cxx:181
virtual css::uno::Sequence< sal_Int32 > SAL_CALL executeBatch() override
Definition: OStatement.cxx:470
static void GetInfo(OConnection const *_pConnection, SQLHANDLE _aConnectionHandle, SQLUSMALLINT _nInfo, OUString &_rValue, const css::uno::Reference< css::uno::XInterface > &_xInterface, rtl_TextEncoding _nTextEncoding)
mutable::osl::Mutex m_aMutex
css::uno::Type const & get()
const OUString & getNameByIndex(sal_Int32 _nIndex) const
Definition: propertyids.cxx:95
Any value
ULONG m_refCount
sal_Int16 nValue
std::mutex m_aMutex
OUString aName
@ Exception
bool getBOOL(const Any &_rAny)
sal_Int64 getINT64(const Any &_rAny)
sal_Int32 getINT32(const Any &_rAny)
OUString getString(const Any &_rAny)
Type
::cppu::ImplHelper1< css::sdbc::XStatement > OStatement_Base
Definition: Statement.hxx:31
::cppu::WeakComponentImplHelper< css::sdbc::XStatement, css::sdbc::XWarningsSupplier, css::util::XCancellable, css::sdbc::XCloseable, css::sdbc::XGeneratedResultSet, css::sdbc::XMultipleResults > OStatement_BASE
Definition: OStatement.hxx:49
void checkDisposed(bool _bThrow)
Definition: dbtools.cxx:1951
void throwFunctionSequenceException(const Reference< XInterface > &Context, const Any &Next)
index
enumrange< T >::Iterator begin(enumrange< T >)
end
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Definition: pq_tools.cxx:100
void dispose()
#define SDB_ODBC_CHAR
Definition: odbc.hxx:68
#define PROPERTY_ID_RESULTSETTYPE
Definition: propertyids.hxx:44
#define PROPERTY_ID_QUERYTIMEOUT
Definition: propertyids.hxx:39
#define PROPERTY_ID_USEBOOKMARKS
Definition: propertyids.hxx:48
#define PROPERTY_ID_CURSORNAME
Definition: propertyids.hxx:42
#define PROPERTY_ID_RESULTSETCONCURRENCY
Definition: propertyids.hxx:43
#define PROPERTY_ID_MAXFIELDSIZE
Definition: propertyids.hxx:40
#define PROPERTY_ID_FETCHSIZE
Definition: propertyids.hxx:46
#define PROPERTY_ID_MAXROWS
Definition: propertyids.hxx:41
#define PROPERTY_ID_ESCAPEPROCESSING
Definition: propertyids.hxx:47
#define PROPERTY_ID_FETCHDIRECTION
Definition: propertyids.hxx:45
unsigned char sal_Bool
Any result
const SvXMLTokenMapEntry aTypes[]