LibreOffice Module connectivity (master) 1
mysqlc_prepared_resultset.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
21#include "mysqlc_general.hxx"
24
25#include <com/sun/star/beans/PropertyAttribute.hpp>
26#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
27#include <com/sun/star/sdbc/ResultSetType.hpp>
28#include <com/sun/star/sdbc/FetchDirection.hpp>
29#include <com/sun/star/sdbcx/CompareBookmark.hpp>
32#include <sal/log.hxx>
33
34using namespace rtl;
35
36#include <cstdlib>
37
38using namespace connectivity::mysqlc;
39using namespace connectivity;
40using namespace cppu;
41using namespace com::sun::star;
42using namespace com::sun::star::lang;
43using namespace com::sun::star::beans;
44using namespace com::sun::star::sdbc;
45using namespace com::sun::star::sdbcx;
46using namespace com::sun::star::container;
47using namespace com::sun::star::io;
48using namespace com::sun::star::util;
49using namespace ::comphelper;
50using ::osl::MutexGuard;
51
52#include <typeindex>
53
54namespace
55{
56std::type_index getTypeFromMysqlType(enum_field_types type)
57{
58 switch (type)
59 {
60 case MYSQL_TYPE_BIT:
61 return std::type_index(typeid(bool));
62 case MYSQL_TYPE_TINY:
63 return std::type_index(typeid(sal_Int8));
64 case MYSQL_TYPE_SHORT:
65 case MYSQL_TYPE_YEAR:
66 return std::type_index(typeid(sal_Int16));
67 case MYSQL_TYPE_LONG:
68 case MYSQL_TYPE_INT24:
69 return std::type_index(typeid(sal_Int32));
70 case MYSQL_TYPE_LONGLONG:
71 return std::type_index(typeid(sal_Int64));
72 case MYSQL_TYPE_FLOAT:
73 return std::type_index(typeid(float));
74 case MYSQL_TYPE_DOUBLE:
75 return std::type_index(typeid(double));
76 case MYSQL_TYPE_TIMESTAMP:
77 case MYSQL_TYPE_DATETIME:
78 return std::type_index(typeid(DateTime));
79 case MYSQL_TYPE_DATE:
80 return std::type_index(typeid(Date));
81 case MYSQL_TYPE_TIME:
82 return std::type_index(typeid(Time));
83 case MYSQL_TYPE_STRING:
84 case MYSQL_TYPE_VAR_STRING:
85 case MYSQL_TYPE_DECIMAL:
86 case MYSQL_TYPE_NEWDECIMAL:
87 return std::type_index(typeid(OUString));
88 case MYSQL_TYPE_BLOB:
89 case MYSQL_TYPE_SET:
90 case MYSQL_TYPE_ENUM:
91 case MYSQL_TYPE_GEOMETRY:
92 case MYSQL_TYPE_NULL:
93 default:
94 return std::type_index(typeid(nullptr));
95 }
96}
97}
98
99bool OPreparedResultSet::fetchResult()
100{
101 // allocate array if it does not exist
102 if (m_aData == nullptr)
103 {
104 m_aData.reset(new MYSQL_BIND[m_nColumnCount]);
105 memset(m_aData.get(), 0, m_nColumnCount * sizeof(MYSQL_BIND));
107 }
108 for (sal_Int32 i = 0; i < m_nColumnCount; ++i)
109 {
110 bool bIsBlobType = false;
111 switch (m_aFields[i].type)
112 {
113 case MYSQL_TYPE_BLOB:
114 case MYSQL_TYPE_TINY_BLOB:
115 case MYSQL_TYPE_MEDIUM_BLOB:
116 case MYSQL_TYPE_LONG_BLOB:
117 bIsBlobType = true;
118 break;
119 default:
120 bIsBlobType = false;
121 }
122 m_aMetaData[i].is_null = false;
123 m_aMetaData[i].length = 0l;
124 m_aMetaData[i].error = false;
125
126 m_aData[i].is_null = &m_aMetaData[i].is_null;
127 m_aData[i].buffer_length = bIsBlobType ? 0 : m_aFields[i].length;
128 m_aData[i].length = &m_aMetaData[i].length;
129 m_aData[i].error = &m_aMetaData[i].error;
130 m_aData[i].buffer = nullptr;
131 m_aData[i].buffer_type = m_aFields[i].type;
132
133 // allocates memory, if it is a fixed size type. If not then nullptr
136 }
137 mysql_stmt_bind_result(m_pStmt, m_aData.get());
138 int failure = mysql_stmt_fetch(m_pStmt);
139
140 for (sal_Int32 i = 0; i < m_nColumnCount; ++i)
141 {
142 if (*m_aData[i].error)
143 {
144 // expected if we have a BLOB, as buffer_length is set to 0. We want to
145 // fetch it piece by piece
146 // see https://bugs.mysql.com/file.php?id=12361&bug_id=33086
147 if (m_aData[i].buffer == nullptr)
148 {
149 m_aData[i].buffer_length = *m_aData[i].length;
150 m_aData[i].buffer = malloc(*m_aData[i].length);
151 mysql_stmt_fetch_column(m_pStmt, &m_aData[i], i, 0);
152 }
153 }
154 }
155
156 if (failure == 1)
157 {
158 MYSQL* pMysql = m_rConnection.getMysqlConnection();
159 mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMysql), mysql_sqlstate(pMysql),
160 mysql_errno(pMysql), *this, m_encoding);
161 }
162 else if (failure == MYSQL_NO_DATA)
163 return false;
164 return true;
165}
166
168{
169 return "com.sun.star.sdbcx.mysqlc.ResultSet";
170}
171
172uno::Sequence<OUString> SAL_CALL OPreparedResultSet::getSupportedServiceNames()
173{
174 return { "com.sun.star.sdbc.ResultSet", "com.sun.star.sdbcx.ResultSet" };
175}
176
177sal_Bool SAL_CALL OPreparedResultSet::supportsService(const OUString& _rServiceName)
178{
179 return cppu::supportsService(this, _rServiceName);
180}
182 MYSQL_STMT* pMyStmt)
185 , m_rConnection(rConn)
186 , m_aStatement(css::uno::Reference(cppu::getXWeak(pStmt)))
187 , m_pStmt(pMyStmt)
188 , m_encoding(rConn.getConnectionEncoding())
189 , m_nColumnCount(mysql_stmt_field_count(pMyStmt))
190{
191 m_pResult = mysql_stmt_result_metadata(m_pStmt);
192 if (m_pResult != nullptr)
193 mysql_stmt_store_result(m_pStmt);
194 m_aFields = mysql_fetch_fields(m_pResult);
195 m_nRowCount = mysql_stmt_num_rows(pMyStmt);
196}
197
199{
201
202 MutexGuard aGuard(m_aMutex);
203
204 m_aStatement.clear();
205 m_xMetaData = nullptr;
206}
207
209{
211 if (!aRet.hasValue())
212 {
214 }
215 return aRet;
216}
217
218uno::Sequence<Type> SAL_CALL OPreparedResultSet::getTypes()
219{
223
225}
226
227sal_Int32 SAL_CALL OPreparedResultSet::findColumn(const OUString& columnName)
228{
229 MutexGuard aGuard(m_aMutex);
230 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
231
232 MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult);
233 for (sal_Int32 i = 0; i < m_nColumnCount; ++i)
234 {
235 if (columnName.equalsIgnoreAsciiCaseAscii(pFields[i].name))
236 return i + 1; // sdbc indexes from 1
237 }
238
239 throw SQLException("The column name '" + columnName + "' is not valid.", *this, "42S22", 0,
240 Any());
241}
242
243template <typename T> T OPreparedResultSet::safelyRetrieveValue(sal_Int32 nColumnIndex)
244{
245 MutexGuard aGuard(m_aMutex);
246 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
247 checkColumnIndex(nColumnIndex);
248 if (*m_aData[nColumnIndex - 1].is_null)
249 {
250 m_bWasNull = true;
251 return T();
252 }
253 m_bWasNull = false;
254
255 return retrieveValue<T>(nColumnIndex);
256}
257
258template <typename T> T OPreparedResultSet::retrieveValue(sal_Int32 nColumnIndex)
259{
260 if (getTypeFromMysqlType(m_aFields[nColumnIndex - 1].type) == std::type_index(typeid(T)))
261 return *static_cast<T*>(m_aData[nColumnIndex - 1].buffer);
262 else
263 {
264 auto const& row = getRowSetValue(nColumnIndex);
265 if constexpr (std::is_same_v<sal_Int64, T>)
266 return row.getLong();
267 else if constexpr (std::is_same_v<sal_Int32, T>)
268 return row.getInt32();
269 else if constexpr (std::is_same_v<sal_Int16, T>)
270 return row.getInt16();
271 else if constexpr (std::is_same_v<sal_Int8, T>)
272 return row.getInt8();
273 else if constexpr (std::is_same_v<double, T>)
274 return row.getDouble();
275 else if constexpr (std::is_same_v<float, T>)
276 return row.getFloat();
277 else if constexpr (std::is_same_v<bool, T>)
278 return row.getBool();
279 else
280 return row;
281 }
282}
283
284template <> uno::Sequence<sal_Int8> OPreparedResultSet::retrieveValue(sal_Int32 column)
285{
286 // TODO make conversion possible
287 return uno::Sequence<sal_Int8>(static_cast<sal_Int8 const*>(m_aData[column - 1].buffer),
288 *m_aData[column - 1].length);
289}
290
291template <> Date OPreparedResultSet::retrieveValue(sal_Int32 column)
292{
293 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(Date)))
294 return getRowSetValue(column).getDate();
295 const MYSQL_TIME* pTime = static_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
296
297 Date d;
298 d.Year = pTime->year;
299 d.Month = pTime->month;
300 d.Day = pTime->day;
301 return d;
302}
303
304template <> Time OPreparedResultSet::retrieveValue(sal_Int32 column)
305{
306 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(Time)))
307 return getRowSetValue(column).getTime();
308 const MYSQL_TIME* pTime = static_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
309
310 Time t;
311 t.Hours = pTime->hour;
312 t.Minutes = pTime->minute;
313 t.Seconds = pTime->second;
314 return t;
315}
316
317template <> DateTime OPreparedResultSet::retrieveValue(sal_Int32 column)
318{
319 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(DateTime)))
320 return getRowSetValue(column).getDateTime();
321 const MYSQL_TIME* pTime = static_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
322
323 DateTime t;
324 t.Year = pTime->year;
325 t.Month = pTime->month;
326 t.Day = pTime->day;
327 t.Hours = pTime->hour;
328 t.Minutes = pTime->minute;
329 t.Seconds = pTime->second;
330 return t;
331}
332
333template <> OUString OPreparedResultSet::retrieveValue(sal_Int32 column)
334{
335 // redirect call to the appropriate method if needed
336 // BLOB can be simply read out as string
337 bool bIsBlobType = false;
338 switch (m_aFields[column - 1].type)
339 {
340 case MYSQL_TYPE_BLOB:
341 case MYSQL_TYPE_TINY_BLOB:
342 case MYSQL_TYPE_MEDIUM_BLOB:
343 case MYSQL_TYPE_LONG_BLOB:
344 bIsBlobType = true;
345 break;
346 default:
347 bIsBlobType = false;
348 }
349
350 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(OUString))
351 && !bIsBlobType)
352 return getRowSetValue(column).getString();
353 const char* sStr = static_cast<const char*>(m_aData[column - 1].buffer);
354
355 return OUString(sStr, *m_aData[column - 1].length, m_encoding);
356}
357
359{
360 switch (m_aFields[nColumnIndex - 1].type)
361 {
362 case MYSQL_TYPE_TINY:
363 return getByte(nColumnIndex);
364 case MYSQL_TYPE_SHORT:
365 case MYSQL_TYPE_YEAR:
366 return getShort(nColumnIndex);
367 case MYSQL_TYPE_LONG:
368 case MYSQL_TYPE_INT24:
369 return getInt(nColumnIndex);
370 case MYSQL_TYPE_BIT:
371 return ORowSetValue(bool(getBoolean(nColumnIndex)));
372 case MYSQL_TYPE_LONGLONG:
373 return getLong(nColumnIndex);
374 case MYSQL_TYPE_FLOAT:
375 return getFloat(nColumnIndex);
376 case MYSQL_TYPE_DOUBLE:
377 return getDouble(nColumnIndex);
378 case MYSQL_TYPE_TIMESTAMP:
379 case MYSQL_TYPE_DATETIME:
380 return getTimestamp(nColumnIndex);
381 case MYSQL_TYPE_DATE:
382 return getDate(nColumnIndex);
383 case MYSQL_TYPE_TIME:
384 return getTime(nColumnIndex);
385 case MYSQL_TYPE_STRING:
386 case MYSQL_TYPE_VAR_STRING:
387 case MYSQL_TYPE_DECIMAL:
388 case MYSQL_TYPE_NEWDECIMAL:
389 return getString(nColumnIndex);
390 case MYSQL_TYPE_BLOB:
391 case MYSQL_TYPE_TINY_BLOB:
392 case MYSQL_TYPE_MEDIUM_BLOB:
393 case MYSQL_TYPE_LONG_BLOB:
394 throw SQLException("Column with type BLOB cannot be converted", *this, "22000", 1,
395 Any());
396 default:
397 SAL_WARN("connectivity.mysqlc", "OPreparedResultSet::getRowSetValue: unknown type: "
398 << m_aFields[nColumnIndex - 1].type);
399 throw SQLException("Unknown column type when fetching result", *this, "22000", 1,
400 Any());
401 }
402}
403
404uno::Reference<XInputStream> SAL_CALL OPreparedResultSet::getBinaryStream(sal_Int32 /*column*/)
405{
406 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBinaryStream",
407 *this);
408 return nullptr;
409}
410
411uno::Reference<XInputStream> SAL_CALL OPreparedResultSet::getCharacterStream(sal_Int32 /*column*/)
412{
414 "OPreparedResultSet::getCharacterStream", *this);
415 return nullptr;
416}
417
418sal_Bool SAL_CALL OPreparedResultSet::getBoolean(sal_Int32 column)
419{
420 return safelyRetrieveValue<bool>(column);
421}
422
423sal_Int8 SAL_CALL OPreparedResultSet::getByte(sal_Int32 column)
424{
425 return safelyRetrieveValue<sal_Int8>(column);
426}
427
428uno::Sequence<sal_Int8> SAL_CALL OPreparedResultSet::getBytes(sal_Int32 column)
429{
430 return safelyRetrieveValue<uno::Sequence<sal_Int8>>(column);
431}
432
433Date SAL_CALL OPreparedResultSet::getDate(sal_Int32 column)
434{
435 return safelyRetrieveValue<Date>(column);
436}
437
438double SAL_CALL OPreparedResultSet::getDouble(sal_Int32 column)
439{
440 return safelyRetrieveValue<double>(column);
441}
442
443float SAL_CALL OPreparedResultSet::getFloat(sal_Int32 column)
444{
445 return safelyRetrieveValue<float>(column);
446}
447
448sal_Int32 SAL_CALL OPreparedResultSet::getInt(sal_Int32 column)
449{
450 return safelyRetrieveValue<sal_Int32>(column);
451}
452
453sal_Int32 SAL_CALL OPreparedResultSet::getRow()
454{
455 MutexGuard aGuard(m_aMutex);
456 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
457
458 return static_cast<sal_Int32>(mysql_field_tell(m_pResult));
459}
460
461sal_Int64 SAL_CALL OPreparedResultSet::getLong(sal_Int32 column)
462{
463 return safelyRetrieveValue<sal_Int64>(column);
464}
465
466uno::Reference<XResultSetMetaData> SAL_CALL OPreparedResultSet::getMetaData()
467{
468 MutexGuard aGuard(m_aMutex);
469 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
470 if (!m_xMetaData.is())
471 {
473 }
474 return m_xMetaData;
475}
476
477uno::Reference<XArray> SAL_CALL OPreparedResultSet::getArray(sal_Int32 column)
478{
479 MutexGuard aGuard(m_aMutex);
480 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
481 checkColumnIndex(column);
482
483 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getArray", *this);
484 return nullptr;
485}
486
487uno::Reference<XClob> SAL_CALL OPreparedResultSet::getClob(sal_Int32 column)
488{
489 MutexGuard aGuard(m_aMutex);
490 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
491 checkColumnIndex(column);
492
493 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getClob", *this);
494 return nullptr;
495}
496
497uno::Reference<XBlob> SAL_CALL OPreparedResultSet::getBlob(sal_Int32 column)
498{
499 MutexGuard aGuard(m_aMutex);
500 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
501 checkColumnIndex(column);
502
503 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBlob", *this);
504 return nullptr;
505}
506
507uno::Reference<XRef> SAL_CALL OPreparedResultSet::getRef(sal_Int32 column)
508{
509 MutexGuard aGuard(m_aMutex);
510 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
511 checkColumnIndex(column);
512
513 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getRef", *this);
514 return nullptr;
515}
516
517Any SAL_CALL OPreparedResultSet::getObject(sal_Int32 column,
518 const uno::Reference<XNameAccess>& /* typeMap */)
519{
520 MutexGuard aGuard(m_aMutex);
521 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
522 checkColumnIndex(column);
523
524 Any aRet;
525
526 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getObject", *this);
527 return aRet;
528}
529
530sal_Int16 SAL_CALL OPreparedResultSet::getShort(sal_Int32 column)
531{
532 return safelyRetrieveValue<sal_Int16>(column);
533}
534
535OUString SAL_CALL OPreparedResultSet::getString(sal_Int32 column)
536{
537 return safelyRetrieveValue<OUString>(column);
538}
539
540Time SAL_CALL OPreparedResultSet::getTime(sal_Int32 column)
541{
542 return safelyRetrieveValue<Time>(column);
543}
544
546{
547 return safelyRetrieveValue<DateTime>(column);
548}
549
551{
552 MutexGuard aGuard(m_aMutex);
553 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
554
555 return m_nCurrentRow == 0;
556}
557
559{
560 MutexGuard aGuard(m_aMutex);
561 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
562
563 return m_nCurrentRow > m_nRowCount;
564}
565
567{
568 MutexGuard aGuard(m_aMutex);
569 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
570
571 return m_nCurrentRow == 1 && !isAfterLast();
572}
573
575{
576 MutexGuard aGuard(m_aMutex);
577 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
578
579 return m_nCurrentRow == m_nRowCount;
580}
581
583{
584 MutexGuard aGuard(m_aMutex);
585 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
586 mysql_stmt_data_seek(m_pStmt, 0);
587
588 m_nCurrentRow = 0;
589 m_aData.reset();
590}
591
593{
594 MutexGuard aGuard(m_aMutex);
595 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
596
597 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::afterLast", *this);
598}
599
601{
602 MutexGuard aGuard(m_aMutex);
603 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
604
605 m_aData.reset();
606 m_aMetaData.reset();
607
608 if (m_pResult)
609 mysql_free_result(m_pResult);
610 mysql_stmt_free_result(m_pStmt);
611 dispose();
612}
613
615{
616 MutexGuard aGuard(m_aMutex);
617 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
618
619 mysql_stmt_data_seek(m_pStmt, 0);
620 m_nCurrentRow = 0;
621 next();
622
623 return true;
624}
625
627{
628 MutexGuard aGuard(m_aMutex);
629 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
630
631 mysql_stmt_data_seek(m_pStmt, m_nRowCount - 1);
632 next();
633
634 return true;
635}
636
638{
639 MutexGuard aGuard(m_aMutex);
640 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
641
642 sal_Int32 nToGo = row < 0 ? m_nRowCount - row : row - 1;
643
644 if (nToGo >= m_nRowCount)
645 nToGo = m_nRowCount - 1;
646 if (nToGo < 0)
647 nToGo = 0;
648
649 mysql_stmt_data_seek(m_pStmt, nToGo);
650 next();
651
652 return true;
653}
654
656{
657 MutexGuard aGuard(m_aMutex);
658 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
659
660 if (row == 0)
661 return true;
662
663 sal_Int32 nToGo = m_nCurrentRow + row;
664 if (nToGo >= m_nRowCount)
665 nToGo = m_nRowCount - 1;
666 if (nToGo < 0)
667 nToGo = 0;
668
669 mysql_stmt_data_seek(m_pStmt, nToGo);
670 next();
671 m_nCurrentRow += row;
672
673 return true;
674}
675
677{
678 MutexGuard aGuard(m_aMutex);
679 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
680
681 if (m_nCurrentRow <= 1)
682 return false;
683
684 mysql_stmt_data_seek(m_pStmt, m_nCurrentRow - 2);
685 next();
687 return true;
688}
689
690uno::Reference<uno::XInterface> SAL_CALL OPreparedResultSet::getStatement()
691{
692 MutexGuard aGuard(m_aMutex);
693 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
694
695 return m_aStatement.get();
696}
697
699{
700 MutexGuard aGuard(m_aMutex);
701 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
702
703 return false;
704}
705
707{
708 MutexGuard aGuard(m_aMutex);
709 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
710
711 return false;
712}
713
715{
716 MutexGuard aGuard(m_aMutex);
717 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
718
719 return false;
720}
721
723{
724 MutexGuard aGuard(m_aMutex);
725 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
726 bool hasData = fetchResult();
727
728 // current field cannot be asked as a number. We have to keep track it
729 // manually.
730 m_nCurrentRow += 1;
731
732 return hasData;
733}
734
736{
737 MutexGuard aGuard(m_aMutex);
738 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
739
740 return m_bWasNull;
741}
742
744{
745 MutexGuard aGuard(m_aMutex);
746 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
747}
748
750
752
754{
755 MutexGuard aGuard(m_aMutex);
756 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
757 // you only have to implement this if you want to insert new rows
758 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::insertRow", *this);
759}
760
762{
763 MutexGuard aGuard(m_aMutex);
764 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
765
766 // only when you allow updates
767 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateRow", *this);
768}
769
771{
772 MutexGuard aGuard(m_aMutex);
773 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
774 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::deleteRow", *this);
775}
776
778{
779 MutexGuard aGuard(m_aMutex);
780 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
781 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::cancelRowUpdates",
782 *this);
783}
784
786{
787 MutexGuard aGuard(m_aMutex);
788 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
789
790 // only when you allow insert's
791 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::moveToInsertRow",
792 *this);
793}
794
796{
797 MutexGuard aGuard(m_aMutex);
798 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
799}
800
801void SAL_CALL OPreparedResultSet::updateNull(sal_Int32 column)
802{
803 MutexGuard aGuard(m_aMutex);
804 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
805 checkColumnIndex(column);
806 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateNull",
807 *this);
808}
809
810void SAL_CALL OPreparedResultSet::updateBoolean(sal_Int32 column, sal_Bool /* x */)
811{
812 MutexGuard aGuard(m_aMutex);
813 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
814 checkColumnIndex(column);
815 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateBoolean",
816 *this);
817}
818
819void SAL_CALL OPreparedResultSet::updateByte(sal_Int32 column, sal_Int8 /* x */)
820{
821 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
822 MutexGuard aGuard(m_aMutex);
823 checkColumnIndex(column);
824 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateByte",
825 *this);
826}
827
828void SAL_CALL OPreparedResultSet::updateShort(sal_Int32 column, sal_Int16 /* x */)
829{
830 MutexGuard aGuard(m_aMutex);
831 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
832 checkColumnIndex(column);
833 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateShort",
834 *this);
835}
836
837void SAL_CALL OPreparedResultSet::updateInt(sal_Int32 column, sal_Int32 /* x */)
838{
839 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
840 MutexGuard aGuard(m_aMutex);
841 checkColumnIndex(column);
842 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateInt", *this);
843}
844
845void SAL_CALL OPreparedResultSet::updateLong(sal_Int32 column, sal_Int64 /* x */)
846{
847 MutexGuard aGuard(m_aMutex);
848 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
849 checkColumnIndex(column);
850 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateLong",
851 *this);
852}
853
854void SAL_CALL OPreparedResultSet::updateFloat(sal_Int32 column, float /* x */)
855{
856 MutexGuard aGuard(m_aMutex);
857 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
858 checkColumnIndex(column);
859 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateFloat",
860 *this);
861}
862
863void SAL_CALL OPreparedResultSet::updateDouble(sal_Int32 column, double /* x */)
864{
865 MutexGuard aGuard(m_aMutex);
866 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
867 checkColumnIndex(column);
868 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateDouble",
869 *this);
870}
871
872void SAL_CALL OPreparedResultSet::updateString(sal_Int32 column, const OUString& /* x */)
873{
874 MutexGuard aGuard(m_aMutex);
875 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
876 checkColumnIndex(column);
877 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateString",
878 *this);
879}
880
881void SAL_CALL OPreparedResultSet::updateBytes(sal_Int32 column,
882 const uno::Sequence<sal_Int8>& /* x */)
883{
884 MutexGuard aGuard(m_aMutex);
885 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
886 checkColumnIndex(column);
887 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateBytes",
888 *this);
889}
890
891void SAL_CALL OPreparedResultSet::updateDate(sal_Int32 column, const Date& /* x */)
892{
893 MutexGuard aGuard(m_aMutex);
894 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
895 checkColumnIndex(column);
896 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateDate",
897 *this);
898}
899
900void SAL_CALL OPreparedResultSet::updateTime(sal_Int32 column, const Time& /* x */)
901{
902 MutexGuard aGuard(m_aMutex);
903 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
904 checkColumnIndex(column);
905 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateTime",
906 *this);
907}
908
909void SAL_CALL OPreparedResultSet::updateTimestamp(sal_Int32 column, const DateTime& /* x */)
910{
911 MutexGuard aGuard(m_aMutex);
912 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
913 checkColumnIndex(column);
914 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateTimestamp",
915 *this);
916}
917
918void SAL_CALL OPreparedResultSet::updateBinaryStream(sal_Int32 column,
919 const uno::Reference<XInputStream>& /* x */,
920 sal_Int32 /* length */)
921{
922 MutexGuard aGuard(m_aMutex);
923 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
924 checkColumnIndex(column);
926 "OPreparedResultSet::updateBinaryStream", *this);
927}
928
929void SAL_CALL OPreparedResultSet::updateCharacterStream(sal_Int32 column,
930 const uno::Reference<XInputStream>& /* x */,
931 sal_Int32 /* length */)
932{
933 MutexGuard aGuard(m_aMutex);
934 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
935 checkColumnIndex(column);
937 "OPreparedResultSet::updateCharacterStream", *this);
938}
939
941{
942 MutexGuard aGuard(m_aMutex);
943 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
944 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::refreshRow",
945 *this);
946}
947
948void SAL_CALL OPreparedResultSet::updateObject(sal_Int32 column, const Any& /* x */)
949{
950 MutexGuard aGuard(m_aMutex);
951 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
952 checkColumnIndex(column);
953 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateObject",
954 *this);
955}
956
957void SAL_CALL OPreparedResultSet::updateNumericObject(sal_Int32 column, const Any& /* x */,
958 sal_Int32 /* scale */)
959{
960 MutexGuard aGuard(m_aMutex);
961 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
962 checkColumnIndex(column);
964 "OPreparedResultSet::updateNumericObject", *this);
965}
966
967// XRowLocate
969{
970 MutexGuard aGuard(m_aMutex);
971 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
972
973 // if you don't want to support bookmark you must remove the XRowLocate interface
974 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBookmark",
975 *this);
976
977 return Any();
978}
979
980sal_Bool SAL_CALL OPreparedResultSet::moveToBookmark(const Any& /* bookmark */)
981{
982 MutexGuard aGuard(m_aMutex);
983 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
984
985 return false;
986}
987
988sal_Bool SAL_CALL OPreparedResultSet::moveRelativeToBookmark(const Any& /* bookmark */,
989 sal_Int32 /* rows */)
990{
991 MutexGuard aGuard(m_aMutex);
992 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
993
995 "OPreparedResultSet::moveRelativeToBookmark", *this);
996 return false;
997}
998
999sal_Int32 SAL_CALL OPreparedResultSet::compareBookmarks(const Any& /* n1 */, const Any& /* n2 */)
1000{
1001 MutexGuard aGuard(m_aMutex);
1002 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
1003
1004 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::compareBookmarks",
1005 *this);
1006
1007 return CompareBookmark::NOT_EQUAL;
1008}
1009
1011
1012sal_Int32 SAL_CALL OPreparedResultSet::hashBookmark(const Any& /* bookmark */)
1013{
1014 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::hashBookmark",
1015 *this);
1016 return 0;
1017}
1018
1019// XDeleteRows
1020uno::Sequence<sal_Int32>
1021 SAL_CALL OPreparedResultSet::deleteRows(const uno::Sequence<Any>& /* rows */)
1022{
1023 MutexGuard aGuard(m_aMutex);
1024 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
1025
1026 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::deleteRows",
1027 *this);
1028 return uno::Sequence<sal_Int32>();
1029}
1030
1032{
1033 return new OPropertyArrayHelper{
1034 { { "FetchDirection", PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0 },
1037 PropertyAttribute::READONLY },
1038 { "ResultSetConcurrency", PROPERTY_ID_RESULTSETCONCURRENCY,
1039 cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY },
1041 PropertyAttribute::READONLY } }
1042 };
1043}
1044
1046
1048 Any& /* rOldValue */, sal_Int32 nHandle,
1049 const Any& /* rValue */)
1050{
1051 switch (nHandle)
1052 {
1057 throw css::lang::IllegalArgumentException();
1060 default:;
1061 }
1062 return false;
1063}
1064
1066 const Any& /* rValue */)
1067{
1068 switch (nHandle)
1069 {
1074 throw uno::Exception("cannot set prop " + OUString::number(nHandle), nullptr);
1076 break;
1078 break;
1079 default:;
1080 }
1081}
1082
1083void OPreparedResultSet::getFastPropertyValue(Any& _rValue, sal_Int32 nHandle) const
1084{
1085 switch (nHandle)
1086 {
1088 _rValue <<= false;
1089 break;
1091 break;
1093 _rValue <<= ResultSetConcurrency::READ_ONLY;
1094 break;
1096 _rValue <<= ResultSetType::SCROLL_INSENSITIVE;
1097 break;
1099 _rValue <<= FetchDirection::FORWARD;
1100 break;
1102 _rValue <<= sal_Int32(50);
1103 break;
1104 ;
1105 default:;
1106 }
1107}
1108
1110
1112
1113css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OPreparedResultSet::getPropertySetInfo()
1114{
1115 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1116}
1117
1119{
1120 if (!m_aData)
1121 throw SQLException("Cursor out of range", *this, "HY109", 1, Any());
1122 if (index < 1 || index > static_cast<int>(m_nColumnCount))
1123 {
1124 /* static object for efficiency or thread safety is a problem ? */
1125 throw SQLException("index out of range", *this, "42S22", 1, Any());
1126 }
1127}
1128
1129/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
double d
void disposing(std::unique_lock< std::mutex > &rGuard)
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
css::util::Time getTime() const
Definition: FValue.cxx:1951
OUString getString() const
Definition: FValue.cxx:933
css::util::Date getDate() const
Definition: FValue.cxx:1893
css::util::DateTime getDateTime() const
Definition: FValue.cxx:1995
void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any &rValue) override
void SAL_CALL updateFloat(sal_Int32 column, float x) override
void SAL_CALL updateInt(sal_Int32 column, sal_Int32 x) override
void SAL_CALL updateBytes(sal_Int32 column, const css::uno::Sequence< sal_Int8 > &x) override
css::uno::Reference< css::sdbc::XRef > SAL_CALL getRef(sal_Int32 column) override
sal_Bool SAL_CALL getBoolean(sal_Int32 column) override
sal_Int16 SAL_CALL getShort(sal_Int32 column) override
::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
css::uno::Reference< css::io::XInputStream > SAL_CALL getCharacterStream(sal_Int32 column) override
void SAL_CALL getFastPropertyValue(Any &rValue, sal_Int32 nHandle) const override
OUString SAL_CALL getString(sal_Int32 column) override
css::uno::Reference< css::sdbc::XResultSetMetaData > SAL_CALL getMetaData() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void SAL_CALL updateByte(sal_Int32 column, sal_Int8 x) override
css::uno::Reference< css::uno::XInterface > SAL_CALL getStatement() override
sal_Bool SAL_CALL convertFastPropertyValue(Any &rConvertedValue, Any &rOldValue, sal_Int32 nHandle, const Any &rValue) override
Any SAL_CALL getObject(sal_Int32 column, const css::uno::Reference< css::container::XNameAccess > &typeMap) override
css::util::DateTime SAL_CALL getTimestamp(sal_Int32 column) override
T safelyRetrieveValue(const sal_Int32 nColumnIndex)
sal_Int32 SAL_CALL compareBookmarks(const Any &first, const Any &second) override
sal_Bool SAL_CALL moveToBookmark(const Any &bookmark) override
sal_Int32 SAL_CALL hashBookmark(const Any &bookmark) override
css::uno::Reference< css::sdbc::XBlob > SAL_CALL getBlob(sal_Int32 column) override
void SAL_CALL updateBoolean(sal_Int32 column, sal_Bool x) override
void SAL_CALL updateLong(sal_Int32 column, sal_Int64 x) override
css::util::Time SAL_CALL getTime(sal_Int32 column) override
css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
sal_Bool SAL_CALL absolute(sal_Int32 row) override
void SAL_CALL updateCharacterStream(sal_Int32 column, const css::uno::Reference< css::io::XInputStream > &x, sal_Int32 length) override
sal_Int8 SAL_CALL getByte(sal_Int32 column) override
void SAL_CALL updateObject(sal_Int32 column, const Any &x) override
sal_Bool SAL_CALL relative(sal_Int32 rows) override
css::uno::Reference< css::sdbc::XResultSetMetaData > m_xMetaData
float SAL_CALL getFloat(sal_Int32 column) override
void SAL_CALL updateTime(sal_Int32 column, const css::util::Time &x) override
::cppu::IPropertyArrayHelper * createArrayHelper() const override
used to implement the creation of the array helper which is shared amongst all instances of the class...
void SAL_CALL updateTimestamp(sal_Int32 column, const css::util::DateTime &x) override
Any SAL_CALL queryInterface(const css::uno::Type &rType) override
void SAL_CALL updateNull(sal_Int32 column) override
virtual sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
void SAL_CALL updateDate(sal_Int32 column, const css::util::Date &x) override
double SAL_CALL getDouble(sal_Int32 column) override
css::uno::Reference< css::sdbc::XClob > SAL_CALL getClob(sal_Int32 column) override
css::uno::Reference< css::sdbc::XArray > SAL_CALL getArray(sal_Int32 column) override
css::util::Date SAL_CALL getDate(sal_Int32 column) override
void SAL_CALL updateString(sal_Int32 column, const OUString &x) override
virtual OUString SAL_CALL getImplementationName() override
connectivity::ORowSetValue getRowSetValue(sal_Int32 nColumnIndex)
sal_Int32 SAL_CALL findColumn(const OUString &columnName) override
void SAL_CALL updateBinaryStream(sal_Int32 column, const css::uno::Reference< css::io::XInputStream > &x, sal_Int32 length) override
OPreparedResultSet(OConnection &rConn, OPreparedStatement *pStmt, MYSQL_STMT *pMyStmt)
css::uno::Sequence< sal_Int32 > SAL_CALL deleteRows(const css::uno::Sequence< Any > &rows) override
void SAL_CALL updateShort(sal_Int32 column, sal_Int16 x) override
sal_Int32 SAL_CALL getInt(sal_Int32 column) override
void SAL_CALL updateNumericObject(sal_Int32 column, const Any &x, sal_Int32 scale) override
sal_Int64 SAL_CALL getLong(sal_Int32 column) override
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
css::uno::Sequence< sal_Int8 > SAL_CALL getBytes(sal_Int32 column) override
void SAL_CALL updateDouble(sal_Int32 column, double x) override
css::uno::Reference< css::io::XInputStream > SAL_CALL getBinaryStream(sal_Int32 column) override
sal_Bool SAL_CALL moveRelativeToBookmark(const Any &bookmark, sal_Int32 rows) override
::cppu::IPropertyArrayHelper * getArrayHelper()
call this in the getInfoHelper method of your derived class.
mutable::osl::Mutex m_aMutex
css::uno::Type const & get()
virtual void SAL_CALL dispose() SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
std::mutex m_aMutex
#define SAL_WARN(area, stream)
Type
static ColumnProperty ** pFields
void checkDisposed(bool _bThrow)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &_rLeft, const css::uno::Sequence< T > &_rRight)
concat two sequences
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Reference
int i
void allocateSqlVar(void **mem, enum_field_types eType, unsigned nSize)
void throwSQLExceptionWithMsg(const char *msg, const char *SQLSTATE, unsigned int errorNum, const css::uno::Reference< css::uno::XInterface > &_context, const rtl_TextEncoding encoding)
void throwFeatureNotImplementedException(const char *_pAsciiFeatureName, const css::uno::Reference< XInterface > &_rxContext)
const char * columnName
Definition: pq_statics.cxx:56
sal_Int32 type
Definition: pq_statics.cxx:60
sal_Int32 nHandle
unsigned char sal_Bool
signed char sal_Int8
const SvXMLTokenMapEntry aTypes[]