[Libreoffice-commits] core.git: connectivity/source

Lionel Elie Mamane (via logerrit) logerrit at kemper.freedesktop.org
Sat May 9 22:12:26 UTC 2020


 connectivity/source/drivers/mysqlc/mysqlc_connection.cxx       |    3 
 connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx |    2 
 connectivity/source/drivers/mysqlc/mysqlc_statement.cxx        |  104 +++++++---
 connectivity/source/drivers/mysqlc/mysqlc_statement.hxx        |    1 
 4 files changed, 81 insertions(+), 29 deletions(-)

New commits:
commit 86c86719782243275b65f1f7f2cfdcc0e56c8cd4
Author:     Lionel Elie Mamane <lionel at mamane.lu>
AuthorDate: Sat May 9 14:24:03 2020 +0200
Commit:     Lionel Elie Mamane <lionel at mamane.lu>
CommitDate: Sun May 10 00:11:47 2020 +0200

    tdf#112423: mysql-sdbc: implement XMultipleResults
    
    Thanks to Julien Nabet for the pointers to MySQL's multiple results
    API documentation:
    https://dev.mysql.com/doc/refman/8.0/en/c-api-multiple-queries.html
    
    Change-Id: Ia6e7f52752ad895210cc415f71bb48d678f3f0ec
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93686
    Tested-by: Lionel Elie Mamane <lionel at mamane.lu>
    Reviewed-by: Lionel Elie Mamane <lionel at mamane.lu>

diff --git a/connectivity/source/drivers/mysqlc/mysqlc_connection.cxx b/connectivity/source/drivers/mysqlc/mysqlc_connection.cxx
index 045da3b41a77..600e131b89b1 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_connection.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_connection.cxx
@@ -175,7 +175,8 @@ void OConnection::construct(const OUString& url, const Sequence<PropertyValue>&
 
     // flags can also be passed as last parameter
     if (!mysql_real_connect(&m_mysql, host_str.getStr(), user_str.getStr(), pass_str.getStr(),
-                            schema_str.getStr(), nPort, socket_str.getStr(), 0))
+                            schema_str.getStr(), nPort, socket_str.getStr(),
+                            CLIENT_MULTI_STATEMENTS))
         mysqlc_sdbc_driver::throwSQLExceptionWithMsg(
             mysql_error(&m_mysql), mysql_sqlstate(&m_mysql), mysql_errno(&m_mysql), *this,
             getConnectionEncoding());
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx b/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
index 960b6c8875fc..db9b5c6e6b55 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
@@ -271,7 +271,7 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated() { return true; }
 
 sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions() { return true; }
 
-sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets() { return false; }
+sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets() { return true; }
 
 sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause() { return true; }
 
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_statement.cxx b/connectivity/source/drivers/mysqlc/mysqlc_statement.cxx
index c6dab15c4b53..b7073be5e6ec 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_statement.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_statement.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <sal/config.h>
+#include <sal/log.hxx>
 
 #include "mysqlc_connection.hxx"
 #include "mysqlc_propertyids.hxx"
@@ -118,6 +119,9 @@ sal_Bool SAL_CALL OCommonStatement::execute(const OUString& sql)
     MutexGuard aGuard(m_aMutex);
     checkDisposed(rBHelper.bDisposed);
 
+    closeResultSet();
+    m_nAffectedRows = -1;
+
     OString toExec = OUStringToOString(sql, m_xConnection->getConnectionSettings().encoding);
 
     MYSQL* pMySql = m_xConnection->getMysqlConnection();
@@ -127,41 +131,28 @@ sal_Bool SAL_CALL OCommonStatement::execute(const OUString& sql)
     // toExec = mysqlc_sdbc_driver::escapeSql(toExec);
     int failure = mysql_real_query(pMySql, toExec.getStr(), toExec.getLength());
 
-    if (failure)
+    if (failure || mysql_errno(pMySql))
         mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMySql), mysql_sqlstate(pMySql),
                                                      mysql_errno(pMySql), *this,
                                                      m_xConnection->getConnectionEncoding());
-    m_nAffectedRows = mysql_affected_rows(pMySql);
 
-    return !failure;
+    return getResult();
 }
 
 Reference<XResultSet> SAL_CALL OCommonStatement::executeQuery(const OUString& sql)
 {
-    MutexGuard aGuard(m_aMutex);
-    checkDisposed(rBHelper.bDisposed);
-    const OUString sSqlStatement = sql; // TODO m_xConnection->transFormPreparedStatement( sql );
-    OString toExec
-        = OUStringToOString(sSqlStatement, m_xConnection->getConnectionSettings().encoding);
-
-    MYSQL* pMySql = m_xConnection->getMysqlConnection();
-    // toExec = mysqlc_sdbc_driver::escapeSql(toExec);
-    int failure = mysql_real_query(pMySql, toExec.getStr(), toExec.getLength());
-    if (failure)
-        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMySql), mysql_sqlstate(pMySql),
-                                                     mysql_errno(pMySql), *this,
-                                                     m_xConnection->getConnectionEncoding());
+    bool isRS(execute(sql));
+    // if a MySQL error occurred, it was already thrown and the below is not executed
+    assert(isRS == m_xResultSet.is());
+    if (!isRS)
+        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(
+            "executeQuery called on SQL command that does not return a ResultSet", "02000", 0,
+            *this);
+    if (!m_xResultSet.is())
+        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(
+            "internal MySQL-SDBC error: executeQuery: no ResultSet after execute() returned true.",
+            "02000", 0, *this);
 
-    MYSQL_RES* pMysqlResult = mysql_store_result(pMySql);
-    if (pMysqlResult == nullptr)
-    {
-        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMySql), mysql_sqlstate(pMySql),
-                                                     mysql_errno(pMySql), *this,
-                                                     m_xConnection->getConnectionEncoding());
-    }
-
-    m_xResultSet = new OResultSet(*getOwnConnection(), this, pMysqlResult,
-                                  m_xConnection->getConnectionEncoding());
     return m_xResultSet;
 }
 
@@ -219,9 +210,68 @@ Reference<XResultSet> SAL_CALL OCommonStatement::getResultSet()
     return m_xResultSet;
 }
 
+sal_Bool OCommonStatement::getResult()
+{
+    // all callers already reset that
+    assert(!m_xResultSet.is());
+    assert(m_nAffectedRows == -1);
+
+    MYSQL* pMySql = m_xConnection->getMysqlConnection();
+    MYSQL_RES* pMysqlResult = mysql_store_result(pMySql);
+    if (pMysqlResult != nullptr)
+    {
+        // MariaDB/MySQL will return the number of rows in the ResultSet from mysql_affected_rows();
+        // sdbc mandates -1 when the command (query) returns a ResultSet
+        assert(m_nAffectedRows == -1);
+        m_xResultSet = new OResultSet(*getOwnConnection(), this, pMysqlResult,
+                                      m_xConnection->getConnectionEncoding());
+        return true;
+    }
+    else if (mysql_field_count(pMySql) == 0)
+    {
+        m_nAffectedRows = mysql_affected_rows(pMySql);
+        return false;
+    }
+    else
+    {
+        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(
+            "mysql_store_result indicated success and SQL command was supposed to return a "
+            "ResultSet, but did not.",
+            "02000", 0, *this);
+    }
+    //unreachable
+    assert(false);
+    // keep -Werror=return-type happy
+    return false;
+}
+
 sal_Bool SAL_CALL OCommonStatement::getMoreResults()
 {
-    return false; // TODO IMPL
+    MutexGuard aGuard(m_aMutex);
+    checkDisposed(rBHelper.bDisposed);
+
+    closeResultSet();
+    m_nAffectedRows = -1;
+
+    MYSQL* pMySql = m_xConnection->getMysqlConnection();
+    int status = mysql_next_result(pMySql);
+
+    if (status > 0 || mysql_errno(pMySql))
+        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMySql), mysql_sqlstate(pMySql),
+                                                     mysql_errno(pMySql), *this,
+                                                     m_xConnection->getConnectionEncoding());
+
+    if (status == -1)
+        return false;
+
+    if (status != 0)
+    {
+        const OUString errMsg("mysql_next_result returned unexpected value: "
+                              + OUString::number(status));
+        mysqlc_sdbc_driver::throwSQLExceptionWithMsg(errMsg, "02000", 0, *this);
+    }
+
+    return getResult();
 }
 
 Any SAL_CALL OCommonStatement::getWarnings()
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_statement.hxx b/connectivity/source/drivers/mysqlc/mysqlc_statement.hxx
index 2ce417259b24..d74e0a6456ce 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_statement.hxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_statement.hxx
@@ -71,6 +71,7 @@ protected:
 
 protected:
     void closeResultSet();
+    sal_Bool getResult();
 
     // OPropertyArrayUsageHelper
     ::cppu::IPropertyArrayHelper* createArrayHelper() const override;


More information about the Libreoffice-commits mailing list