connectivity/qa/connectivity/mysql/mysql.cxx | 2 + connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx | 29 +++++++++++----- connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx | 4 +- 3 files changed, 24 insertions(+), 11 deletions(-)
New commits: commit 7ca071120941f04b97e4d855102e88e87fe4cfa5 Author: Tamas Bunth <tamas.bu...@collabora.co.uk> AuthorDate: Mon Dec 10 10:43:14 2018 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Fri Dec 14 21:22:51 2018 +0100 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> diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx index f5e878590363..1a6d1e89e0e8 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 392a037b3ed3..2c680d7e1328 100644 --- a/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx +++ b/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx @@ -136,6 +136,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. @@ -145,20 +157,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]) }); } @@ -204,11 +214,12 @@ sal_Int32 SAL_CALL OResultSet::findColumn(const rtl::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, @@ -1094,7 +1105,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, rtl::OUString(), 1, Any()); diff --git a/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx b/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx index 7e19f9946f5a..75311d3dd4d0 100644 --- a/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx +++ b/connectivity/source/drivers/mysqlc/mysqlc_resultset.hxx @@ -66,12 +66,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; @@ -104,6 +103,7 @@ class OResultSet final : public OBase_Mutex, virtual ~OResultSet() override = default; void ensureResultFetched(); + void ensureFieldInfoFetched(); void fetchResult(); public: _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits