[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 2 commits - connectivity/qa connectivity/source

Tamas Bunth (via logerrit) logerrit at kemper.freedesktop.org
Fri Aug 2 14:49:48 UTC 2019


 connectivity/qa/connectivity/mysql/mysql.cxx                    |   84 ++++++++
 connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx  |    2 
 connectivity/source/drivers/mysqlc/mysqlc_general.cxx           |   26 +-
 connectivity/source/drivers/mysqlc/mysqlc_general.hxx           |    4 
 connectivity/source/drivers/mysqlc/mysqlc_preparedstatement.cxx |    2 
 connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx         |    9 
 connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.cxx |   99 +++++-----
 connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.hxx |   31 +--
 8 files changed, 182 insertions(+), 75 deletions(-)

New commits:
commit 3d5adeab32a1b40dff203face30223ce7d298c26
Author:     Tamas Bunth <tamas.bunth at collabora.co.uk>
AuthorDate: Tue Jan 22 13:06:45 2019 +0100
Commit:     Tamás Bunth <btomi96 at gmail.com>
CommitDate: Fri Aug 2 16:49:13 2019 +0200

    mysqlc: resultset's previous() on first position..
    
    .. should move the cursor backwards to beforeFirst position and return
    false.
    
    Change-Id: Icbb4bed0ea39ea3a0bf375d5616e3ef768fc69d9
    Reviewed-on: https://gerrit.libreoffice.org/66730
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/76729
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>

diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx
index 414a0de569e2..77e82c9cdfc5 100644
--- a/connectivity/qa/connectivity/mysql/mysql.cxx
+++ b/connectivity/qa/connectivity/mysql/mysql.cxx
@@ -241,6 +241,12 @@ void MysqlTestDriver::testDBPositionChange()
     xResultSet->first();
     CPPUNIT_ASSERT_EQUAL(1, xResultSet->getRow());
 
+    // Now previous should put the cursor to before-first position, but it
+    // should return with false.
+    successPrevious = xResultSet->previous();
+    CPPUNIT_ASSERT(!successPrevious);
+    CPPUNIT_ASSERT_EQUAL(0, xResultSet->getRow());
+
     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 be02c7c73ee3..1d93aa952383 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_resultset.cxx
@@ -659,8 +659,15 @@ sal_Bool SAL_CALL OResultSet::previous()
     MutexGuard aGuard(m_aMutex);
     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
 
-    if (m_nRowPosition <= 0)
+    if (m_nRowPosition == 0)
+    {
+        m_nRowPosition--;
         return false;
+    }
+    else if (m_nRowPosition < 0)
+    {
+        return false;
+    }
 
     m_nRowPosition--;
     return true;
commit 4348e54817da8b8b4348935fff74ca9d8b7ab4e0
Author:     Tamas Bunth <tamas.bunth at collabora.co.uk>
AuthorDate: Sat Dec 29 15:22:56 2018 +0100
Commit:     Tamás Bunth <btomi96 at gmail.com>
CommitDate: Fri Aug 2 16:49:03 2019 +0200

    mysqlc: Fix result set metadata related issue
    
    In order to allow fetching result of multiple result sets at time same
    time, all the data is fetched and copied on demand from the mysql result
    set. The mysql result set (MYSQL_RES) is freed afterwards.
    
    That means we need a copy of the meta information as well. Now all the
    meta data is stored in the driver for each result set, so it does not
    depend on the MYSQL_RES structure anymore.
    
    Also add test case for invoking some meta data queries before and after
    fetching the result set.
    
    Change-Id: Ie8bf993926ebe89cd362ab0b311d1f3d164b84df
    Reviewed-on: https://gerrit.libreoffice.org/65855
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/76726
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>

diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx
index 24436641fe6c..414a0de569e2 100644
--- a/connectivity/qa/connectivity/mysql/mysql.cxx
+++ b/connectivity/qa/connectivity/mysql/mysql.cxx
@@ -13,7 +13,10 @@
 #include <com/sun/star/sdbc/XColumnLocate.hpp>
 #include <com/sun/star/sdbc/XConnection.hpp>
 #include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
 #include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
 #include <com/sun/star/sdbc/XParameters.hpp>
 #include <com/sun/star/sdbc/XStatement.hpp>
 #include <com/sun/star/sdbc/XDriver.hpp>
@@ -44,11 +47,15 @@ public:
     void testCreateAndDropTable();
     void testIntegerInsertAndQuery();
     void testDBPositionChange();
+    void testMultipleResultsets();
+    void testDBMetaData();
 
     CPPUNIT_TEST_SUITE(MysqlTestDriver);
     CPPUNIT_TEST(testDBConnection);
     CPPUNIT_TEST(testCreateAndDropTable);
     CPPUNIT_TEST(testIntegerInsertAndQuery);
+    CPPUNIT_TEST(testMultipleResultsets);
+    CPPUNIT_TEST(testDBMetaData);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -238,6 +245,77 @@ void MysqlTestDriver::testDBPositionChange()
     CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
 }
 
+void MysqlTestDriver::testMultipleResultsets()
+{
+    Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+    CPPUNIT_ASSERT(xConnection.is());
+    Reference<XStatement> xStatement = xConnection->createStatement();
+    CPPUNIT_ASSERT(xStatement.is());
+    // create two tables
+    xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+    xStatement->executeUpdate("DROP TABLE IF EXISTS otherTable");
+    xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)");
+    xStatement->executeUpdate("INSERT INTO myTestTable VALUES (1)");
+    xStatement->executeUpdate("CREATE TABLE otherTable (id INTEGER PRIMARY KEY)");
+    xStatement->executeUpdate("INSERT INTO otherTable VALUES (2)");
+
+    // create first result set
+    Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT id from myTestTable");
+    CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is());
+    // use it
+    xResultSet->next();
+    Reference<XRow> xRowFirst(xResultSet, UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(1l, xRowFirst->getLong(1));
+    // create second result set
+    Reference<XResultSet> xResultSet2 = xStatement->executeQuery("SELECT id from otherTable");
+    // use second result set
+    xResultSet2->next();
+    Reference<XRow> xRowSecond(xResultSet2, UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(2l, xRowSecond->getLong(1));
+    // now use the first result set again
+    CPPUNIT_ASSERT_EQUAL(1l, xRowFirst->getLong(1));
+
+    xStatement->executeUpdate("DROP TABLE myTestTable");
+    xStatement->executeUpdate("DROP TABLE otherTable");
+}
+
+void MysqlTestDriver::testDBMetaData()
+{
+    Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+    if (!xConnection.is())
+        CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+    uno::Reference<XStatement> xStatement = xConnection->createStatement();
+    CPPUNIT_ASSERT(xStatement.is());
+    xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+    auto nUpdateCount = xStatement->executeUpdate(
+        "CREATE TABLE myTestTable (id INTEGER PRIMARY KEY, name VARCHAR(20))");
+    Reference<XPreparedStatement> xPrepared
+        = xConnection->prepareStatement(OUString{ "INSERT INTO myTestTable VALUES (?, ?)" });
+    Reference<XParameters> xParams(xPrepared, UNO_QUERY);
+    constexpr int ROW_COUNT = 3;
+    for (int i = 0; i < ROW_COUNT; ++i)
+    {
+        xParams->setLong(1, i);
+        xParams->setString(2, "lorem");
+        xPrepared->executeUpdate();
+    }
+
+    Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT * from myTestTable");
+    Reference<XResultSetMetaDataSupplier> xMetaDataSupplier(xResultSet, UNO_QUERY);
+    Reference<XResultSetMetaData> xMetaData = xMetaDataSupplier->getMetaData();
+    CPPUNIT_ASSERT_EQUAL(OUString{ "id" }, xMetaData->getColumnName(1));
+    CPPUNIT_ASSERT_EQUAL(OUString{ "name" }, xMetaData->getColumnName(2));
+    CPPUNIT_ASSERT(!xMetaData->isAutoIncrement(1));
+    CPPUNIT_ASSERT(!xMetaData->isCaseSensitive(2)); // default collation should be case insensitive
+    xResultSet->next(); // use it
+    // test that meta data is usable even after fetching result set
+    CPPUNIT_ASSERT_EQUAL(OUString{ "name" }, xMetaData->getColumnName(2));
+    CPPUNIT_ASSERT_THROW_MESSAGE("exception expected when indexing out of range",
+                                 xMetaData->getColumnName(3), sdbc::SQLException);
+    nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable");
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(MysqlTestDriver);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx b/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
index f4355ae7a169..736fa20d1f40 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
@@ -45,6 +45,8 @@ using namespace com::sun::star::lang;
 using namespace com::sun::star::beans;
 using namespace com::sun::star::sdbc;
 
+#include <sal/macros.h>
+
 static std::string wild("%");
 
 static void lcl_setRows_throw(const Reference<XResultSet>& _xResultSet, sal_Int32 _nType,
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_general.cxx b/connectivity/source/drivers/mysqlc/mysqlc_general.cxx
index f5b20cb55715..59ca48d3329a 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_general.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_general.cxx
@@ -109,8 +109,8 @@ void throwSQLExceptionWithMsg(const char* msg, unsigned int errorNum,
 {
     OString errorMsg{ msg };
     // TODO error code?
-    throw SQLException(OStringToOUString(errorMsg, encoding), _context, OUString(), errorNum,
-                       Any());
+    throw SQLException(rtl::OStringToOUString(errorMsg, encoding), _context, rtl::OUString(),
+                       errorNum, Any());
 }
 
 sal_Int32 mysqlToOOOType(int eType, int charsetnr) noexcept
@@ -225,11 +225,13 @@ sal_Int32 mysqlStrToOOOType(const OUString& sType)
     return css::sdbc::DataType::VARCHAR;
 }
 
-OUString mysqlTypeToStr(MYSQL_FIELD* field)
+OUString mysqlTypeToStr(MYSQL_FIELD* field) { return mysqlTypeToStr(field->type, field->flags); }
+
+OUString mysqlTypeToStr(unsigned type, unsigned flags)
 {
-    bool isUnsigned = (field->flags & UNSIGNED_FLAG) != 0;
-    bool isZerofill = (field->flags & ZEROFILL_FLAG) != 0;
-    switch (field->type)
+    bool isUnsigned = (flags & UNSIGNED_FLAG) != 0;
+    bool isZerofill = (flags & ZEROFILL_FLAG) != 0;
+    switch (type)
     {
         case MYSQL_TYPE_BIT:
             return OUString{ "BIT" };
@@ -294,21 +296,21 @@ OUString mysqlTypeToStr(MYSQL_FIELD* field)
         }
         case MYSQL_TYPE_VARCHAR:
         case MYSQL_TYPE_VAR_STRING:
-            if (field->flags & ENUM_FLAG)
+            if (flags & ENUM_FLAG)
             {
                 return OUString{ "ENUM" };
             }
-            if (field->flags & SET_FLAG)
+            if (flags & SET_FLAG)
             {
                 return OUString{ "SET" };
             }
             return OUString{ "VARCHAR" };
         case MYSQL_TYPE_STRING:
-            if (field->flags & ENUM_FLAG)
+            if (flags & ENUM_FLAG)
             {
                 return OUString{ "ENUM" };
             }
-            if (field->flags & SET_FLAG)
+            if (flags & SET_FLAG)
             {
                 return OUString{ "SET" };
             }
@@ -322,9 +324,9 @@ OUString mysqlTypeToStr(MYSQL_FIELD* field)
     }
 }
 
-OUString convert(const ::std::string& _string, const rtl_TextEncoding encoding)
+rtl::OUString convert(const ::std::string& _string, const rtl_TextEncoding encoding)
 {
-    return OUString(_string.c_str(), _string.size(), encoding);
+    return rtl::OUString(_string.c_str(), _string.size(), encoding);
 }
 
 } /* namespace */
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_general.hxx b/connectivity/source/drivers/mysqlc/mysqlc_general.hxx
index a7886c3015d2..f8d866964318 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_general.hxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_general.hxx
@@ -92,12 +92,10 @@ void resetSqlVar(void** target, T* pValue, enum_field_types type, sal_Int32 nSiz
 
 void allocateSqlVar(void** mem, enum_field_types eType, unsigned nSize = 0);
 
-/// @throws css::sdbc::SQLException
 void throwFeatureNotImplementedException(
     const sal_Char* _pAsciiFeatureName,
     const css::uno::Reference<css::uno::XInterface>& _rxContext);
 
-/// @throws css::sdbc::SQLException
 void throwInvalidArgumentException(const sal_Char* _pAsciiFeatureName,
                                    const css::uno::Reference<css::uno::XInterface>& _rxContext);
 
@@ -109,6 +107,8 @@ sal_Int32 mysqlToOOOType(int eType, int charsetnr) noexcept;
 
 OUString mysqlTypeToStr(MYSQL_FIELD* pField);
 
+OUString mysqlTypeToStr(unsigned mysql_type, unsigned mysql_flags);
+
 sal_Int32 mysqlStrToOOOType(const OUString& sType);
 
 OUString convert(const ::std::string& _string, const rtl_TextEncoding encoding);
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_preparedstatement.cxx b/connectivity/source/drivers/mysqlc/mysqlc_preparedstatement.cxx
index 9b687f74e8ad..e340a0774342 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_preparedstatement.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_preparedstatement.cxx
@@ -108,7 +108,7 @@ Reference<XResultSetMetaData> SAL_CALL OPreparedStatement::getMetaData()
     {
         MYSQL_RES* pRes = mysql_stmt_result_metadata(m_pStmt);
         // TODO warning or error if no meta data.
-        m_xMetaData = new OResultSetMetaData(*m_xConnection, pRes);
+        m_xMetaData = new OResultSetMetaData(*m_xConnection.get(), pRes);
     }
     return m_xMetaData;
 }
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.cxx b/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.cxx
index f5962a2a54ff..ba8c36da83ce 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.cxx
@@ -23,41 +23,61 @@
 
 #include <com/sun/star/sdbc/XRow.hpp>
 #include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
 
 using namespace connectivity::mysqlc;
 using namespace com::sun::star::uno;
 using namespace com::sun::star::lang;
 using namespace com::sun::star::sdbc;
 
-MYSQL_FIELD* OResultSetMetaData::getField(sal_Int32 column) const
+OResultSetMetaData::OResultSetMetaData(OConnection& rConn, MYSQL_RES* pResult)
+    : m_rConnection(rConn)
 {
-    return mysql_fetch_field_direct(m_pRes, column - 1);
+    MYSQL_FIELD* fields = mysql_fetch_field(pResult);
+    unsigned nFieldCount = mysql_num_fields(pResult);
+    for (unsigned i = 0; i < nFieldCount; ++i)
+    {
+        MySqlFieldInfo fieldInfo{
+            OUString{ fields[i].name, static_cast<sal_Int32>(fields[i].name_length),
+                      m_rConnection.getConnectionEncoding() }, // column name
+            static_cast<sal_Int32>(fields[i].length), // length
+            mysqlc_sdbc_driver::mysqlToOOOType(fields[i].type, fields[i].charsetnr), // type
+            fields[i].type, // mysql_type
+            fields[i].charsetnr, // charset number
+            fields[i].flags,
+            OUString{ fields[i].db, static_cast<sal_Int32>(fields[i].db_length),
+                      m_rConnection.getConnectionEncoding() }, // schema name
+            OUString{ fields[i].table, static_cast<sal_Int32>(fields[i].table_length),
+                      m_rConnection.getConnectionEncoding() }, // table name
+            OUString{ fields[i].catalog, static_cast<sal_Int32>(fields[i].catalog_length),
+                      m_rConnection.getConnectionEncoding() }, // catalog
+            static_cast<sal_Int32>(fields[i].decimals),
+            static_cast<sal_Int32>(fields[i].max_length)
+        };
+        m_fields.push_back(std::move(fieldInfo));
+    }
 }
 
 sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize(sal_Int32 column)
 {
-    MYSQL_FIELD* pField = getField(column);
-    return pField->length;
+    checkColumnIndex(column);
+    return m_fields.at(column - 1).length;
 }
 
 sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-
-    return mysqlc_sdbc_driver::mysqlToOOOType(pField->type, pField->charsetnr);
+    return m_fields.at(column - 1).type;
 }
 
-sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount() { return mysql_num_fields(m_pRes); }
+sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount() { return m_fields.size(); }
 
 sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive(sal_Int32 column)
 {
-    checkColumnIndex(column);
     //   MYSQL_FIELD::charsetnr is the collation identifier
     //   _ci postfix means it's insensitive
-    MYSQL_FIELD* pField = getField(column);
     OUStringBuffer sql{ "SHOW COLLATION WHERE Id =" };
-    sql.append(OUString::number(pField->charsetnr));
+    sql.append(OUString::number(m_fields.at(column - 1).charsetNumber));
 
     Reference<XStatement> stmt = m_rConnection.createStatement();
     Reference<XResultSet> rs = stmt->executeQuery(sql.makeStringAndClear());
@@ -74,54 +94,43 @@ sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive(sal_Int32 column)
 OUString SAL_CALL OResultSetMetaData::getSchemaName(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-
-    return OStringToOUString(pField->db, m_rConnection.getConnectionEncoding());
+    return m_fields.at(column - 1).schemaName;
 }
 
 OUString SAL_CALL OResultSetMetaData::getColumnName(sal_Int32 column)
 {
     checkColumnIndex(column);
-
-    MYSQL_FIELD* pField = getField(column);
-    return OStringToOUString(pField->name, m_rConnection.getConnectionEncoding());
+    return m_fields.at(column - 1).columnName;
 }
 
 OUString SAL_CALL OResultSetMetaData::getTableName(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return OStringToOUString(pField->table, m_rConnection.getConnectionEncoding());
+    return m_fields.at(column - 1).tableName;
 }
 
 OUString SAL_CALL OResultSetMetaData::getCatalogName(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return OStringToOUString(pField->catalog, m_rConnection.getConnectionEncoding());
+    return m_fields.at(column - 1).catalogName;
 }
 
 OUString SAL_CALL OResultSetMetaData::getColumnTypeName(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-
-    return mysqlc_sdbc_driver::mysqlTypeToStr(pField);
+    return mysqlc_sdbc_driver::mysqlTypeToStr(m_fields.at(column - 1).mysql_type,
+                                              m_fields.at(column - 1).flags);
 }
 
 OUString SAL_CALL OResultSetMetaData::getColumnLabel(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return OStringToOUString(pField->name, m_rConnection.getConnectionEncoding());
+    return getColumnName(column);
 }
 
-OUString SAL_CALL OResultSetMetaData::getColumnServiceName(sal_Int32 column)
+OUString SAL_CALL OResultSetMetaData::getColumnServiceName(sal_Int32 /*column*/)
 {
-    checkColumnIndex(column);
-
-    OUString aRet = OUString();
-    return aRet;
+    return OUString{};
 }
 
 sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32 /*column*/)
@@ -132,47 +141,43 @@ sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32 /*column*/)
 sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement(sal_Int32 column)
 {
     checkColumnIndex(column);
-
-    MYSQL_FIELD* pField = getField(column);
-    return (pField->flags & AUTO_INCREMENT_FLAG) != 0;
+    return (m_fields.at(column - 1).flags & AUTO_INCREMENT_FLAG) != 0;
 }
 
 sal_Bool SAL_CALL OResultSetMetaData::isSigned(sal_Int32 column)
 {
     checkColumnIndex(column);
-
-    MYSQL_FIELD* pField = getField(column);
-    return !(pField->flags & UNSIGNED_FLAG);
+    return !(m_fields.at(column - 1).flags & UNSIGNED_FLAG);
 }
 
 sal_Int32 SAL_CALL OResultSetMetaData::getPrecision(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return pField->max_length - pField->decimals;
+    return m_fields.at(column - 1).max_length - m_fields.at(column - 1).decimals;
 }
 
 sal_Int32 SAL_CALL OResultSetMetaData::getScale(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return pField->decimals;
+    return m_fields.at(column - 1).decimals;
 }
 
 sal_Int32 SAL_CALL OResultSetMetaData::isNullable(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return (pField->flags & NOT_NULL_FLAG) ? 0 : 1;
+    return (m_fields.at(column - 1).flags & NOT_NULL_FLAG) ? 0 : 1;
 }
 
