connectivity/qa/connectivity/mysql/mysql.cxx | 13 ++++- connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx | 37 +++++++++++----- connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx | 4 - 3 files changed, 40 insertions(+), 14 deletions(-)
New commits: commit 366915de3f1f123b345eebbeb3a4646d69ae72da Author: Tamas Bunth <tamas.bu...@collabora.co.uk> AuthorDate: Mon Dec 10 10:43:14 2018 +0100 Commit: Tamás Bunth <btom...@gmail.com> CommitDate: Thu Aug 1 13:50:31 2019 +0200 mysqlc: Fix obtaining field information in rs Result set field information should be stored correctly. It is queried from database on demand and stored locally. Change-Id: Ia62c62e6db32b45640b9fcd5f48c6249aecc41a2 Reviewed-on: https://gerrit.libreoffice.org/64861 Tested-by: Jenkins Reviewed-by: Tamás Bunth <btom...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/65160 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/76724 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx index 16172439df0f..24436641fe6c 100644 --- a/connectivity/qa/connectivity/mysql/mysql.cxx +++ b/connectivity/qa/connectivity/mysql/mysql.cxx @@ -165,6 +165,7 @@ void MysqlTestDriver::testIntegerInsertAndQuery() Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT id from myTestTable"); CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is()); Reference<XRow> xRow(xResultSet, UNO_QUERY); + Reference<XColumnLocate> xColumnLocate(xResultSet, UNO_QUERY); CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is()); for (long i = 0; i < ROW_COUNT; ++i) @@ -172,6 +173,7 @@ void MysqlTestDriver::testIntegerInsertAndQuery() bool hasRow = xResultSet->next(); CPPUNIT_ASSERT_MESSAGE("not enough result after query", hasRow); CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(1)); // first and only column + CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(xColumnLocate->findColumn("id"))); // test findColumn } CPPUNIT_ASSERT_MESSAGE("Cursor is not on last position.", xResultSet->isLast()); // cursor is on last position diff --git a/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx b/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx index 5ee7aa943206..d6c2a9b724b4 100644 --- a/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx +++ b/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx @@ -134,6 +134,18 @@ void OResultSet::ensureResultFetched() } } +void OResultSet::ensureFieldInfoFetched() +{ + if (!m_aFields.empty()) + return; + unsigned nFieldCount = mysql_num_fields(m_pResult); + MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult); + m_aFields.reserve(nFieldCount); + for (unsigned i = 0; i < nFieldCount; ++i) + m_aFields.push_back(OUString{ + pFields[i].name, static_cast<sal_Int32>(strlen(pFields[i].name)), m_encoding }); +} + void OResultSet::fetchResult() { // Mysql C API does not allow simultaneously opened result sets, but sdbc does. @@ -143,20 +155,18 @@ void OResultSet::fetchResult() // TODO ensure that m_nRowCount = mysql_num_rows(m_pResult); + ensureFieldInfoFetched(); + // fetch all the data m_aRows.reserve(m_nRowCount); - m_nFieldCount = mysql_num_fields(m_pResult); - MYSQL_FIELD* pFields = mysql_fetch_fields(m_pResult); - m_aFields.assign(pFields, pFields + m_nFieldCount); - for (sal_Int32 row = 0; row < m_nRowCount; ++row) { MYSQL_ROW data = mysql_fetch_row(m_pResult); unsigned long* lengths = mysql_fetch_lengths(m_pResult); m_aRows.push_back(DataFields{}); // MYSQL_ROW is char**, array of strings - for (unsigned col = 0; col < m_nFieldCount; ++col) + for (std::size_t col = 0; col < m_aFields.size(); ++col) { m_aRows.back().push_back(OString{ data[col], static_cast<sal_Int32>(lengths[col]) }); } @@ -202,11 +212,12 @@ sal_Int32 SAL_CALL OResultSet::findColumn(const OUString& columnName) { MutexGuard aGuard(m_aMutex); checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + ensureFieldInfoFetched(); - for (unsigned int i = 0; i < m_nFieldCount; ++i) + for (std::size_t i = 0; i < m_aFields.size(); ++i) { - if (columnName.equalsIgnoreAsciiCaseAscii(m_aFields[i].name)) - return i + 1; // sdbc indexes from 1 + if (columnName.equalsIgnoreAsciiCase(m_aFields[i])) + return static_cast<sal_Int32>(i) + 1; // sdbc indexes from 1 } throw SQLException("The column name '" + columnName + "' is not valid.", *this, "42S22", 0, @@ -1092,7 +1103,7 @@ css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OResultSet::getProper void OResultSet::checkColumnIndex(sal_Int32 index) { - if (index < 1 || index > static_cast<int>(m_nFieldCount)) + if (index < 1 || index > static_cast<int>(m_aFields.size())) { /* static object for efficiency or thread safety is a problem ? */ throw SQLException("index out of range", *this, OUString(), 1, Any()); diff --git a/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx b/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx index e3fb1994cc15..d3afafbdb6cc 100644 --- a/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx +++ b/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx @@ -64,12 +64,11 @@ class OResultSet final : public OBase_Mutex, { using DataFields = std::vector<OString>; std::vector<DataFields> m_aRows; - std::vector<MYSQL_FIELD> m_aFields; + std::vector<OUString> m_aFields; MYSQL* m_pMysql = nullptr; css::uno::WeakReferenceHelper m_aStatement; css::uno::Reference<css::sdbc::XResultSetMetaData> m_xMetaData; MYSQL_RES* m_pResult; - unsigned int m_nFieldCount = 0; rtl_TextEncoding m_encoding; bool m_bWasNull = false; // did the last getXXX result null? bool m_bResultFetched = false; @@ -101,6 +100,7 @@ class OResultSet final : public OBase_Mutex, virtual ~OResultSet() override = default; void ensureResultFetched(); + void ensureFieldInfoFetched(); void fetchResult(); public: commit cc59dd1a89ca83ad730929d157b737276fcff843 Author: Tamas Bunth <tamas.bu...@collabora.co.uk> AuthorDate: Fri Nov 23 18:31:37 2018 +0100 Commit: Tamás Bunth <btom...@gmail.com> CommitDate: Thu Aug 1 13:50:24 2019 +0200 mysqlc: next() should move cursor from Last XResultSet::next() should move cursor when called while cursor is on the last position. It is not documented, but older versions of the mysqlc extension are implemented that way. The cursor goes to the so called afterlast position. Even so, the next() call on the last position should return false. Change-Id: I0fd145c920077151364a6a8c12e05290496b99c8 Reviewed-on: https://gerrit.libreoffice.org/63895 Tested-by: Jenkins Reviewed-by: Tamás Bunth <btom...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/64017 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/76723 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx index 44488848b5d6..16172439df0f 100644 --- a/connectivity/qa/connectivity/mysql/mysql.cxx +++ b/connectivity/qa/connectivity/mysql/mysql.cxx @@ -173,9 +173,16 @@ void MysqlTestDriver::testIntegerInsertAndQuery() CPPUNIT_ASSERT_MESSAGE("not enough result after query", hasRow); CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(1)); // first and only column } - bool hasRow = xResultSet->next(); - // no more rows + CPPUNIT_ASSERT_MESSAGE("Cursor is not on last position.", + xResultSet->isLast()); // cursor is on last position + CPPUNIT_ASSERT_EQUAL(ROW_COUNT, xResultSet->getRow()); // which is the last position + + bool hasRow = xResultSet->next(); // go to afterlast + // no more rows, next should return false CPPUNIT_ASSERT_MESSAGE("next returns true after last row", !hasRow); + // cursor should be in afterlast position + CPPUNIT_ASSERT_EQUAL(ROW_COUNT + 1, xResultSet->getRow()); + CPPUNIT_ASSERT_MESSAGE("Cursor is not on after-last position.", xResultSet->isAfterLast()); nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable"); CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement diff --git a/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx b/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx index f0f83e42c3a7..5ee7aa943206 100644 --- a/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx +++ b/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx @@ -691,8 +691,14 @@ sal_Bool SAL_CALL OResultSet::next() MutexGuard aGuard(m_aMutex); checkDisposed(OResultSet_BASE::rBHelper.bDisposed); ensureResultFetched(); - if (m_nRowPosition + 1 >= m_nRowCount) + if (m_nRowPosition + 1 > m_nRowCount) // afterlast return false; + if (m_nRowPosition + 1 == m_nRowCount) // last + { + // return false but take it to afterlast anyway + ++m_nRowPosition; + return false; + } ++m_nRowPosition; return true; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits