bump product version to 6.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / mysqlc / mysqlc_resultset.cxx
blob05d5c1321604abd7688a20f6773ccf66f92353d6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "mysqlc_propertyids.hxx"
21 #include "mysqlc_general.hxx"
22 #include "mysqlc_resultset.hxx"
23 #include "mysqlc_resultsetmetadata.hxx"
25 #include <com/sun/star/beans/PropertyAttribute.hpp>
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/sdbc/DataType.hpp>
28 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
29 #include <com/sun/star/sdbc/ResultSetType.hpp>
30 #include <com/sun/star/sdbc/FetchDirection.hpp>
31 #include <com/sun/star/sdbcx/CompareBookmark.hpp>
32 #include <cppuhelper/supportsservice.hxx>
33 #include <cppuhelper/typeprovider.hxx>
34 #include <comphelper/seqstream.hxx>
36 #include <sal/log.hxx>
38 using namespace rtl;
39 #include <comphelper/string.hxx>
41 #include <cstdlib>
43 using namespace connectivity::mysqlc;
44 using namespace cppu;
45 using namespace com::sun::star;
46 using namespace com::sun::star::lang;
47 using namespace com::sun::star::beans;
48 using namespace com::sun::star::sdbc;
49 using namespace com::sun::star::sdbcx;
50 using namespace com::sun::star::container;
51 using namespace com::sun::star::io;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::util;
54 using namespace ::comphelper;
55 using ::osl::MutexGuard;
57 #include <stdio.h>
59 namespace
61 // copied from string misc, it should be replaced when library is not an
62 // extension anymore
63 std::vector<OString> lcl_split(const OString& rStr, char cSeparator)
65 std::vector<OString> vec;
66 sal_Int32 idx = 0;
69 OString kw = rStr.getToken(0, cSeparator, idx);
70 kw = kw.trim();
71 if (!kw.isEmpty())
73 vec.push_back(kw);
75 } while (idx >= 0);
76 return vec;
80 void OResultSet::checkRowIndex()
82 if (m_nRowPosition < 0 || m_nRowPosition >= m_nRowCount)
84 throw SQLException("Cursor position out of range", *this, OUString(), 1, Any());
88 bool OResultSet::checkNull(sal_Int32 column)
90 if (m_aRows[m_nRowPosition][column - 1].isEmpty())
92 m_bWasNull = true;
93 return true;
95 m_bWasNull = false;
96 return false;
99 OUString SAL_CALL OResultSet::getImplementationName()
101 return OUString("com.sun.star.sdbcx.mysqlc.ResultSet");
104 uno::Sequence<OUString> SAL_CALL OResultSet::getSupportedServiceNames()
106 uno::Sequence<OUString> aSupported(2);
107 aSupported[0] = "com.sun.star.sdbc.ResultSet";
108 aSupported[1] = "com.sun.star.sdbcx.ResultSet";
109 return aSupported;
112 sal_Bool SAL_CALL OResultSet::supportsService(const OUString& _rServiceName)
114 return cppu::supportsService(this, _rServiceName);
117 OResultSet::OResultSet(OConnection& rConn, OCommonStatement* pStmt, MYSQL_RES* pResult,
118 rtl_TextEncoding _encoding)
119 : OResultSet_BASE(m_aMutex)
120 , OPropertySetHelper(OResultSet_BASE::rBHelper)
121 , m_pMysql(rConn.getMysqlConnection())
122 , m_aStatement(static_cast<OWeakObject*>(pStmt))
123 , m_pResult(pResult)
124 , m_encoding(_encoding)
126 m_xMetaData = new OResultSetMetaData(rConn, m_pResult);
129 void OResultSet::ensureResultFetched()
131 if (!m_bResultFetched)
133 fetchResult();
137 void OResultSet::ensureFieldInfoFetched()
139 if (m_bResultFetched)
140 return; // already fetched
142 // it works only if result set is produced via mysql_store_result
143 // TODO ensure that
144 m_nRowCount = mysql_num_rows(m_pResult);
146 if (!m_aFields.empty())
147 return;
148 unsigned nFieldCount = mysql_num_fields(m_pResult);
149 MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult);
150 m_aFields.reserve(nFieldCount);
151 for (unsigned i = 0; i < nFieldCount; ++i)
152 m_aFields.push_back(OUString{
153 pFields[i].name, static_cast<sal_Int32>(strlen(pFields[i].name)), m_encoding });
156 void OResultSet::fetchResult()
158 // Mysql C API does not allow simultaneously opened result sets, but sdbc does.
159 // Because of that we need to fetch all of the data ASAP
160 ensureFieldInfoFetched();
162 // fetch all the data
163 m_aRows.reserve(m_nRowCount);
165 for (sal_Int32 row = 0; row < m_nRowCount; ++row)
167 MYSQL_ROW data = mysql_fetch_row(m_pResult);
168 unsigned long* lengths = mysql_fetch_lengths(m_pResult);
169 m_aRows.push_back(DataFields{});
170 // MYSQL_ROW is char**, array of strings
171 for (std::size_t col = 0; col < m_aFields.size(); ++col)
173 m_aRows.back().push_back(OString{ data[col], static_cast<sal_Int32>(lengths[col]) });
176 unsigned errorNum = mysql_errno(m_pMysql);
177 if (errorNum)
178 mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(m_pMysql), errorNum, *this,
179 m_encoding);
180 m_bResultFetched = true;
181 mysql_free_result(m_pResult);
184 void OResultSet::disposing()
186 OPropertySetHelper::disposing();
188 MutexGuard aGuard(m_aMutex);
190 m_aStatement = nullptr;
191 m_xMetaData = nullptr;
194 Any SAL_CALL OResultSet::queryInterface(const Type& rType)
196 Any aRet = OPropertySetHelper::queryInterface(rType);
197 if (!aRet.hasValue())
199 aRet = OResultSet_BASE::queryInterface(rType);
201 return aRet;
204 uno::Sequence<Type> SAL_CALL OResultSet::getTypes()
206 OTypeCollection aTypes(cppu::UnoType<XMultiPropertySet>::get(),
207 cppu::UnoType<XFastPropertySet>::get(),
208 cppu::UnoType<XPropertySet>::get());
210 return concatSequences(aTypes.getTypes(), OResultSet_BASE::getTypes());
213 sal_Int32 SAL_CALL OResultSet::findColumn(const OUString& columnName)
215 MutexGuard aGuard(m_aMutex);
216 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
217 ensureFieldInfoFetched();
219 for (std::size_t i = 0; i < m_aFields.size(); ++i)
221 if (columnName.equalsIgnoreAsciiCase(m_aFields[i]))
222 return static_cast<sal_Int32>(i) + 1; // sdbc indexes from 1
225 throw SQLException("The column name '" + columnName + "' is not valid.", *this, "42S22", 0,
226 Any());
229 uno::Reference<XInputStream> SAL_CALL OResultSet::getBinaryStream(sal_Int32 column)
231 MutexGuard aGuard(m_aMutex);
232 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
233 checkBordersAndEnsureFetched(column);
234 if (checkNull(column))
235 return nullptr;
237 OString sVal = m_aRows[m_nRowPosition][column - 1];
238 return new SequenceInputStream{ uno::Sequence<sal_Int8>(
239 reinterpret_cast<sal_Int8 const*>(sVal.getStr()), getDataLength(column)) };
242 uno::Reference<XInputStream> SAL_CALL OResultSet::getCharacterStream(sal_Int32 column)
244 MutexGuard aGuard(m_aMutex);
245 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
246 checkBordersAndEnsureFetched(column);
247 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getCharacterStream",
248 *this);
249 return nullptr;
252 sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 column)
254 MutexGuard aGuard(m_aMutex);
255 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
256 checkBordersAndEnsureFetched(column);
257 if (checkNull(column))
258 return false;
260 OString sVal = m_aRows[m_nRowPosition][column - 1];
261 return sVal.toInt32() != 0;
264 sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 column)
266 MutexGuard aGuard(m_aMutex);
267 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
268 checkBordersAndEnsureFetched(column);
269 if (checkNull(column))
270 return 0;
272 OString sVal = m_aRows[m_nRowPosition][column - 1];
274 return static_cast<sal_Int8>(sVal.toInt32());
277 uno::Sequence<sal_Int8> SAL_CALL OResultSet::getBytes(sal_Int32 column)
279 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
280 MutexGuard aGuard(m_aMutex);
281 checkBordersAndEnsureFetched(column);
282 OString sVal = m_aRows[m_nRowPosition][column - 1];
283 if (checkNull(column))
284 return uno::Sequence<sal_Int8>();
286 return uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const*>(sVal.getStr()),
287 getDataLength(column));
290 Date SAL_CALL OResultSet::getDate(sal_Int32 column)
292 MutexGuard aGuard(m_aMutex);
293 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
294 checkBordersAndEnsureFetched(column);
296 Date d;
298 if (checkNull(column))
299 return d;
301 OString dateStr = m_aRows[m_nRowPosition][column - 1];
303 OString dateString(dateStr);
304 OString token;
305 sal_Int32 nIndex = 0, i = 0;
308 token = dateString.getToken(0, '-', nIndex);
309 switch (i)
311 case 0:
312 d.Year = static_cast<sal_uInt16>(token.toUInt32());
313 break;
314 case 1:
315 d.Month = static_cast<sal_uInt16>(token.toUInt32());
316 break;
317 case 2:
318 d.Day = static_cast<sal_uInt16>(token.toUInt32());
319 break;
320 default:;
322 i++;
323 } while (nIndex >= 0);
324 return d;
327 double SAL_CALL OResultSet::getDouble(sal_Int32 column)
329 MutexGuard aGuard(m_aMutex);
330 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
331 checkBordersAndEnsureFetched(column);
333 if (checkNull(column))
334 return 0.0;
336 OString sVal = m_aRows[m_nRowPosition][column - 1];
337 return sVal.toDouble();
340 float SAL_CALL OResultSet::getFloat(sal_Int32 column)
342 MutexGuard aGuard(m_aMutex);
343 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
344 checkBordersAndEnsureFetched(column);
345 if (checkNull(column))
346 return 0.0f;
348 OString sVal = m_aRows[m_nRowPosition][column - 1];
349 return sVal.toFloat();
352 sal_Int32 SAL_CALL OResultSet::getInt(sal_Int32 column)
354 MutexGuard aGuard(m_aMutex);
355 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
356 checkBordersAndEnsureFetched(column);
357 if (checkNull(column))
358 return 0;
360 OString sVal = m_aRows[m_nRowPosition][column - 1];
361 return sVal.toInt32();
364 sal_Int32 SAL_CALL OResultSet::getRow()
366 MutexGuard aGuard(m_aMutex);
367 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
369 return m_nRowPosition + 1; // indexed from 1
372 sal_Int64 SAL_CALL OResultSet::getLong(sal_Int32 column)
374 MutexGuard aGuard(m_aMutex);
375 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
376 checkBordersAndEnsureFetched(column);
377 if (checkNull(column))
378 return 0LL;
380 OString sVal = m_aRows[m_nRowPosition][column - 1];
381 return sVal.toInt64();
384 uno::Reference<XResultSetMetaData> SAL_CALL OResultSet::getMetaData()
386 MutexGuard aGuard(m_aMutex);
387 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
388 return m_xMetaData;
391 uno::Reference<XArray> SAL_CALL OResultSet::getArray(sal_Int32 column)
393 MutexGuard aGuard(m_aMutex);
394 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
395 checkBordersAndEnsureFetched(column);
397 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getArray", *this);
398 return nullptr;
401 uno::Reference<XClob> SAL_CALL OResultSet::getClob(sal_Int32 column)
403 MutexGuard aGuard(m_aMutex);
404 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
405 checkBordersAndEnsureFetched(column);
407 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getClob", *this);
408 return nullptr;
411 uno::Reference<XBlob> SAL_CALL OResultSet::getBlob(sal_Int32 column)
413 MutexGuard aGuard(m_aMutex);
414 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
415 checkBordersAndEnsureFetched(column);
417 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getBlob", *this);
418 return nullptr;
421 uno::Reference<XRef> SAL_CALL OResultSet::getRef(sal_Int32 column)
423 MutexGuard aGuard(m_aMutex);
424 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
425 checkBordersAndEnsureFetched(column);
427 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getRef", *this);
428 return nullptr;
431 Any SAL_CALL OResultSet::getObject(sal_Int32 column,
432 const uno::Reference<XNameAccess>& /* typeMap */)
434 MutexGuard aGuard(m_aMutex);
435 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
436 checkBordersAndEnsureFetched(column);
438 Any aRet = Any();
440 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getObject", *this);
441 return aRet;
444 sal_Int16 SAL_CALL OResultSet::getShort(sal_Int32 column)
446 MutexGuard aGuard(m_aMutex);
447 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
448 checkBordersAndEnsureFetched(column);
449 if (checkNull(column))
450 return 0;
452 OString sVal = m_aRows[m_nRowPosition][column - 1];
453 return sVal.toInt32();
456 OUString SAL_CALL OResultSet::getString(sal_Int32 column)
458 MutexGuard aGuard(m_aMutex);
459 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
460 checkBordersAndEnsureFetched(column);
461 if (checkNull(column))
462 return rtl::OUString{};
464 OString sVal = m_aRows[m_nRowPosition][column - 1];
465 return OStringToOUString(sVal, m_encoding);
468 Time SAL_CALL OResultSet::getTime(sal_Int32 column)
470 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
471 MutexGuard aGuard(m_aMutex);
472 checkBordersAndEnsureFetched(column);
474 Time t;
475 if (checkNull(column))
476 return t;
478 OString sVal = m_aRows[m_nRowPosition][column - 1];
479 OString timeString{ sVal.getStr(), getDataLength(column) };
480 OString token;
481 sal_Int32 nIndex, i = 0;
483 nIndex = timeString.indexOf(' ') + 1;
486 token = timeString.getToken(0, ':', nIndex);
487 switch (i)
489 case 0:
490 t.Hours = static_cast<sal_uInt16>(token.toUInt32());
491 break;
492 case 1:
493 t.Minutes = static_cast<sal_uInt16>(token.toUInt32());
494 break;
495 case 2:
496 t.Seconds = static_cast<sal_uInt16>(token.toUInt32());
497 break;
499 i++;
500 } while (nIndex >= 0);
502 return t;
505 DateTime SAL_CALL OResultSet::getTimestamp(sal_Int32 column)
507 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
508 MutexGuard aGuard(m_aMutex);
509 checkBordersAndEnsureFetched(column);
511 if (checkNull(column))
512 return DateTime{};
514 OString sVal = m_aRows[m_nRowPosition][column - 1];
516 // YY-MM-DD HH:MM:SS
517 std::vector<OString> dateAndTime
518 = lcl_split(OString{ sVal.getStr(), getDataLength(column) }, ' ');
520 auto dateParts = lcl_split(dateAndTime.at(0), '-');
521 auto timeParts = lcl_split(dateAndTime.at(1), ':');
523 if (dateParts.size() < 2 || timeParts.size() < 2)
524 throw SQLException("Timestamp has a wrong format", *this, OUString(), 1, Any());
526 DateTime dt;
528 dt.Year = dateParts.at(0).toUInt32();
529 dt.Month = dateParts.at(1).toUInt32();
530 dt.Day = dateParts.at(2).toUInt32();
531 dt.Hours = timeParts.at(0).toUInt32();
532 dt.Minutes = timeParts.at(1).toUInt32();
533 dt.Seconds = timeParts.at(2).toUInt32();
534 return dt;
537 sal_Bool SAL_CALL OResultSet::isBeforeFirst()
539 MutexGuard aGuard(m_aMutex);
540 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
542 return m_nRowPosition < 0;
545 sal_Bool SAL_CALL OResultSet::isAfterLast()
547 MutexGuard aGuard(m_aMutex);
548 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
549 ensureFieldInfoFetched();
551 return m_nRowPosition >= m_nRowCount;
554 sal_Bool SAL_CALL OResultSet::isFirst()
556 MutexGuard aGuard(m_aMutex);
557 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
558 ensureFieldInfoFetched();
560 return m_nRowPosition == 0 && !isAfterLast();
563 sal_Bool SAL_CALL OResultSet::isLast()
565 MutexGuard aGuard(m_aMutex);
566 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
567 ensureFieldInfoFetched();
569 return m_nRowPosition == m_nRowCount - 1;
572 void SAL_CALL OResultSet::beforeFirst()
574 MutexGuard aGuard(m_aMutex);
575 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
576 m_nRowPosition = -1;
579 void SAL_CALL OResultSet::afterLast()
581 MutexGuard aGuard(m_aMutex);
582 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
583 ensureFieldInfoFetched();
584 m_nRowPosition = m_nRowCount;
587 void SAL_CALL OResultSet::close()
589 MutexGuard aGuard(m_aMutex);
590 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
592 m_pResult = nullptr;
593 dispose();
596 sal_Bool SAL_CALL OResultSet::first()
598 MutexGuard aGuard(m_aMutex);
599 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
600 m_nRowPosition = 0;
602 return true;
605 sal_Bool SAL_CALL OResultSet::last()
607 MutexGuard aGuard(m_aMutex);
608 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
609 ensureFieldInfoFetched();
610 m_nRowPosition = m_nRowCount - 1;
612 return true;
615 sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 row)
617 MutexGuard aGuard(m_aMutex);
618 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
619 ensureFieldInfoFetched();
621 sal_Int32 nToGo = row < 0 ? (m_nRowCount - 1) - row : row - 1;
623 if (nToGo >= m_nRowCount)
624 nToGo = m_nRowCount - 1;
625 if (nToGo < 0)
626 nToGo = 0;
628 m_nRowPosition = nToGo;
630 return true;
633 sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row)
635 MutexGuard aGuard(m_aMutex);
636 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
637 ensureFieldInfoFetched();
639 if (row == 0)
640 return true;
642 sal_Int32 nToGo = m_nRowPosition + row;
643 if (nToGo >= m_nRowCount)
644 nToGo = m_nRowCount - 1;
645 if (nToGo < 0)
646 nToGo = 0;
648 m_nRowPosition = nToGo;
650 return true;
653 sal_Bool SAL_CALL OResultSet::previous()
655 MutexGuard aGuard(m_aMutex);
656 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
658 if (m_nRowPosition == 0)
660 m_nRowPosition--;
661 return false;
663 else if (m_nRowPosition < 0)
665 return false;
668 m_nRowPosition--;
669 return true;
672 uno::Reference<uno::XInterface> SAL_CALL OResultSet::getStatement()
674 MutexGuard aGuard(m_aMutex);
675 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
677 return m_aStatement.get();
680 sal_Bool SAL_CALL OResultSet::rowDeleted()
682 MutexGuard aGuard(m_aMutex);
683 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
685 return false;
688 sal_Bool SAL_CALL OResultSet::rowInserted()
690 MutexGuard aGuard(m_aMutex);
691 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
693 return false;
696 sal_Bool SAL_CALL OResultSet::rowUpdated()
698 MutexGuard aGuard(m_aMutex);
699 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
701 return false;
704 sal_Bool SAL_CALL OResultSet::next()
706 MutexGuard aGuard(m_aMutex);
707 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
708 ensureFieldInfoFetched();
709 if (m_nRowPosition + 1 > m_nRowCount) // afterlast
710 return false;
711 if (m_nRowPosition + 1 == m_nRowCount) // last
713 // return false but take it to afterlast anyway
714 ++m_nRowPosition;
715 return false;
717 ++m_nRowPosition;
718 return true;
721 sal_Bool SAL_CALL OResultSet::wasNull()
723 MutexGuard aGuard(m_aMutex);
724 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
726 return m_bWasNull;
729 void SAL_CALL OResultSet::cancel()
731 MutexGuard aGuard(m_aMutex);
732 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
735 void SAL_CALL OResultSet::clearWarnings() {}
737 Any SAL_CALL OResultSet::getWarnings()
739 Any aRet = Any();
740 return aRet;
743 void SAL_CALL OResultSet::insertRow()
745 MutexGuard aGuard(m_aMutex);
746 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
747 // you only have to implement this if you want to insert new rows
748 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::insertRow", *this);
751 void SAL_CALL OResultSet::updateRow()
753 MutexGuard aGuard(m_aMutex);
754 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
756 // only when you allow updates
757 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateRow", *this);
760 void SAL_CALL OResultSet::deleteRow()
762 MutexGuard aGuard(m_aMutex);
763 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
764 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::deleteRow", *this);
767 void SAL_CALL OResultSet::cancelRowUpdates()
769 MutexGuard aGuard(m_aMutex);
770 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
771 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::cancelRowUpdates", *this);
774 void SAL_CALL OResultSet::moveToInsertRow()
776 MutexGuard aGuard(m_aMutex);
777 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
779 // only when you allow insert's
780 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::moveToInsertRow", *this);
783 void SAL_CALL OResultSet::moveToCurrentRow()
785 MutexGuard aGuard(m_aMutex);
786 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
789 void SAL_CALL OResultSet::updateNull(sal_Int32 column)
791 MutexGuard aGuard(m_aMutex);
792 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
793 checkColumnIndex(column);
794 checkRowIndex();
795 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateNull", *this);
798 void SAL_CALL OResultSet::updateBoolean(sal_Int32 column, sal_Bool /* x */)
800 MutexGuard aGuard(m_aMutex);
801 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
802 checkColumnIndex(column);
803 checkRowIndex();
804 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBoolean", *this);
807 void SAL_CALL OResultSet::updateByte(sal_Int32 column, sal_Int8 /* x */)
809 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
810 MutexGuard aGuard(m_aMutex);
811 checkColumnIndex(column);
812 checkRowIndex();
813 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateByte", *this);
816 void SAL_CALL OResultSet::updateShort(sal_Int32 column, sal_Int16 /* x */)
818 MutexGuard aGuard(m_aMutex);
819 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
820 checkColumnIndex(column);
821 checkRowIndex();
822 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateShort", *this);
825 void SAL_CALL OResultSet::updateInt(sal_Int32 column, sal_Int32 /* x */)
827 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
828 MutexGuard aGuard(m_aMutex);
829 checkColumnIndex(column);
830 checkRowIndex();
831 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateInt", *this);
834 void SAL_CALL OResultSet::updateLong(sal_Int32 column, sal_Int64 /* x */)
836 MutexGuard aGuard(m_aMutex);
837 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
838 checkColumnIndex(column);
839 checkRowIndex();
840 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateLong", *this);
843 void SAL_CALL OResultSet::updateFloat(sal_Int32 column, float /* x */)
845 MutexGuard aGuard(m_aMutex);
846 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
847 checkColumnIndex(column);
848 checkRowIndex();
849 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateFloat", *this);
852 void SAL_CALL OResultSet::updateDouble(sal_Int32 column, double /* x */)
854 MutexGuard aGuard(m_aMutex);
855 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
856 checkColumnIndex(column);
857 checkRowIndex();
858 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateDouble", *this);
861 void SAL_CALL OResultSet::updateString(sal_Int32 column, const OUString& /* x */)
863 MutexGuard aGuard(m_aMutex);
864 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
865 checkColumnIndex(column);
866 checkRowIndex();
867 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateString", *this);
870 void SAL_CALL OResultSet::updateBytes(sal_Int32 column, const uno::Sequence<sal_Int8>& /* x */)
872 MutexGuard aGuard(m_aMutex);
873 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
874 checkColumnIndex(column);
875 checkRowIndex();
876 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBytes", *this);
879 void SAL_CALL OResultSet::updateDate(sal_Int32 column, const Date& /* x */)
881 MutexGuard aGuard(m_aMutex);
882 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
883 checkColumnIndex(column);
884 checkRowIndex();
885 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateDate", *this);
888 void SAL_CALL OResultSet::updateTime(sal_Int32 column, const Time& /* x */)
890 MutexGuard aGuard(m_aMutex);
891 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
892 checkColumnIndex(column);
893 checkRowIndex();
894 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateTime", *this);
897 void SAL_CALL OResultSet::updateTimestamp(sal_Int32 column, const DateTime& /* x */)
899 MutexGuard aGuard(m_aMutex);
900 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
901 checkColumnIndex(column);
902 checkRowIndex();
903 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateTimestamp", *this);
906 void SAL_CALL OResultSet::updateBinaryStream(sal_Int32 column,
907 const uno::Reference<XInputStream>& /* x */,
908 sal_Int32 /* length */)
910 MutexGuard aGuard(m_aMutex);
911 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
912 checkColumnIndex(column);
913 checkRowIndex();
914 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBinaryStream",
915 *this);
918 void SAL_CALL OResultSet::updateCharacterStream(sal_Int32 column,
919 const uno::Reference<XInputStream>& /* x */,
920 sal_Int32 /* length */)
922 MutexGuard aGuard(m_aMutex);
923 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
924 checkColumnIndex(column);
925 checkRowIndex();
926 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateCharacterStream",
927 *this);
930 void SAL_CALL OResultSet::refreshRow()
932 MutexGuard aGuard(m_aMutex);
933 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
934 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::refreshRow", *this);
937 void SAL_CALL OResultSet::updateObject(sal_Int32 column, const Any& /* x */)
939 MutexGuard aGuard(m_aMutex);
940 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
941 checkColumnIndex(column);
942 checkRowIndex();
943 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateObject", *this);
946 void SAL_CALL OResultSet::updateNumericObject(sal_Int32 column, const Any& /* x */,
947 sal_Int32 /* scale */)
949 MutexGuard aGuard(m_aMutex);
950 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
951 checkColumnIndex(column);
952 checkRowIndex();
953 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateNumericObject",
954 *this);
957 // XRowLocate
958 Any SAL_CALL OResultSet::getBookmark()
960 MutexGuard aGuard(m_aMutex);
961 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
962 Any aRet = Any();
964 // if you don't want to support bookmark you must remove the XRowLocate interface
965 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getBookmark", *this);
967 return aRet;
970 sal_Bool SAL_CALL OResultSet::moveToBookmark(const Any& /* bookmark */)
972 MutexGuard aGuard(m_aMutex);
973 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
975 return false;
978 sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark(const Any& /* bookmark */,
979 sal_Int32 /* rows */)
981 MutexGuard aGuard(m_aMutex);
982 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
984 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::moveRelativeToBookmark",
985 *this);
986 return false;
989 sal_Int32 SAL_CALL OResultSet::compareBookmarks(const Any& /* n1 */, const Any& /* n2 */)
991 MutexGuard aGuard(m_aMutex);
992 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
994 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::compareBookmarks", *this);
996 return CompareBookmark::NOT_EQUAL;
999 sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks() { return false; }
1001 sal_Int32 SAL_CALL OResultSet::hashBookmark(const Any& /* bookmark */)
1003 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::hashBookmark", *this);
1004 return 0;
1007 // XDeleteRows
1008 uno::Sequence<sal_Int32> SAL_CALL OResultSet::deleteRows(const uno::Sequence<Any>& /* rows */)
1010 MutexGuard aGuard(m_aMutex);
1011 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1012 uno::Sequence<sal_Int32> aRet = uno::Sequence<sal_Int32>();
1014 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::deleteRows", *this);
1015 return aRet;
1018 IPropertyArrayHelper* OResultSet::createArrayHelper() const
1020 uno::Sequence<Property> aProps(5);
1021 Property* pProperties = aProps.getArray();
1022 sal_Int32 nPos = 0;
1023 pProperties[nPos++] = Property("FetchDirection", PROPERTY_ID_FETCHDIRECTION,
1024 cppu::UnoType<sal_Int32>::get(), 0);
1025 pProperties[nPos++]
1026 = Property("FetchSize", PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0);
1027 pProperties[nPos++] = Property("IsBookmarkable", PROPERTY_ID_ISBOOKMARKABLE,
1028 cppu::UnoType<bool>::get(), PropertyAttribute::READONLY);
1029 pProperties[nPos++] = Property("ResultSetConcurrency", PROPERTY_ID_RESULTSETCONCURRENCY,
1030 cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
1031 pProperties[nPos++] = Property("ResultSetType", PROPERTY_ID_RESULTSETTYPE,
1032 cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
1034 return new OPropertyArrayHelper(aProps);
1037 IPropertyArrayHelper& OResultSet::getInfoHelper() { return *getArrayHelper(); }
1039 sal_Bool OResultSet::convertFastPropertyValue(Any& /* rConvertedValue */, Any& /* rOldValue */,
1040 sal_Int32 nHandle, const Any& /* rValue */)
1042 switch (nHandle)
1044 case PROPERTY_ID_ISBOOKMARKABLE:
1045 case PROPERTY_ID_CURSORNAME:
1046 case PROPERTY_ID_RESULTSETCONCURRENCY:
1047 case PROPERTY_ID_RESULTSETTYPE:
1048 throw css::lang::IllegalArgumentException();
1049 case PROPERTY_ID_FETCHDIRECTION:
1050 case PROPERTY_ID_FETCHSIZE:
1051 default:;
1053 return false;
1056 void OResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& /* rValue */)
1058 switch (nHandle)
1060 case PROPERTY_ID_ISBOOKMARKABLE:
1061 case PROPERTY_ID_CURSORNAME:
1062 case PROPERTY_ID_RESULTSETCONCURRENCY:
1063 case PROPERTY_ID_RESULTSETTYPE:
1064 throw uno::Exception("cannot set prop " + OUString::number(nHandle), nullptr);
1065 case PROPERTY_ID_FETCHDIRECTION:
1066 break;
1067 case PROPERTY_ID_FETCHSIZE:
1068 break;
1069 default:;
1073 void OResultSet::getFastPropertyValue(Any& _rValue, sal_Int32 nHandle) const
1075 switch (nHandle)
1077 case PROPERTY_ID_ISBOOKMARKABLE:
1078 _rValue <<= false;
1079 break;
1080 case PROPERTY_ID_CURSORNAME:
1081 break;
1082 case PROPERTY_ID_RESULTSETCONCURRENCY:
1083 _rValue <<= ResultSetConcurrency::READ_ONLY;
1084 break;
1085 case PROPERTY_ID_RESULTSETTYPE:
1086 _rValue <<= ResultSetType::SCROLL_INSENSITIVE;
1087 break;
1088 case PROPERTY_ID_FETCHDIRECTION:
1089 _rValue <<= FetchDirection::FORWARD;
1090 break;
1091 case PROPERTY_ID_FETCHSIZE:
1092 _rValue <<= sal_Int32(50);
1093 break;
1095 default:;
1099 void SAL_CALL OResultSet::acquire() throw() { OResultSet_BASE::acquire(); }
1101 void SAL_CALL OResultSet::release() throw() { OResultSet_BASE::release(); }
1103 css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OResultSet::getPropertySetInfo()
1105 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1108 void OResultSet::checkColumnIndex(sal_Int32 index)
1110 if (index < 1 || index > static_cast<int>(m_aFields.size()))
1112 /* static object for efficiency or thread safety is a problem ? */
1113 throw SQLException("index out of range", *this, OUString(), 1, Any());
1117 void OResultSet::checkBordersAndEnsureFetched(sal_Int32 index)
1119 ensureResultFetched();
1120 checkColumnIndex(index);
1121 checkRowIndex();
1124 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */