bump product version to 6.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / mysqlc / mysqlc_prepared_resultset.cxx
blobb3630072c143e774f3d9fad19122432b8588fd3a
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_prepared_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>
35 using namespace rtl;
36 #include <comphelper/string.hxx>
38 #include <cstdlib>
40 using namespace connectivity::mysqlc;
41 using namespace connectivity;
42 using namespace cppu;
43 using namespace com::sun::star;
44 using namespace com::sun::star::lang;
45 using namespace com::sun::star::beans;
46 using namespace com::sun::star::sdbc;
47 using namespace com::sun::star::sdbcx;
48 using namespace com::sun::star::container;
49 using namespace com::sun::star::io;
50 using namespace com::sun::star::util;
51 using namespace ::comphelper;
52 using ::osl::MutexGuard;
54 #include <stdio.h>
55 #include <typeinfo>
56 #include <typeindex>
58 namespace
60 const std::type_index getTypeFromMysqlType(enum_field_types type)
62 switch (type)
64 case MYSQL_TYPE_TINY:
65 return std::type_index(typeid(sal_Int8));
66 case MYSQL_TYPE_SHORT:
67 return std::type_index(typeid(sal_Int16));
68 case MYSQL_TYPE_LONG:
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_YEAR:
90 case MYSQL_TYPE_BIT:
91 case MYSQL_TYPE_INT24:
92 case MYSQL_TYPE_SET:
93 case MYSQL_TYPE_ENUM:
94 case MYSQL_TYPE_GEOMETRY:
95 case MYSQL_TYPE_NULL:
96 default:
97 return std::type_index(typeid(nullptr));
102 OUString SAL_CALL OPreparedResultSet::getImplementationName()
104 return OUString("com.sun.star.sdbcx.mysqlc.ResultSet");
107 uno::Sequence<OUString> SAL_CALL OPreparedResultSet::getSupportedServiceNames()
109 uno::Sequence<OUString> aSupported(2);
110 aSupported[0] = "com.sun.star.sdbc.ResultSet";
111 aSupported[1] = "com.sun.star.sdbcx.ResultSet";
112 return aSupported;
115 sal_Bool SAL_CALL OPreparedResultSet::supportsService(const OUString& _rServiceName)
117 return cppu::supportsService(this, _rServiceName);
119 OPreparedResultSet::OPreparedResultSet(OConnection& rConn, OPreparedStatement* pPrepared,
120 MYSQL_STMT* pStmt)
121 : OPreparedResultSet_BASE(m_aMutex)
122 , OPropertySetHelper(OPreparedResultSet_BASE::rBHelper)
123 , m_rConnection(rConn)
124 , m_aStatement(static_cast<OWeakObject*>(pPrepared))
125 , m_pStmt(pStmt)
126 , m_encoding(rConn.getConnectionEncoding())
128 m_nFieldCount = mysql_stmt_field_count(pStmt);
129 m_pResult = mysql_stmt_result_metadata(m_pStmt);
130 m_aFields = mysql_fetch_fields(m_pResult);
133 void OPreparedResultSet::disposing()
135 OPropertySetHelper::disposing();
137 MutexGuard aGuard(m_aMutex);
139 m_aStatement = nullptr;
140 m_xMetaData = nullptr;
143 Any SAL_CALL OPreparedResultSet::queryInterface(const Type& rType)
145 Any aRet = OPropertySetHelper::queryInterface(rType);
146 if (!aRet.hasValue())
148 aRet = OPreparedResultSet_BASE::queryInterface(rType);
150 return aRet;
153 uno::Sequence<Type> SAL_CALL OPreparedResultSet::getTypes()
155 OTypeCollection aTypes(cppu::UnoType<XMultiPropertySet>::get(),
156 cppu::UnoType<XFastPropertySet>::get(),
157 cppu::UnoType<XPropertySet>::get());
159 return concatSequences(aTypes.getTypes(), OPreparedResultSet_BASE::getTypes());
162 sal_Int32 SAL_CALL OPreparedResultSet::findColumn(const OUString& columnName)
164 MutexGuard aGuard(m_aMutex);
165 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
167 MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult);
168 for (sal_Int32 i = 0; i < m_nFieldCount; ++i)
170 if (columnName.equalsIgnoreAsciiCaseAscii(pFields[i].name))
171 return i + 1; // sdbc indexes from 1
174 throw SQLException("The column name '" + columnName + "' is not valid.", *this, "42S22", 0,
175 Any());
178 template <typename T> T OPreparedResultSet::safelyRetrieveValue(sal_Int32 nColumnIndex)
180 MutexGuard aGuard(m_aMutex);
181 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
182 checkColumnIndex(nColumnIndex);
183 if (*m_aData[nColumnIndex - 1].is_null)
185 m_bWasNull = true;
186 return T();
188 m_bWasNull = false;
190 return retrieveValue<T>(nColumnIndex);
193 template <typename T> T OPreparedResultSet::retrieveValue(sal_Int32 nColumnIndex)
195 if (getTypeFromMysqlType(m_aFields[nColumnIndex - 1].type) == std::type_index(typeid(T)))
196 return *static_cast<T*>(m_aData[nColumnIndex - 1].buffer);
197 else
198 return getRowSetValue(nColumnIndex);
201 template <> uno::Sequence<sal_Int8> OPreparedResultSet::retrieveValue(sal_Int32 column)
203 // TODO make conversion possible
204 return uno::Sequence<sal_Int8>(static_cast<sal_Int8 const*>(m_aData[column - 1].buffer),
205 *m_aData[column - 1].length);
208 template <> Date OPreparedResultSet::retrieveValue(sal_Int32 column)
210 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(Date)))
211 return getRowSetValue(column);
212 const MYSQL_TIME* pTime = static_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
214 Date d;
215 d.Year = pTime->year;
216 d.Month = pTime->month;
217 d.Day = pTime->day;
218 return d;
221 template <> Time OPreparedResultSet::retrieveValue(sal_Int32 column)
223 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(Time)))
224 return getRowSetValue(column);
225 const MYSQL_TIME* pTime = static_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
227 Time t;
228 t.Hours = pTime->hour;
229 t.Minutes = pTime->minute;
230 t.Seconds = pTime->second;
231 return t;
234 template <> DateTime OPreparedResultSet::retrieveValue(sal_Int32 column)
236 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(DateTime)))
237 return getRowSetValue(column);
238 const MYSQL_TIME* pTime = static_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
240 DateTime t;
241 t.Year = pTime->year;
242 t.Month = pTime->month;
243 t.Day = pTime->day;
244 t.Hours = pTime->hour;
245 t.Minutes = pTime->minute;
246 t.Seconds = pTime->second;
247 return t;
250 template <> OUString OPreparedResultSet::retrieveValue(sal_Int32 column)
252 if (getTypeFromMysqlType(m_aFields[column - 1].type) != std::type_index(typeid(OUString)))
253 return getRowSetValue(column);
254 const char* sStr = static_cast<const char*>(m_aData[column - 1].buffer);
256 OUString sReturn = OUString(sStr, *m_aData[column - 1].length, m_encoding);
257 return sReturn;
260 ORowSetValue OPreparedResultSet::getRowSetValue(sal_Int32 nColumnIndex)
262 switch (m_aFields[nColumnIndex - 1].type)
264 case MYSQL_TYPE_TINY:
265 return getByte(nColumnIndex);
266 case MYSQL_TYPE_SHORT:
267 return getShort(nColumnIndex);
268 case MYSQL_TYPE_LONG:
269 return getInt(nColumnIndex);
270 case MYSQL_TYPE_LONGLONG:
271 return getLong(nColumnIndex);
272 case MYSQL_TYPE_FLOAT:
273 case MYSQL_TYPE_DOUBLE:
274 return getDouble(nColumnIndex);
275 case MYSQL_TYPE_TIMESTAMP:
276 case MYSQL_TYPE_DATETIME:
277 return getTimestamp(nColumnIndex);
278 case MYSQL_TYPE_DATE:
279 return getDate(nColumnIndex);
280 case MYSQL_TYPE_TIME:
281 return getTime(nColumnIndex);
282 case MYSQL_TYPE_STRING:
283 case MYSQL_TYPE_VAR_STRING:
284 case MYSQL_TYPE_DECIMAL:
285 case MYSQL_TYPE_NEWDECIMAL:
286 return getString(nColumnIndex);
287 default:
288 mysqlc_sdbc_driver::throwFeatureNotImplementedException(
289 "OPreparedResultSet::getRowSetValue", *this);
290 return ORowSetValue();
294 uno::Reference<XInputStream> SAL_CALL OPreparedResultSet::getBinaryStream(sal_Int32 /*column*/)
296 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBinaryStream",
297 *this);
298 return nullptr;
301 uno::Reference<XInputStream> SAL_CALL OPreparedResultSet::getCharacterStream(sal_Int32 /*column*/)
303 mysqlc_sdbc_driver::throwFeatureNotImplementedException(
304 "OPreparedResultSet::getCharacterStream", *this);
305 return nullptr;
308 sal_Bool SAL_CALL OPreparedResultSet::getBoolean(sal_Int32 column)
310 return safelyRetrieveValue<bool>(column);
313 sal_Int8 SAL_CALL OPreparedResultSet::getByte(sal_Int32 column)
315 return safelyRetrieveValue<sal_Int8>(column);
318 uno::Sequence<sal_Int8> SAL_CALL OPreparedResultSet::getBytes(sal_Int32 column)
320 return safelyRetrieveValue<uno::Sequence<sal_Int8>>(column);
323 Date SAL_CALL OPreparedResultSet::getDate(sal_Int32 column)
325 return safelyRetrieveValue<Date>(column);
328 double SAL_CALL OPreparedResultSet::getDouble(sal_Int32 column)
330 return safelyRetrieveValue<double>(column);
333 float SAL_CALL OPreparedResultSet::getFloat(sal_Int32 column)
335 return safelyRetrieveValue<float>(column);
338 sal_Int32 SAL_CALL OPreparedResultSet::getInt(sal_Int32 column)
340 return safelyRetrieveValue<sal_Int32>(column);
343 sal_Int32 SAL_CALL OPreparedResultSet::getRow()
345 MutexGuard aGuard(m_aMutex);
346 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
348 return static_cast<sal_Int32>(mysql_field_tell(m_pResult));
351 sal_Int64 SAL_CALL OPreparedResultSet::getLong(sal_Int32 column)
353 return safelyRetrieveValue<sal_Int64>(column);
356 uno::Reference<XResultSetMetaData> SAL_CALL OPreparedResultSet::getMetaData()
358 MutexGuard aGuard(m_aMutex);
359 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
360 if (!m_xMetaData.is())
362 m_xMetaData = new OResultSetMetaData(m_rConnection, m_pResult);
364 return m_xMetaData;
367 uno::Reference<XArray> SAL_CALL OPreparedResultSet::getArray(sal_Int32 column)
369 MutexGuard aGuard(m_aMutex);
370 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
371 checkColumnIndex(column);
373 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getArray", *this);
374 return nullptr;
377 uno::Reference<XClob> SAL_CALL OPreparedResultSet::getClob(sal_Int32 column)
379 MutexGuard aGuard(m_aMutex);
380 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
381 checkColumnIndex(column);
383 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getClob", *this);
384 return nullptr;
387 uno::Reference<XBlob> SAL_CALL OPreparedResultSet::getBlob(sal_Int32 column)
389 MutexGuard aGuard(m_aMutex);
390 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
391 checkColumnIndex(column);
393 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBlob", *this);
394 return nullptr;
397 uno::Reference<XRef> SAL_CALL OPreparedResultSet::getRef(sal_Int32 column)
399 MutexGuard aGuard(m_aMutex);
400 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
401 checkColumnIndex(column);
403 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getRef", *this);
404 return nullptr;
407 Any SAL_CALL OPreparedResultSet::getObject(sal_Int32 column,
408 const uno::Reference<XNameAccess>& /* typeMap */)
410 MutexGuard aGuard(m_aMutex);
411 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
412 checkColumnIndex(column);
414 Any aRet = Any();
416 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getObject", *this);
417 return aRet;
420 sal_Int16 SAL_CALL OPreparedResultSet::getShort(sal_Int32 column)
422 return safelyRetrieveValue<sal_Int16>(column);
425 OUString SAL_CALL OPreparedResultSet::getString(sal_Int32 column)
427 return safelyRetrieveValue<OUString>(column);
430 Time SAL_CALL OPreparedResultSet::getTime(sal_Int32 column)
432 return safelyRetrieveValue<Time>(column);
435 DateTime SAL_CALL OPreparedResultSet::getTimestamp(sal_Int32 column)
437 return safelyRetrieveValue<DateTime>(column);
440 sal_Bool SAL_CALL OPreparedResultSet::isBeforeFirst()
442 MutexGuard aGuard(m_aMutex);
443 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
445 return m_nCurrentField == 0;
448 sal_Bool SAL_CALL OPreparedResultSet::isAfterLast()
450 MutexGuard aGuard(m_aMutex);
451 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
453 return m_nCurrentField >= m_nFieldCount;
456 sal_Bool SAL_CALL OPreparedResultSet::isFirst()
458 MutexGuard aGuard(m_aMutex);
459 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
461 return m_nCurrentField == 1 && !isAfterLast();
464 sal_Bool SAL_CALL OPreparedResultSet::isLast()
466 MutexGuard aGuard(m_aMutex);
467 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
469 return mysql_field_tell(m_pResult) == static_cast<unsigned>(m_nFieldCount);
472 void SAL_CALL OPreparedResultSet::beforeFirst()
474 MutexGuard aGuard(m_aMutex);
475 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
477 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::beforeFirst",
478 *this);
481 void SAL_CALL OPreparedResultSet::afterLast()
483 MutexGuard aGuard(m_aMutex);
484 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
486 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::afterLast", *this);
489 void SAL_CALL OPreparedResultSet::close()
491 MutexGuard aGuard(m_aMutex);
492 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
494 m_aData.reset();
495 m_aMetaData.reset();
497 if (m_pResult)
498 mysql_free_result(m_pResult);
499 mysql_stmt_free_result(m_pStmt);
500 dispose();
503 sal_Bool SAL_CALL OPreparedResultSet::first()
505 MutexGuard aGuard(m_aMutex);
506 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
508 mysql_stmt_data_seek(m_pStmt, 0);
509 next();
511 return true;
514 sal_Bool SAL_CALL OPreparedResultSet::last()
516 MutexGuard aGuard(m_aMutex);
517 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
519 mysql_stmt_data_seek(m_pStmt, m_nFieldCount - 1);
520 next();
522 return true;
525 sal_Bool SAL_CALL OPreparedResultSet::absolute(sal_Int32 row)
527 MutexGuard aGuard(m_aMutex);
528 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
530 sal_Int32 nFields = m_nFieldCount;
531 sal_Int32 nToGo = row < 0 ? nFields - row : row - 1;
533 if (nToGo >= nFields)
534 nToGo = nFields - 1;
535 if (nToGo < 0)
536 nToGo = 0;
538 mysql_stmt_data_seek(m_pStmt, nToGo);
539 next();
541 return true;
544 sal_Bool SAL_CALL OPreparedResultSet::relative(sal_Int32 row)
546 MutexGuard aGuard(m_aMutex);
547 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
549 sal_Int32 nFields = m_nFieldCount;
550 if (row == 0)
551 return true;
553 sal_Int32 nToGo = m_nCurrentField + row;
554 if (nToGo >= nFields)
555 nToGo = nFields - 1;
556 if (nToGo < 0)
557 nToGo = 0;
559 mysql_stmt_data_seek(m_pStmt, nToGo);
560 next();
561 m_nCurrentField += row;
563 return true;
566 sal_Bool SAL_CALL OPreparedResultSet::previous()
568 MutexGuard aGuard(m_aMutex);
569 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
571 if (m_nCurrentField <= 1)
572 return false;
574 mysql_stmt_data_seek(m_pStmt, m_nCurrentField - 2);
575 next();
576 --m_nFieldCount;
577 return true;
580 uno::Reference<uno::XInterface> SAL_CALL OPreparedResultSet::getStatement()
582 MutexGuard aGuard(m_aMutex);
583 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
585 return m_aStatement.get();
588 sal_Bool SAL_CALL OPreparedResultSet::rowDeleted()
590 MutexGuard aGuard(m_aMutex);
591 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
593 return false;
596 sal_Bool SAL_CALL OPreparedResultSet::rowInserted()
598 MutexGuard aGuard(m_aMutex);
599 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
601 return false;
604 sal_Bool SAL_CALL OPreparedResultSet::rowUpdated()
606 MutexGuard aGuard(m_aMutex);
607 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
609 return false;
612 sal_Bool SAL_CALL OPreparedResultSet::next()
614 MutexGuard aGuard(m_aMutex);
615 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
617 bool bFirstRun = false;
618 // allocate array if it does not exist
619 if (m_aData == nullptr)
621 bFirstRun = true;
622 m_aData.reset(new MYSQL_BIND[m_nFieldCount]);
623 memset(m_aData.get(), 0, m_nFieldCount * sizeof(MYSQL_BIND));
624 m_aMetaData.reset(new BindMetaData[m_nFieldCount]);
626 for (sal_Int32 i = 0; i < m_nFieldCount; ++i)
628 m_aMetaData[i].is_null = 0;
629 m_aMetaData[i].length = 0l;
630 m_aMetaData[i].error = 0;
632 m_aData[i].is_null = &m_aMetaData[i].is_null;
633 m_aData[i].buffer_length = m_aFields[i].type == MYSQL_TYPE_BLOB ? 0 : m_aFields[i].length;
634 m_aData[i].length = &m_aMetaData[i].length;
635 m_aData[i].error = &m_aMetaData[i].error;
636 m_aData[i].buffer = nullptr;
637 m_aData[i].buffer_type = m_aFields[i].type;
639 // allocates memory, if it is a fixed size type. If not then nullptr
640 mysqlc_sdbc_driver::allocateSqlVar(&m_aData[i].buffer, m_aData[i].buffer_type,
641 m_aFields[i].length);
643 mysql_stmt_bind_result(m_pStmt, m_aData.get());
644 if (bFirstRun)
645 mysql_stmt_store_result(m_pStmt);
646 int failure = mysql_stmt_fetch(m_pStmt);
648 for (sal_Int32 i = 0; i < m_nFieldCount; ++i)
650 if (*m_aData[i].error)
652 // expected if we have a BLOB, as buffer_length is set to 0. We want to
653 // fetch it piece by piece
654 // see https://bugs.mysql.com/file.php?id=12361&bug_id=33086
655 if (m_aData[i].buffer == nullptr)
657 m_aData[i].buffer_length = *m_aData[i].length;
658 m_aData[i].buffer = malloc(*m_aData[i].length);
659 mysql_stmt_fetch_column(m_pStmt, &m_aData[i], i, 0);
664 if (failure == 1)
666 MYSQL* pMysql = m_rConnection.getMysqlConnection();
667 mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMysql), mysql_errno(pMysql),
668 *this, m_encoding);
670 else if (failure == MYSQL_NO_DATA)
671 return false;
673 // current field cannot be asked as a number. We have to keep track it
674 // manually.
675 m_nCurrentField += 1;
677 return true;
680 sal_Bool SAL_CALL OPreparedResultSet::wasNull()
682 MutexGuard aGuard(m_aMutex);
683 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
685 return m_bWasNull;
688 void SAL_CALL OPreparedResultSet::cancel()
690 MutexGuard aGuard(m_aMutex);
691 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
694 void SAL_CALL OPreparedResultSet::clearWarnings() {}
696 Any SAL_CALL OPreparedResultSet::getWarnings()
698 Any aRet = Any();
699 return aRet;
702 void SAL_CALL OPreparedResultSet::insertRow()
704 MutexGuard aGuard(m_aMutex);
705 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
706 // you only have to implement this if you want to insert new rows
707 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::insertRow", *this);
710 void SAL_CALL OPreparedResultSet::updateRow()
712 MutexGuard aGuard(m_aMutex);
713 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
715 // only when you allow updates
716 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateRow", *this);
719 void SAL_CALL OPreparedResultSet::deleteRow()
721 MutexGuard aGuard(m_aMutex);
722 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
723 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::deleteRow", *this);
726 void SAL_CALL OPreparedResultSet::cancelRowUpdates()
728 MutexGuard aGuard(m_aMutex);
729 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
730 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::cancelRowUpdates",
731 *this);
734 void SAL_CALL OPreparedResultSet::moveToInsertRow()
736 MutexGuard aGuard(m_aMutex);
737 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
739 // only when you allow insert's
740 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::moveToInsertRow",
741 *this);
744 void SAL_CALL OPreparedResultSet::moveToCurrentRow()
746 MutexGuard aGuard(m_aMutex);
747 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
750 void SAL_CALL OPreparedResultSet::updateNull(sal_Int32 column)
752 MutexGuard aGuard(m_aMutex);
753 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
754 checkColumnIndex(column);
755 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateNull",
756 *this);
759 void SAL_CALL OPreparedResultSet::updateBoolean(sal_Int32 column, sal_Bool /* x */)
761 MutexGuard aGuard(m_aMutex);
762 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
763 checkColumnIndex(column);
764 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateBoolean",
765 *this);
768 void SAL_CALL OPreparedResultSet::updateByte(sal_Int32 column, sal_Int8 /* x */)
770 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
771 MutexGuard aGuard(m_aMutex);
772 checkColumnIndex(column);
773 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateByte",
774 *this);
777 void SAL_CALL OPreparedResultSet::updateShort(sal_Int32 column, sal_Int16 /* x */)
779 MutexGuard aGuard(m_aMutex);
780 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
781 checkColumnIndex(column);
782 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateShort",
783 *this);
786 void SAL_CALL OPreparedResultSet::updateInt(sal_Int32 column, sal_Int32 /* x */)
788 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
789 MutexGuard aGuard(m_aMutex);
790 checkColumnIndex(column);
791 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateInt", *this);
794 void SAL_CALL OPreparedResultSet::updateLong(sal_Int32 column, sal_Int64 /* x */)
796 MutexGuard aGuard(m_aMutex);
797 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
798 checkColumnIndex(column);
799 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateLong",
800 *this);
803 void SAL_CALL OPreparedResultSet::updateFloat(sal_Int32 column, float /* x */)
805 MutexGuard aGuard(m_aMutex);
806 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
807 checkColumnIndex(column);
808 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateFloat",
809 *this);
812 void SAL_CALL OPreparedResultSet::updateDouble(sal_Int32 column, double /* x */)
814 MutexGuard aGuard(m_aMutex);
815 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
816 checkColumnIndex(column);
817 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateDouble",
818 *this);
821 void SAL_CALL OPreparedResultSet::updateString(sal_Int32 column, const OUString& /* x */)
823 MutexGuard aGuard(m_aMutex);
824 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
825 checkColumnIndex(column);
826 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateString",
827 *this);
830 void SAL_CALL OPreparedResultSet::updateBytes(sal_Int32 column,
831 const uno::Sequence<sal_Int8>& /* x */)
833 MutexGuard aGuard(m_aMutex);
834 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
835 checkColumnIndex(column);
836 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateBytes",
837 *this);
840 void SAL_CALL OPreparedResultSet::updateDate(sal_Int32 column, const Date& /* x */)
842 MutexGuard aGuard(m_aMutex);
843 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
844 checkColumnIndex(column);
845 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateDate",
846 *this);
849 void SAL_CALL OPreparedResultSet::updateTime(sal_Int32 column, const Time& /* x */)
851 MutexGuard aGuard(m_aMutex);
852 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
853 checkColumnIndex(column);
854 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateTime",
855 *this);
858 void SAL_CALL OPreparedResultSet::updateTimestamp(sal_Int32 column, const DateTime& /* x */)
860 MutexGuard aGuard(m_aMutex);
861 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
862 checkColumnIndex(column);
863 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateTimestamp",
864 *this);
867 void SAL_CALL OPreparedResultSet::updateBinaryStream(sal_Int32 column,
868 const uno::Reference<XInputStream>& /* x */,
869 sal_Int32 /* length */)
871 MutexGuard aGuard(m_aMutex);
872 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
873 checkColumnIndex(column);
874 mysqlc_sdbc_driver::throwFeatureNotImplementedException(
875 "OPreparedResultSet::updateBinaryStream", *this);
878 void SAL_CALL OPreparedResultSet::updateCharacterStream(sal_Int32 column,
879 const uno::Reference<XInputStream>& /* x */,
880 sal_Int32 /* length */)
882 MutexGuard aGuard(m_aMutex);
883 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
884 checkColumnIndex(column);
885 mysqlc_sdbc_driver::throwFeatureNotImplementedException(
886 "OPreparedResultSet::updateCharacterStream", *this);
889 void SAL_CALL OPreparedResultSet::refreshRow()
891 MutexGuard aGuard(m_aMutex);
892 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
893 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::refreshRow",
894 *this);
897 void SAL_CALL OPreparedResultSet::updateObject(sal_Int32 column, const Any& /* x */)
899 MutexGuard aGuard(m_aMutex);
900 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
901 checkColumnIndex(column);
902 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateObject",
903 *this);
906 void SAL_CALL OPreparedResultSet::updateNumericObject(sal_Int32 column, const Any& /* x */,
907 sal_Int32 /* scale */)
909 MutexGuard aGuard(m_aMutex);
910 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
911 checkColumnIndex(column);
912 mysqlc_sdbc_driver::throwFeatureNotImplementedException(
913 "OPreparedResultSet::updateNumericObject", *this);
916 // XRowLocate
917 Any SAL_CALL OPreparedResultSet::getBookmark()
919 MutexGuard aGuard(m_aMutex);
920 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
921 Any aRet = Any();
923 // if you don't want to support bookmark you must remove the XRowLocate interface
924 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBookmark",
925 *this);
927 return aRet;
930 sal_Bool SAL_CALL OPreparedResultSet::moveToBookmark(const Any& /* bookmark */)
932 MutexGuard aGuard(m_aMutex);
933 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
935 return false;
938 sal_Bool SAL_CALL OPreparedResultSet::moveRelativeToBookmark(const Any& /* bookmark */,
939 sal_Int32 /* rows */)
941 MutexGuard aGuard(m_aMutex);
942 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
944 mysqlc_sdbc_driver::throwFeatureNotImplementedException(
945 "OPreparedResultSet::moveRelativeToBookmark", *this);
946 return false;
949 sal_Int32 SAL_CALL OPreparedResultSet::compareBookmarks(const Any& /* n1 */, const Any& /* n2 */)
951 MutexGuard aGuard(m_aMutex);
952 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
954 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::compareBookmarks",
955 *this);
957 return CompareBookmark::NOT_EQUAL;
960 sal_Bool SAL_CALL OPreparedResultSet::hasOrderedBookmarks() { return false; }
962 sal_Int32 SAL_CALL OPreparedResultSet::hashBookmark(const Any& /* bookmark */)
964 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::hashBookmark",
965 *this);
966 return 0;
969 // XDeleteRows
970 uno::Sequence<sal_Int32>
971 SAL_CALL OPreparedResultSet::deleteRows(const uno::Sequence<Any>& /* rows */)
973 MutexGuard aGuard(m_aMutex);
974 checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
975 uno::Sequence<sal_Int32> aRet = uno::Sequence<sal_Int32>();
977 mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::deleteRows",
978 *this);
979 return aRet;
982 IPropertyArrayHelper* OPreparedResultSet::createArrayHelper() const
984 uno::Sequence<Property> aProps(5);
985 Property* pProperties = aProps.getArray();
986 sal_Int32 nPos = 0;
987 pProperties[nPos++] = Property("FetchDirection", PROPERTY_ID_FETCHDIRECTION,
988 cppu::UnoType<sal_Int32>::get(), 0);
989 pProperties[nPos++]
990 = Property("FetchSize", PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0);
991 pProperties[nPos++] = Property("IsBookmarkable", PROPERTY_ID_ISBOOKMARKABLE,
992 cppu::UnoType<bool>::get(), PropertyAttribute::READONLY);
993 pProperties[nPos++] = Property("ResultSetConcurrency", PROPERTY_ID_RESULTSETCONCURRENCY,
994 cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
995 pProperties[nPos++] = Property("ResultSetType", PROPERTY_ID_RESULTSETTYPE,
996 cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
998 return new OPropertyArrayHelper(aProps);
1001 IPropertyArrayHelper& OPreparedResultSet::getInfoHelper() { return *getArrayHelper(); }
1003 sal_Bool OPreparedResultSet::convertFastPropertyValue(Any& /* rConvertedValue */,
1004 Any& /* rOldValue */, sal_Int32 nHandle,
1005 const Any& /* rValue */)
1007 switch (nHandle)
1009 case PROPERTY_ID_ISBOOKMARKABLE:
1010 case PROPERTY_ID_CURSORNAME:
1011 case PROPERTY_ID_RESULTSETCONCURRENCY:
1012 case PROPERTY_ID_RESULTSETTYPE:
1013 throw css::lang::IllegalArgumentException();
1014 case PROPERTY_ID_FETCHDIRECTION:
1015 case PROPERTY_ID_FETCHSIZE:
1016 default:;
1018 return false;
1021 void OPreparedResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,
1022 const Any& /* rValue */)
1024 switch (nHandle)
1026 case PROPERTY_ID_ISBOOKMARKABLE:
1027 case PROPERTY_ID_CURSORNAME:
1028 case PROPERTY_ID_RESULTSETCONCURRENCY:
1029 case PROPERTY_ID_RESULTSETTYPE:
1030 throw uno::Exception("cannot set prop " + OUString::number(nHandle), nullptr);
1031 case PROPERTY_ID_FETCHDIRECTION:
1032 break;
1033 case PROPERTY_ID_FETCHSIZE:
1034 break;
1035 default:;
1039 void OPreparedResultSet::getFastPropertyValue(Any& _rValue, sal_Int32 nHandle) const
1041 switch (nHandle)
1043 case PROPERTY_ID_ISBOOKMARKABLE:
1044 _rValue <<= false;
1045 break;
1046 case PROPERTY_ID_CURSORNAME:
1047 break;
1048 case PROPERTY_ID_RESULTSETCONCURRENCY:
1049 _rValue <<= ResultSetConcurrency::READ_ONLY;
1050 break;
1051 case PROPERTY_ID_RESULTSETTYPE:
1052 _rValue <<= ResultSetType::SCROLL_INSENSITIVE;
1053 break;
1054 case PROPERTY_ID_FETCHDIRECTION:
1055 _rValue <<= FetchDirection::FORWARD;
1056 break;
1057 case PROPERTY_ID_FETCHSIZE:
1058 _rValue <<= sal_Int32(50);
1059 break;
1061 default:;
1065 void SAL_CALL OPreparedResultSet::acquire() throw() { OPreparedResultSet_BASE::acquire(); }
1067 void SAL_CALL OPreparedResultSet::release() throw() { OPreparedResultSet_BASE::release(); }
1069 css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OPreparedResultSet::getPropertySetInfo()
1071 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1074 void OPreparedResultSet::checkColumnIndex(sal_Int32 index)
1076 if (!m_aData)
1077 throw SQLException("Cursor out of range", *this, OUString(), 1, Any());
1078 if (index < 1 || index > static_cast<int>(m_nFieldCount))
1080 /* static object for efficiency or thread safety is a problem ? */
1081 throw SQLException("index out of range", *this, OUString(), 1, Any());
1085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */