Kaydet (Commit) 763d490d authored tarafından Tamas Bunth's avatar Tamas Bunth Kaydeden (comit) Andras Timar

mysqlc: fetch data exactly when it's needed

It fixes the issue that one could not call getXXX on a result set
on which next() method was never called before.

Change-Id: I972bb9d475d192a14ba1534dcbdac81c20f211d0
Reviewed-on: https://gerrit.libreoffice.org/66431Reviewed-by: 's avatarAndras Timar <andras.timar@collabora.com>
Tested-by: 's avatarAndras Timar <andras.timar@collabora.com>
üst 38ef8e9e
...@@ -138,6 +138,13 @@ void OResultSet::ensureResultFetched() ...@@ -138,6 +138,13 @@ void OResultSet::ensureResultFetched()
void OResultSet::ensureFieldInfoFetched() void OResultSet::ensureFieldInfoFetched()
{ {
if (m_bResultFetched)
return; // already fetched
// it works only if result set is produced via mysql_store_result
// TODO ensure that
m_nRowCount = mysql_num_rows(m_pResult);
if (!m_aFields.empty()) if (!m_aFields.empty())
return; return;
unsigned nFieldCount = mysql_num_fields(m_pResult); unsigned nFieldCount = mysql_num_fields(m_pResult);
...@@ -152,11 +159,6 @@ void OResultSet::fetchResult() ...@@ -152,11 +159,6 @@ void OResultSet::fetchResult()
{ {
// Mysql C API does not allow simultaneously opened result sets, but sdbc does. // Mysql C API does not allow simultaneously opened result sets, but sdbc does.
// Because of that we need to fetch all of the data ASAP // Because of that we need to fetch all of the data ASAP
// it works only if result set is produced via mysql_store_result
// TODO ensure that
m_nRowCount = mysql_num_rows(m_pResult);
ensureFieldInfoFetched(); ensureFieldInfoFetched();
// fetch all the data // fetch all the data
...@@ -230,8 +232,7 @@ uno::Reference<XInputStream> SAL_CALL OResultSet::getBinaryStream(sal_Int32 colu ...@@ -230,8 +232,7 @@ uno::Reference<XInputStream> SAL_CALL OResultSet::getBinaryStream(sal_Int32 colu
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return nullptr; return nullptr;
...@@ -244,8 +245,7 @@ uno::Reference<XInputStream> SAL_CALL OResultSet::getCharacterStream(sal_Int32 c ...@@ -244,8 +245,7 @@ uno::Reference<XInputStream> SAL_CALL OResultSet::getCharacterStream(sal_Int32 c
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getCharacterStream", mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getCharacterStream",
*this); *this);
return nullptr; return nullptr;
...@@ -255,8 +255,7 @@ sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 column) ...@@ -255,8 +255,7 @@ sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return false; return false;
...@@ -268,8 +267,7 @@ sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 column) ...@@ -268,8 +267,7 @@ sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return 0; return 0;
...@@ -282,6 +280,7 @@ uno::Sequence<sal_Int8> SAL_CALL OResultSet::getBytes(sal_Int32 column) ...@@ -282,6 +280,7 @@ uno::Sequence<sal_Int8> SAL_CALL OResultSet::getBytes(sal_Int32 column)
{ {
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkBordersAndEnsureFetched(column);
OString sVal = m_aRows[m_nRowPosition][column - 1]; OString sVal = m_aRows[m_nRowPosition][column - 1];
if (checkNull(column)) if (checkNull(column))
return uno::Sequence<sal_Int8>(); return uno::Sequence<sal_Int8>();
...@@ -294,8 +293,7 @@ Date SAL_CALL OResultSet::getDate(sal_Int32 column) ...@@ -294,8 +293,7 @@ Date SAL_CALL OResultSet::getDate(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
Date d; Date d;
...@@ -332,8 +330,7 @@ double SAL_CALL OResultSet::getDouble(sal_Int32 column) ...@@ -332,8 +330,7 @@ double SAL_CALL OResultSet::getDouble(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return 0.0; return 0.0;
...@@ -346,8 +343,7 @@ float SAL_CALL OResultSet::getFloat(sal_Int32 column) ...@@ -346,8 +343,7 @@ float SAL_CALL OResultSet::getFloat(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return 0.0f; return 0.0f;
...@@ -359,6 +355,7 @@ sal_Int32 SAL_CALL OResultSet::getInt(sal_Int32 column) ...@@ -359,6 +355,7 @@ sal_Int32 SAL_CALL OResultSet::getInt(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkBordersAndEnsureFetched(column);
if (checkNull(column)) if (checkNull(column))
return 0; return 0;
...@@ -378,8 +375,7 @@ sal_Int64 SAL_CALL OResultSet::getLong(sal_Int32 column) ...@@ -378,8 +375,7 @@ sal_Int64 SAL_CALL OResultSet::getLong(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return 0LL; return 0LL;
...@@ -398,8 +394,7 @@ uno::Reference<XArray> SAL_CALL OResultSet::getArray(sal_Int32 column) ...@@ -398,8 +394,7 @@ uno::Reference<XArray> SAL_CALL OResultSet::getArray(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getArray", *this); mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getArray", *this);
return nullptr; return nullptr;
...@@ -409,8 +404,7 @@ uno::Reference<XClob> SAL_CALL OResultSet::getClob(sal_Int32 column) ...@@ -409,8 +404,7 @@ uno::Reference<XClob> SAL_CALL OResultSet::getClob(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getClob", *this); mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getClob", *this);
return nullptr; return nullptr;
...@@ -420,8 +414,7 @@ uno::Reference<XBlob> SAL_CALL OResultSet::getBlob(sal_Int32 column) ...@@ -420,8 +414,7 @@ uno::Reference<XBlob> SAL_CALL OResultSet::getBlob(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getBlob", *this); mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getBlob", *this);
return nullptr; return nullptr;
...@@ -431,8 +424,7 @@ uno::Reference<XRef> SAL_CALL OResultSet::getRef(sal_Int32 column) ...@@ -431,8 +424,7 @@ uno::Reference<XRef> SAL_CALL OResultSet::getRef(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getRef", *this); mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getRef", *this);
return nullptr; return nullptr;
...@@ -443,8 +435,7 @@ Any SAL_CALL OResultSet::getObject(sal_Int32 column, ...@@ -443,8 +435,7 @@ Any SAL_CALL OResultSet::getObject(sal_Int32 column,
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
Any aRet = Any(); Any aRet = Any();
...@@ -456,8 +447,7 @@ sal_Int16 SAL_CALL OResultSet::getShort(sal_Int32 column) ...@@ -456,8 +447,7 @@ sal_Int16 SAL_CALL OResultSet::getShort(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return 0; return 0;
...@@ -469,8 +459,7 @@ rtl::OUString SAL_CALL OResultSet::getString(sal_Int32 column) ...@@ -469,8 +459,7 @@ rtl::OUString SAL_CALL OResultSet::getString(sal_Int32 column)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return rtl::OUString{}; return rtl::OUString{};
...@@ -482,9 +471,8 @@ Time SAL_CALL OResultSet::getTime(sal_Int32 column) ...@@ -482,9 +471,8 @@ Time SAL_CALL OResultSet::getTime(sal_Int32 column)
{ {
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkBordersAndEnsureFetched(column);
checkColumnIndex(column);
checkRowIndex();
Time t; Time t;
if (checkNull(column)) if (checkNull(column))
return t; return t;
...@@ -520,8 +508,7 @@ DateTime SAL_CALL OResultSet::getTimestamp(sal_Int32 column) ...@@ -520,8 +508,7 @@ DateTime SAL_CALL OResultSet::getTimestamp(sal_Int32 column)
{ {
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkColumnIndex(column); checkBordersAndEnsureFetched(column);
checkRowIndex();
if (checkNull(column)) if (checkNull(column))
return DateTime{}; return DateTime{};
...@@ -558,6 +545,7 @@ sal_Bool SAL_CALL OResultSet::isAfterLast() ...@@ -558,6 +545,7 @@ sal_Bool SAL_CALL OResultSet::isAfterLast()
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
return m_nRowPosition >= m_nRowCount; return m_nRowPosition >= m_nRowCount;
} }
...@@ -566,6 +554,7 @@ sal_Bool SAL_CALL OResultSet::isFirst() ...@@ -566,6 +554,7 @@ sal_Bool SAL_CALL OResultSet::isFirst()
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
return m_nRowPosition == 0 && !isAfterLast(); return m_nRowPosition == 0 && !isAfterLast();
} }
...@@ -574,6 +563,7 @@ sal_Bool SAL_CALL OResultSet::isLast() ...@@ -574,6 +563,7 @@ sal_Bool SAL_CALL OResultSet::isLast()
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
return m_nRowPosition == m_nRowCount - 1; return m_nRowPosition == m_nRowCount - 1;
} }
...@@ -589,6 +579,7 @@ void SAL_CALL OResultSet::afterLast() ...@@ -589,6 +579,7 @@ void SAL_CALL OResultSet::afterLast()
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
m_nRowPosition = m_nRowCount; m_nRowPosition = m_nRowCount;
} }
...@@ -614,7 +605,7 @@ sal_Bool SAL_CALL OResultSet::last() ...@@ -614,7 +605,7 @@ sal_Bool SAL_CALL OResultSet::last()
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureResultFetched(); ensureFieldInfoFetched();
m_nRowPosition = m_nRowCount - 1; m_nRowPosition = m_nRowCount - 1;
return true; return true;
...@@ -624,6 +615,7 @@ sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 row) ...@@ -624,6 +615,7 @@ sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 row)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
sal_Int32 nToGo = row < 0 ? (m_nRowCount - 1) - row : row - 1; sal_Int32 nToGo = row < 0 ? (m_nRowCount - 1) - row : row - 1;
...@@ -641,6 +633,7 @@ sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row) ...@@ -641,6 +633,7 @@ sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row)
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureFieldInfoFetched();
if (row == 0) if (row == 0)
return true; return true;
...@@ -704,7 +697,7 @@ sal_Bool SAL_CALL OResultSet::next() ...@@ -704,7 +697,7 @@ sal_Bool SAL_CALL OResultSet::next()
{ {
MutexGuard aGuard(m_aMutex); MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed); checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
ensureResultFetched(); ensureFieldInfoFetched();
if (m_nRowPosition + 1 > m_nRowCount) // afterlast if (m_nRowPosition + 1 > m_nRowCount) // afterlast
return false; return false;
if (m_nRowPosition + 1 == m_nRowCount) // last if (m_nRowPosition + 1 == m_nRowCount) // last
...@@ -1113,4 +1106,11 @@ void OResultSet::checkColumnIndex(sal_Int32 index) ...@@ -1113,4 +1106,11 @@ void OResultSet::checkColumnIndex(sal_Int32 index)
} }
} }
void OResultSet::checkBordersAndEnsureFetched(sal_Int32 index)
{
ensureResultFetched();
checkColumnIndex(index);
checkRowIndex();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -102,8 +102,30 @@ class OResultSet final : public OBase_Mutex, ...@@ -102,8 +102,30 @@ class OResultSet final : public OBase_Mutex,
virtual ~OResultSet() override = default; virtual ~OResultSet() override = default;
/**
* Ensures that the results of the query has already been fetched.
*/
void ensureResultFetched(); void ensureResultFetched();
/**
* Ensures that meta data of the corresponding result set has been already
* queried. It should be called before freeing the result set, unless the
* information is lost.
*/
void ensureFieldInfoFetched(); void ensureFieldInfoFetched();
/**
* Check the following things:
* - cursor is out of range. Throws expception if true.
* - column index is out of range. Throws exception if true.
* - result set is fetched. If no, then it fetches the result.
*/
void checkBordersAndEnsureFetched(sal_Int32 index);
/**
* Fetches all the data from the MYSQL_RES object related to the class. It
* frees the MYSQL_RES object afterwards, so it cannot be used anymore.
*/
void fetchResult(); void fetchResult();
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment