[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