LibreOffice Module connectivity (master) 1
mysqlc_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"
22#include "mysqlc_resultset.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>
33#include <o3tl/safeint.hxx>
34#include <o3tl/string_view.hxx>
35
36using namespace rtl;
37
38using namespace connectivity::mysqlc;
39using namespace cppu;
40using namespace com::sun::star;
41using namespace com::sun::star::lang;
42using namespace com::sun::star::beans;
43using namespace com::sun::star::sdbc;
44using namespace com::sun::star::sdbcx;
45using namespace com::sun::star::container;
46using namespace com::sun::star::io;
47using namespace com::sun::star::uno;
48using namespace com::sun::star::util;
49using namespace ::comphelper;
50using ::osl::MutexGuard;
51
52namespace
53{
54// copied from string misc, it should be replaced when library is not an
55// extension anymore
56std::vector<OString> lcl_split(std::string_view rStr, char cSeparator)
57{
58 std::vector<OString> vec;
59 sal_Int32 idx = 0;
60 do
61 {
62 OString kw(o3tl::trim(o3tl::getToken(rStr, 0, cSeparator, idx)));
63 if (!kw.isEmpty())
64 {
65 vec.push_back(kw);
66 }
67 } while (idx >= 0);
68 return vec;
69}
70}
71
72void OResultSet::checkRowIndex()
73{
74 if (m_nRowPosition < 0 || m_nRowPosition >= m_nRowCount)
75 {
76 throw SQLException("Cursor position out of range", *this, OUString(), 1, Any());
77 }
78}
79
80bool OResultSet::checkNull(sal_Int32 column)
81{
82 if (m_aRows[m_nRowPosition][column - 1].isEmpty())
83 {
84 m_bWasNull = true;
85 return true;
86 }
87 m_bWasNull = false;
88 return false;
89}
90
92{
93 return "com.sun.star.sdbcx.mysqlc.ResultSet";
94}
95
96uno::Sequence<OUString> SAL_CALL OResultSet::getSupportedServiceNames()
97{
98 return { "com.sun.star.sdbc.ResultSet", "com.sun.star.sdbcx.ResultSet" };
99}
100
101sal_Bool SAL_CALL OResultSet::supportsService(const OUString& _rServiceName)
102{
103 return cppu::supportsService(this, _rServiceName);
104}
105
106OResultSet::OResultSet(OConnection& rConn, OCommonStatement* pStmt, MYSQL_RES* pResult,
107 rtl_TextEncoding _encoding)
110 , m_pMysql(rConn.getMysqlConnection())
111 , m_aStatement(css::uno::Reference(cppu::getXWeak(pStmt)))
112 , m_pResult(pResult)
113 , m_encoding(_encoding)
114{
115 assert(m_pResult);
117}
118
120{
121 if (m_pResult)
122 {
123 fetchResult();
124 }
125}
126
128{
129 if (m_pResult == nullptr)
130 return; // already fetched
131
132 // it works only if result set is produced via mysql_store_result
133 // TODO ensure that
134 m_nRowCount = mysql_num_rows(m_pResult);
135
136 if (!m_aFields.empty())
137 return;
138 unsigned nFieldCount = mysql_num_fields(m_pResult);
139 MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult);
140 m_aFields.reserve(nFieldCount);
141 for (unsigned i = 0; i < nFieldCount; ++i)
142 m_aFields.push_back(OUString{
143 pFields[i].name, static_cast<sal_Int32>(strlen(pFields[i].name)), m_encoding });
144}
145
147{
148 // Mysql C API does not allow simultaneously opened result sets, but sdbc does.
149 // Because of that we need to fetch all of the data ASAP
151
152 // fetch all the data
153 m_aRows.reserve(m_nRowCount);
154
155 for (sal_Int32 row = 0; row < m_nRowCount; ++row)
156 {
157 MYSQL_ROW data = mysql_fetch_row(m_pResult);
158 unsigned long* lengths = mysql_fetch_lengths(m_pResult);
159 m_aRows.push_back(DataFields{});
160 // MYSQL_ROW is char**, array of strings
161 for (std::size_t col = 0; col < m_aFields.size(); ++col)
162 {
163 m_aRows.back().push_back(OString{ data[col], static_cast<sal_Int32>(lengths[col]) });
164 }
165 }
166 unsigned errorNum = mysql_errno(m_pMysql);
167 if (errorNum)
169 mysql_error(m_pMysql), mysql_sqlstate(m_pMysql), errorNum, *this, m_encoding);
170 mysql_free_result(m_pResult);
171 m_pResult = nullptr;
172}
173
175{
177
178 MutexGuard aGuard(m_aMutex);
179
180 if (m_pResult != nullptr)
181 {
182 mysql_free_result(m_pResult);
183 m_pResult = nullptr;
184 }
185 m_aStatement.clear();
186 m_xMetaData = nullptr;
187}
188
189Any SAL_CALL OResultSet::queryInterface(const Type& rType)
190{
192 if (!aRet.hasValue())
193 {
195 }
196 return aRet;
197}
198
199uno::Sequence<Type> SAL_CALL OResultSet::getTypes()
200{
204
206}
207
208sal_Int32 SAL_CALL OResultSet::findColumn(const OUString& columnName)
209{
210 MutexGuard aGuard(m_aMutex);
211 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
213
214 for (std::size_t i = 0; i < m_aFields.size(); ++i)
215 {
216 if (columnName.equalsIgnoreAsciiCase(m_aFields[i]))
217 return static_cast<sal_Int32>(i) + 1; // sdbc indexes from 1
218 }
219
220 throw SQLException("The column name '" + columnName + "' is not valid.", *this, "42S22", 0,
221 Any());
222}
223
224uno::Reference<XInputStream> SAL_CALL OResultSet::getBinaryStream(sal_Int32 column)
225{
226 MutexGuard aGuard(m_aMutex);
227 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
229 if (checkNull(column))
230 return nullptr;
231
232 OString sVal = m_aRows[m_nRowPosition][column - 1];
233 return new SequenceInputStream{ uno::Sequence<sal_Int8>(
234 reinterpret_cast<sal_Int8 const*>(sVal.getStr()), getDataLength(column)) };
235}
236
237uno::Reference<XInputStream> SAL_CALL OResultSet::getCharacterStream(sal_Int32 column)
238{
239 MutexGuard aGuard(m_aMutex);
240 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
242 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getCharacterStream",
243 *this);
244 return nullptr;
245}
246
247sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 column)
248{
249 MutexGuard aGuard(m_aMutex);
250 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
252 if (checkNull(column))
253 return false;
254
255 OString sVal = m_aRows[m_nRowPosition][column - 1];
256 return sVal.toInt32() != 0;
257}
258
259sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 column)
260{
261 MutexGuard aGuard(m_aMutex);
262 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
264 if (checkNull(column))
265 return 0;
266
267 OString sVal = m_aRows[m_nRowPosition][column - 1];
268
269 return static_cast<sal_Int8>(sVal.toInt32());
270}
271
272uno::Sequence<sal_Int8> SAL_CALL OResultSet::getBytes(sal_Int32 column)
273{
274 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
275 MutexGuard aGuard(m_aMutex);
277 OString sVal = m_aRows[m_nRowPosition][column - 1];
278 if (checkNull(column))
279 return uno::Sequence<sal_Int8>();
280
281 return uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const*>(sVal.getStr()),
282 getDataLength(column));
283}
284
285Date SAL_CALL OResultSet::getDate(sal_Int32 column)
286{
287 MutexGuard aGuard(m_aMutex);
288 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
290
291 Date d;
292
293 if (checkNull(column))
294 return d;
295
296 const OString& dateStr = m_aRows[m_nRowPosition][column - 1];
297
298 std::string_view dateString(dateStr);
299 sal_Int32 nIndex = 0, i = 0;
300 do
301 {
302 std::string_view token = o3tl::getToken(dateString, 0, '-', nIndex);
303 switch (i)
304 {
305 case 0:
306 d.Year = static_cast<sal_uInt16>(o3tl::toUInt32(token));
307 break;
308 case 1:
309 d.Month = static_cast<sal_uInt16>(o3tl::toUInt32(token));
310 break;
311 case 2:
312 d.Day = static_cast<sal_uInt16>(o3tl::toUInt32(token));
313 break;
314 default:;
315 }
316 i++;
317 } while (nIndex >= 0);
318 return d;
319}
320
321double SAL_CALL OResultSet::getDouble(sal_Int32 column)
322{
323 MutexGuard aGuard(m_aMutex);
324 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
326
327 if (checkNull(column))
328 return 0.0;
329
330 OString sVal = m_aRows[m_nRowPosition][column - 1];
331 return sVal.toDouble();
332}
333
334float SAL_CALL OResultSet::getFloat(sal_Int32 column)
335{
336 MutexGuard aGuard(m_aMutex);
337 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
339 if (checkNull(column))
340 return 0.0f;
341
342 OString sVal = m_aRows[m_nRowPosition][column - 1];
343 return sVal.toFloat();
344}
345
346sal_Int32 SAL_CALL OResultSet::getInt(sal_Int32 column)
347{
348 MutexGuard aGuard(m_aMutex);
349 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
351 if (checkNull(column))
352 return 0;
353
354 OString sVal = m_aRows[m_nRowPosition][column - 1];
355 return sVal.toInt32();
356}
357
358sal_Int32 SAL_CALL OResultSet::getRow()
359{
360 MutexGuard aGuard(m_aMutex);
361 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
362
363 return m_nRowPosition + 1; // indexed from 1
364}
365
366sal_Int64 SAL_CALL OResultSet::getLong(sal_Int32 column)
367{
368 MutexGuard aGuard(m_aMutex);
369 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
371 if (checkNull(column))
372 return 0LL;
373
374 OString sVal = m_aRows[m_nRowPosition][column - 1];
375 return sVal.toInt64();
376}
377
378uno::Reference<XResultSetMetaData> SAL_CALL OResultSet::getMetaData()
379{
380 MutexGuard aGuard(m_aMutex);
381 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
382 return m_xMetaData;
383}
384
385uno::Reference<XArray> SAL_CALL OResultSet::getArray(sal_Int32 column)
386{
387 MutexGuard aGuard(m_aMutex);
388 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
390
391 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getArray", *this);
392 return nullptr;
393}
394
395uno::Reference<XClob> SAL_CALL OResultSet::getClob(sal_Int32 column)
396{
397 MutexGuard aGuard(m_aMutex);
398 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
400
402 return nullptr;
403}
404
405uno::Reference<XBlob> SAL_CALL OResultSet::getBlob(sal_Int32 column)
406{
407 MutexGuard aGuard(m_aMutex);
408 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
410
412 return nullptr;
413}
414
415uno::Reference<XRef> SAL_CALL OResultSet::getRef(sal_Int32 column)
416{
417 MutexGuard aGuard(m_aMutex);
418 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
420
422 return nullptr;
423}
424
425Any SAL_CALL OResultSet::getObject(sal_Int32 column,
426 const uno::Reference<XNameAccess>& /* typeMap */)
427{
428 MutexGuard aGuard(m_aMutex);
429 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
431
432 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getObject", *this);
433 return Any();
434}
435
436sal_Int16 SAL_CALL OResultSet::getShort(sal_Int32 column)
437{
438 MutexGuard aGuard(m_aMutex);
439 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
441 if (checkNull(column))
442 return 0;
443
444 OString sVal = m_aRows[m_nRowPosition][column - 1];
445 return sVal.toInt32();
446}
447
448OUString SAL_CALL OResultSet::getString(sal_Int32 column)
449{
450 MutexGuard aGuard(m_aMutex);
451 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
453 if (checkNull(column))
454 return rtl::OUString{};
455
456 OString sVal = m_aRows[m_nRowPosition][column - 1];
457 return OStringToOUString(sVal, m_encoding);
458}
459
460Time SAL_CALL OResultSet::getTime(sal_Int32 column)
461{
462 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
463 MutexGuard aGuard(m_aMutex);
465
466 Time t;
467 if (checkNull(column))
468 return t;
469
470 const OString& sVal = m_aRows[m_nRowPosition][column - 1];
471 std::string_view timeString{ sVal.getStr(), o3tl::make_unsigned(getDataLength(column)) };
472 sal_Int32 nIndex, i = 0;
473
474 size_t idx = timeString.find(' ');
475 if (idx == std::string_view::npos)
476 nIndex = 0;
477 else
478 nIndex = idx + 1;
479 do
480 {
481 std::string_view token = o3tl::getToken(timeString, 0, ':', nIndex);
482 switch (i)
483 {
484 case 0:
485 t.Hours = static_cast<sal_uInt16>(o3tl::toUInt32(token));
486 break;
487 case 1:
488 t.Minutes = static_cast<sal_uInt16>(o3tl::toUInt32(token));
489 break;
490 case 2:
491 t.Seconds = static_cast<sal_uInt16>(o3tl::toUInt32(token));
492 break;
493 }
494 i++;
495 } while (nIndex >= 0);
496
497 return t;
498}
499
500DateTime SAL_CALL OResultSet::getTimestamp(sal_Int32 column)
501{
502 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
503 MutexGuard aGuard(m_aMutex);
505
506 if (checkNull(column))
507 return DateTime{};
508
509 OString sVal = m_aRows[m_nRowPosition][column - 1];
510
511 // YY-MM-DD HH:MM:SS
512 std::vector<OString> dateAndTime = lcl_split(sVal.subView(0, getDataLength(column)), ' ');
513
514 auto dateParts = lcl_split(dateAndTime.at(0), '-');
515 auto timeParts = lcl_split(dateAndTime.at(1), ':');
516
517 if (dateParts.size() < 2 || timeParts.size() < 2)
518 throw SQLException("Timestamp has a wrong format", *this, OUString(), 1, Any());
519
520 DateTime dt;
521
522 dt.Year = dateParts.at(0).toUInt32();
523 dt.Month = dateParts.at(1).toUInt32();
524 dt.Day = dateParts.at(2).toUInt32();
525 dt.Hours = timeParts.at(0).toUInt32();
526 dt.Minutes = timeParts.at(1).toUInt32();
527 dt.Seconds = timeParts.at(2).toUInt32();
528 return dt;
529}
530
532{
533 MutexGuard aGuard(m_aMutex);
534 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
535
536 return m_nRowPosition < 0;
537}
538
540{
541 MutexGuard aGuard(m_aMutex);
542 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
544
545 return m_nRowPosition >= m_nRowCount;
546}
547
549{
550 MutexGuard aGuard(m_aMutex);
551 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
553
554 return m_nRowPosition == 0 && !isAfterLast();
555}
556
558{
559 MutexGuard aGuard(m_aMutex);
560 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
562
563 return m_nRowPosition == m_nRowCount - 1;
564}
565
567{
568 MutexGuard aGuard(m_aMutex);
569 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
570 m_nRowPosition = -1;
571}
572
574{
575 MutexGuard aGuard(m_aMutex);
576 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
579}
580
581void SAL_CALL OResultSet::close()
582{
583 MutexGuard aGuard(m_aMutex);
584 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
585
586 if (m_pResult != nullptr)
587 {
588 mysql_free_result(m_pResult);
589 m_pResult = nullptr;
590 }
591 dispose();
592}
593
595{
596 MutexGuard aGuard(m_aMutex);
597 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
598 m_nRowPosition = 0;
599
600 return true;
601}
602
604{
605 MutexGuard aGuard(m_aMutex);
606 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
609
610 return true;
611}
612
613sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 row)
614{
615 MutexGuard aGuard(m_aMutex);
616 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
618
619 sal_Int32 nToGo = row < 0 ? (m_nRowCount - 1) - row : row - 1;
620
621 if (nToGo >= m_nRowCount)
622 nToGo = m_nRowCount - 1;
623 if (nToGo < 0)
624 nToGo = 0;
625
626 m_nRowPosition = nToGo;
627
628 return true;
629}
630
631sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row)
632{
633 MutexGuard aGuard(m_aMutex);
634 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
636
637 if (row == 0)
638 return true;
639
640 sal_Int32 nToGo = m_nRowPosition + row;
641 if (nToGo >= m_nRowCount)
642 nToGo = m_nRowCount - 1;
643 if (nToGo < 0)
644 nToGo = 0;
645
646 m_nRowPosition = nToGo;
647
648 return true;
649}
650
652{
653 MutexGuard aGuard(m_aMutex);
654 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
655
656 if (m_nRowPosition == 0)
657 {
659 return false;
660 }
661 else if (m_nRowPosition < 0)
662 {
663 return false;
664 }
665
667 return true;
668}
669
670uno::Reference<uno::XInterface> SAL_CALL OResultSet::getStatement()
671{
672 MutexGuard aGuard(m_aMutex);
673 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
674
675 return m_aStatement.get();
676}
677
679{
680 MutexGuard aGuard(m_aMutex);
681 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
682
683 return false;
684}
685
687{
688 MutexGuard aGuard(m_aMutex);
689 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
690
691 return false;
692}
693
695{
696 MutexGuard aGuard(m_aMutex);
697 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
698
699 return false;
700}
701
703{
704 MutexGuard aGuard(m_aMutex);
705 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
707 if (m_nRowPosition + 1 > m_nRowCount) // afterlast
708 return false;
709 if (m_nRowPosition + 1 == m_nRowCount) // last
710 {
711 // return false but take it to afterlast anyway
713 return false;
714 }
716 return true;
717}
718
720{
721 MutexGuard aGuard(m_aMutex);
722 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
723
724 return m_bWasNull;
725}
726
727void SAL_CALL OResultSet::cancel()
728{
729 MutexGuard aGuard(m_aMutex);
730 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
731}
732
734
735Any SAL_CALL OResultSet::getWarnings() { return Any(); }
736
738{
739 MutexGuard aGuard(m_aMutex);
740 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
741 // you only have to implement this if you want to insert new rows
742 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::insertRow", *this);
743}
744
746{
747 MutexGuard aGuard(m_aMutex);
748 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
749
750 // only when you allow updates
751 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateRow", *this);
752}
753
755{
756 MutexGuard aGuard(m_aMutex);
757 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
758 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::deleteRow", *this);
759}
760
762{
763 MutexGuard aGuard(m_aMutex);
764 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
765 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::cancelRowUpdates", *this);
766}
767
769{
770 MutexGuard aGuard(m_aMutex);
771 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
772
773 // only when you allow insert's
774 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::moveToInsertRow", *this);
775}
776
778{
779 MutexGuard aGuard(m_aMutex);
780 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
781}
782
783void SAL_CALL OResultSet::updateNull(sal_Int32 column)
784{
785 MutexGuard aGuard(m_aMutex);
786 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
787 checkColumnIndex(column);
789 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateNull", *this);
790}
791
792void SAL_CALL OResultSet::updateBoolean(sal_Int32 column, sal_Bool /* x */)
793{
794 MutexGuard aGuard(m_aMutex);
795 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
796 checkColumnIndex(column);
798 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBoolean", *this);
799}
800
801void SAL_CALL OResultSet::updateByte(sal_Int32 column, sal_Int8 /* x */)
802{
803 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
804 MutexGuard aGuard(m_aMutex);
805 checkColumnIndex(column);
807 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateByte", *this);
808}
809
810void SAL_CALL OResultSet::updateShort(sal_Int32 column, sal_Int16 /* x */)
811{
812 MutexGuard aGuard(m_aMutex);
813 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
814 checkColumnIndex(column);
816 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateShort", *this);
817}
818
819void SAL_CALL OResultSet::updateInt(sal_Int32 column, sal_Int32 /* x */)
820{
821 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
822 MutexGuard aGuard(m_aMutex);
823 checkColumnIndex(column);
825 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateInt", *this);
826}
827
828void SAL_CALL OResultSet::updateLong(sal_Int32 column, sal_Int64 /* x */)
829{
830 MutexGuard aGuard(m_aMutex);
831 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
832 checkColumnIndex(column);
834 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateLong", *this);
835}
836
837void SAL_CALL OResultSet::updateFloat(sal_Int32 column, float /* x */)
838{
839 MutexGuard aGuard(m_aMutex);
840 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
841 checkColumnIndex(column);
843 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateFloat", *this);
844}
845
846void SAL_CALL OResultSet::updateDouble(sal_Int32 column, double /* x */)
847{
848 MutexGuard aGuard(m_aMutex);
849 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
850 checkColumnIndex(column);
852 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateDouble", *this);
853}
854
855void SAL_CALL OResultSet::updateString(sal_Int32 column, const OUString& /* x */)
856{
857 MutexGuard aGuard(m_aMutex);
858 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
859 checkColumnIndex(column);
861 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateString", *this);
862}
863
864void SAL_CALL OResultSet::updateBytes(sal_Int32 column, const uno::Sequence<sal_Int8>& /* x */)
865{
866 MutexGuard aGuard(m_aMutex);
867 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
868 checkColumnIndex(column);
870 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBytes", *this);
871}
872
873void SAL_CALL OResultSet::updateDate(sal_Int32 column, const Date& /* x */)
874{
875 MutexGuard aGuard(m_aMutex);
876 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
877 checkColumnIndex(column);
879 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateDate", *this);
880}
881
882void SAL_CALL OResultSet::updateTime(sal_Int32 column, const Time& /* x */)
883{
884 MutexGuard aGuard(m_aMutex);
885 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
886 checkColumnIndex(column);
888 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateTime", *this);
889}
890
891void SAL_CALL OResultSet::updateTimestamp(sal_Int32 column, const DateTime& /* x */)
892{
893 MutexGuard aGuard(m_aMutex);
894 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
895 checkColumnIndex(column);
897 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateTimestamp", *this);
898}
899
900void SAL_CALL OResultSet::updateBinaryStream(sal_Int32 column,
901 const uno::Reference<XInputStream>& /* x */,
902 sal_Int32 /* length */)
903{
904 MutexGuard aGuard(m_aMutex);
905 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
906 checkColumnIndex(column);
908 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBinaryStream",
909 *this);
910}
911
912void SAL_CALL OResultSet::updateCharacterStream(sal_Int32 column,
913 const uno::Reference<XInputStream>& /* x */,
914 sal_Int32 /* length */)
915{
916 MutexGuard aGuard(m_aMutex);
917 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
918 checkColumnIndex(column);
920 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateCharacterStream",
921 *this);
922}
923
925{
926 MutexGuard aGuard(m_aMutex);
927 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
928 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::refreshRow", *this);
929}
930
931void SAL_CALL OResultSet::updateObject(sal_Int32 column, const Any& /* x */)
932{
933 MutexGuard aGuard(m_aMutex);
934 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
935 checkColumnIndex(column);
937 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateObject", *this);
938}
939
940void SAL_CALL OResultSet::updateNumericObject(sal_Int32 column, const Any& /* x */,
941 sal_Int32 /* scale */)
942{
943 MutexGuard aGuard(m_aMutex);
944 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
945 checkColumnIndex(column);
947 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateNumericObject",
948 *this);
949}
950
951// XRowLocate
953{
954 MutexGuard aGuard(m_aMutex);
955 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
956
957 // if you don't want to support bookmark you must remove the XRowLocate interface
958 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getBookmark", *this);
959
960 return Any();
961}
962
963sal_Bool SAL_CALL OResultSet::moveToBookmark(const Any& /* bookmark */)
964{
965 MutexGuard aGuard(m_aMutex);
966 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
967
968 return false;
969}
970
971sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark(const Any& /* bookmark */,
972 sal_Int32 /* rows */)
973{
974 MutexGuard aGuard(m_aMutex);
975 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
976
977 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::moveRelativeToBookmark",
978 *this);
979 return false;
980}
981
982sal_Int32 SAL_CALL OResultSet::compareBookmarks(const Any& /* n1 */, const Any& /* n2 */)
983{
984 MutexGuard aGuard(m_aMutex);
985 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
986
987 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::compareBookmarks", *this);
988
989 return CompareBookmark::NOT_EQUAL;
990}
991
992sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks() { return false; }
993
994sal_Int32 SAL_CALL OResultSet::hashBookmark(const Any& /* bookmark */)
995{
996 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::hashBookmark", *this);
997 return 0;
998}
999
1000// XDeleteRows
1001uno::Sequence<sal_Int32> SAL_CALL OResultSet::deleteRows(const uno::Sequence<Any>& /* rows */)
1002{
1003 MutexGuard aGuard(m_aMutex);
1004 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1005
1006 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::deleteRows", *this);
1007 return uno::Sequence<sal_Int32>();
1008}
1009
1011{
1012 return new OPropertyArrayHelper{
1013 { { "FetchDirection", PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0 },
1016 PropertyAttribute::READONLY },
1017 { "ResultSetConcurrency", PROPERTY_ID_RESULTSETCONCURRENCY,
1018 cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY },
1020 PropertyAttribute::READONLY } }
1021 };
1022}
1023
1025
1026sal_Bool OResultSet::convertFastPropertyValue(Any& /* rConvertedValue */, Any& /* rOldValue */,
1027 sal_Int32 nHandle, const Any& /* rValue */)
1028{
1029 switch (nHandle)
1030 {
1035 throw css::lang::IllegalArgumentException();
1038 default:;
1039 }
1040 return false;
1041}
1042
1043void OResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& /* rValue */)
1044{
1045 switch (nHandle)
1046 {
1051 throw uno::Exception("cannot set prop " + OUString::number(nHandle), nullptr);
1053 break;
1055 break;
1056 default:;
1057 }
1058}
1059
1060void OResultSet::getFastPropertyValue(Any& _rValue, sal_Int32 nHandle) const
1061{
1062 switch (nHandle)
1063 {
1065 _rValue <<= false;
1066 break;
1068 break;
1070 _rValue <<= ResultSetConcurrency::READ_ONLY;
1071 break;
1073 _rValue <<= ResultSetType::SCROLL_INSENSITIVE;
1074 break;
1076 _rValue <<= FetchDirection::FORWARD;
1077 break;
1079 _rValue <<= sal_Int32(50);
1080 break;
1081 ;
1082 default:;
1083 }
1084}
1085
1086void SAL_CALL OResultSet::acquire() noexcept { OResultSet_BASE::acquire(); }
1087
1088void SAL_CALL OResultSet::release() noexcept { OResultSet_BASE::release(); }
1089
1090css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OResultSet::getPropertySetInfo()
1091{
1092 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1093}
1094
1095void OResultSet::checkColumnIndex(sal_Int32 index)
1096{
1097 if (index < 1 || o3tl::make_unsigned(index) > m_aFields.size())
1098 {
1099 /* static object for efficiency or thread safety is a problem ? */
1100 throw SQLException("index out of range", *this, OUString(), 1, Any());
1101 }
1102}
1103
1105{
1108 checkRowIndex();
1109}
1110
1111/* 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
::cppu::IPropertyArrayHelper * getArrayHelper()
call this in the getInfoHelper method of your derived class.
std::vector< OUString > m_aFields
sal_Bool SAL_CALL getBoolean(sal_Int32 column) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
sal_Bool SAL_CALL rowUpdated() override
void SAL_CALL updateNull(sal_Int32 column) override
sal_Bool SAL_CALL first() override
void ensureFieldInfoFetched()
Ensures that meta data of the corresponding result set has been already queried.
void ensureResultFetched()
Ensures that the results of the query has already been fetched.
void SAL_CALL updateByte(sal_Int32 column, sal_Int8 x) override
void SAL_CALL updateString(sal_Int32 column, const OUString &x) override
void SAL_CALL updateBinaryStream(sal_Int32 column, const css::uno::Reference< css::io::XInputStream > &x, sal_Int32 length) override
sal_Bool SAL_CALL absolute(sal_Int32 row) override
css::util::DateTime SAL_CALL getTimestamp(sal_Int32 column) override
void SAL_CALL updateFloat(sal_Int32 column, float x) override
sal_Bool SAL_CALL moveToBookmark(const Any &bookmark) override
sal_Int32 SAL_CALL getInt(sal_Int32 column) override
void SAL_CALL disposing() override
void SAL_CALL deleteRow() override
sal_Bool SAL_CALL relative(sal_Int32 rows) override
OResultSet(OConnection &rConn, OCommonStatement *pStmt, MYSQL_RES *pResult, rtl_TextEncoding _encoding)
void SAL_CALL updateDate(sal_Int32 column, const css::util::Date &x) override
void SAL_CALL clearWarnings() override
void SAL_CALL close() override
sal_Bool SAL_CALL isLast() override
Any SAL_CALL getObject(sal_Int32 column, const css::uno::Reference< css::container::XNameAccess > &typeMap) override
void SAL_CALL updateNumericObject(sal_Int32 column, const Any &x, sal_Int32 scale) override
sal_Int32 SAL_CALL compareBookmarks(const Any &first, const Any &second) override
void checkColumnIndex(sal_Int32 index)
sal_Int32 getDataLength(sal_Int32 column)
sal_Bool SAL_CALL isFirst() override
::cppu::IPropertyArrayHelper * createArrayHelper() const override
used to implement the creation of the array helper which is shared amongst all instances of the class...
virtual OUString SAL_CALL getImplementationName() override
virtual sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
float SAL_CALL getFloat(sal_Int32 column) override
std::vector< OString > DataFields
sal_Bool SAL_CALL hasOrderedBookmarks() override
sal_Bool SAL_CALL convertFastPropertyValue(Any &rConvertedValue, Any &rOldValue, sal_Int32 nHandle, const Any &rValue) override
css::uno::Reference< css::sdbc::XArray > SAL_CALL getArray(sal_Int32 column) override
sal_Bool SAL_CALL next() override
void SAL_CALL beforeFirst() override
css::uno::WeakReferenceHelper m_aStatement
void SAL_CALL updateDouble(sal_Int32 column, double x) override
Any SAL_CALL getWarnings() override
css::uno::Sequence< sal_Int8 > SAL_CALL getBytes(sal_Int32 column) override
void SAL_CALL updateTime(sal_Int32 column, const css::util::Time &x) override
sal_Int32 m_nRowPosition
Position of cursor indexed from 0.
void SAL_CALL updateTimestamp(sal_Int32 column, const css::util::DateTime &x) override
void SAL_CALL moveToInsertRow() override
css::uno::Reference< css::sdbc::XRef > SAL_CALL getRef(sal_Int32 column) override
void SAL_CALL updateBytes(sal_Int32 column, const css::uno::Sequence< sal_Int8 > &x) override
Any SAL_CALL getBookmark() override
sal_Int32 SAL_CALL findColumn(const OUString &columnName) override
sal_Bool SAL_CALL isAfterLast() override
void SAL_CALL afterLast() override
void SAL_CALL release() noexcept override
Any SAL_CALL queryInterface(const css::uno::Type &rType) override
css::uno::Sequence< sal_Int32 > SAL_CALL deleteRows(const css::uno::Sequence< Any > &rows) override
sal_Bool SAL_CALL isBeforeFirst() override
sal_Int16 SAL_CALL getShort(sal_Int32 column) override
void SAL_CALL updateBoolean(sal_Int32 column, sal_Bool x) override
sal_Bool SAL_CALL last() override
void fetchResult()
Fetches all the data from the MYSQL_RES object related to the class.
::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
void SAL_CALL insertRow() override
void SAL_CALL getFastPropertyValue(Any &rValue, sal_Int32 nHandle) const override
css::uno::Reference< css::uno::XInterface > SAL_CALL getStatement() override
void SAL_CALL acquire() noexcept override
void SAL_CALL updateRow() override
double SAL_CALL getDouble(sal_Int32 column) override
css::uno::Reference< css::sdbc::XBlob > SAL_CALL getBlob(sal_Int32 column) override
void SAL_CALL updateObject(sal_Int32 column, const Any &x) override
void SAL_CALL updateCharacterStream(sal_Int32 column, const css::uno::Reference< css::io::XInputStream > &x, sal_Int32 length) override
void SAL_CALL refreshRow() override
void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any &rValue) override
sal_Bool SAL_CALL previous() override
void SAL_CALL updateShort(sal_Int32 column, sal_Int16 x) override
OUString SAL_CALL getString(sal_Int32 column) override
css::uno::Reference< css::io::XInputStream > SAL_CALL getCharacterStream(sal_Int32 column) override
css::uno::Reference< css::sdbc::XClob > SAL_CALL getClob(sal_Int32 column) override
sal_Int32 SAL_CALL hashBookmark(const Any &bookmark) override
sal_Bool SAL_CALL rowInserted() override
void SAL_CALL cancel() override
void SAL_CALL moveToCurrentRow() override
css::uno::Reference< css::sdbc::XResultSetMetaData > m_xMetaData
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
std::vector< DataFields > m_aRows
sal_Bool SAL_CALL wasNull() override
bool checkNull(sal_Int32 column)
css::util::Time SAL_CALL getTime(sal_Int32 column) override
void SAL_CALL cancelRowUpdates() override
void SAL_CALL updateInt(sal_Int32 column, sal_Int32 x) override
sal_Bool SAL_CALL rowDeleted() override
css::uno::Reference< css::io::XInputStream > SAL_CALL getBinaryStream(sal_Int32 column) override
sal_Int32 SAL_CALL getRow() override
css::uno::Reference< css::sdbc::XResultSetMetaData > SAL_CALL getMetaData() override
sal_Int64 SAL_CALL getLong(sal_Int32 column) override
void checkBordersAndEnsureFetched(sal_Int32 index)
Check the following things:
css::util::Date SAL_CALL getDate(sal_Int32 column) override
void SAL_CALL updateLong(sal_Int32 column, sal_Int64 x) override
sal_Int8 SAL_CALL getByte(sal_Int32 column) override
sal_Bool SAL_CALL moveRelativeToBookmark(const Any &bookmark, sal_Int32 rows) override
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
const sal_uInt16 idx[]
sal_Int32 nIndex
RttiCompleteObjectLocator col
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
index
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)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
sal_uInt32 toUInt32(std::u16string_view str, sal_Int16 radix=10)
const char * columnName
Definition: pq_statics.cxx:56
sal_Int32 nHandle
unsigned char sal_Bool
signed char sal_Int8
const SvXMLTokenMapEntry aTypes[]