-sal_Bool SAL_CALL OResultSetMetaData::isSearchable(sal_Int32 /*column*/) { return true; }
+sal_Bool SAL_CALL OResultSetMetaData::isSearchable(sal_Int32 column)
+{
+    checkColumnIndex(column);
+    return true;
+}
 
 sal_Bool SAL_CALL OResultSetMetaData::isReadOnly(sal_Int32 column)
 {
     checkColumnIndex(column);
-    MYSQL_FIELD* pField = getField(column);
-    return !(pField->db && strlen(pField->db));
+    return m_fields.at(column - 1).schemaName.isEmpty();
 }
 
 sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable(sal_Int32 column)
@@ -189,7 +194,7 @@ sal_Bool SAL_CALL OResultSetMetaData::isWritable(sal_Int32 column)
 
 void OResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex)
 {
-    unsigned nColCount = mysql_num_fields(m_pRes);
+    auto nColCount = m_fields.size();
     if (columnIndex < 1 || columnIndex > static_cast<sal_Int32>(nColCount))
     {
         OUStringBuffer buf;
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.hxx b/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.hxx
index 346695def388..5f61499dce98 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.hxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_resultsetmetadata.hxx
@@ -37,6 +37,21 @@ using ::com::sun::star::sdbc::SQLException;
 using ::com::sun::star::uno::RuntimeException;
 using ::com::sun::star::uno::RuntimeException;
 
+struct MySqlFieldInfo
+{
+    OUString columnName;
+    sal_Int32 length = 0;
+    sal_Int32 type = 0;
+    unsigned mysql_type = 0;
+    unsigned charsetNumber = 0;
+    unsigned flags = 0;
+    OUString schemaName;
+    OUString tableName;
+    OUString catalogName;
+    sal_Int32 decimals;
+    sal_Int32 max_length;
+};
+
 //************ Class: ResultSetMetaData
 
 typedef ::cppu::WeakImplHelper1<css::sdbc::XResultSetMetaData> OResultSetMetaData_BASE;
@@ -45,19 +60,15 @@ class OResultSetMetaData final : public OResultSetMetaData_BASE
 {
 private:
     OConnection& m_rConnection;
-    MYSQL_RES* m_pRes;
+    std::vector<MySqlFieldInfo> m_fields;
 
+    void checkColumnIndex(sal_Int32 columnIndex);
     virtual ~OResultSetMetaData() override = default;
-    MYSQL_FIELD* getField(sal_Int32 column) const;
 
 public:
-    OResultSetMetaData(OConnection& rConn, MYSQL_RES* pResult)
-        : m_rConnection(rConn)
-        , m_pRes(pResult)
-    {
-    }
+    OResultSetMetaData(OConnection& rConn, MYSQL_RES* pResult);
 
-    sal_Int32 SAL_CALL getColumnCount() override;
+    sal_Int32 SAL_CALL getColumnCount() SAL_OVERRIDE;
 
     sal_Bool SAL_CALL isAutoIncrement(sal_Int32 column) override;
     sal_Bool SAL_CALL isCaseSensitive(sal_Int32 column) override;
@@ -89,10 +100,6 @@ public:
     sal_Bool SAL_CALL isDefinitelyWritable(sal_Int32 column) override;
 
     OUString SAL_CALL getColumnServiceName(sal_Int32 column) override;
-
-    /// @throws SQLException
-    /// @throws RuntimeException
-    void checkColumnIndex(sal_Int32 columnIndex);
 };
 }
 }


More information about the Libreoffice-commits mailing list