summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTamas Bunth <tamas.bunth@collabora.co.uk>2018-06-17 18:09:43 +0200
committerTamás Bunth <btomi96@gmail.com>2018-08-12 23:15:21 +0200
commit3478d7453a3d65b3d8d164e8f898a0b79f005c58 (patch)
tree9443239e076b735e2def217b66d7c305e8eaf254
parentResolves: tdf#112343 remove last dbus-glib mentions (diff)
downloadcore-3478d7453a3d65b3d8d164e8f898a0b79f005c58.tar.gz
core-3478d7453a3d65b3d8d164e8f898a0b79f005c58.zip
Switch from mysql to MariaDB C API
In order to get rid of the MySQL C++ Connector, the sdbc driver should be implemented using the MariaDB C connector instead. MariaDB Connector/C is LGPL licensed, so later it can be used in the connectivity module. This way mysqlc won't be an extension, so it could be maintained easier. Change-Id: I99c13ccf154b33b145d34b1e06eec85946dc82a0 Reviewed-on: https://gerrit.libreoffice.org/55960 Reviewed-by: Tamás Bunth <btomi96@gmail.com> Tested-by: Tamás Bunth <btomi96@gmail.com>
-rw-r--r--mysqlc/Library_mysqlc.mk3
-rw-r--r--mysqlc/source/mysqlc_connection.cxx140
-rw-r--r--mysqlc/source/mysqlc_connection.hxx19
-rw-r--r--mysqlc/source/mysqlc_databasemetadata.cxx1127
-rw-r--r--mysqlc/source/mysqlc_databasemetadata.hxx4
-rw-r--r--mysqlc/source/mysqlc_driver.cxx2
-rw-r--r--mysqlc/source/mysqlc_general.cxx266
-rw-r--r--mysqlc/source/mysqlc_general.hxx65
-rw-r--r--mysqlc/source/mysqlc_prepared_resultset.cxx1097
-rw-r--r--mysqlc/source/mysqlc_prepared_resultset.hxx248
-rw-r--r--mysqlc/source/mysqlc_preparedstatement.cxx510
-rw-r--r--mysqlc/source/mysqlc_preparedstatement.hxx24
-rw-r--r--mysqlc/source/mysqlc_resultset.cxx497
-rw-r--r--mysqlc/source/mysqlc_resultset.hxx20
-rw-r--r--mysqlc/source/mysqlc_resultsetmetadata.cxx247
-rw-r--r--mysqlc/source/mysqlc_resultsetmetadata.hxx17
-rw-r--r--mysqlc/source/mysqlc_statement.cxx103
-rw-r--r--mysqlc/source/mysqlc_statement.hxx12
18 files changed, 2724 insertions, 1677 deletions
diff --git a/mysqlc/Library_mysqlc.mk b/mysqlc/Library_mysqlc.mk
index 97f2b63500a2..39c6230d2f05 100644
--- a/mysqlc/Library_mysqlc.mk
+++ b/mysqlc/Library_mysqlc.mk
@@ -12,12 +12,14 @@ $(eval $(call gb_Library_Library,mysqlc))
$(eval $(call gb_Library_use_externals,mysqlc,\
boost_headers \
mysql-connector-cpp \
+ mariadb-connector-c \
))
ifeq ($(SYSTEM_MYSQL_CONNECTOR_CPP),)
$(eval $(call gb_Library_add_libs,mysqlc,\
$(if $(filter-out WNT,$(OS)),$(if $(filter MACOSX SOLARIS,$(OS)),-lz -lm,\
-rdynamic -lz -lcrypt -lm)) \
+ $(if $(filter LINUX,$(OS)),-lpthread -ldl,) \
))
endif
@@ -46,6 +48,7 @@ $(eval $(call gb_Library_add_exception_objects,mysqlc,\
mysqlc/source/mysqlc_services \
mysqlc/source/mysqlc_connection \
mysqlc/source/mysqlc_resultset \
+ mysqlc/source/mysqlc_prepared_resultset \
mysqlc/source/mysqlc_resultsetmetadata \
mysqlc/source/mysqlc_statement \
mysqlc/source/mysqlc_preparedstatement \
diff --git a/mysqlc/source/mysqlc_connection.cxx b/mysqlc/source/mysqlc_connection.cxx
index c9b4c6d2e471..73581734a293 100644
--- a/mysqlc/source/mysqlc_connection.cxx
+++ b/mysqlc/source/mysqlc_connection.cxx
@@ -61,12 +61,25 @@ using ::osl::MutexGuard;
#define MYSQLC_URI_PREFIX "sdbc:mysqlc:"
-OConnection::OConnection(MysqlCDriver& _rDriver, sql::Driver * _cppDriver)
+namespace
+{
+ void lcl_executeUpdate(MYSQL* pMySql, const rtl::OString& sql)
+ {
+ mysql_real_query(pMySql, sql.getStr(), sql.getLength());
+ // TODO handle error
+ }
+}
+
+OConnection::OConnection(MysqlCDriver& _rDriver)
:OMetaConnection_BASE(m_aMutex)
,m_xMetaData(nullptr)
,m_xDriver(&_rDriver)
- ,cppDriver(_cppDriver)
{
+ mysql_init(&m_mysql);
+
+ // use TCP as connection
+ mysql_protocol_type protocol = MYSQL_PROTOCOL_TCP;
+ mysql_options(&m_mysql, MYSQL_OPT_PROTOCOL, reinterpret_cast<int*>(&protocol));
}
OConnection::~OConnection()
@@ -144,29 +157,22 @@ void OConnection::construct(const rtl::OUString& url, const Sequence< PropertyVa
}
if (!bEmbedded) {
- try {
- sql::ConnectOptionsMap connProps;
- std::string host_str = rtl::OUStringToOString(aHostName, m_settings.encoding).getStr();
- std::string user_str = rtl::OUStringToOString(aUser, m_settings.encoding).getStr();
- std::string pass_str = rtl::OUStringToOString(aPass, m_settings.encoding).getStr();
- std::string schema_str = rtl::OUStringToOString(aDbName, m_settings.encoding).getStr();
- connProps["hostName"] = sql::ConnectPropertyVal(host_str);
- connProps["userName"] = sql::ConnectPropertyVal(user_str);
- connProps["password"] = sql::ConnectPropertyVal(pass_str);
- connProps["schema"] = sql::ConnectPropertyVal(schema_str);
- connProps["port"] = sql::ConnectPropertyVal(static_cast<int>(nPort));
- if (unixSocketPassed) {
- sql::SQLString socket_str = rtl::OUStringToOString(sUnixSocket, m_settings.encoding).getStr();
- connProps["socket"] = socket_str;
- } else if (namedPipePassed) {
- sql::SQLString pipe_str = rtl::OUStringToOString(sNamedPipe, m_settings.encoding).getStr();
- connProps["socket"] = pipe_str;
- }
-
- m_settings.cppConnection.reset(cppDriver->connect(connProps));
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
+ rtl::OString host_str = rtl::OUStringToOString(aHostName, m_settings.encoding);
+ rtl::OString user_str = rtl::OUStringToOString(aUser, m_settings.encoding);
+ rtl::OString pass_str = rtl::OUStringToOString(aPass, m_settings.encoding);
+ rtl::OString schema_str = rtl::OUStringToOString(aDbName, m_settings.encoding);
+ rtl::OString socket_str;
+ if (unixSocketPassed) {
+ socket_str = rtl::OUStringToOString(sUnixSocket, m_settings.encoding);
+ } else if (namedPipePassed) {
+ socket_str = rtl::OUStringToOString(sNamedPipe, m_settings.encoding);
}
+
+ // 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))
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(&m_mysql),
+ mysql_errno(&m_mysql),*this, getConnectionEncoding());
} else {
// TODO: support for embedded server
}
@@ -182,9 +188,9 @@ void OConnection::construct(const rtl::OUString& url, const Sequence< PropertyVa
0,
Any());
}
- std::unique_ptr<sql::Statement> stmt(m_settings.cppConnection->createStatement());
- stmt->executeUpdate("SET session sql_mode='ANSI_QUOTES'");
- stmt->executeUpdate("SET NAMES utf8");
+
+ lcl_executeUpdate(&m_mysql, rtl::OString{"SET session sql_mode='ANSI_QUOTES'"});
+ lcl_executeUpdate(&m_mysql, rtl::OString{"SET NAMES utf8"});
}
rtl::OUString OConnection::getImplementationName()
@@ -213,7 +219,7 @@ Reference< XStatement > SAL_CALL OConnection::createStatement()
Reference< XStatement > xReturn;
// the statement can only be executed once
try {
- xReturn = new OStatement(this, m_settings.cppConnection->createStatement());
+ xReturn = new OStatement(this);
m_aStatements.push_back(WeakReferenceHelper(xReturn));
return xReturn;
} catch (const sql::SQLException & e) {
@@ -226,18 +232,20 @@ Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement(const rtl
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
- const rtl::OUString sSqlStatement = transFormPreparedStatement( _sSql );
+ const rtl::OString sSqlStatement = rtl::OUStringToOString(
+ _sSql, getConnectionEncoding()); // FIXME transform statement ?
+
+ MYSQL_STMT* pStmt = mysql_stmt_init(&m_mysql);
+ mysql_stmt_prepare(pStmt, sSqlStatement.getStr(), sSqlStatement.getLength());
+
+ unsigned int nErrorNum = mysql_errno(&m_mysql);
+ if(nErrorNum != 0)
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(&m_mysql),
+ nErrorNum,*this, getConnectionEncoding());
Reference< XPreparedStatement > xStatement;
- try {
- // create a statement
- // the statement can only be executed more than once
- xStatement = new OPreparedStatement(this,
- m_settings.cppConnection->prepareStatement(rtl::OUStringToOString(sSqlStatement, getConnectionEncoding()).getStr()));
- m_aStatements.push_back( WeakReferenceHelper( xStatement ) );
- } catch (const sql::SQLException & e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
- }
+ xStatement = new OPreparedStatement(this, pStmt);
+ m_aStatements.push_back( WeakReferenceHelper( xStatement ) );
return xStatement;
}
@@ -269,11 +277,8 @@ void SAL_CALL OConnection::setAutoCommit(sal_Bool autoCommit)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
- try {
- m_settings.cppConnection->setAutoCommit(autoCommit);
- } catch (const sql::SQLException & e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
- }
+ if(!mysql_autocommit(&m_mysql, autoCommit))
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(&m_mysql), mysql_errno(&m_mysql), *this, getConnectionEncoding());
}
sal_Bool SAL_CALL OConnection::getAutoCommit()
@@ -281,6 +286,7 @@ sal_Bool SAL_CALL OConnection::getAutoCommit()
// you have to distinguish which if you are in autocommit mode or not
// at normal case true should be fine here
+ // TODO use SELECT @@autocommit query for that
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
@@ -297,22 +303,18 @@ void SAL_CALL OConnection::commit()
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
- try {
- m_settings.cppConnection->commit();
- } catch (const sql::SQLException & e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
- }
+
+ if(!mysql_commit(&m_mysql))
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(&m_mysql), mysql_errno(&m_mysql), *this, getConnectionEncoding());
}
void SAL_CALL OConnection::rollback()
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
- try {
- m_settings.cppConnection->rollback();
- } catch (const sql::SQLException & e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
- }
+
+ if(!mysql_rollback(&m_mysql))
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(&m_mysql), mysql_errno(&m_mysql), *this, getConnectionEncoding());
}
sal_Bool SAL_CALL OConnection::isClosed()
@@ -329,12 +331,9 @@ Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData()
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
- if (!xMetaData.is()) {
- try {
- xMetaData = new ODatabaseMetaData(*this); // need the connection because it can return it
- } catch (const sql::SQLException & e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
- }
+ if (!xMetaData.is())
+ {
+ xMetaData = new ODatabaseMetaData(*this, &m_mysql);
m_xMetaData = xMetaData;
}
@@ -363,6 +362,7 @@ void SAL_CALL OConnection::setCatalog(const rtl::OUString& catalog)
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
+ // TODO How?
try {
// m_settings.cppConnection->setCatalog(rtl::OUStringToOString(catalog, m_settings.encoding).getStr());
m_settings.cppConnection->setSchema(rtl::OUStringToOString(catalog, getConnectionEncoding()).getStr());
@@ -376,6 +376,7 @@ rtl::OUString SAL_CALL OConnection::getCatalog()
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
+ // TODO How?
rtl::OUString catalog;
try {
catalog = mysqlc_sdbc_driver::convert(m_settings.cppConnection->getSchema(), getConnectionEncoding());
@@ -467,6 +468,7 @@ void SAL_CALL OConnection::close()
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
}
+ mysql_close(&m_mysql);
dispose();
}
@@ -507,15 +509,8 @@ sal_Int32 OConnection::getMysqlVersion()
MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
- sal_Int32 version(0);
- try {
- version = 10000 * m_settings.cppConnection->getMetaData()->getDatabaseMajorVersion();
- version += 100 * m_settings.cppConnection->getMetaData()->getDatabaseMinorVersion();
- version += m_settings.cppConnection->getMetaData()->getDatabasePatchVersion();
- } catch (const sql::SQLException & e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
- }
- return version;
+ unsigned long version = mysql_get_server_version(&m_mysql);
+ return static_cast<sal_Int32>(version);
}
rtl::OUString OConnection::transFormPreparedStatement(const rtl::OUString& _sSQL)
@@ -539,13 +534,4 @@ rtl::OUString OConnection::transFormPreparedStatement(const rtl::OUString& _sSQL
}
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_connection.hxx b/mysqlc/source/mysqlc_connection.hxx
index a305d6a9ab89..72af3c89e886 100644
--- a/mysqlc/source/mysqlc_connection.hxx
+++ b/mysqlc/source/mysqlc_connection.hxx
@@ -43,6 +43,8 @@
#include <rtl/string.hxx>
#include <rtl/ref.hxx>
+#include <mysql.h>
+
#include <map>
@@ -85,6 +87,8 @@ namespace connectivity
class OConnection final : public OBase_Mutex,
public OConnection_BASE
{
+ private:
+ MYSQL m_mysql;
ConnectionSettings m_settings;
css::uno::Reference< css::container::XNameAccess > m_typeMap;
css::uno::Reference< css::util::XStringSubstitution > m_xParameterSubstitution;
@@ -98,9 +102,9 @@ namespace connectivity
// for this Connection
rtl::Reference<MysqlCDriver> m_xDriver; // Pointer to the owning driver object
- sql::Driver* cppDriver;
-
public:
+ MYSQL* getMysqlConnection() { return &m_mysql; }
+
/// @throws SQLException
/// @throws RuntimeException
sal_Int32 getMysqlVersion();
@@ -108,7 +112,7 @@ namespace connectivity
/// @throws SQLException
void construct(const rtl::OUString& url,const css::uno::Sequence< css::beans::PropertyValue >& info);
- OConnection(MysqlCDriver& _rDriver, sql::Driver * cppDriver);
+ OConnection(MysqlCDriver& _rDriver );
virtual ~OConnection();
rtl_TextEncoding getConnectionEncoding() const { return m_settings.encoding; }
@@ -184,13 +188,4 @@ namespace connectivity
} /* connectivity */
#endif // INCLUDED_MYSQLC_SOURCE_MYSQLC_CONNECTION_HXX
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_databasemetadata.cxx b/mysqlc/source/mysqlc_databasemetadata.cxx
index 68dad0cbcf84..0f9e539e6df3 100644
--- a/mysqlc/source/mysqlc_databasemetadata.cxx
+++ b/mysqlc/source/mysqlc_databasemetadata.cxx
@@ -29,7 +29,7 @@
#include <com/sun/star/sdbc/ColumnType.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
-
+#include <rtl/ustrbuf.hxx>
#include "mysqlc_general.hxx"
#include "mysqlc_statement.hxx"
#include "mysqlc_driver.hxx"
@@ -44,12 +44,6 @@ using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
using mysqlc_sdbc_driver::getStringFromAny;
-#include <cppconn/connection.h>
-#include <cppconn/resultset.h>
-#include <cppconn/metadata.h>
-#include <cppconn/statement.h>
-#include <cppconn/prepared_statement.h>
-
#include <sal/macros.h>
static std::string wild("%");
@@ -76,9 +70,9 @@ void lcl_setRows_throw(const Reference< XResultSet >& _xResultSet,sal_Int32 _nTy
xIni->initialize(aArgs);
}
-ODatabaseMetaData::ODatabaseMetaData(OConnection& _rCon)
+ODatabaseMetaData::ODatabaseMetaData(OConnection& _rCon, MYSQL* pMySql)
:m_rConnection(_rCon)
- ,meta(_rCon.getConnectionSettings().cppConnection->getMetaData())
+ ,m_pMySql(pMySql)
,identifier_quote_string_set(false)
{
}
@@ -87,564 +81,477 @@ ODatabaseMetaData::~ODatabaseMetaData()
{
}
-rtl::OUString ODatabaseMetaData::impl_getStringMetaData(const sal_Char* _methodName, const sql::SQLString& (sql::DatabaseMetaData::*Method)() )
-{
- rtl::OUString stringMetaData;
- try {
- stringMetaData = mysqlc_sdbc_driver::convert((meta->*Method)(), m_rConnection.getConnectionEncoding());
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException(_methodName, *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException(_methodName, *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
- return stringMetaData;
-}
-
-rtl::OUString ODatabaseMetaData::impl_getStringMetaData(const sal_Char* _methodName, sql::SQLString (sql::DatabaseMetaData::*Method)() )
-{
- rtl::OUString stringMetaData;
- try {
- stringMetaData = mysqlc_sdbc_driver::convert((meta->*Method)(), m_rConnection.getConnectionEncoding());
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException(_methodName, *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException(_methodName, *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
- return stringMetaData;
-}
-
-sal_Int32 ODatabaseMetaData::impl_getInt32MetaData(const sal_Char* _methodName, unsigned int (sql::DatabaseMetaData::*Method)() )
-{
- sal_Int32 int32MetaData(0);
- try {
- int32MetaData = (meta->*Method)();
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException(_methodName, *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException(_methodName, *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
- return int32MetaData;
-}
-
-bool ODatabaseMetaData::impl_getBoolMetaData(const sal_Char* _methodName, bool (sql::DatabaseMetaData::*Method)() )
-{
- bool boolMetaData(false);
- try {
- boolMetaData = (meta->*Method)();
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException(_methodName, *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException(_methodName, *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
- return boolMetaData;
-}
-
-bool ODatabaseMetaData::impl_getBoolMetaData(const sal_Char* _methodName, bool (sql::DatabaseMetaData::*Method)(int), sal_Int32 _arg )
-{
- bool boolMetaData(false);
- try {
- boolMetaData = (meta->*Method)( _arg );
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException(_methodName, *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException(_methodName, *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
- return boolMetaData;
-}
-
-bool ODatabaseMetaData::impl_getRSTypeMetaData(const sal_Char* _methodName, bool (sql::DatabaseMetaData::*Method)(int), sal_Int32 _resultSetType )
-{
- int resultSetType(sql::ResultSet::TYPE_FORWARD_ONLY);
- switch ( _resultSetType ) {
- case ResultSetType::SCROLL_INSENSITIVE: resultSetType = sql::ResultSet::TYPE_SCROLL_INSENSITIVE; break;
- case ResultSetType::SCROLL_SENSITIVE: resultSetType = sql::ResultSet::TYPE_SCROLL_SENSITIVE; break;
- }
-
- return impl_getBoolMetaData(_methodName, Method, resultSetType);
-}
-
rtl::OUString SAL_CALL ODatabaseMetaData::getCatalogSeparator()
{
- return impl_getStringMetaData("getCatalogSeparator", &sql::DatabaseMetaData::getCatalogSeparator);
+ return rtl::OUString();
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxBinaryLiteralLength()
{
- return impl_getInt32MetaData("getMaxBinaryLiteralLength", &sql::DatabaseMetaData::getMaxBinaryLiteralLength);
+ return 16777208L;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxRowSize()
{
- return impl_getInt32MetaData("getMaxRowSize", &sql::DatabaseMetaData::getMaxRowSize);
+ return 2147483647L - 8; // Max buffer size - HEADER
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCatalogNameLength()
{
- return impl_getInt32MetaData("getMaxCatalogNameLength", &sql::DatabaseMetaData::getMaxCatalogNameLength);
+ return 32;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCharLiteralLength()
{
- return impl_getInt32MetaData("getMaxCharLiteralLength", &sql::DatabaseMetaData::getMaxCharLiteralLength);
+ return 16777208;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnNameLength()
{
- return impl_getInt32MetaData("getMaxColumnNameLength", &sql::DatabaseMetaData::getMaxColumnNameLength);
+ return 64;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInIndex()
{
- return impl_getInt32MetaData("getMaxColumnsInIndex", &sql::DatabaseMetaData::getMaxColumnsInIndex);
+ return 16;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCursorNameLength()
{
- return impl_getInt32MetaData("getMaxCursorNameLength", &sql::DatabaseMetaData::getMaxCursorNameLength);
+ return 64;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxConnections()
{
- return impl_getInt32MetaData("getMaxConnections", &sql::DatabaseMetaData::getMaxConnections);
+ // TODO
+ // SELECT @@max_connections
+ return 100;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInTable()
{
- return impl_getInt32MetaData("getMaxColumnsInTable", &sql::DatabaseMetaData::getMaxColumnsInTable);
+ return 512;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatementLength()
{
- return impl_getInt32MetaData("getMaxStatementLength", &sql::DatabaseMetaData::getMaxStatementLength);
+ // TODO
+ // "SHOW VARIABLES LIKE 'max_allowed_packet'"
+ return 32767;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTableNameLength()
{
- return impl_getInt32MetaData("getMaxTableNameLength", &sql::DatabaseMetaData::getMaxTableNameLength);
+ return 64;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTablesInSelect()
{
- return impl_getInt32MetaData("getMaxTablesInSelect", &sql::DatabaseMetaData::getMaxTablesInSelect);
+ return 256;
}
sal_Bool SAL_CALL ODatabaseMetaData::doesMaxRowSizeIncludeBlobs()
{
- return impl_getBoolMetaData("doesMaxRowSizeIncludeBlobs", &sql::DatabaseMetaData::doesMaxRowSizeIncludeBlobs);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
{
- return impl_getBoolMetaData("storesLowerCaseQuotedIdentifiers", &sql::DatabaseMetaData::storesLowerCaseQuotedIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseIdentifiers()
{
- return impl_getBoolMetaData("storesLowerCaseIdentifiers", &sql::DatabaseMetaData::storesLowerCaseIdentifiers);
+ //TODO;
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseQuotedIdentifiers()
{
- return impl_getBoolMetaData("storesMixedCaseQuotedIdentifiers", &sql::DatabaseMetaData::storesMixedCaseQuotedIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseIdentifiers()
{
- return impl_getBoolMetaData("storesMixedCaseIdentifiers", &sql::DatabaseMetaData::storesMixedCaseIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
{
- return impl_getBoolMetaData("storesUpperCaseQuotedIdentifiers", &sql::DatabaseMetaData::storesUpperCaseQuotedIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseIdentifiers()
{
- return impl_getBoolMetaData("storesUpperCaseIdentifiers", &sql::DatabaseMetaData::storesUpperCaseIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithAddColumn()
{
- return impl_getBoolMetaData("supportsAlterTableWithAddColumn", &sql::DatabaseMetaData::supportsAlterTableWithAddColumn);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithDropColumn()
{
- return impl_getBoolMetaData("supportsAlterTableWithDropColumn", &sql::DatabaseMetaData::supportsAlterTableWithDropColumn);
+ return true;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxIndexLength()
{
- return impl_getInt32MetaData("getMaxIndexLength", &sql::DatabaseMetaData::getMaxIndexLength);
+ return 256;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsNonNullableColumns()
{
- return impl_getBoolMetaData("supportsNonNullableColumns", &sql::DatabaseMetaData::supportsNonNullableColumns);
+ return true;
}
rtl::OUString SAL_CALL ODatabaseMetaData::getCatalogTerm()
{
- return impl_getStringMetaData("getCatalogTerm", &sql::DatabaseMetaData::getCatalogTerm);
+ return rtl::OUString("n/a");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getIdentifierQuoteString()
{
- if (!identifier_quote_string_set) {
- identifier_quote_string = impl_getStringMetaData("getIdentifierQuoteString", &sql::DatabaseMetaData::getIdentifierQuoteString);
- identifier_quote_string_set = true;
- }
- return identifier_quote_string;
+ return rtl::OUString("\"");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getExtraNameCharacters()
{
- return impl_getStringMetaData("getExtraNameCharacters", &sql::DatabaseMetaData::getExtraNameCharacters);
+ return rtl::OUString("#@");
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsDifferentTableCorrelationNames()
{
- return impl_getBoolMetaData("supportsDifferentTableCorrelationNames", &sql::DatabaseMetaData::supportsDifferentTableCorrelationNames);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::isCatalogAtStart()
{
- return impl_getBoolMetaData("isCatalogAtStart", &sql::DatabaseMetaData::isCatalogAtStart);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
{
- return impl_getBoolMetaData("dataDefinitionIgnoredInTransactions", &sql::DatabaseMetaData::dataDefinitionIgnoredInTransactions);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
{
- return impl_getBoolMetaData("dataDefinitionCausesTransactionCommit", &sql::DatabaseMetaData::dataDefinitionCausesTransactionCommit);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
{
- return impl_getBoolMetaData("supportsDataManipulationTransactionsOnly", &sql::DatabaseMetaData::supportsDataManipulationTransactionsOnly);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions()
{
- return impl_getBoolMetaData("supportsDataDefinitionAndDataManipulationTransactions", &sql::DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedDelete()
{
- return impl_getBoolMetaData("supportsPositionedDelete", &sql::DatabaseMetaData::supportsPositionedDelete);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedUpdate()
{
- return impl_getBoolMetaData("supportsPositionedUpdate", &sql::DatabaseMetaData::supportsPositionedUpdate);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
{
- return impl_getBoolMetaData("supportsOpenStatementsAcrossRollback", &sql::DatabaseMetaData::supportsOpenStatementsAcrossRollback);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
{
- return impl_getBoolMetaData("supportsOpenStatementsAcrossCommit", &sql::DatabaseMetaData::supportsOpenStatementsAcrossCommit);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
{
- return impl_getBoolMetaData("supportsOpenCursorsAcrossCommit", &sql::DatabaseMetaData::supportsOpenCursorsAcrossCommit);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
{
- return impl_getBoolMetaData("supportsOpenCursorsAcrossRollback", &sql::DatabaseMetaData::supportsOpenCursorsAcrossRollback);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel(sal_Int32 level)
+sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel(sal_Int32 /*level*/)
{
- return impl_getBoolMetaData("supportsTransactionIsolationLevel", &sql::DatabaseMetaData::supportsTransactionIsolationLevel, level);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInDataManipulation()
{
- return impl_getBoolMetaData("supportsSchemasInDataManipulation", &sql::DatabaseMetaData::supportsSchemasInDataManipulation);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92FullSQL()
{
- return impl_getBoolMetaData("supportsANSI92FullSQL", &sql::DatabaseMetaData::supportsANSI92FullSQL);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92EntryLevelSQL()
{
- return impl_getBoolMetaData("supportsANSI92EntryLevelSQL", &sql::DatabaseMetaData::supportsANSI92EntryLevelSQL);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsIntegrityEnhancementFacility()
{
- return impl_getBoolMetaData("supportsIntegrityEnhancementFacility", &sql::DatabaseMetaData::supportsIntegrityEnhancementFacility);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInIndexDefinitions()
{
- return impl_getBoolMetaData("supportsSchemasInIndexDefinitions", &sql::DatabaseMetaData::supportsSchemasInIndexDefinitions);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInTableDefinitions()
{
- return impl_getBoolMetaData("supportsSchemasInTableDefinitions", &sql::DatabaseMetaData::supportsSchemasInTableDefinitions);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInTableDefinitions()
{
- return impl_getBoolMetaData("supportsCatalogsInTableDefinitions", &sql::DatabaseMetaData::supportsCatalogsInTableDefinitions);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInIndexDefinitions()
{
- return impl_getBoolMetaData("supportsCatalogsInIndexDefinitions", &sql::DatabaseMetaData::supportsCatalogsInIndexDefinitions);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInDataManipulation()
{
- return impl_getBoolMetaData("supportsCatalogsInDataManipulation", &sql::DatabaseMetaData::supportsCatalogsInDataManipulation);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsOuterJoins()
{
- return impl_getBoolMetaData("supportsOuterJoins", &sql::DatabaseMetaData::supportsOuterJoins);
+ return true;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatements()
{
- return impl_getInt32MetaData("getMaxStatements", &sql::DatabaseMetaData::getMaxStatements);
+ return 0;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxProcedureNameLength()
{
- return impl_getInt32MetaData("getMaxProcedureNameLength", &sql::DatabaseMetaData::getMaxProcedureNameLength);
+ return 64;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxSchemaNameLength()
{
- return impl_getInt32MetaData("getMaxSchemaNameLength", &sql::DatabaseMetaData::getMaxSchemaNameLength);
+ return 64;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactions()
{
- return impl_getBoolMetaData("supportsTransactions", &sql::DatabaseMetaData::supportsTransactions);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::allProceduresAreCallable()
{
- return impl_getBoolMetaData("allProceduresAreCallable", &sql::DatabaseMetaData::allProceduresAreCallable);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsStoredProcedures()
{
- return impl_getBoolMetaData("supportsStoredProcedures", &sql::DatabaseMetaData::supportsStoredProcedures);
+ return m_rConnection.getMysqlVersion() >= 50000;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSelectForUpdate()
{
- return impl_getBoolMetaData("supportsSelectForUpdate", &sql::DatabaseMetaData::supportsSelectForUpdate);
+ return m_rConnection.getMysqlVersion() >= 40000;
}
sal_Bool SAL_CALL ODatabaseMetaData::allTablesAreSelectable()
{
- return impl_getBoolMetaData("allTablesAreSelectable", &sql::DatabaseMetaData::allTablesAreSelectable);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::isReadOnly()
{
- return impl_getBoolMetaData("isReadOnly", &sql::DatabaseMetaData::isReadOnly);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFiles()
{
- return impl_getBoolMetaData("usesLocalFiles", &sql::DatabaseMetaData::usesLocalFiles);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFilePerTable()
{
- return impl_getBoolMetaData("usesLocalFilePerTable", &sql::DatabaseMetaData::usesLocalFilePerTable);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsTypeConversion()
{
- return impl_getBoolMetaData("supportsTypeConversion", &sql::DatabaseMetaData::supportsTypeConversion);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::nullPlusNonNullIsNull()
{
- return impl_getBoolMetaData("nullPlusNonNullIsNull", &sql::DatabaseMetaData::nullPlusNonNullIsNull);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsColumnAliasing()
{
- return impl_getBoolMetaData("supportsColumnAliasing", &sql::DatabaseMetaData::supportsColumnAliasing);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsTableCorrelationNames()
{
- return impl_getBoolMetaData("supportsTableCorrelationNames", &sql::DatabaseMetaData::supportsTableCorrelationNames);
+ return true;
}
-sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert(sal_Int32 /* fromType */, sal_Int32 /* toType */)
+sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert(sal_Int32 /*fromType*/, sal_Int32 /*toType*/)
{
- try {
- /* ToDo -> use supportsConvert( fromType, toType) */
- return meta->supportsConvert();
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::supportsConvert", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::supportsConvert", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
+ // TODO
return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsExpressionsInOrderBy()
{
- return impl_getBoolMetaData("supportsExpressionsInOrderBy", &sql::DatabaseMetaData::supportsExpressionsInOrderBy);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupBy()
{
- return impl_getBoolMetaData("supportsGroupBy", &sql::DatabaseMetaData::supportsGroupBy);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByBeyondSelect()
{
- return impl_getBoolMetaData("supportsGroupByBeyondSelect", &sql::DatabaseMetaData::supportsGroupByBeyondSelect);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated()
{
- return impl_getBoolMetaData("supportsGroupByUnrelated", &sql::DatabaseMetaData::supportsGroupByUnrelated);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions()
{
- return impl_getBoolMetaData("supportsMultipleTransactions", &sql::DatabaseMetaData::supportsMultipleTransactions);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets()
{
- return impl_getBoolMetaData("supportsMultipleResultSets", &sql::DatabaseMetaData::supportsMultipleResultSets);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause()
{
- return impl_getBoolMetaData("supportsLikeEscapeClause", &sql::DatabaseMetaData::supportsLikeEscapeClause);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsOrderByUnrelated()
{
- return impl_getBoolMetaData("supportsOrderByUnrelated", &sql::DatabaseMetaData::supportsOrderByUnrelated);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsUnion()
{
- return impl_getBoolMetaData("supportsUnion", &sql::DatabaseMetaData::supportsUnion);
+ return m_rConnection.getMysqlVersion() >= 40000;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsUnionAll()
{
- return impl_getBoolMetaData("supportsUnionAll", &sql::DatabaseMetaData::supportsUnionAll);
+ return m_rConnection.getMysqlVersion() >= 40000;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseIdentifiers()
{
- return impl_getBoolMetaData("supportsMixedCaseIdentifiers", &sql::DatabaseMetaData::supportsMixedCaseIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers()
{
- return impl_getBoolMetaData("supportsMixedCaseQuotedIdentifiers", &sql::DatabaseMetaData::supportsMixedCaseQuotedIdentifiers);
+ // TODO
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtEnd()
{
- return impl_getBoolMetaData("nullsAreSortedAtEnd", &sql::DatabaseMetaData::nullsAreSortedAtEnd);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtStart()
{
- return impl_getBoolMetaData("nullsAreSortedAtStart", &sql::DatabaseMetaData::nullsAreSortedAtStart);
+ return m_rConnection.getMysqlVersion() > 40001 && m_rConnection.getMysqlVersion() < 40011;
}
sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedHigh()
{
- return impl_getBoolMetaData("nullsAreSortedHigh", &sql::DatabaseMetaData::nullsAreSortedHigh);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedLow()
{
- return impl_getBoolMetaData("nullsAreSortedLow", &sql::DatabaseMetaData::nullsAreSortedLow);
+ return !nullsAreSortedHigh();
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInProcedureCalls()
{
- return impl_getBoolMetaData("supportsSchemasInProcedureCalls", &sql::DatabaseMetaData::supportsSchemasInProcedureCalls);
+ return m_rConnection.getMysqlVersion() >= 32200;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
{
- return impl_getBoolMetaData("supportsSchemasInPrivilegeDefinitions", &sql::DatabaseMetaData::supportsSchemasInPrivilegeDefinitions);
+ return m_rConnection.getMysqlVersion() >= 32200;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInProcedureCalls()
{
- return impl_getBoolMetaData("supportsCatalogsInProcedureCalls", &sql::DatabaseMetaData::supportsCatalogsInProcedureCalls);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions()
{
- return impl_getBoolMetaData("supportsCatalogsInPrivilegeDefinitions", &sql::DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCorrelatedSubqueries()
{
- return impl_getBoolMetaData("supportsCorrelatedSubqueries", &sql::DatabaseMetaData::supportsCorrelatedSubqueries);
+ return m_rConnection.getMysqlVersion() >= 40100;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInComparisons()
{
- return impl_getBoolMetaData("supportsSubqueriesInComparisons", &sql::DatabaseMetaData::supportsSubqueriesInComparisons);
+ return m_rConnection.getMysqlVersion() >= 40100;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInExists()
{
- return impl_getBoolMetaData("supportsSubqueriesInExists", &sql::DatabaseMetaData::supportsSubqueriesInExists);
+ return m_rConnection.getMysqlVersion() >= 40100;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInIns()
{
- return impl_getBoolMetaData("supportsSubqueriesInIns", &sql::DatabaseMetaData::supportsSubqueriesInIns);
+ return m_rConnection.getMysqlVersion() >= 40100;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInQuantifieds()
{
- return impl_getBoolMetaData("supportsSubqueriesInQuantifieds", &sql::DatabaseMetaData::supportsSubqueriesInQuantifieds);
+ return m_rConnection.getMysqlVersion() >= 40100;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92IntermediateSQL()
{
- return impl_getBoolMetaData("supportsANSI92IntermediateSQL", &sql::DatabaseMetaData::supportsANSI92IntermediateSQL);
+ return false;
}
rtl::OUString SAL_CALL ODatabaseMetaData::getURL()
@@ -654,7 +561,8 @@ rtl::OUString SAL_CALL ODatabaseMetaData::getURL()
rtl::OUString SAL_CALL ODatabaseMetaData::getUserName()
{
- return impl_getStringMetaData("getUserName", &sql::DatabaseMetaData::getUserName);
+ // TODO execute "SELECT USER()"
+ return rtl::OUString();
}
rtl::OUString SAL_CALL ODatabaseMetaData::getDriverName()
@@ -669,199 +577,236 @@ rtl::OUString SAL_CALL ODatabaseMetaData::getDriverVersion()
rtl::OUString SAL_CALL ODatabaseMetaData::getDatabaseProductVersion()
{
- return impl_getStringMetaData("getDatabaseProductVersion", &sql::DatabaseMetaData::getDatabaseProductVersion);
+ return rtl::OStringToOUString(mysql_get_server_info(m_pMySql),
+ m_rConnection.getConnectionEncoding());
}
rtl::OUString SAL_CALL ODatabaseMetaData::getDatabaseProductName()
{
- return impl_getStringMetaData("getDatabaseProductName", &sql::DatabaseMetaData::getDatabaseProductName);
+ return rtl::OUString("MySQL");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getProcedureTerm()
{
- return impl_getStringMetaData("getProcedureTerm", &sql::DatabaseMetaData::getProcedureTerm);
+ return rtl::OUString("procedure");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getSchemaTerm()
{
- return impl_getStringMetaData("getSchemaTerm", &sql::DatabaseMetaData::getSchemaTerm);
+ return rtl::OUString("database");
}
sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMajorVersion()
{
+ // TODO
return MARIADBC_VERSION_MAJOR;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getDefaultTransactionIsolation()
{
- try {
- switch (meta->getDefaultTransactionIsolation()) {
- case sql::TRANSACTION_SERIALIZABLE: return TransactionIsolation::SERIALIZABLE;
- case sql::TRANSACTION_REPEATABLE_READ: return TransactionIsolation::REPEATABLE_READ;
- case sql::TRANSACTION_READ_COMMITTED: return TransactionIsolation::READ_COMMITTED;
- case sql::TRANSACTION_READ_UNCOMMITTED: return TransactionIsolation::READ_UNCOMMITTED;
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getDriverMajorVersion", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getDriverMajorVersion", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
- return TransactionIsolation::NONE;
+ return m_rConnection.getMysqlVersion() >= 32336 ? TransactionIsolation::READ_COMMITTED :
+ TransactionIsolation::NONE;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMinorVersion()
{
+ // TODO
return MARIADBC_VERSION_MINOR;
}
rtl::OUString SAL_CALL ODatabaseMetaData::getSQLKeywords()
{
- return impl_getStringMetaData("getSQLKeywords", &sql::DatabaseMetaData::getSQLKeywords);
+ return rtl::OUString(
+ "ACCESSIBLE, ADD, ALL,"\
+ "ALTER, ANALYZE, AND, AS, ASC, ASENSITIVE, BEFORE,"\
+ "BETWEEN, BIGINT, BINARY, BLOB, BOTH, BY, CALL,"\
+ "CASCADE, CASE, CHANGE, CHAR, CHARACTER, CHECK,"\
+ "COLLATE, COLUMN, CONDITION, CONNECTION, CONSTRAINT,"\
+ "CONTINUE, CONVERT, CREATE, CROSS, CURRENT_DATE,"\
+ "CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,"\
+ "DATABASE, DATABASES, DAY_HOUR, DAY_MICROSECOND,"\
+ "DAY_MINUTE, DAY_SECOND, DEC, DECIMAL, DECLARE,"\
+ "DEFAULT, DELAYED, DELETE, DESC, DESCRIBE,"\
+ "DETERMINISTIC, DISTINCT, DISTINCTROW, DIV, DOUBLE,"\
+ "DROP, DUAL, EACH, ELSE, ELSEIF, ENCLOSED,"\
+ "ESCAPED, EXISTS, EXIT, EXPLAIN, FALSE, FETCH,"\
+ "FLOAT, FLOAT4, FLOAT8, FOR, FORCE, FOREIGN, FROM,"\
+ "FULLTEXT, GRANT, GROUP, HAVING, HIGH_PRIORITY,"\
+ "HOUR_MICROSECOND, HOUR_MINUTE, HOUR_SECOND, IF,"\
+ "IGNORE, IN, INDEX, INFILE, INNER, INOUT,"\
+ "INSENSITIVE, INSERT, INT, INT1, INT2, INT3, INT4,"\
+ "INT8, INTEGER, INTERVAL, INTO, IS, ITERATE, JOIN,"\
+ "KEY, KEYS, KILL, LEADING, LEAVE, LEFT, LIKE,"\
+ "LOCALTIMESTAMP, LOCK, LONG, LONGBLOB, LONGTEXT,"\
+ "LOOP, LOW_PRIORITY, MATCH, MEDIUMBLOB, MEDIUMINT,"\
+ "MEDIUMTEXT, MIDDLEINT, MINUTE_MICROSECOND,"\
+ "MINUTE_SECOND, MOD, MODIFIES, NATURAL, NOT,"\
+ "NO_WRITE_TO_BINLOG, NULL, NUMERIC, ON, OPTIMIZE,"\
+ "OPTION, OPTIONALLY, OR, ORDER, OUT, OUTER,"\
+ "OUTFILE, PRECISION, PRIMARY, PROCEDURE, PURGE,"\
+ "RANGE, READ, READS, READ_ONLY, READ_WRITE, REAL,"\
+ "REFERENCES, REGEXP, RELEASE, RENAME, REPEAT,"\
+ "REPLACE, REQUIRE, RESTRICT, RETURN, REVOKE, RIGHT,"\
+ "RLIKE, SCHEMA, SCHEMAS, SECOND_MICROSECOND, SELECT,"\
+ "SENSITIVE, SEPARATOR, SET, SHOW, SMALLINT, SPATIAL,"\
+ "SPECIFIC, SQL, SQLEXCEPTION, SQLSTATE, SQLWARNING,"\
+ "SQL_BIG_RESULT, SQL_CALC_FOUND_ROWS, SQL_SMALL_RESULT,"\
+ "SSL, STARTING, STRAIGHT_JOIN, TABLE, TERMINATED,"\
+ "THEN, TINYBLOB, TINYINT, TINYTEXT, TO, TRAILING,"\
+ "TRIGGER, TRUE, UNDO, UNION, UNIQUE, UNLOCK,"\
+ "UNSIGNED, UPDATE, USAGE, USE, USING, UTC_DATE,"\
+ "UTC_TIME, UTC_TIMESTAMP, VALUES, VARBINARY, VARCHAR,"\
+ "VARCHARACTER, VARYING, WHEN, WHERE, WHILE, WITH,"\
+ "WRITE, X509, XOR, YEAR_MONTH, ZEROFILL" \
+ "GENERAL, IGNORE_SERVER_IDS, MASTER_HEARTBEAT_PERIOD," \
+ "MAXVALUE, RESIGNAL, SIGNAL, SLOW");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getSearchStringEscape()
{
- return impl_getStringMetaData("getSearchStringEscape", &sql::DatabaseMetaData::getSearchStringEscape);
+ return rtl::OUString("\\");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getStringFunctions()
{
- return impl_getStringMetaData("getStringFunctions", &sql::DatabaseMetaData::getStringFunctions);
+ return rtl::OUString(
+ "ASCII,BIN,BIT_LENGTH,CHAR,CHARACTER_LENGTH,CHAR_LENGTH,CONCAT,"
+ "CONCAT_WS,CONV,ELT,EXPORT_SET,FIELD,FIND_IN_SET,HEX,INSERT,"
+ "INSTR,LCASE,LEFT,LENGTH,LOAD_FILE,LOCATE,LOCATE,LOWER,LPAD,"
+ "LTRIM,MAKE_SET,MATCH,MID,OCT,OCTET_LENGTH,ORD,POSITION,"
+ "QUOTE,REPEAT,REPLACE,REVERSE,RIGHT,RPAD,RTRIM,SOUNDEX,"
+ "SPACE,STRCMP,SUBSTRING,SUBSTRING,SUBSTRING,SUBSTRING,"
+ "SUBSTRING_INDEX,TRIM,UCASE,UPPER");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getTimeDateFunctions()
{
- return impl_getStringMetaData("getTimeDateFunctions", &sql::DatabaseMetaData::getTimeDateFunctions);
+ return rtl::OUString(
+ "DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR,MONTH,DAYNAME,"
+ "MONTHNAME,QUARTER,WEEK,YEAR,HOUR,MINUTE,SECOND,PERIOD_ADD,"
+ "PERIOD_DIFF,TO_DAYS,FROM_DAYS,DATE_FORMAT,TIME_FORMAT,"
+ "CURDATE,CURRENT_DATE,CURTIME,CURRENT_TIME,NOW,SYSDATE,"
+ "CURRENT_TIMESTAMP,UNIX_TIMESTAMP,FROM_UNIXTIME,"
+ "SEC_TO_TIME,TIME_TO_SEC");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getSystemFunctions()
{
- return impl_getStringMetaData("getSystemFunctions", &sql::DatabaseMetaData::getSystemFunctions);
+ return rtl::OUString(
+ "DATABASE,USER,SYSTEM_USER,"
+ "SESSION_USER,PASSWORD,ENCRYPT,LAST_INSERT_ID,VERSION");
}
rtl::OUString SAL_CALL ODatabaseMetaData::getNumericFunctions()
{
- return impl_getStringMetaData("getNumericFunctions", &sql::DatabaseMetaData::getNumericFunctions);
+ return rtl::OUString("ABS,ACOS,ASIN,ATAN,ATAN2,BIT_COUNT,CEILING,COS,"
+ "COT,DEGREES,EXP,FLOOR,LOG,LOG10,MAX,MIN,MOD,PI,POW,"
+ "POWER,RADIANS,RAND,ROUND,SIN,SQRT,TAN,TRUNCATE");
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsExtendedSQLGrammar()
{
- return impl_getBoolMetaData("supportsExtendedSQLGrammar", &sql::DatabaseMetaData::supportsExtendedSQLGrammar);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsCoreSQLGrammar()
{
- return impl_getBoolMetaData("supportsCoreSQLGrammar", &sql::DatabaseMetaData::supportsCoreSQLGrammar);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsMinimumSQLGrammar()
{
- return impl_getBoolMetaData("supportsMinimumSQLGrammar", &sql::DatabaseMetaData::supportsMinimumSQLGrammar);
+ return true;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsFullOuterJoins()
{
- return impl_getBoolMetaData("supportsFullOuterJoins", &sql::DatabaseMetaData::supportsFullOuterJoins);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsLimitedOuterJoins()
{
- return impl_getBoolMetaData("supportsLimitedOuterJoins", &sql::DatabaseMetaData::supportsLimitedOuterJoins);
+ return true;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInGroupBy()
{
- return impl_getInt32MetaData("getMaxColumnsInGroupBy", &sql::DatabaseMetaData::getMaxColumnsInGroupBy);
+ return 64;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInOrderBy()
{
- return impl_getInt32MetaData("getMaxColumnsInOrderBy", &sql::DatabaseMetaData::getMaxColumnsInOrderBy);
+ return 64;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInSelect()
{
- return impl_getInt32MetaData("getMaxColumnsInSelect", &sql::DatabaseMetaData::getMaxColumnsInSelect);
+ return 256;
}
sal_Int32 SAL_CALL ODatabaseMetaData::getMaxUserNameLength()
{
- return impl_getInt32MetaData("getMaxUserNameLength", &sql::DatabaseMetaData::getMaxUserNameLength);
+ return 16;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetType(sal_Int32 setType)
{
- return impl_getRSTypeMetaData("supportsResultSetType", &sql::DatabaseMetaData::supportsResultSetType, setType);
+ return setType == ResultSetType::SCROLL_SENSITIVE;
}
-sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetConcurrency(sal_Int32 setType, sal_Int32 concurrency)
+sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetConcurrency(sal_Int32 /*setType*/, sal_Int32 /*concurrency*/)
{
- /* TODO: Check this out */
- try {
- return meta->supportsResultSetConcurrency(setType, concurrency==css::sdbc::TransactionIsolation::READ_COMMITTED?
- sql::TRANSACTION_READ_COMMITTED:
- (concurrency == css::sdbc::TransactionIsolation::SERIALIZABLE?
- sql::TRANSACTION_SERIALIZABLE:sql::TRANSACTION_SERIALIZABLE));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::supportsResultSetConcurrency", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::supportsResultSetConcurrency", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("ownUpdatesAreVisible", &sql::DatabaseMetaData::ownUpdatesAreVisible, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("ownDeletesAreVisible", &sql::DatabaseMetaData::ownDeletesAreVisible, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("ownInsertsAreVisible", &sql::DatabaseMetaData::ownInsertsAreVisible, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("othersUpdatesAreVisible", &sql::DatabaseMetaData::othersUpdatesAreVisible, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("othersDeletesAreVisible", &sql::DatabaseMetaData::othersDeletesAreVisible, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("othersInsertsAreVisible", &sql::DatabaseMetaData::othersInsertsAreVisible, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("updatesAreDetected", &sql::DatabaseMetaData::updatesAreDetected, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("deletesAreDetected", &sql::DatabaseMetaData::deletesAreDetected, setType);
+ return false;
}
-sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected(sal_Int32 setType)
+sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected(sal_Int32 /*setType*/)
{
- return impl_getRSTypeMetaData("insertsAreDetected", &sql::DatabaseMetaData::insertsAreDetected, setType);
+ return false;
}
sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates()
{
- return impl_getBoolMetaData("supportsBatchUpdates", &sql::DatabaseMetaData::supportsBatchUpdates);
+ return true;
}
Reference< XConnection > SAL_CALL ODatabaseMetaData::getConnection()
@@ -937,29 +882,6 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs()
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
- std::vector< std::vector< Any > > rRows;
-
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getCatalogs());
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getCatalogs", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getCatalogs", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
- lcl_setRows_throw(xResultSet, 0, rRows);
return xResultSet;
}
@@ -968,31 +890,32 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas()
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getSchemas());
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- bool informationSchema = false;
- for (sal_uInt32 i = 1; i <= columns; i++) {
- sql::SQLString columnStringValue = rset->getString(i);
- if (i == 1) { // TABLE_SCHEM
- informationSchema = (0 == columnStringValue.compare("information_schema"));
- }
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(columnStringValue, encoding)));
- }
- if (!informationSchema ) {
- rRows.push_back(aRow);
+ rtl::OUString sSql = m_rConnection.getMysqlVersion() > 49999?
+ rtl::OUString{"SELECT SCHEMA_NAME AS TABLE_SCHEM, CATALOG_NAME AS TABLE_CATALOG FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY SCHEMA_NAME"}:
+ rtl::OUString{"SHOW DATABASES"};
+
+ Reference< XStatement > statement = m_rConnection.createStatement();
+ Reference< XInterface > executed = statement->executeQuery(sSql);
+ Reference< XResultSet > rs( executed, UNO_QUERY_THROW);
+ Reference< XResultSetMetaDataSupplier > supp( executed, UNO_QUERY_THROW);
+ Reference< XResultSetMetaData > rs_meta = supp->getMetaData();
+
+ Reference< XRow > xRow( rs, UNO_QUERY_THROW );
+ sal_uInt32 columns = rs_meta->getColumnCount();
+ while( rs->next() )
+ {
+ std::vector< Any > aRow { Any() };
+ bool informationSchema = false;
+ for (sal_uInt32 i = 1; i <= columns; i++) {
+ rtl::OUString columnStringValue = xRow->getString(i);
+ if (i == 1) { // TABLE_SCHEM
+ informationSchema = (0 == columnStringValue.equalsIgnoreAsciiCase("information_schema"));
}
+ aRow.push_back(makeAny(columnStringValue));
+ }
+ if (!informationSchema ) {
+ rRows.push_back(aRow);
}
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getSchemas", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getSchemas", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
}
lcl_setRows_throw(xResultSet, 1, rRows);
@@ -1000,142 +923,169 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas()
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges(
- const Any& catalog,
+ const Any& /*catalog*/,
const rtl::OUString& schema,
const rtl::OUString& table,
const rtl::OUString& columnNamePattern)
{
- Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
- std::vector< std::vector< Any > > rRows;
+ rtl::OUString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS "
+ "TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, NULL AS GRANTOR, "
+ "GRANTEE, PRIVILEGE_TYPE AS PRIVILEGE, IS_GRANTABLE FROM "
+ "INFORMATION_SCHEMA.COLUMN_PRIVILEGES WHERE TABLE_SCHEMA LIKE "
+ "'?' AND TABLE_NAME='?' AND COLUMN_NAME LIKE '?' ORDER BY "
+ "COLUMN_NAME, PRIVILEGE_TYPE");
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sch(rtl::OUStringToOString(schema, m_rConnection.getConnectionEncoding()).getStr()),
- tab(rtl::OUStringToOString(table, m_rConnection.getConnectionEncoding()).getStr()),
- cNamePattern(rtl::OUStringToOString(columnNamePattern, m_rConnection.getConnectionEncoding()).getStr());
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getColumnPrivileges(cat, sch, tab, cNamePattern.compare("")? cNamePattern:wild));
-
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getColumnPrivileges", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getColumnPrivileges", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
+ query = query.replaceFirst("?", schema);
+ query = query.replaceFirst("?", table);
+ query = query.replaceFirst("?", columnNamePattern);
- lcl_setRows_throw(xResultSet, 2, rRows);
- return xResultSet;
+ Reference<XStatement> statement = m_rConnection.createStatement();
+ Reference<XResultSet> rs = statement->executeQuery(query);
+ return rs;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns(
- const Any& catalog,
- const rtl::OUString& schemaPattern,
+ const Any& /*catalog*/,
+ const rtl::OUString& /*schemaPattern*/,
const rtl::OUString& tableNamePattern,
const rtl::OUString& columnNamePattern)
{
- Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
- std::vector< std::vector< Any > > rRows;
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sPattern(rtl::OUStringToOString(schemaPattern, m_rConnection.getConnectionEncoding()).getStr()),
- tNamePattern(rtl::OUStringToOString(tableNamePattern, m_rConnection.getConnectionEncoding()).getStr()),
- cNamePattern(rtl::OUStringToOString(columnNamePattern, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- std::unique_ptr< sql::ResultSet> rset( meta->getColumns(cat,
- sPattern.compare("")? sPattern:wild,
- tNamePattern.compare("")? tNamePattern:wild,
- cNamePattern.compare("")? cNamePattern:wild));
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- if (i == 5) { // ColumnType
- sal_Int32 sdbc_type = mysqlc_sdbc_driver::mysqlToOOOType(atoi(rset->getString(i).c_str()));
- aRow.push_back(makeAny(sdbc_type));
- } else {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getColumns", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getColumns", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
+ rtl::OUStringBuffer queryBuf("SELECT TABLE_CATALOG AS TABLE_CAT, " // 1
+ "TABLE_SCHEMA AS TABLE_SCHEM, " // 2
+ "TABLE_NAME, " // 3
+ "COLUMN_NAME, " // 4
+ "DATA_TYPE, " // 5
+ // TYPE_NAME missing
+ "CHARACTER_MAXIMUM_LENGTH, " // 6
+ "NUMERIC_PRECISION, " // 7
+ // buffer length missing
+ "NUMERIC_SCALE AS DECIMAL_DIGITS, " // 8
+ // NUM_PREC_RADIX missing
+ // NULLABLE missing
+ "COLUMN_COMMENT AS REMARKS, " // 9
+ "COLUMN_DEFAULT AS COLUMN_DEF," // 10
+ "CHARACTER_OCTET_LENGTH, " // 11
+ "ORDINAL_POSITION, " // 12
+ "IS_NULLABLE, " // 13
+ "COLUMN_TYPE " // 14
+ "FROM INFORMATION_SCHEMA.COLUMNS "
+ "WHERE (1 = 1) ");
+
+ if (!tableNamePattern.isEmpty())
+ {
+ rtl::OUString sAppend;
+ if (tableNamePattern.match("%"))
+ sAppend = "AND TABLE_NAME LIKE '%' ";
+ else
+ sAppend = "AND TABLE_NAME = '%' ";
+ queryBuf.append(sAppend.replaceAll("%", tableNamePattern));
+ }
+ if (!columnNamePattern.isEmpty())
+ {
+ rtl::OUString sAppend;
+ if (columnNamePattern.match("%"))
+ sAppend = "AND COLUMN_NAME LIKE '%' ";
+ else
+ sAppend = "AND COLUMN_NAME = '%' ";
+ queryBuf.append(sAppend.replaceAll("%", columnNamePattern));
}
- lcl_setRows_throw(xResultSet, 3, rRows);
+
+ rtl::OUString query = queryBuf.makeStringAndClear();
+ Reference<XStatement> statement = m_rConnection.createStatement();
+ Reference<XResultSet> rs = statement->executeQuery(query.getStr());
+ Reference<XRow> xRow( rs, UNO_QUERY_THROW );
+
+ Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance(
+ "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
+ std::vector< std::vector< Any > > aRows;
+ while( rs->next() )
+ {
+ std::vector< Any > aRow { Any() }; // 0. element is unused
+
+ // catalog name
+ aRow.push_back(makeAny(xRow->getString(1)));
+ // schema name
+ aRow.push_back(makeAny(xRow->getString(2)));
+ // table name
+ aRow.push_back(makeAny(xRow->getString(3)));
+ // column name
+ aRow.push_back(makeAny(xRow->getString(4)));
+ // data type
+ rtl::OUString sDataType = xRow->getString(5);
+ aRow.push_back(makeAny(mysqlc_sdbc_driver::mysqlStrToOOOType(sDataType)));
+ // type name
+ aRow.push_back(makeAny(sDataType)); // TODO
+ // column size
+ sal_Int32 nColumnSize = 0;
+ rtl::OUString sColumnType = xRow->getString(14);
+ sal_Int32 nCharMaxLen = xRow->getShort(6);
+ bool bIsCharMax = !xRow->wasNull();
+ if( sDataType.equalsIgnoreAsciiCase("year") )
+ nColumnSize = sColumnType.copy(6, 1).toInt32(); // 'year(' length is 5
+ else if(sDataType.equalsIgnoreAsciiCase("date"))
+ nColumnSize = 10;
+ else if(sDataType.equalsIgnoreAsciiCase("date"))
+ nColumnSize = 8;
+ else if(sDataType.equalsIgnoreAsciiCase("datetime")
+ || sDataType.equalsIgnoreAsciiCase("timestamp"))
+ nColumnSize = 19;
+ else if(!bIsCharMax)
+ nColumnSize = xRow->getShort(7); // numeric precision
+ else
+ nColumnSize = nCharMaxLen;
+ aRow.push_back(makeAny(nColumnSize));
+ aRow.push_back( Any() ); // buffer length - unused
+ // decimal digits (scale)
+ aRow.push_back(makeAny(xRow->getShort(8)));
+ // num_prec_radix
+ aRow.push_back(makeAny(sal_Int32(10)));
+ // nullable
+ rtl::OUString sIsNullable = xRow->getString(13);
+ if(xRow->wasNull())
+ aRow.push_back(makeAny(ColumnValue::NULLABLE_UNKNOWN));
+ else if(sIsNullable.equalsIgnoreAsciiCase("YES"))
+ aRow.push_back(makeAny(ColumnValue::NULLABLE));
+ else
+ aRow.push_back(makeAny(ColumnValue::NO_NULLS));
+ // remarks
+ aRow.push_back(makeAny(xRow->getString(9)));
+ // default
+ aRow.push_back(makeAny(xRow->getString(10)));
+
+ aRow.push_back( Any{} ); // sql_data_type - unused
+ aRow.push_back( Any{} ); // sql_datetime_sub - unused
+
+ // character octet length
+ aRow.push_back(makeAny(xRow->getString(11)));
+ // ordinal position
+ aRow.push_back(makeAny(xRow->getString(12)));
+ // is nullable
+ aRow.push_back(makeAny(sIsNullable));
+ aRows.push_back(aRow);
+ }
+ lcl_setRows_throw(xResultSet, 1, aRows);
return xResultSet;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables(
- const Any& catalog,
+ const Any& /*catalog*/,
const rtl::OUString& schemaPattern,
const rtl::OUString& tableNamePattern,
- const Sequence< rtl::OUString >& types )
+ const Sequence< rtl::OUString >& /*types */)
{
- sal_Int32 nLength = types.getLength();
+ rtl::OUString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME,"
+ "IF(STRCMP(TABLE_TYPE,'BASE TABLE'), TABLE_TYPE, 'TABLE') AS TABLE_TYPE, TABLE_COMMENT AS REMARKS "
+ "FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA LIKE '?' AND TABLE_NAME LIKE '?' "
+ "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME");
- Reference< XResultSet > xResultSet(getOwnConnection().
- getDriver().getFactory()->createInstance(
- "org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
- std::vector< std::vector< Any > > rRows;
+ // TODO use prepared stmt instead
+ // TODO escape schema, table name ?
+ query = query.replaceFirst("?", schemaPattern);
+ query = query.replaceFirst("?", tableNamePattern);
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sPattern(rtl::OUStringToOString(schemaPattern, m_rConnection.getConnectionEncoding()).getStr()),
- tNamePattern(rtl::OUStringToOString(tableNamePattern, m_rConnection.getConnectionEncoding()).getStr());
-
- std::list<sql::SQLString> tabTypes;
- for (const rtl::OUString *pStart = types.getConstArray(), *p = pStart, *pEnd = pStart + nLength; p != pEnd; ++p) {
- tabTypes.push_back(rtl::OUStringToOString(*p, m_rConnection.getConnectionEncoding()).getStr());
- }
-
- try {
- std::unique_ptr< sql::ResultSet> rset( meta->getTables(cat,
- sPattern.compare("")? sPattern:wild,
- tNamePattern.compare("")? tNamePattern:wild,
- tabTypes));
-
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- bool informationSchema = false;
- for (sal_uInt32 i = 1; (i <= columns) && !informationSchema; ++i) {
- sql::SQLString columnStringValue = rset->getString(i);
- if (i == 2) { // TABLE_SCHEM
- informationSchema = ( 0 == columnStringValue.compare("information_schema"));
- }
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(columnStringValue, encoding)));
- }
- if (!informationSchema) {
- rRows.push_back(aRow);
- }
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getTables", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getTables", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
- lcl_setRows_throw(xResultSet, 4, rRows);
- return xResultSet;
+ Reference<XStatement> statement = m_rConnection.createStatement();
+ Reference<XResultSet> rs = statement->executeQuery(query);
+ return rs;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedureColumns(
@@ -1149,41 +1099,13 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedureColumns(
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedures(
- const Any& catalog,
- const rtl::OUString& schemaPattern,
- const rtl::OUString& procedureNamePattern)
+ const Any& /*catalog*/,
+ const rtl::OUString& /*schemaPattern*/,
+ const rtl::OUString& /*procedureNamePattern*/)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
-
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sPattern(rtl::OUStringToOString(schemaPattern, m_rConnection.getConnectionEncoding()).getStr()),
- procNamePattern(rtl::OUStringToOString(procedureNamePattern, m_rConnection.getConnectionEncoding()).getStr());
-
-
- try {
- std::unique_ptr< sql::ResultSet> rset( meta->getProcedures(cat,
- sPattern.compare("")? sPattern:wild,
- procNamePattern.compare("")? procNamePattern:wild));
-
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getProcedures", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getProcedures", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO IMPL
lcl_setRows_throw(xResultSet, 7,rRows);
return xResultSet;
}
@@ -1200,283 +1122,101 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getVersionColumns(
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getExportedKeys(
- const Any& catalog ,
- const rtl::OUString& schema ,
- const rtl::OUString& table )
+ const Any& /*catalog */,
+ const rtl::OUString& /*schema */,
+ const rtl::OUString& /*table */)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sch(rtl::OUStringToOString(schema, m_rConnection.getConnectionEncoding()).getStr()),
- tab(rtl::OUStringToOString(table, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getExportedKeys(cat, sch, tab));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getExportedKeys", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getExportedKeys", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO implement
lcl_setRows_throw(xResultSet, 8, rRows);
return xResultSet;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getImportedKeys(
- const Any& catalog,
- const rtl::OUString& schema,
- const rtl::OUString& table)
+ const Any& /*catalog*/,
+ const rtl::OUString& /*schema*/,
+ const rtl::OUString& /*table*/)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
-
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sch(rtl::OUStringToOString(schema, m_rConnection.getConnectionEncoding()).getStr()),
- tab(rtl::OUStringToOString(table, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getImportedKeys(cat, sch, tab));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getImportedKeys", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getImportedKeys", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO implement
lcl_setRows_throw(xResultSet,9,rRows);
return xResultSet;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys(
- const Any& catalog,
+ const Any& /*catalog*/,
const rtl::OUString& schema,
const rtl::OUString& table)
{
- Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
- std::vector< std::vector< Any > > rRows;
-
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sch(rtl::OUStringToOString(schema, m_rConnection.getConnectionEncoding()).getStr()),
- tab(rtl::OUStringToOString(table, m_rConnection.getConnectionEncoding()).getStr());
+ rtl::OUString query("SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA "
+ "AS TABLE_SCHEM, TABLE_NAME, " "COLUMN_NAME, SEQ_IN_INDEX AS KEY_SEQ,"
+ "INDEX_NAME AS PK_NAME FROM INFORMATION_SCHEMA.STATISTICS "
+ "WHERE TABLE_SCHEMA LIKE '?' AND TABLE_NAME LIKE '?' AND INDEX_NAME='PRIMARY' "
+ "ORDER BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX");
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getPrimaryKeys(cat, sch, tab));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getPrimaryKeys", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getPrimaryKeys", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
+ // TODO use prepared stmt instead
+ // TODO escape schema, table name ?
+ query = query.replaceFirst("?", schema);
+ query = query.replaceFirst("?", table);
- lcl_setRows_throw(xResultSet, 10, rRows);
- return xResultSet;
+ Reference<XStatement> statement = m_rConnection.createStatement();
+ Reference<XResultSet> rs = statement->executeQuery(query);
+ return rs;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo(
- const Any& catalog,
- const rtl::OUString& schema,
- const rtl::OUString& table,
- sal_Bool unique,
- sal_Bool approximate)
+ const Any& /*catalog*/,
+ const rtl::OUString& /*schema*/,
+ const rtl::OUString& /*table*/,
+ sal_Bool /*unique*/,
+ sal_Bool /*approximate*/)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
-
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sch(rtl::OUStringToOString(schema, m_rConnection.getConnectionEncoding()).getStr()),
- tab(rtl::OUStringToOString(table, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getIndexInfo(cat, sch, tab, unique, approximate));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getIndexInfo", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getIndexInfo", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO
lcl_setRows_throw(xResultSet, 11, rRows);
return xResultSet;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getBestRowIdentifier(
- const Any& catalog,
- const rtl::OUString& schema,
- const rtl::OUString& table,
- sal_Int32 scope,
- sal_Bool nullable)
+ const Any& /*catalog*/,
+ const rtl::OUString& /*schema*/,
+ const rtl::OUString& /*table*/,
+ sal_Int32 /*scope*/,
+ sal_Bool /*nullable*/)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
-
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sch(rtl::OUStringToOString(schema, m_rConnection.getConnectionEncoding()).getStr()),
- tab(rtl::OUStringToOString(table, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getBestRowIdentifier(cat, sch, tab, scope, nullable));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getBestRowIdentifier", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getBestRowIdentifier", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO
lcl_setRows_throw(xResultSet, 15, rRows);
return xResultSet;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTablePrivileges(
- const Any& catalog,
- const rtl::OUString& schemaPattern,
- const rtl::OUString& tableNamePattern)
+ const Any& /*catalog*/,
+ const rtl::OUString& /*schemaPattern*/,
+ const rtl::OUString& /*tableNamePattern*/)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
-
- std::string cat(catalog.hasValue()? rtl::OUStringToOString(getStringFromAny(catalog), m_rConnection.getConnectionEncoding()).getStr():""),
- sPattern(rtl::OUStringToOString(schemaPattern, m_rConnection.getConnectionEncoding()).getStr()),
- tPattern(rtl::OUStringToOString(tableNamePattern, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- static bool fakeTablePrivileges = false;
- if (fakeTablePrivileges) {
- static const sal_Char* allPrivileges[] = {
- "ALTER", "DELETE", "DROP", "INDEX", "INSERT", "LOCK TABLES", "SELECT", "UPDATE"
- };
- Any userName; userName <<= getUserName();
- for (size_t i = 0; i < SAL_N_ELEMENTS( allPrivileges ); ++i) {
- std::vector< Any > aRow;
- aRow.push_back(makeAny( sal_Int32( i ) ));
- aRow.push_back(catalog); // TABLE_CAT
- aRow.push_back(makeAny( schemaPattern )); // TABLE_SCHEM
- aRow.push_back(makeAny( tableNamePattern )); // TABLE_NAME
- aRow.push_back(Any()); // GRANTOR
- aRow.push_back(userName); // GRANTEE
- aRow.push_back(makeAny( rtl::OUString::createFromAscii( allPrivileges[i] ) )); // PRIVILEGE
- aRow.push_back(Any()); // IS_GRANTABLE
-
- rRows.push_back(aRow);
- }
- } else {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getTablePrivileges(cat, sPattern.compare("")? sPattern:wild, tPattern.compare("")? tPattern:wild));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getTablePrivileges", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getTablePrivileges", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO
lcl_setRows_throw(xResultSet,12,rRows);
return xResultSet;
}
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCrossReference(
- const Any& primaryCatalog,
- const rtl::OUString& primarySchema_,
- const rtl::OUString& primaryTable_,
- const Any& foreignCatalog,
- const rtl::OUString& foreignSchema,
- const rtl::OUString& foreignTable)
+ const Any& /*primaryCatalog*/,
+ const rtl::OUString& /*primarySchema_*/,
+ const rtl::OUString& /*primaryTable_*/,
+ const Any& /*foreignCatalog*/,
+ const rtl::OUString& /*foreignSchema*/,
+ const rtl::OUString& /*foreignTable*/)
{
Reference< XResultSet > xResultSet(getOwnConnection().getDriver().getFactory()->createInstance("org.openoffice.comp.helper.DatabaseMetaDataResultSet"),UNO_QUERY);
std::vector< std::vector< Any > > rRows;
-
- std::string primaryCat(primaryCatalog.hasValue()? rtl::OUStringToOString(getStringFromAny(primaryCatalog), m_rConnection.getConnectionEncoding()).getStr():""),
- foreignCat(foreignCatalog.hasValue()? rtl::OUStringToOString(getStringFromAny(foreignCatalog), m_rConnection.getConnectionEncoding()).getStr():""),
- primarySchema(rtl::OUStringToOString(primarySchema_, m_rConnection.getConnectionEncoding()).getStr()),
- primaryTable(rtl::OUStringToOString(primaryTable_, m_rConnection.getConnectionEncoding()).getStr()),
- fSchema(rtl::OUStringToOString(foreignSchema, m_rConnection.getConnectionEncoding()).getStr()),
- fTable(rtl::OUStringToOString(foreignTable, m_rConnection.getConnectionEncoding()).getStr());
-
- try {
- rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding();
- std::unique_ptr< sql::ResultSet> rset( meta->getCrossReference(primaryCat, primarySchema, primaryTable, foreignCat, fSchema, fTable));
- sql::ResultSetMetaData * rs_meta = rset->getMetaData();
- sal_uInt32 columns = rs_meta->getColumnCount();
- while (rset->next()) {
- std::vector< Any > aRow { Any() };
- for (sal_uInt32 i = 1; i <= columns; i++) {
- aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding)));
- }
- rRows.push_back(aRow);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("ODatabaseMetaData::getCrossReference", *this);
- } catch (const sql::InvalidArgumentException &) {
- mysqlc_sdbc_driver::throwInvalidArgumentException("ODatabaseMetaData::getCrossReference", *this);
- } catch (const sql::SQLException& e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_rConnection.getConnectionEncoding());
- }
-
+ // TODO
lcl_setRows_throw(xResultSet,13,rRows);
return xResultSet;
}
@@ -1491,13 +1231,4 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getUDTs(
return nullptr;
}
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_databasemetadata.hxx b/mysqlc/source/mysqlc_databasemetadata.hxx
index 9f09e534215d..3801acadc4a7 100644
--- a/mysqlc/source/mysqlc_databasemetadata.hxx
+++ b/mysqlc/source/mysqlc_databasemetadata.hxx
@@ -42,7 +42,7 @@ namespace connectivity
class ODatabaseMetaData final : public ODatabaseMetaData_BASE
{
OConnection& m_rConnection;
- sql::DatabaseMetaData * meta;
+ MYSQL * m_pMySql;
rtl::OUString identifier_quote_string;
bool identifier_quote_string_set;
@@ -56,7 +56,7 @@ namespace connectivity
public:
const OConnection& getOwnConnection() const { return m_rConnection; }
- explicit ODatabaseMetaData(OConnection& _rCon);
+ explicit ODatabaseMetaData(OConnection& _rCon, MYSQL* pMySql);
virtual ~ODatabaseMetaData();
// as I mentioned before this interface is really BIG
diff --git a/mysqlc/source/mysqlc_driver.cxx b/mysqlc/source/mysqlc_driver.cxx
index 18e2db4cb9ae..40cab769e912 100644
--- a/mysqlc/source/mysqlc_driver.cxx
+++ b/mysqlc/source/mysqlc_driver.cxx
@@ -198,7 +198,7 @@ Reference< XConnection > SAL_CALL MysqlCDriver::connect(const rtl::OUString& url
Reference< XConnection > xConn;
// create a new connection with the given properties and append it to our vector
try {
- OConnection* pCon = new OConnection(*this, cppDriver);
+ OConnection* pCon = new OConnection(*this);
xConn = pCon;
pCon->construct(url,info);
diff --git a/mysqlc/source/mysqlc_general.cxx b/mysqlc/source/mysqlc_general.cxx
index 2c4eb1f53853..8f3d0ed619d2 100644
--- a/mysqlc/source/mysqlc_general.cxx
+++ b/mysqlc/source/mysqlc_general.cxx
@@ -19,8 +19,7 @@
#include "mysqlc_general.hxx"
#include "mysqlc_resultsetmetadata.hxx"
-#include <cppconn/exception.h>
-#include <cppconn/datatype.h>
+#include <rtl/ustring.hxx>
using com::sun::star::sdbc::SQLException;
@@ -28,10 +27,77 @@ using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Any;
+using namespace rtl;
+
namespace mysqlc_sdbc_driver
{
-void throwFeatureNotImplementedException( const sal_Char* _pAsciiFeatureName, const Reference< XInterface >& _rxContext )
+void allocateSqlVar(void** mem, enum_field_types eType, unsigned nSize)
+{
+ assert(mem);
+ switch(eType)
+ {
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_INT24:
+ *mem = malloc(sizeof(sal_Int32));
+ break;
+ case MYSQL_TYPE_SHORT:
+ *mem = malloc(sizeof(sal_Int16));
+ break;
+ case MYSQL_TYPE_BIT:
+ case MYSQL_TYPE_TINY:
+ *mem = malloc(sizeof(sal_Int8));
+ break;
+ case MYSQL_TYPE_LONGLONG:
+ *mem = malloc(sizeof(sal_Int64));
+ break;
+ case MYSQL_TYPE_FLOAT:
+ *mem = malloc(sizeof(float));
+ break;
+ case MYSQL_TYPE_DOUBLE:
+ *mem = malloc(sizeof(double));
+ break;
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_YEAR: // FIXME below
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_GEOMETRY:
+ *mem = malloc(sizeof(MYSQL_TIME));
+ break;
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_NEWDECIMAL:
+ *mem = malloc(sizeof(char)*nSize);
+ break;
+ case MYSQL_TYPE_NULL:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ *mem = nullptr;
+ break;
+ default:
+ SAL_WARN("connectivity","unknown enum_field_type");
+ }
+}
+
+/// Use this intead of mysql_real_escape_string, because that one also escapes
+/// single quote ('), which should not be escaped
+rtl::OString escapeSql( const rtl::OString& from )
+{
+ rtl::OString sRet = from.replaceAll("\\", "\\\\");
+ sRet = sRet.replaceAll("\"", "\\\"");
+ sRet = sRet.replaceAll("`", "\\`");
+ return sRet;
+}
+
+void throwFeatureNotImplementedException( const sal_Char* _pAsciiFeatureName, const css::uno::Reference< XInterface >& _rxContext )
{
const rtl::OUString sMessage = rtl::OUString::createFromAscii( _pAsciiFeatureName ) + ": feature not implemented.";
throw SQLException(
@@ -43,7 +109,7 @@ void throwFeatureNotImplementedException( const sal_Char* _pAsciiFeatureName, co
);
}
-void throwInvalidArgumentException( const sal_Char* _pAsciiFeatureName, const Reference< XInterface >& _rxContext )
+void throwInvalidArgumentException( const sal_Char* _pAsciiFeatureName, const css::uno::Reference< XInterface >& _rxContext )
{
const rtl::OUString sMessage = rtl::OUString::createFromAscii( _pAsciiFeatureName ) + ": invalid arguments.";
throw SQLException(
@@ -66,6 +132,14 @@ void translateAndThrow(const ::sql::SQLException& _error, const css::uno::Refere
);
}
+void throwSQLExceptionWithMsg(const char* msg, unsigned int errorNum, const css::uno::Reference< css::uno::XInterface >& _context, const rtl_TextEncoding encoding)
+{
+ rtl::OString errorMsg{msg};
+ // TODO error code?
+ throw SQLException( rtl::OStringToOUString(errorMsg, encoding),
+ _context, rtl::OUString(), errorNum, Any());
+}
+
rtl::OUString getStringFromAny(const Any& _rAny)
{
rtl::OUString nReturn;
@@ -73,77 +147,195 @@ rtl::OUString getStringFromAny(const Any& _rAny)
return nReturn;
}
-int mysqlToOOOType(int cppConnType)
- throw ()
+int mysqlToOOOType(int eType, int charsetnr) noexcept
{
- switch (cppConnType) {
- case sql::DataType::BIT:
+ // charset number 63 indicates binary
+ switch (eType) {
+ case MYSQL_TYPE_BIT:
return css::sdbc::DataType::VARCHAR;
- case sql::DataType::TINYINT:
+ case MYSQL_TYPE_TINY:
return css::sdbc::DataType::TINYINT;
- case sql::DataType::SMALLINT:
+ case MYSQL_TYPE_SHORT:
return css::sdbc::DataType::SMALLINT;
- case sql::DataType::INTEGER:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_LONG:
return css::sdbc::DataType::INTEGER;
- case sql::DataType::BIGINT:
+ case MYSQL_TYPE_LONGLONG:
return css::sdbc::DataType::BIGINT;
- case sql::DataType::REAL:
+ case MYSQL_TYPE_FLOAT:
return css::sdbc::DataType::REAL;
- case sql::DataType::DOUBLE:
+ case MYSQL_TYPE_DOUBLE:
return css::sdbc::DataType::DOUBLE;
- case sql::DataType::DECIMAL:
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_NEWDECIMAL:
return css::sdbc::DataType::DECIMAL;
- case sql::DataType::CHAR:
+ case MYSQL_TYPE_STRING:
+ if(charsetnr == 63)
+ return css::sdbc::DataType::BINARY;
return css::sdbc::DataType::CHAR;
- case sql::DataType::BINARY:
- return css::sdbc::DataType::BINARY;
-
- case sql::DataType::ENUM:
- case sql::DataType::SET:
- case sql::DataType::VARCHAR:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_VAR_STRING:
+ if(charsetnr == 63)
+ return css::sdbc::DataType::VARBINARY;
return css::sdbc::DataType::VARCHAR;
- case sql::DataType::VARBINARY:
- return css::sdbc::DataType::VARBINARY;
-
- case sql::DataType::LONGVARCHAR:
+ case MYSQL_TYPE_BLOB:
+ if(charsetnr == 63)
+ return css::sdbc::DataType::LONGVARBINARY;
return css::sdbc::DataType::LONGVARCHAR;
- case sql::DataType::LONGVARBINARY:
- return css::sdbc::DataType::LONGVARBINARY;
-
- case sql::DataType::TIMESTAMP:
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DATETIME:
return css::sdbc::DataType::TIMESTAMP;
- case sql::DataType::DATE:
+ case MYSQL_TYPE_DATE:
return css::sdbc::DataType::DATE;
- case sql::DataType::TIME:
+ case MYSQL_TYPE_TIME:
return css::sdbc::DataType::TIME;
- case sql::DataType::GEOMETRY:
+ case MYSQL_TYPE_GEOMETRY:
return css::sdbc::DataType::VARCHAR;
- case sql::DataType::SQLNULL:
+ case MYSQL_TYPE_NULL:
return css::sdbc::DataType::SQLNULL;
-
- case sql::DataType::UNKNOWN:
- return css::sdbc::DataType::VARCHAR;
}
OSL_FAIL( "mysqlToOOOType: unhandled case, falling back to VARCHAR" );
return css::sdbc::DataType::VARCHAR;
}
+int mysqlStrToOOOType(const rtl::OUString& sType)
+{
+ // TODO other types.
+ if(sType.equalsIgnoreAsciiCase("tiny") || sType.equalsIgnoreAsciiCase("tinyint"))
+ return css::sdbc::DataType::TINYINT;
+ if(sType.equalsIgnoreAsciiCase("smallint"))
+ return css::sdbc::DataType::SMALLINT;
+ if(sType.equalsIgnoreAsciiCase("longtext"))
+ return css::sdbc::DataType::LONGVARCHAR;
+ if(sType.equalsIgnoreAsciiCase("int"))
+ return css::sdbc::DataType::INTEGER;
+ if(sType.equalsIgnoreAsciiCase("varchar") || sType.equalsIgnoreAsciiCase("set") ||
+ sType.equalsIgnoreAsciiCase("enum"))
+ return css::sdbc::DataType::VARCHAR;
+ if(sType.equalsIgnoreAsciiCase("bigint"))
+ return css::sdbc::DataType::BIGINT;
+ if(sType.equalsIgnoreAsciiCase("blob") || sType.equalsIgnoreAsciiCase("longblob"))
+ return css::sdbc::DataType::BLOB;
+ if(sType.equalsIgnoreAsciiCase("varbinary"))
+ return css::sdbc::DataType::VARBINARY;
+ if(sType.equalsIgnoreAsciiCase("text"))
+ return css::sdbc::DataType::CHAR;
+ if(sType.equalsIgnoreAsciiCase("binary"))
+ return css::sdbc::DataType::BINARY;
+ if(sType.equalsIgnoreAsciiCase("time"))
+ return css::sdbc::DataType::TIME;
+ if(sType.equalsIgnoreAsciiCase("date"))
+ return css::sdbc::DataType::DATE;
+ if(sType.equalsIgnoreAsciiCase("datetime"))
+ return css::sdbc::DataType::TIMESTAMP;
+ if(sType.equalsIgnoreAsciiCase("decimal"))
+ return css::sdbc::DataType::DECIMAL;
+ if(sType.equalsIgnoreAsciiCase("real") || sType.equalsIgnoreAsciiCase("float"))
+ return css::sdbc::DataType::REAL;
+ if(sType.equalsIgnoreAsciiCase("double"))
+ return css::sdbc::DataType::DOUBLE;
+ if(sType.equalsIgnoreAsciiCase("bit") || sType.equalsIgnoreAsciiCase("bool") ||
+ sType.equalsIgnoreAsciiCase("boolean"))
+ return css::sdbc::DataType::BOOLEAN;
+ OSL_FAIL("Unknown type name from string, failing back to varchar.");
+ return css::sdbc::DataType::VARCHAR;
+}
+
+rtl::OUString mysqlTypeToStr(MYSQL_FIELD* field)
+{
+ bool isUnsigned = (field->flags & UNSIGNED_FLAG) != 0;
+ bool isZerofill = (field->flags & ZEROFILL_FLAG) != 0;
+ switch (field->type)
+ {
+ case MYSQL_TYPE_BIT:
+ return OUString{"BIT"};
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_NEWDECIMAL:
+ return isUnsigned ? (isZerofill? OUString{"DECIMAL UNSIGNED ZEROFILL"} : OUString{"DECIMAL UNSIGNED"}): OUString{"DECIMAL"};
+ case MYSQL_TYPE_TINY:
+ return isUnsigned ? (isZerofill? OUString{"TINYINT UNSIGNED ZEROFILL"} : OUString{"TINYINT UNSIGNED"}): OUString{"TINYINT"};
+ case MYSQL_TYPE_SHORT:
+ return isUnsigned ? (isZerofill? OUString{"SMALLINT UNSIGNED ZEROFILL"} : OUString{"SMALLINT UNSIGNED"}): OUString{"SMALLINT"};
+ case MYSQL_TYPE_LONG:
+ return isUnsigned ? (isZerofill? OUString{"INT UNSIGNED ZEROFILL"} : OUString{"INT UNSIGNED"}): OUString{"INT"};
+ case MYSQL_TYPE_FLOAT:
+ return isUnsigned ? (isZerofill? OUString{"FLOAT UNSIGNED ZEROFILL"} : OUString{"FLOAT UNSIGNED"}): OUString{"FLOAT"};
+ case MYSQL_TYPE_DOUBLE:
+ return isUnsigned ? (isZerofill? OUString{"DOUBLE UNSIGNED ZEROFILL"} : OUString{"DOUBLE UNSIGNED"}): OUString{"DOUBLE"};
+ case MYSQL_TYPE_NULL:
+ return OUString{"NULL"};
+ case MYSQL_TYPE_TIMESTAMP:
+ return OUString{"TIMESTAMP"};
+ case MYSQL_TYPE_LONGLONG:
+ return isUnsigned ? (isZerofill? OUString{"BIGINT UNSIGNED ZEROFILL"} : OUString{"BIGINT UNSIGNED"}) : OUString{"BIGINT"};
+ case MYSQL_TYPE_INT24:
+ return isUnsigned ? (isZerofill? OUString{"MEDIUMINT UNSIGNED ZEROFILL"} : OUString{"MEDIUMINT UNSIGNED"}) : OUString{"MEDIUMINT"};
+ case MYSQL_TYPE_DATE:
+ return OUString{"DATE"};
+ case MYSQL_TYPE_TIME:
+ return OUString{"TIME"};
+ case MYSQL_TYPE_DATETIME:
+ return OUString{"DATETIME"};
+ case MYSQL_TYPE_TINY_BLOB:
+ {
+ return OUString{"TINYBLOB"};
+ }
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ {
+ return OUString{"MEDIUMBLOB"};
+ }
+ case MYSQL_TYPE_LONG_BLOB:
+ {
+ return OUString{"LONGBLOB"};
+ }
+ case MYSQL_TYPE_BLOB:
+ {
+ return OUString{"BLOB"};
+ }
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_VAR_STRING:
+ if (field->flags & ENUM_FLAG) {
+ return OUString{"ENUM"};
+ }
+ if (field->flags & SET_FLAG) {
+ return OUString{"SET"};
+ }
+ return OUString{"VARCHAR"};
+ case MYSQL_TYPE_STRING:
+ if (field->flags & ENUM_FLAG) {
+ return OUString{"ENUM"};
+ }
+ if (field->flags & SET_FLAG) {
+ return OUString{"SET"};
+ }
+ return OUString{"CHAR"};
+ case MYSQL_TYPE_YEAR:
+ return OUString{"YEAR"};
+ case MYSQL_TYPE_GEOMETRY:
+ return OUString{"GEOMETRY"};
+ default:
+ return OUString{"UNKNOWN"};
+ }
+
+}
+
rtl::OUString convert(const ::std::string& _string, const rtl_TextEncoding encoding)
{
return rtl::OUString( _string.c_str(), _string.size(), encoding );
diff --git a/mysqlc/source/mysqlc_general.hxx b/mysqlc/source/mysqlc_general.hxx
index 5d0b828c3e51..43544a2a172e 100644
--- a/mysqlc/source/mysqlc_general.hxx
+++ b/mysqlc/source/mysqlc_general.hxx
@@ -25,6 +25,9 @@
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/sdbc/SQLException.hpp>
+#include <osl/diagnose.h>
+#include <mysql.h>
+
#if defined __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
@@ -36,6 +39,61 @@
namespace mysqlc_sdbc_driver
{
+ template<typename T>
+ void resetSqlVar(void** target, T* pValue, enum_field_types type, sal_Int32 nSize = 0)
+ {
+ if(*target)
+ {
+ free(*target);
+ *target = nullptr;
+ }
+ constexpr auto nUnitSize = sizeof(T);
+ switch(type)
+ {
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_YEAR:
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_BIT:
+ case MYSQL_TYPE_GEOMETRY:
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_LONGLONG:
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ *target = malloc(nUnitSize);
+ memcpy(*target, pValue, nUnitSize);
+ break;
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_NEWDECIMAL:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ *target = malloc(nUnitSize*nSize);
+ memcpy(*target, pValue, nUnitSize*nSize);
+ break;
+ case MYSQL_TYPE_NULL:
+ // nothing I guess
+ break;
+ default:
+ OSL_FAIL("resetSqlVar: unknown enum_field_type");
+ }
+ }
+
+ void allocateSqlVar(void** mem, enum_field_types eType, unsigned nSize = 0);
+
+ rtl::OString escapeSql(const rtl::OString& from);
+
rtl::OUString getStringFromAny(const css::uno::Any& _rAny);
/// @throws css::sdbc::SQLException
@@ -52,8 +110,13 @@ namespace mysqlc_sdbc_driver
void translateAndThrow(const ::sql::SQLException& _error, const css::uno::Reference< css::uno::XInterface >& _context, const rtl_TextEncoding encoding);
- int mysqlToOOOType(int mysqlType) throw ();
+ void throwSQLExceptionWithMsg(const char* msg, unsigned int errorNum, const css::uno::Reference< css::uno::XInterface >& _context, const rtl_TextEncoding encoding);
+
+ int mysqlToOOOType(int eType, int charsetnr) noexcept;
+
+ rtl::OUString mysqlTypeToStr(MYSQL_FIELD* pField);
+ int mysqlStrToOOOType(const rtl::OUString& sType);
rtl::OUString convert(const ::std::string& _string, const rtl_TextEncoding encoding);
diff --git a/mysqlc/source/mysqlc_prepared_resultset.cxx b/mysqlc/source/mysqlc_prepared_resultset.cxx
new file mode 100644
index 000000000000..3bc6b9424752
--- /dev/null
+++ b/mysqlc/source/mysqlc_prepared_resultset.cxx
@@ -0,0 +1,1097 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "mysqlc_propertyids.hxx"
+#include "mysqlc_general.hxx"
+#include "mysqlc_prepared_resultset.hxx"
+#include "mysqlc_resultsetmetadata.hxx"
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/sdbc/FetchDirection.hpp>
+#include <com/sun/star/sdbcx/CompareBookmark.hpp>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+using namespace rtl;
+#include <comphelper/string.hxx>
+
+#include <cstdlib>
+
+using namespace connectivity::mysqlc;
+using namespace cppu;
+using namespace com::sun::star;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::sdbcx;
+using namespace com::sun::star::container;
+using namespace com::sun::star::io;
+using namespace com::sun::star::util;
+using namespace ::comphelper;
+using ::osl::MutexGuard;
+
+#include <cppconn/resultset.h>
+#include <cppconn/resultset_metadata.h>
+
+#include <stdio.h>
+
+rtl::OUString SAL_CALL OPreparedResultSet::getImplementationName()
+{
+ return rtl::OUString("com.sun.star.sdbcx.mysqlc.ResultSet");
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL OPreparedResultSet::getSupportedServiceNames()
+{
+ uno::Sequence<rtl::OUString> aSupported(2);
+ aSupported[0] = "com.sun.star.sdbc.ResultSet";
+ aSupported[1] = "com.sun.star.sdbcx.ResultSet";
+ return aSupported;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::supportsService(const rtl::OUString& _rServiceName)
+{
+ return cppu::supportsService(this, _rServiceName);
+}
+OPreparedResultSet::OPreparedResultSet(OConnection& rConn, OPreparedStatement* pPrepared,
+ MYSQL_STMT* pStmt)
+ : OPreparedResultSet_BASE(m_aMutex)
+ , OPropertySetHelper(OPreparedResultSet_BASE::rBHelper)
+ , m_rConnection(rConn)
+ , m_aStatement(static_cast<OWeakObject*>(pPrepared))
+ , m_xMetaData(nullptr)
+ , m_pStmt(pStmt)
+ , m_encoding(rConn.getConnectionEncoding())
+{
+ m_nFieldCount = mysql_stmt_field_count(pStmt);
+ m_pResult = mysql_stmt_result_metadata(m_pStmt);
+ m_aFields = mysql_fetch_fields(m_pResult);
+}
+
+OPreparedResultSet::~OPreparedResultSet() {}
+
+void OPreparedResultSet::disposing()
+{
+ OPropertySetHelper::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+
+ m_aStatement = nullptr;
+ m_xMetaData = nullptr;
+}
+
+Any SAL_CALL OPreparedResultSet::queryInterface(const Type& rType)
+{
+ Any aRet = OPropertySetHelper::queryInterface(rType);
+ if (!aRet.hasValue())
+ {
+ aRet = OPreparedResultSet_BASE::queryInterface(rType);
+ }
+ return aRet;
+}
+
+uno::Sequence<Type> SAL_CALL OPreparedResultSet::getTypes()
+{
+ OTypeCollection aTypes(cppu::UnoType<XMultiPropertySet>::get(),
+ cppu::UnoType<XFastPropertySet>::get(),
+ cppu::UnoType<XPropertySet>::get());
+
+ return concatSequences(aTypes.getTypes(), OPreparedResultSet_BASE::getTypes());
+}
+
+sal_Int32 SAL_CALL OPreparedResultSet::findColumn(const rtl::OUString& columnName)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ MYSQL_FIELD* pFields = mysql_fetch_field(m_pResult);
+ for (sal_Int32 i = 0; i < m_nFieldCount; ++i)
+ {
+ if (columnName.equalsIgnoreAsciiCaseAscii(pFields[i].name))
+ return i + 1; // sdbc indexes from 1
+ }
+
+ throw SQLException("The column name '" + columnName + "' is not valid.", *this,
+ rtl::OUString("42S22"), 0, Any());
+}
+
+uno::Reference<XInputStream> SAL_CALL OPreparedResultSet::getBinaryStream(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBinaryStream",
+ *this);
+ return nullptr;
+}
+
+uno::Reference<XInputStream> SAL_CALL OPreparedResultSet::getCharacterStream(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException(
+ "OPreparedResultSet::getCharacterStream", *this);
+ return nullptr;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::getBoolean(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return false;
+ }
+ m_bWasNull = false;
+ return *reinterpret_cast<bool*>(m_aData[column - 1].buffer);
+}
+
+sal_Int8 SAL_CALL OPreparedResultSet::getByte(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return 0;
+ }
+ m_bWasNull = false;
+ return *reinterpret_cast<sal_Int8*>(m_aData[column - 1].buffer);
+}
+
+uno::Sequence<sal_Int8> SAL_CALL OPreparedResultSet::getBytes(sal_Int32 column)
+{
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ MutexGuard aGuard(m_aMutex);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return uno::Sequence<sal_Int8>();
+ }
+ m_bWasNull = false;
+
+ return uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const*>(m_aData[column - 1].buffer),
+ *m_aData[column - 1].length);
+}
+
+Date SAL_CALL OPreparedResultSet::getDate(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return Date{}; // TODO init
+ }
+ m_bWasNull = false;
+
+ const MYSQL_TIME* pTime = reinterpret_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
+
+ assert(pTime != nullptr);
+
+ Date d;
+ d.Year = pTime->year;
+ d.Month = pTime->month;
+ d.Day = pTime->day;
+ return d;
+}
+
+double SAL_CALL OPreparedResultSet::getDouble(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return double{};
+ }
+ m_bWasNull = false;
+
+ return *reinterpret_cast<double*>(m_aData[column - 1].buffer);
+}
+
+float SAL_CALL OPreparedResultSet::getFloat(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return float{};
+ }
+ m_bWasNull = false;
+
+ return *reinterpret_cast<float*>(m_aData[column - 1].buffer);
+}
+
+sal_Int32 SAL_CALL OPreparedResultSet::getInt(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return sal_Int32{};
+ }
+ m_bWasNull = false;
+
+ return *reinterpret_cast<sal_Int32*>(m_aData[column - 1].buffer);
+}
+
+sal_Int32 SAL_CALL OPreparedResultSet::getRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return static_cast<sal_Int32>(mysql_field_tell(m_pResult));
+}
+
+sal_Int64 SAL_CALL OPreparedResultSet::getLong(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ return sal_Int64{};
+
+ return *reinterpret_cast<sal_Int64*>(m_aData[column - 1].buffer);
+}
+
+uno::Reference<XResultSetMetaData> SAL_CALL OPreparedResultSet::getMetaData()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ if (!m_xMetaData.is())
+ {
+ m_xMetaData = new OResultSetMetaData(m_rConnection, m_pResult, m_encoding);
+ }
+ return m_xMetaData;
+}
+
+uno::Reference<XArray> SAL_CALL OPreparedResultSet::getArray(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getArray", *this);
+ return nullptr;
+}
+
+uno::Reference<XClob> SAL_CALL OPreparedResultSet::getClob(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getClob", *this);
+ return nullptr;
+}
+
+uno::Reference<XBlob> SAL_CALL OPreparedResultSet::getBlob(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBlob", *this);
+ return nullptr;
+}
+
+uno::Reference<XRef> SAL_CALL OPreparedResultSet::getRef(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getRef", *this);
+ return nullptr;
+}
+
+Any SAL_CALL OPreparedResultSet::getObject(sal_Int32 column,
+ const uno::Reference<XNameAccess>& /* typeMap */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ Any aRet = Any();
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getObject", *this);
+ return aRet;
+}
+
+sal_Int16 SAL_CALL OPreparedResultSet::getShort(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return sal_Int16{};
+ }
+ m_bWasNull = false;
+
+ return *reinterpret_cast<sal_Int16*>(m_aData[column - 1].buffer);
+}
+
+rtl::OUString SAL_CALL OPreparedResultSet::getString(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return OUString{};
+ }
+ m_bWasNull = false;
+
+ if (m_aFields[column - 1].type == MYSQL_TYPE_BIT)
+ {
+ if (*reinterpret_cast<sal_Int8*>(m_aData[column - 1].buffer) != 0)
+ return OUString{ "YES" };
+ return OUString{ "NO" };
+ }
+
+ const char* sStr = reinterpret_cast<const char*>(m_aData[column - 1].buffer);
+
+ OUString sReturn = rtl::OUString(sStr, *m_aData[column - 1].length, m_encoding);
+ return sReturn;
+}
+
+Time SAL_CALL OPreparedResultSet::getTime(sal_Int32 column)
+{
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ MutexGuard aGuard(m_aMutex);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return Time{}; // TODO init
+ }
+ m_bWasNull = false;
+
+ const MYSQL_TIME* pTime = reinterpret_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
+
+ assert(pTime != nullptr);
+
+ Time t;
+ t.Hours = pTime->hour;
+ t.Minutes = pTime->minute;
+ t.Seconds = pTime->second;
+ return t;
+}
+
+DateTime SAL_CALL OPreparedResultSet::getTimestamp(sal_Int32 column)
+{
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ MutexGuard aGuard(m_aMutex);
+ checkColumnIndex(column);
+
+ if (*m_aData[column - 1].is_null)
+ {
+ m_bWasNull = true;
+ return DateTime{};
+ }
+ m_bWasNull = false;
+
+ const MYSQL_TIME* pTime = reinterpret_cast<MYSQL_TIME*>(m_aData[column - 1].buffer);
+
+ assert(pTime != nullptr);
+
+ DateTime t;
+ t.Year = pTime->year;
+ t.Month = pTime->month;
+ t.Day = pTime->day;
+ t.Hours = pTime->hour;
+ t.Minutes = pTime->minute;
+ t.Seconds = pTime->second;
+ return t;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::isBeforeFirst()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return m_nCurrentField == 0;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::isAfterLast()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return m_nCurrentField >= m_nFieldCount;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::isFirst()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return m_nCurrentField == 1 && !isAfterLast();
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::isLast()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return mysql_field_tell(m_pResult) == static_cast<unsigned>(m_nFieldCount);
+}
+
+void SAL_CALL OPreparedResultSet::beforeFirst()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::beforeFirst",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::afterLast()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::afterLast", *this);
+}
+
+void SAL_CALL OPreparedResultSet::close()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ if (m_aData)
+ {
+ delete[] m_aData;
+ delete[] m_aMetaData;
+ }
+
+ if (m_pResult)
+ mysql_free_result(m_pResult);
+ mysql_stmt_free_result(m_pStmt);
+ dispose();
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::first()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ mysql_stmt_data_seek(m_pStmt, 0);
+ next();
+
+ return true;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::last()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ mysql_stmt_data_seek(m_pStmt, m_nFieldCount - 1);
+ next();
+
+ return true;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::absolute(sal_Int32 row)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ sal_Int32 nFields = static_cast<sal_Int32>(m_nFieldCount);
+ sal_Int32 nToGo = row < 0 ? nFields - row : row - 1;
+
+ if (nToGo >= nFields)
+ nToGo = nFields - 1;
+ if (nToGo < 0)
+ nToGo = 0;
+
+ mysql_stmt_data_seek(m_pStmt, nToGo);
+ next();
+
+ return true;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::relative(sal_Int32 row)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ sal_Int32 nFields = static_cast<sal_Int32>(m_nFieldCount);
+ if (row == 0)
+ return true;
+
+ sal_Int32 nToGo = m_nCurrentField + row;
+ if (nToGo >= nFields)
+ nToGo = nFields - 1;
+ if (nToGo < 0)
+ nToGo = 0;
+
+ mysql_stmt_data_seek(m_pStmt, nToGo);
+ next();
+ m_nCurrentField += row;
+
+ return true;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::previous()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ if (m_nCurrentField <= 1)
+ return false;
+
+ mysql_stmt_data_seek(m_pStmt, m_nCurrentField - 2);
+ next();
+ --m_nFieldCount;
+ return true;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL OPreparedResultSet::getStatement()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return m_aStatement.get();
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::rowDeleted()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return false;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::rowInserted()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return false;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::rowUpdated()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return false;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::next()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ bool bFirstRun = false;
+ // allocate array if it does not exist
+ if (m_aData == nullptr)
+ {
+ bFirstRun = true;
+ m_aData = new MYSQL_BIND[m_nFieldCount];
+ memset(m_aData, 0, m_nFieldCount * sizeof(MYSQL_BIND));
+ m_aMetaData = new BindMetaData[m_nFieldCount];
+ }
+ for (sal_Int32 i = 0; i < m_nFieldCount; ++i)
+ {
+ m_aMetaData[i].is_null = 0;
+ m_aMetaData[i].length = 0l;
+ m_aMetaData[i].error = 0;
+
+ m_aData[i].is_null = &m_aMetaData[i].is_null;
+ m_aData[i].buffer_length = m_aFields[i].type == MYSQL_TYPE_BLOB ? 0 : m_aFields[i].length;
+ m_aData[i].length = &m_aMetaData[i].length;
+ m_aData[i].error = &m_aMetaData[i].error;
+ m_aData[i].buffer = nullptr;
+ m_aData[i].buffer_type = m_aFields[i].type;
+
+ // allocates memory, if it is a fixed size type. If not then nullptr
+ mysqlc_sdbc_driver::allocateSqlVar(&m_aData[i].buffer, m_aData[i].buffer_type,
+ m_aFields[i].length);
+ }
+ mysql_stmt_bind_result(m_pStmt, m_aData);
+ if (bFirstRun)
+ mysql_stmt_store_result(m_pStmt);
+ int failure = mysql_stmt_fetch(m_pStmt);
+
+ for (sal_Int32 i = 0; i < m_nFieldCount; ++i)
+ {
+ if (*m_aData[i].error)
+ {
+ // expected if we have a BLOB, as buffer_length is set to 0. We want to
+ // fetch it piece by piece
+ // see https://bugs.mysql.com/file.php?id=12361&bug_id=33086
+ if (m_aData[i].buffer == nullptr)
+ {
+ m_aData[i].buffer_length = *m_aData[i].length;
+ m_aData[i].buffer = malloc(*m_aData[i].length);
+ mysql_stmt_fetch_column(m_pStmt, &m_aData[i], i, 0);
+ }
+ }
+ }
+
+ if (failure == 1)
+ {
+ MYSQL* pMysql = m_rConnection.getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMysql), mysql_errno(pMysql),
+ *this, m_encoding);
+ }
+ else if (failure == MYSQL_NO_DATA)
+ return false;
+
+ // current field cannot be asked as a number. We have to keep track it
+ // manually.
+ m_nCurrentField += 1;
+
+ return true;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::wasNull()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return m_bWasNull;
+}
+
+void SAL_CALL OPreparedResultSet::cancel()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+}
+
+void SAL_CALL OPreparedResultSet::clearWarnings() {}
+
+Any SAL_CALL OPreparedResultSet::getWarnings()
+{
+ Any aRet = Any();
+ return aRet;
+}
+
+void SAL_CALL OPreparedResultSet::insertRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ // you only have to implement this if you want to insert new rows
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::insertRow", *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ // only when you allow updates
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateRow", *this);
+}
+
+void SAL_CALL OPreparedResultSet::deleteRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::deleteRow", *this);
+}
+
+void SAL_CALL OPreparedResultSet::cancelRowUpdates()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::cancelRowUpdates",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::moveToInsertRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ // only when you allow insert's
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::moveToInsertRow",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::moveToCurrentRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+}
+
+void SAL_CALL OPreparedResultSet::updateNull(sal_Int32 column)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateNull",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateBoolean(sal_Int32 column, sal_Bool /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateBoolean",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateByte(sal_Int32 column, sal_Int8 /* x */)
+{
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ MutexGuard aGuard(m_aMutex);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateByte",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateShort(sal_Int32 column, sal_Int16 /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateShort",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateInt(sal_Int32 column, sal_Int32 /* x */)
+{
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ MutexGuard aGuard(m_aMutex);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateInt", *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateLong(sal_Int32 column, sal_Int64 /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateLong",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateFloat(sal_Int32 column, float /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateFloat",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateDouble(sal_Int32 column, double /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateDouble",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateString(sal_Int32 column, const rtl::OUString& /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateString",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateBytes(sal_Int32 column,
+ const uno::Sequence<sal_Int8>& /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateBytes",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateDate(sal_Int32 column, const Date& /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateDate",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateTime(sal_Int32 column, const Time& /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateTime",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateTimestamp(sal_Int32 column, const DateTime& /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateTimestamp",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateBinaryStream(sal_Int32 column,
+ const uno::Reference<XInputStream>& /* x */,
+ sal_Int32 /* length */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException(
+ "OPreparedResultSet::updateBinaryStream", *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateCharacterStream(sal_Int32 column,
+ const uno::Reference<XInputStream>& /* x */,
+ sal_Int32 /* length */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException(
+ "OPreparedResultSet::updateCharacterStream", *this);
+}
+
+void SAL_CALL OPreparedResultSet::refreshRow()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::refreshRow",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateObject(sal_Int32 column, const Any& /* x */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::updateObject",
+ *this);
+}
+
+void SAL_CALL OPreparedResultSet::updateNumericObject(sal_Int32 column, const Any& /* x */,
+ sal_Int32 /* scale */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException(
+ "OPreparedResultSet::updateNumericObject", *this);
+}
+
+// XRowLocate
+Any SAL_CALL OPreparedResultSet::getBookmark()
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ Any aRet = Any();
+
+ // if you don't want to support bookmark you must remove the XRowLocate interface
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::getBookmark",
+ *this);
+
+ return aRet;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::moveToBookmark(const Any& /* bookmark */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ return false;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::moveRelativeToBookmark(const Any& /* bookmark */,
+ sal_Int32 /* rows */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException(
+ "OPreparedResultSet::moveRelativeToBookmark", *this);
+ return false;
+}
+
+sal_Int32 SAL_CALL OPreparedResultSet::compareBookmarks(const Any& /* n1 */, const Any& /* n2 */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::compareBookmarks",
+ *this);
+
+ return CompareBookmark::NOT_EQUAL;
+}
+
+sal_Bool SAL_CALL OPreparedResultSet::hasOrderedBookmarks() { return false; }
+
+sal_Int32 SAL_CALL OPreparedResultSet::hashBookmark(const Any& /* bookmark */)
+{
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::hashBookmark",
+ *this);
+ return 0;
+}
+
+// XDeleteRows
+uno::Sequence<sal_Int32>
+ SAL_CALL OPreparedResultSet::deleteRows(const uno::Sequence<Any>& /* rows */)
+{
+ MutexGuard aGuard(m_aMutex);
+ checkDisposed(OPreparedResultSet_BASE::rBHelper.bDisposed);
+ uno::Sequence<sal_Int32> aRet = uno::Sequence<sal_Int32>();
+
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedResultSet::deleteRows",
+ *this);
+ return aRet;
+}
+
+IPropertyArrayHelper* OPreparedResultSet::createArrayHelper() const
+{
+ uno::Sequence<Property> aProps(5);
+ Property* pProperties = aProps.getArray();
+ sal_Int32 nPos = 0;
+ pProperties[nPos++] = Property("FetchDirection", PROPERTY_ID_FETCHDIRECTION,
+ cppu::UnoType<sal_Int32>::get(), 0);
+ pProperties[nPos++]
+ = Property("FetchSize", PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0);
+ pProperties[nPos++] = Property("IsBookmarkable", PROPERTY_ID_ISBOOKMARKABLE,
+ cppu::UnoType<bool>::get(), PropertyAttribute::READONLY);
+ pProperties[nPos++] = Property("ResultSetConcurrency", PROPERTY_ID_RESULTSETCONCURRENCY,
+ cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
+ pProperties[nPos++] = Property("ResultSetType", PROPERTY_ID_RESULTSETTYPE,
+ cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
+
+ return new OPropertyArrayHelper(aProps);
+}
+
+IPropertyArrayHelper& OPreparedResultSet::getInfoHelper() { return *getArrayHelper(); }
+
+sal_Bool OPreparedResultSet::convertFastPropertyValue(Any& /* rConvertedValue */,
+ Any& /* rOldValue */, sal_Int32 nHandle,
+ const Any& /* rValue */)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_ISBOOKMARKABLE:
+ case PROPERTY_ID_CURSORNAME:
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ case PROPERTY_ID_RESULTSETTYPE:
+ throw css::lang::IllegalArgumentException();
+ case PROPERTY_ID_FETCHDIRECTION:
+ case PROPERTY_ID_FETCHSIZE:
+ default:;
+ }
+ return false;
+}
+
+void OPreparedResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,
+ const Any& /* rValue */)
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_ISBOOKMARKABLE:
+ case PROPERTY_ID_CURSORNAME:
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ case PROPERTY_ID_RESULTSETTYPE:
+ throw uno::Exception("cannot set prop " + rtl::OUString::number(nHandle), nullptr);
+ case PROPERTY_ID_FETCHDIRECTION:
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ break;
+ default:;
+ }
+}
+
+void OPreparedResultSet::getFastPropertyValue(Any& _rValue, sal_Int32 nHandle) const
+{
+ switch (nHandle)
+ {
+ case PROPERTY_ID_ISBOOKMARKABLE:
+ _rValue <<= false;
+ break;
+ case PROPERTY_ID_CURSORNAME:
+ break;
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ _rValue <<= ResultSetConcurrency::READ_ONLY;
+ break;
+ case PROPERTY_ID_RESULTSETTYPE:
+ _rValue <<= ResultSetType::SCROLL_INSENSITIVE;
+ break;
+ case PROPERTY_ID_FETCHDIRECTION:
+ _rValue <<= FetchDirection::FORWARD;
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ _rValue <<= sal_Int32(50);
+ break;
+ ;
+ default:;
+ }
+}
+
+void SAL_CALL OPreparedResultSet::acquire() throw() { OPreparedResultSet_BASE::acquire(); }
+
+void SAL_CALL OPreparedResultSet::release() throw() { OPreparedResultSet_BASE::release(); }
+
+css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL OPreparedResultSet::getPropertySetInfo()
+{
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+}
+
+void OPreparedResultSet::checkColumnIndex(sal_Int32 index)
+{
+ if (index < 1 || index > static_cast<int>(m_nFieldCount))
+ {
+ /* static object for efficiency or thread safety is a problem ? */
+ throw SQLException("index out of range", *this, rtl::OUString(), 1, Any());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_prepared_resultset.hxx b/mysqlc/source/mysqlc_prepared_resultset.hxx
new file mode 100644
index 000000000000..db3e1034cb76
--- /dev/null
+++ b/mysqlc/source/mysqlc_prepared_resultset.hxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_MYSQLC_SOURCE_MYSQLC_RESULTSET_HXX
+#define INCLUDED_MYSQLC_SOURCE_MYSQLC_RESULTSET_HXX
+
+#include "mysqlc_preparedstatement.hxx"
+#include "mysqlc_statement.hxx"
+#include "mysqlc_subcomponent.hxx"
+#include "mysqlc_connection.hxx"
+
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/sdbc/XColumnLocate.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowUpdate.hpp>
+#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
+#include <com/sun/star/sdbcx/XDeleteRows.hpp>
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#include <com/sun/star/util/XCancellable.hpp>
+
+#include <cppuhelper/compbase12.hxx>
+
+namespace connectivity
+{
+namespace mysqlc
+{
+using ::com::sun::star::sdbc::SQLException;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::RuntimeException;
+
+typedef ::cppu::WeakComponentImplHelper12<
+ css::sdbc::XResultSet, css::sdbc::XRow, css::sdbc::XResultSetMetaDataSupplier,
+ css::util::XCancellable, css::sdbc::XWarningsSupplier, css::sdbc::XResultSetUpdate,
+ css::sdbc::XRowUpdate, css::sdbcx::XRowLocate, css::sdbcx::XDeleteRows, css::sdbc::XCloseable,
+ css::sdbc::XColumnLocate, css::lang::XServiceInfo>
+ OPreparedResultSet_BASE;
+
+class OPreparedResultSet final : public OBase_Mutex,
+ public OPreparedResultSet_BASE,
+ public ::cppu::OPropertySetHelper,
+ public OPropertyArrayUsageHelper<OPreparedResultSet>
+{
+ OConnection& m_rConnection;
+ css::uno::WeakReferenceHelper m_aStatement;
+ css::uno::Reference<css::sdbc::XResultSetMetaData> m_xMetaData;
+ MYSQL_RES* m_pResult;
+ MYSQL_STMT* m_pStmt;
+ rtl_TextEncoding m_encoding;
+ sal_Int32 m_nCurrentField = 0;
+ sal_Int32 m_nFieldCount;
+
+ // Use c style arrays, because we have to work with pointers
+ // on these.
+ MYSQL_BIND* m_aData = nullptr;
+ MYSQL_FIELD* m_aFields = nullptr;
+ BindMetaData* m_aMetaData = nullptr;
+
+ bool m_bWasNull = false;
+
+ // OPropertyArrayUsageHelper
+ ::cppu::IPropertyArrayHelper* createArrayHelper() const SAL_OVERRIDE;
+ // OPropertySetHelper
+ ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() SAL_OVERRIDE;
+
+ sal_Bool SAL_CALL convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue,
+ sal_Int32 nHandle, const Any& rValue) SAL_OVERRIDE;
+
+ void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,
+ const Any& rValue) SAL_OVERRIDE;
+
+ void SAL_CALL getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const SAL_OVERRIDE;
+
+ // you can't delete objects of this type
+ virtual ~OPreparedResultSet();
+
+public:
+ virtual rtl::OUString SAL_CALL getImplementationName() SAL_OVERRIDE;
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const& ServiceName) SAL_OVERRIDE;
+
+ virtual css::uno::Sequence<rtl::OUString> SAL_CALL getSupportedServiceNames() SAL_OVERRIDE;
+
+ OPreparedResultSet(OConnection& rConn, OPreparedStatement* pStmt, MYSQL_STMT* pMyStmt);
+
+ // ::cppu::OComponentHelper
+ void SAL_CALL disposing() SAL_OVERRIDE;
+
+ // XInterface
+ Any SAL_CALL queryInterface(const css::uno::Type& rType) SAL_OVERRIDE;
+
+ void SAL_CALL acquire() throw() SAL_OVERRIDE;
+ void SAL_CALL release() throw() SAL_OVERRIDE;
+
+ //XTypeProvider
+ css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() SAL_OVERRIDE;
+
+ // XPropertySet
+ css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() SAL_OVERRIDE;
+
+ // XResultSet
+ sal_Bool SAL_CALL next() SAL_OVERRIDE;
+ sal_Bool SAL_CALL isBeforeFirst() SAL_OVERRIDE;
+ sal_Bool SAL_CALL isAfterLast() SAL_OVERRIDE;
+ sal_Bool SAL_CALL isFirst() SAL_OVERRIDE;
+ sal_Bool SAL_CALL isLast() SAL_OVERRIDE;
+
+ void SAL_CALL beforeFirst() SAL_OVERRIDE;
+ void SAL_CALL afterLast() SAL_OVERRIDE;
+
+ sal_Bool SAL_CALL first() SAL_OVERRIDE;
+ sal_Bool SAL_CALL last() SAL_OVERRIDE;
+
+ sal_Int32 SAL_CALL getRow() SAL_OVERRIDE;
+
+ sal_Bool SAL_CALL absolute(sal_Int32 row) SAL_OVERRIDE;
+ sal_Bool SAL_CALL relative(sal_Int32 rows) SAL_OVERRIDE;
+ sal_Bool SAL_CALL previous() SAL_OVERRIDE;
+
+ void SAL_CALL refreshRow() SAL_OVERRIDE;
+
+ sal_Bool SAL_CALL rowUpdated() SAL_OVERRIDE;
+ sal_Bool SAL_CALL rowInserted() SAL_OVERRIDE;
+ sal_Bool SAL_CALL rowDeleted() SAL_OVERRIDE;
+
+ css::uno::Reference<css::uno::XInterface> SAL_CALL getStatement() SAL_OVERRIDE;
+ // XRow
+ sal_Bool SAL_CALL wasNull() SAL_OVERRIDE;
+
+ rtl::OUString SAL_CALL getString(sal_Int32 column) SAL_OVERRIDE;
+
+ sal_Bool SAL_CALL getBoolean(sal_Int32 column) SAL_OVERRIDE;
+ sal_Int8 SAL_CALL getByte(sal_Int32 column) SAL_OVERRIDE;
+ sal_Int16 SAL_CALL getShort(sal_Int32 column) SAL_OVERRIDE;
+ sal_Int32 SAL_CALL getInt(sal_Int32 column) SAL_OVERRIDE;
+ sal_Int64 SAL_CALL getLong(sal_Int32 column) SAL_OVERRIDE;
+
+ float SAL_CALL getFloat(sal_Int32 column) SAL_OVERRIDE;
+ double SAL_CALL getDouble(sal_Int32 column) SAL_OVERRIDE;
+
+ css::uno::Sequence<sal_Int8> SAL_CALL getBytes(sal_Int32 column) SAL_OVERRIDE;
+ css::util::Date SAL_CALL getDate(sal_Int32 column) SAL_OVERRIDE;
+ css::util::Time SAL_CALL getTime(sal_Int32 column) SAL_OVERRIDE;
+ css::util::DateTime SAL_CALL getTimestamp(sal_Int32 column) SAL_OVERRIDE;
+
+ css::uno::Reference<css::io::XInputStream>
+ SAL_CALL getBinaryStream(sal_Int32 column) SAL_OVERRIDE;
+ css::uno::Reference<css::io::XInputStream>
+ SAL_CALL getCharacterStream(sal_Int32 column) SAL_OVERRIDE;
+
+ Any SAL_CALL getObject(sal_Int32 column, const my_XNameAccessRef& typeMap) SAL_OVERRIDE;
+
+ css::uno::Reference<css::sdbc::XRef> SAL_CALL getRef(sal_Int32 column) SAL_OVERRIDE;
+ css::uno::Reference<css::sdbc::XBlob> SAL_CALL getBlob(sal_Int32 column) SAL_OVERRIDE;
+ css::uno::Reference<css::sdbc::XClob> SAL_CALL getClob(sal_Int32 column) SAL_OVERRIDE;
+ css::uno::Reference<css::sdbc::XArray> SAL_CALL getArray(sal_Int32 column) SAL_OVERRIDE;
+
+ // XResultSetMetaDataSupplier
+ css::uno::Reference<css::sdbc::XResultSetMetaData> SAL_CALL getMetaData() SAL_OVERRIDE;
+
+ // XCancellable
+ void SAL_CALL cancel() SAL_OVERRIDE;
+
+ // XCloseable
+ void SAL_CALL close() SAL_OVERRIDE;
+
+ // XWarningsSupplier
+ Any SAL_CALL getWarnings() SAL_OVERRIDE;
+
+ void SAL_CALL clearWarnings() SAL_OVERRIDE;
+
+ // XResultSetUpdate
+ void SAL_CALL insertRow() SAL_OVERRIDE;
+ void SAL_CALL updateRow() SAL_OVERRIDE;
+ void SAL_CALL deleteRow() SAL_OVERRIDE;
+ void SAL_CALL cancelRowUpdates() SAL_OVERRIDE;
+ void SAL_CALL moveToInsertRow() SAL_OVERRIDE;
+ void SAL_CALL moveToCurrentRow() SAL_OVERRIDE;
+
+ // XRowUpdate
+ void SAL_CALL updateNull(sal_Int32 column) SAL_OVERRIDE;
+ void SAL_CALL updateBoolean(sal_Int32 column, sal_Bool x) SAL_OVERRIDE;
+ void SAL_CALL updateByte(sal_Int32 column, sal_Int8 x) SAL_OVERRIDE;
+ void SAL_CALL updateShort(sal_Int32 column, sal_Int16 x) SAL_OVERRIDE;
+ void SAL_CALL updateInt(sal_Int32 column, sal_Int32 x) SAL_OVERRIDE;
+ void SAL_CALL updateLong(sal_Int32 column, sal_Int64 x) SAL_OVERRIDE;
+ void SAL_CALL updateFloat(sal_Int32 column, float x) SAL_OVERRIDE;
+ void SAL_CALL updateDouble(sal_Int32 column, double x) SAL_OVERRIDE;
+ void SAL_CALL updateString(sal_Int32 column, const rtl::OUString& x) SAL_OVERRIDE;
+ void SAL_CALL updateBytes(sal_Int32 column, const css::uno::Sequence<sal_Int8>& x) SAL_OVERRIDE;
+ void SAL_CALL updateDate(sal_Int32 column, const css::util::Date& x) SAL_OVERRIDE;
+ void SAL_CALL updateTime(sal_Int32 column, const css::util::Time& x) SAL_OVERRIDE;
+ void SAL_CALL updateTimestamp(sal_Int32 column, const css::util::DateTime& x) SAL_OVERRIDE;
+ void SAL_CALL updateBinaryStream(sal_Int32 column,
+ const css::uno::Reference<css::io::XInputStream>& x,
+ sal_Int32 length) SAL_OVERRIDE;
+ void SAL_CALL updateCharacterStream(sal_Int32 column,
+ const css::uno::Reference<css::io::XInputStream>& x,
+ sal_Int32 length) SAL_OVERRIDE;
+ void SAL_CALL updateObject(sal_Int32 column, const Any& x) SAL_OVERRIDE;
+ void SAL_CALL updateNumericObject(sal_Int32 column, const Any& x, sal_Int32 scale) SAL_OVERRIDE;
+
+ // XColumnLocate
+ sal_Int32 SAL_CALL findColumn(const rtl::OUString& columnName) SAL_OVERRIDE;
+
+ // XRowLocate
+ Any SAL_CALL getBookmark() SAL_OVERRIDE;
+
+ sal_Bool SAL_CALL moveToBookmark(const Any& bookmark) SAL_OVERRIDE;
+ sal_Bool SAL_CALL moveRelativeToBookmark(const Any& bookmark, sal_Int32 rows) SAL_OVERRIDE;
+ sal_Int32 SAL_CALL compareBookmarks(const Any& first, const Any& second) SAL_OVERRIDE;
+ sal_Bool SAL_CALL hasOrderedBookmarks() SAL_OVERRIDE;
+ sal_Int32 SAL_CALL hashBookmark(const Any& bookmark) SAL_OVERRIDE;
+
+ // XDeleteRows
+ css::uno::Sequence<sal_Int32>
+ SAL_CALL deleteRows(const css::uno::Sequence<Any>& rows) SAL_OVERRIDE;
+
+ /// @throws SQLException
+ /// @throws RuntimeException
+ void checkColumnIndex(sal_Int32 index);
+
+private:
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+};
+} /* mysqlc */
+} /* connectivity */
+#endif // CONNECTIVITY_SRESULTSET_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_preparedstatement.cxx b/mysqlc/source/mysqlc_preparedstatement.cxx
index fae2a6642724..88b899a55814 100644
--- a/mysqlc/source/mysqlc_preparedstatement.cxx
+++ b/mysqlc/source/mysqlc_preparedstatement.cxx
@@ -18,6 +18,7 @@
*/
#include "mysqlc_general.hxx"
+#include "mysqlc_prepared_resultset.hxx"
#include "mysqlc_preparedstatement.hxx"
#include "mysqlc_propertyids.hxx"
#include "mysqlc_resultsetmetadata.hxx"
@@ -48,13 +49,6 @@ using namespace com::sun::star::io;
using namespace com::sun::star::util;
using ::osl::MutexGuard;
-
-static inline char * my_i_to_a(char * buf, size_t buf_size, int a)
-{
- snprintf(buf, buf_size, "%d", a);
- return buf;
-}
-
rtl::OUString OPreparedStatement::getImplementationName()
{
return rtl::OUString("com.sun.star.sdbcx.mysqlc.PreparedStatement");
@@ -72,15 +66,22 @@ sal_Bool OPreparedStatement::supportsService(rtl::OUString const & ServiceName)
return cppu::supportsService(this, ServiceName);
}
-OPreparedStatement::OPreparedStatement(OConnection* _pConnection, sql::PreparedStatement * _cppPrepStmt)
- :OCommonStatement(_pConnection, _cppPrepStmt)
+OPreparedStatement::OPreparedStatement(OConnection* _pConnection, MYSQL_STMT* pStmt)
+ :OCommonStatement(_pConnection)
+ ,m_pStmt(pStmt)
{
- m_xConnection = _pConnection;
-
- try {
- m_paramCount = static_cast<sql::PreparedStatement *>(cppStatement.get())->getParameterMetaData()->getParameterCount();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ m_paramCount = mysql_stmt_param_count(m_pStmt);
+ m_binds.reserve(m_paramCount);
+ m_bindMetas.reserve(m_paramCount);
+ for(unsigned i=0; i<m_paramCount; ++i)
+ {
+ MYSQL_BIND bind;
+ memset(&bind, 0, sizeof(MYSQL_BIND));
+ m_binds.push_back(bind);
+ m_bindMetas.push_back(BindMetaData{});
+ m_binds.back().is_null = &m_bindMetas.back().is_null;
+ m_binds.back().length = &m_bindMetas.back().length;
+ m_binds.back().buffer = nullptr;
}
}
@@ -119,17 +120,12 @@ Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData()
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
- try {
- if (!m_xMetaData.is()) {
- m_xMetaData = new OResultSetMetaData(
- static_cast<sql::PreparedStatement *>(cppStatement.get())->getMetaData(),
- getOwnConnection()->getConnectionEncoding()
- );
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ if (!m_xMetaData.is())
+ {
+ MYSQL_RES* pRes = mysql_stmt_result_metadata(m_pStmt);
+ // TODO warning or error if no meta data.
+ m_xMetaData = new OResultSetMetaData( *m_xConnection.get(), pRes,
+ getOwnConnection()->getConnectionEncoding());
}
return m_xMetaData;
}
@@ -139,16 +135,14 @@ void SAL_CALL OPreparedStatement::close()
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
- try {
- clearWarnings();
- clearParameters();
- OCommonStatement::close();
- } catch (const SQLException &) {
- // If we get an error, ignore
+ if(mysql_stmt_close(m_pStmt))
+ {
+ SAL_WARN("connectivity", "failed to close mysql prepared statement");
}
-
- // Remove this Statement object from the Connection object's
- // list
+ m_pStmt = nullptr; // it's deallocated already
+ clearWarnings();
+ clearParameters();
+ OCommonStatement::close();
}
sal_Bool SAL_CALL OPreparedStatement::execute()
@@ -156,13 +150,22 @@ sal_Bool SAL_CALL OPreparedStatement::execute()
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
- bool success = false;
- try {
- success = static_cast<sql::PreparedStatement *>(cppStatement.get())->execute();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ if(!m_binds.empty() && mysql_stmt_bind_param(m_pStmt, m_binds.data()))
+ {
+ MYSQL* pMysql = m_xConnection.get()->getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_stmt_error(m_pStmt),
+ mysql_errno(pMysql), *this, m_xConnection.get()->getConnectionEncoding());
}
- return success;
+
+ int nFail = mysql_stmt_execute(m_pStmt);
+ if(nFail != 0)
+ {
+ MYSQL* pMysql = m_xConnection.get()->getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_stmt_error(m_pStmt),
+ mysql_errno(pMysql), *this, m_xConnection.get()->getConnectionEncoding());
+ }
+
+ return !nFail;
}
sal_Int32 SAL_CALL OPreparedStatement::executeUpdate()
@@ -170,12 +173,23 @@ sal_Int32 SAL_CALL OPreparedStatement::executeUpdate()
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
- sal_Int32 affectedRows = 0;
- try {
- affectedRows = static_cast<sql::PreparedStatement *>(cppStatement.get())->executeUpdate();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ if(!m_binds.empty() && mysql_stmt_bind_param(m_pStmt, m_binds.data()))
+ {
+ MYSQL* pMysql = m_xConnection.get()->getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_stmt_error(m_pStmt),
+ mysql_errno(pMysql), *this, m_xConnection.get()->getConnectionEncoding());
}
+
+ int nFail = mysql_stmt_execute(m_pStmt);
+
+ if(nFail != 0)
+ {
+ MYSQL* pMysql = m_xConnection.get()->getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_stmt_error(m_pStmt),
+ mysql_errno(pMysql), *this, m_xConnection.get()->getConnectionEncoding());
+ }
+
+ sal_Int32 affectedRows = mysql_stmt_affected_rows(m_pStmt);
return affectedRows;
}
@@ -185,14 +199,13 @@ void SAL_CALL OPreparedStatement::setString(sal_Int32 parameter, const rtl::OUSt
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- std::string stringie(rtl::OUStringToOString(x, m_xConnection->getConnectionEncoding()).getStr());
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setString(parameter, stringie);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::clearParameters", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ rtl::OString stringie(rtl::OUStringToOString(x,
+ m_xConnection->getConnectionEncoding()));
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_STRING;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, stringie.getStr(), MYSQL_TYPE_STRING, stringie.getLength());
+ m_bindMetas[nIndex].is_null = 0;
+ m_bindMetas[nIndex].length = stringie.getLength();
}
Reference< XConnection > SAL_CALL OPreparedStatement::getConnection()
@@ -208,13 +221,24 @@ Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery()
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
- Reference< XResultSet > xResultSet;
- try {
- sql::ResultSet * res = static_cast<sql::PreparedStatement *>(cppStatement.get())->executeQuery();
- xResultSet = new OResultSet(this, res, getOwnConnection()->getConnectionEncoding());
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ if(!m_binds.empty() && mysql_stmt_bind_param(m_pStmt, m_binds.data()))
+ {
+ MYSQL* pMysql = m_xConnection.get()->getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_stmt_error(m_pStmt),
+ mysql_errno(pMysql), *this, m_xConnection.get()->getConnectionEncoding());
}
+
+ int nFail = mysql_stmt_execute(m_pStmt);
+
+ if(nFail != 0)
+ {
+ MYSQL* pMysql = m_xConnection.get()->getMysqlConnection();
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_stmt_error(m_pStmt),
+ mysql_errno(pMysql), *this, m_xConnection.get()->getConnectionEncoding());
+ }
+
+ Reference< XResultSet > xResultSet;
+ xResultSet = new OPreparedResultSet(*m_xConnection.get(), this, m_pStmt);
return xResultSet;
}
@@ -224,13 +248,10 @@ void SAL_CALL OPreparedStatement::setBoolean(sal_Int32 parameter, sal_Bool x)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setBoolean(parameter, x);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setBoolean", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_TINY;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_TINY);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setByte(sal_Int32 parameter, sal_Int8 x)
@@ -239,13 +260,10 @@ void SAL_CALL OPreparedStatement::setByte(sal_Int32 parameter, sal_Int8 x)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setInt(parameter, x);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setByte", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_TINY;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_TINY);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setDate(sal_Int32 parameter, const Date& aData)
@@ -254,21 +272,16 @@ void SAL_CALL OPreparedStatement::setDate(sal_Int32 parameter, const Date& aData
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- std::string dateStr;
- char buf[20];
- dateStr.append(my_i_to_a(buf, sizeof(buf)-1, aData.Year));
- dateStr.append("-", 1);
- dateStr.append(my_i_to_a(buf, sizeof(buf)-1, aData.Month));
- dateStr.append("-", 1);
- dateStr.append(my_i_to_a(buf, sizeof(buf)-1, aData.Day));
-
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setDateTime(parameter, dateStr);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setDate", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ MYSQL_TIME my_time;
+
+ my_time.year = aData.Year;
+ my_time.month = aData.Month;
+ my_time.day = aData.Day;
+
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_DATE;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &my_time, MYSQL_TYPE_DATE);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setTime(sal_Int32 parameter, const Time& aVal)
@@ -277,21 +290,16 @@ void SAL_CALL OPreparedStatement::setTime(sal_Int32 parameter, const Time& aVal)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- std::string timeStr;
- char buf[20];
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Hours));
- timeStr.append(":", 1);
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Minutes));
- timeStr.append(":", 1);
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Seconds));
-
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setDateTime(parameter, timeStr);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setTime", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ MYSQL_TIME my_time;
+
+ my_time.hour = aVal.Hours;
+ my_time.minute = aVal.Minutes;
+ my_time.second = aVal.Seconds;
+
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_TIME;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &my_time, MYSQL_TYPE_TIME);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setTimestamp(sal_Int32 parameter, const DateTime& aVal)
@@ -300,29 +308,19 @@ void SAL_CALL OPreparedStatement::setTimestamp(sal_Int32 parameter, const DateTi
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- std::string timeStr;
- char buf[20];
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Year));
- timeStr.append("-", 1);
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Month));
- timeStr.append("-", 1);
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Day));
-
- timeStr.append(" ", 1);
-
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Hours));
- timeStr.append(":", 1);
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Minutes));
- timeStr.append(":", 1);
- timeStr.append(my_i_to_a(buf, sizeof(buf)-1, aVal.Seconds));
-
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setDateTime(parameter, timeStr);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setTimestamp", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ MYSQL_TIME my_time;
+
+ my_time.hour = aVal.Hours;
+ my_time.minute = aVal.Minutes;
+ my_time.second = aVal.Seconds;
+ my_time.year = aVal.Year;
+ my_time.month = aVal.Month;
+ my_time.day = aVal.Day;
+
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_TIME;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &my_time, MYSQL_TYPE_DATETIME);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setDouble(sal_Int32 parameter, double x)
@@ -331,13 +329,10 @@ void SAL_CALL OPreparedStatement::setDouble(sal_Int32 parameter, double x)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setDouble(parameter, x);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setDouble", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_DOUBLE;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_DOUBLE);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setFloat(sal_Int32 parameter, float x)
@@ -346,13 +341,10 @@ void SAL_CALL OPreparedStatement::setFloat(sal_Int32 parameter, float x)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setDouble(parameter, x);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setFloat", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_FLOAT;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_FLOAT);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setInt(sal_Int32 parameter, sal_Int32 x)
@@ -361,13 +353,10 @@ void SAL_CALL OPreparedStatement::setInt(sal_Int32 parameter, sal_Int32 x)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setInt(parameter, x);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setInt", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_LONG;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_LONG);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setLong(sal_Int32 parameter, sal_Int64 aVal)
@@ -376,28 +365,22 @@ void SAL_CALL OPreparedStatement::setLong(sal_Int32 parameter, sal_Int64 aVal)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setInt64(parameter, aVal);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setLong", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_LONGLONG;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &aVal, MYSQL_TYPE_LONGLONG);
+ m_bindMetas[nIndex].is_null = 0;
}
-void SAL_CALL OPreparedStatement::setNull(sal_Int32 parameter, sal_Int32 sqlType)
+void SAL_CALL OPreparedStatement::setNull(sal_Int32 parameter, sal_Int32 /*sqlType*/)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setNull(parameter, sqlType);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setNull", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_bindMetas[nIndex].is_null = 1;
+ free(m_binds[nIndex].buffer);
+ m_binds[nIndex].buffer = nullptr;
}
void SAL_CALL OPreparedStatement::setClob(sal_Int32 parameter, const Reference< XClob >& /* x */)
@@ -436,88 +419,42 @@ void SAL_CALL OPreparedStatement::setRef(sal_Int32 parameter, const Reference< X
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setRef", *this);
}
-namespace
-{
- template < class COMPLEXTYPE >
- bool impl_setObject( const Reference< XParameters >& _rxParam, sal_Int32 _parameterIndex, const Any& _value,
- void ( SAL_CALL XParameters::*Setter )( sal_Int32, const COMPLEXTYPE& ), bool _throwIfNotExtractable )
- {
- COMPLEXTYPE aValue;
- if ( _value >>= aValue )
- {
- (_rxParam.get()->*Setter)( _parameterIndex, aValue );
- return true;
- }
-
- if ( _throwIfNotExtractable )
- mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", _rxParam );
- return false;
- }
-
- template < class INTTYPE >
- void impl_setObject( const Reference< XParameters >& _rxParam, sal_Int32 _parameterIndex, const Any& _value,
- void ( SAL_CALL XParameters::*Setter )( sal_Int32, INTTYPE ) )
- {
- sal_Int32 nValue(0);
- if ( !( _value >>= nValue ) )
- mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", _rxParam );
- (_rxParam.get()->*Setter)( _parameterIndex, static_cast<INTTYPE>(nValue) );
- }
-}
-
-void SAL_CALL OPreparedStatement::setObjectWithInfo(sal_Int32 _parameterIndex, const Any& _value, sal_Int32 _targetSqlType, sal_Int32 /* scale */)
+void SAL_CALL OPreparedStatement::setObjectWithInfo(sal_Int32 parameterIndex, const Any& value, sal_Int32 targetSqlType, sal_Int32 /* scale */)
{
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
MutexGuard aGuard(m_aMutex);
- checkParameterIndex( _parameterIndex );
+ checkParameterIndex( parameterIndex );
- if ( !_value.hasValue() )
+ const sal_Int32 nIndex = parameterIndex - 1;
+ if ( !value.hasValue() )
{
- setNull( _parameterIndex, _targetSqlType );
+ free(m_binds[nIndex].buffer);
+ m_binds[nIndex].buffer = nullptr;
+ m_bindMetas[parameterIndex-1].is_null = 1;
return;
}
- switch ( _targetSqlType )
+ switch ( targetSqlType )
{
case DataType::DECIMAL:
case DataType::NUMERIC:
{
double nValue(0);
- if ( _value >>= nValue )
+ if ( value >>= nValue )
{
- setDouble( _parameterIndex, nValue );
+ setDouble( parameterIndex, nValue );
break;
}
-#if defined __GNUC__ && __GNUC__ >= 7
- [[fallthrough]];
-#else
- BOOST_FALLTHROUGH;
-#endif
- }
-
- case DataType::CHAR:
- case DataType::VARCHAR:
- case DataType::LONGVARCHAR:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setString, true );
- break;
-
- case DataType::BIGINT:
- {
- sal_Int64 nValue = 0;
- if ( !( _value >>= nValue ) )
- mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", *this );
- setLong( _parameterIndex, nValue );
- }
- break;
-
- case DataType::FLOAT:
- case DataType::REAL:
- {
- float nValue = 0;
- if ( _value >>= nValue )
+ else
{
- setFloat(_parameterIndex,nValue);
- break;
+ rtl::OUString sValue;
+ if( value >>= sValue )
+ {
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_NEWDECIMAL;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, sValue.getStr(), MYSQL_TYPE_LONGLONG, sValue.getLength());
+ m_bindMetas[nIndex].is_null = 0;
+ }
+
}
#if defined __GNUC__ && __GNUC__ >= 7
[[fallthrough]];
@@ -526,78 +463,7 @@ void SAL_CALL OPreparedStatement::setObjectWithInfo(sal_Int32 _parameterIndex, c
#endif
}
- case DataType::DOUBLE:
- {
- double nValue(0);
- if ( !( _value >>= nValue ) )
- mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", *this );
- setDouble( _parameterIndex, nValue );
- }
- break;
-
- case DataType::DATE:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setDate, true );
- break;
-
- case DataType::TIME:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setTime, true );
- break;
-
- case DataType::TIMESTAMP:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setTimestamp, true );
- break;
-
- case DataType::BINARY:
- case DataType::VARBINARY:
- case DataType::LONGVARBINARY:
- {
- if ( impl_setObject( this, _parameterIndex, _value, &XParameters::setBytes, false )
- || impl_setObject( this, _parameterIndex, _value, &XParameters::setBlob, false )
- || impl_setObject( this, _parameterIndex, _value, &XParameters::setClob, false )
- )
- break;
-
- Reference< css::io::XInputStream > xBinStream;
- if ( _value >>= xBinStream )
- {
- setBinaryStream( _parameterIndex, xBinStream, xBinStream->available() );
- break;
- }
-
- mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", *this );
- }
- break;
-
- case DataType::BIT:
- case DataType::BOOLEAN:
- {
- bool bValue( false );
- if ( _value >>= bValue )
- {
- setBoolean( _parameterIndex, bValue );
- break;
- }
- sal_Int32 nValue( 0 );
- if ( _value >>= nValue )
- {
- setBoolean( _parameterIndex, ( nValue != 0 ) );
- break;
- }
- mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", *this );
- }
- break;
-
- case DataType::TINYINT:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setByte );
- break;
-
- case DataType::SMALLINT:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setShort );
- break;
-
- case DataType::INTEGER:
- impl_setObject( this, _parameterIndex, _value, &XParameters::setInt );
- break;
+ // TODO other types
default:
mysqlc_sdbc_driver::throwInvalidArgumentException( "OPreparedStatement::setObjectWithInfo", *this );
@@ -629,13 +495,10 @@ void SAL_CALL OPreparedStatement::setShort(sal_Int32 parameter, sal_Int16 x)
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setInt(parameter, x);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setShort", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_SHORT;
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_SHORT);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setBytes(sal_Int32 parameter, const Sequence< sal_Int8 >& x)
@@ -644,14 +507,10 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 parameter, const Sequence<
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
checkParameterIndex(parameter);
- std::string blobby(reinterpret_cast<char const *>(x.getConstArray()), x.getLength());
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->setString(parameter, blobby);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::setBytes", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
+ const sal_Int32 nIndex = parameter-1;
+ m_binds[nIndex].buffer_type = MYSQL_TYPE_BLOB; // FIXME
+ mysqlc_sdbc_driver::resetSqlVar(&m_binds[nIndex].buffer, &x, MYSQL_TYPE_BLOB);
+ m_bindMetas[nIndex].is_null = 0;
}
void SAL_CALL OPreparedStatement::setCharacterStream(sal_Int32 parameter,
@@ -681,12 +540,11 @@ void SAL_CALL OPreparedStatement::clearParameters()
MutexGuard aGuard(m_aMutex);
checkDisposed(OPreparedStatement::rBHelper.bDisposed);
- try {
- static_cast<sql::PreparedStatement *>(cppStatement.get())->clearParameters();
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OPreparedStatement::clearParameters", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ for(size_t i=0; i<m_binds.size(); ++i)
+ {
+ m_bindMetas[i].is_null = 1;
+ free(m_binds[i].buffer);
+ m_binds[i].buffer = nullptr;
}
}
@@ -731,14 +589,4 @@ void OPreparedStatement::checkParameterIndex(sal_Int32 column)
}
}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_preparedstatement.hxx b/mysqlc/source/mysqlc_preparedstatement.hxx
index b82f88ecac38..7305c0dd005b 100644
--- a/mysqlc/source/mysqlc_preparedstatement.hxx
+++ b/mysqlc/source/mysqlc_preparedstatement.hxx
@@ -41,6 +41,13 @@ namespace connectivity
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::sdbc::XResultSetMetaData;
+ struct BindMetaData
+ {
+ char is_null = 0;
+ unsigned long length = 0;
+ char error = 0;
+ };
+
typedef ::cppu::ImplHelper5< css::sdbc::XPreparedStatement,
css::sdbc::XParameters,
css::sdbc::XPreparedBatchExecution,
@@ -50,8 +57,11 @@ namespace connectivity
class OPreparedStatement final : public OCommonStatement,
public OPreparedStatement_BASE
{
- unsigned int m_paramCount; // number of placeholders
+ unsigned int m_paramCount = 0; // number of placeholders
Reference< XResultSetMetaData > m_xMetaData;
+ MYSQL_STMT* m_pStmt;
+ std::vector<MYSQL_BIND> m_binds;
+ std::vector<BindMetaData> m_bindMetas;
void checkParameterIndex(sal_Int32 parameter);
@@ -68,7 +78,7 @@ namespace connectivity
getSupportedServiceNames()
SAL_OVERRIDE;
- OPreparedStatement(OConnection* _pConnection, sql::PreparedStatement * cppPrepStmt);
+ OPreparedStatement(OConnection* _pConnection, MYSQL_STMT* pStmt);
//XInterface
Any SAL_CALL queryInterface(const Type & rType) SAL_OVERRIDE;
@@ -150,14 +160,4 @@ namespace connectivity
} /* connectivity */
#endif // INCLUDED_MYSQLC_SOURCE_MYSQLC_PREPAREDSTATEMENT_HXX
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_resultset.cxx b/mysqlc/source/mysqlc_resultset.cxx
index faa9357f3cae..252f6633089d 100644
--- a/mysqlc/source/mysqlc_resultset.cxx
+++ b/mysqlc/source/mysqlc_resultset.cxx
@@ -32,9 +32,14 @@
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/typeprovider.hxx>
+using namespace rtl;
+#include <comphelper/string.hxx>
+
+#include <cstdlib>
+
using namespace connectivity::mysqlc;
using namespace cppu;
-using namespace com::sun::star::uno;
+using namespace com::sun::star;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
@@ -42,6 +47,7 @@ using namespace com::sun::star::sdbcx;
using namespace com::sun::star::container;
using namespace com::sun::star::io;
using namespace com::sun::star::util;
+using namespace ::comphelper;
using ::osl::MutexGuard;
#include <cppconn/resultset.h>
@@ -49,14 +55,36 @@ using ::osl::MutexGuard;
#include <stdio.h>
+namespace
+{
+ // copied from string misc, it should be replaced when library is not an
+ // extension anymore
+ std::vector<OUString> lcl_split(const OUString& rStr, sal_Unicode cSeparator)
+ {
+ std::vector< OUString > vec;
+ sal_Int32 idx = 0;
+ do
+ {
+ OUString kw =
+ rStr.getToken(0, cSeparator, idx);
+ kw = kw.trim();
+ if (!kw.isEmpty())
+ {
+ vec.push_back(kw);
+ }
+ } while (idx >= 0);
+ return vec;
+ }
+}
+
rtl::OUString SAL_CALL OResultSet::getImplementationName()
{
return rtl::OUString( "com.sun.star.sdbcx.mysqlc.ResultSet" );
}
-Sequence< rtl::OUString > SAL_CALL OResultSet::getSupportedServiceNames()
+uno::Sequence< rtl::OUString > SAL_CALL OResultSet::getSupportedServiceNames()
{
- Sequence< rtl::OUString > aSupported(2);
+ uno::Sequence< rtl::OUString > aSupported(2);
aSupported[0] = "com.sun.star.sdbc.ResultSet";
aSupported[1] = "com.sun.star.sdbcx.ResultSet";
return aSupported;
@@ -67,21 +95,18 @@ sal_Bool SAL_CALL OResultSet::supportsService(const rtl::OUString& _rServiceName
return cppu::supportsService(this, _rServiceName);
}
-OResultSet::OResultSet(OCommonStatement * pStmt, sql::ResultSet * result, rtl_TextEncoding _encoding )
+OResultSet::OResultSet(OConnection& rConn, OCommonStatement * pStmt, MYSQL_RES * pResult, rtl_TextEncoding _encoding )
: OResultSet_BASE(m_aMutex)
,OPropertySetHelper(OResultSet_BASE::rBHelper)
+ ,m_rConnection(rConn)
+ ,m_pMysql(rConn.getMysqlConnection())
,m_aStatement(static_cast<OWeakObject*>(pStmt))
,m_xMetaData(nullptr)
- ,m_result(result)
+ ,m_pResult(pResult)
,fieldCount( 0 )
,m_encoding( _encoding )
{
- try {
- sql::ResultSetMetaData * rs_meta = m_result->getMetaData();
- fieldCount = rs_meta->getColumnCount();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
+ fieldCount = mysql_num_fields(pResult);
}
OResultSet::~OResultSet()
@@ -107,7 +132,7 @@ Any SAL_CALL OResultSet::queryInterface(const Type & rType)
return aRet;
}
-Sequence< Type > SAL_CALL OResultSet::getTypes()
+uno::Sequence< Type > SAL_CALL OResultSet::getTypes()
{
OTypeCollection aTypes( cppu::UnoType<XMultiPropertySet>::get(),
cppu::UnoType<XFastPropertySet>::get(),
@@ -121,18 +146,13 @@ sal_Int32 SAL_CALL OResultSet::findColumn(const rtl::OUString& columnName)
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- // find the first column with the name columnName
- sql::ResultSetMetaData * meta = m_result->getMetaData();
- for (sal_uInt32 i = 1; i <= fieldCount; i++) {
- if (columnName.equalsIgnoreAsciiCaseAscii(meta->getColumnName(i).c_str())) {
- /* SDBC knows them indexed from 1 */
- return i;
- }
+ MYSQL_FIELD* pFields = mysql_fetch_field(m_pResult);
+ for(unsigned int i = 0; i< fieldCount; ++i)
+ {
+ if(columnName.equalsIgnoreAsciiCaseAscii(pFields[i].name))
+ return i + 1; // sdbc indexes from 1
}
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
+
throw SQLException(
"The column name '" + columnName + "' is not valid.",
*this,
@@ -142,7 +162,7 @@ sal_Int32 SAL_CALL OResultSet::findColumn(const rtl::OUString& columnName)
);
}
-Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream(sal_Int32 column)
+uno::Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -152,7 +172,7 @@ Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream(sal_Int32 column)
return nullptr;
}
-Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream(sal_Int32 column)
+uno::Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -166,41 +186,50 @@ sal_Bool SAL_CALL OResultSet::getBoolean(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
checkColumnIndex(column);
- try {
- return m_result->getBoolean(column);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return false;
}
- return false;
+
+ m_bWasNull = false;
+ return static_cast<bool>(std::atoi(pValue));
}
sal_Int8 SAL_CALL OResultSet::getByte(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
checkColumnIndex(column);
- try {
- return m_result->getInt(column);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return 0;
}
- return 0; // fool compiler
+
+ m_bWasNull = false;
+ return static_cast<sal_Int8>(std::atoi(pValue));
}
-Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 column)
+uno::Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes(sal_Int32 column)
{
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
MutexGuard aGuard(m_aMutex);
- sql::SQLString val = m_result->getString(column);
- if (!val.length()) {
- return Sequence< sal_Int8>();
- } else {
- return Sequence< sal_Int8 > (reinterpret_cast<sal_Int8 const *>(val.c_str()), val.length());
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return uno::Sequence< sal_Int8>();
}
+ m_bWasNull = false;
+ return uno::Sequence< sal_Int8 > (reinterpret_cast<sal_Int8 const *>(
+ pValue), m_aLengths[column-1]);
}
Date SAL_CALL OResultSet::getDate(sal_Int32 column)
@@ -209,31 +238,34 @@ Date SAL_CALL OResultSet::getDate(sal_Int32 column)
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
checkColumnIndex(column);
- Date d;
- try {
- rtl::OUString dateString = getString(column);
- rtl::OUString token;
- sal_Int32 nIndex = 0, i=0;
-
- do {
- token = dateString.getToken (0, '-', nIndex);
- switch (i) {
- case 0:
- d.Year = static_cast<sal_uInt16>(token.toUInt32());
- break;
- case 1:
- d.Month = static_cast<sal_uInt16>(token.toUInt32());
- break;
- case 2:
- d.Day = static_cast<sal_uInt16>(token.toUInt32());
- break;
- default:;
- }
- i++;
- } while (nIndex >= 0);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+ Date d; // TODO initialize
+ char* dateStr = m_aRow[column-1];
+ if(!dateStr)
+ {
+ m_bWasNull = true;
+ return d;
}
+
+ rtl::OString dateString(dateStr);
+ rtl::OString token;
+ sal_Int32 nIndex = 0, i=0;
+ do {
+ token = dateString.getToken (0, '-', nIndex);
+ switch (i) {
+ case 0:
+ d.Year = static_cast<sal_uInt16>(token.toUInt32());
+ break;
+ case 1:
+ d.Month = static_cast<sal_uInt16>(token.toUInt32());
+ break;
+ case 2:
+ d.Day = static_cast<sal_uInt16>(token.toUInt32());
+ break;
+ default:;
+ }
+ i++;
+ } while (nIndex >= 0);
+ m_bWasNull = false;
return d;
}
@@ -241,42 +273,49 @@ double SAL_CALL OResultSet::getDouble(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
checkColumnIndex(column);
- try {
- return m_result->getDouble(column);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return 0.0;
}
- return 0.0; // fool compiler
+
+ m_bWasNull = false;
+ return std::strtod(pValue, nullptr);
}
float SAL_CALL OResultSet::getFloat(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
checkColumnIndex(column);
- try {
- return m_result->getDouble(column);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return 0.0f;
}
- return 0.0; // fool compiler
+
+ m_bWasNull = false;
+ return std::strtod(pValue, nullptr);
}
sal_Int32 SAL_CALL OResultSet::getInt(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
- checkColumnIndex(column);
- try {
- return m_result->getInt(column);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return 0;
}
- return 0; // fool compiler
+
+ m_bWasNull = false;
+ return std::atoi(pValue);
}
sal_Int32 SAL_CALL OResultSet::getRow()
@@ -284,45 +323,37 @@ sal_Int32 SAL_CALL OResultSet::getRow()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->getRow();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return 0; // fool compiler
+ return static_cast<sal_Int32>(mysql_field_tell(m_pResult));
}
sal_Int64 SAL_CALL OResultSet::getLong(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
checkColumnIndex(column);
- try {
- return m_result->getInt64(column);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return 0LL;
}
- return 0; // fool compiler
+
+ m_bWasNull = false;
+ return std::atol(pValue);
}
-Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData()
+uno::Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData()
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- if (!m_xMetaData.is()) {
- m_xMetaData = new OResultSetMetaData(m_result->getMetaData(), m_encoding);
- }
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+ if (!m_xMetaData.is()) {
+ m_xMetaData = new OResultSetMetaData(m_rConnection, m_pResult, m_encoding);
}
return m_xMetaData;
}
-Reference< XArray > SAL_CALL OResultSet::getArray(sal_Int32 column)
+uno::Reference< XArray > SAL_CALL OResultSet::getArray(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -332,7 +363,7 @@ Reference< XArray > SAL_CALL OResultSet::getArray(sal_Int32 column)
return nullptr;
}
-Reference< XClob > SAL_CALL OResultSet::getClob(sal_Int32 column)
+uno::Reference< XClob > SAL_CALL OResultSet::getClob(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -342,7 +373,7 @@ Reference< XClob > SAL_CALL OResultSet::getClob(sal_Int32 column)
return nullptr;
}
-Reference< XBlob > SAL_CALL OResultSet::getBlob(sal_Int32 column)
+uno::Reference< XBlob > SAL_CALL OResultSet::getBlob(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -352,7 +383,7 @@ Reference< XBlob > SAL_CALL OResultSet::getBlob(sal_Int32 column)
return nullptr;
}
-Reference< XRef > SAL_CALL OResultSet::getRef(sal_Int32 column)
+uno::Reference< XRef > SAL_CALL OResultSet::getRef(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -362,7 +393,7 @@ Reference< XRef > SAL_CALL OResultSet::getRef(sal_Int32 column)
return nullptr;
}
-Any SAL_CALL OResultSet::getObject(sal_Int32 column, const Reference< XNameAccess >& /* typeMap */)
+Any SAL_CALL OResultSet::getObject(sal_Int32 column, const uno::Reference< XNameAccess >& /* typeMap */)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -378,33 +409,32 @@ sal_Int16 SAL_CALL OResultSet::getShort(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
+ checkColumnIndex(column);
- try {
- return static_cast<sal_Int16>(m_result->getInt(column));
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return 0;
}
- return 0; // fool compiler
+ m_bWasNull = false;
+ return std::atoi(pValue);
}
rtl::OUString SAL_CALL OResultSet::getString(sal_Int32 column)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
-
checkColumnIndex(column);
- try {
- sql::SQLString val = m_result->getString(column);
- if (!m_result->wasNull()) {
- return rtl::OUString( val.c_str(), val.length(), m_encoding );
- } else {
- return rtl::OUString();
- }
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return rtl::OUString{};
}
- return rtl::OUString(); // fool compiler
+ m_bWasNull = false;
+ return rtl::OUString(pValue, static_cast<sal_Int32>(m_aLengths[column-1]), m_encoding);
}
Time SAL_CALL OResultSet::getTime(sal_Int32 column)
@@ -413,13 +443,18 @@ Time SAL_CALL OResultSet::getTime(sal_Int32 column)
MutexGuard aGuard(m_aMutex);
checkColumnIndex(column);
- Time t;
- rtl::OUString timeString = getString(column);
+ Time t; // initialize
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return t;
+ }
+ rtl::OUString timeString{pValue, static_cast<sal_Int32>(m_aLengths[column-1]), m_encoding};
rtl::OUString token;
sal_Int32 nIndex, i=0;
nIndex = timeString.indexOf(' ') + 1;
-
do {
token = timeString.getToken (0, ':', nIndex);
switch (i) {
@@ -436,6 +471,7 @@ Time SAL_CALL OResultSet::getTime(sal_Int32 column)
i++;
} while (nIndex >= 0);
+ m_bWasNull = false;
return t;
}
@@ -443,18 +479,32 @@ DateTime SAL_CALL OResultSet::getTimestamp(sal_Int32 column)
{
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
MutexGuard aGuard(m_aMutex);
-
checkColumnIndex(column);
+
+ char* pValue = m_aRow[column-1];
+ if(!pValue)
+ {
+ m_bWasNull = true;
+ return DateTime{}; // init
+ }
+
+ // YY-MM-DD HH:MM:SS
+ std::vector<rtl::OUString> dateAndTime = lcl_split(rtl::OUString{pValue,
+ static_cast<sal_Int32>(m_aLengths[column-1]), m_encoding},
+ u' ');
+
+ auto dateParts = lcl_split(dateAndTime.at(0), u'-');
+ auto timeParts = lcl_split(dateAndTime.at(1), u':');
+
DateTime dt;
- Date d = getDate(column);
- Time t = getTime(column);
-
- dt.Year = d.Year;
- dt.Month = d.Month;
- dt.Day = d.Day;
- dt.Hours = t.Hours;
- dt.Minutes = t.Minutes;
- dt.Seconds = t.Seconds;
+
+ dt.Year = dateParts.at(0).toUInt32();
+ dt.Month = dateParts.at(1).toUInt32();
+ dt.Day = dateParts.at(2).toUInt32();
+ dt.Hours = timeParts.at(0).toUInt32();
+ dt.Minutes = timeParts.at(1).toUInt32();
+ dt.Seconds = timeParts.at(2).toUInt32();
+ m_bWasNull = false;
return dt;
}
@@ -463,12 +513,7 @@ sal_Bool SAL_CALL OResultSet::isBeforeFirst()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->isBeforeFirst();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ return m_nCurrentField == 0;
}
sal_Bool SAL_CALL OResultSet::isAfterLast()
@@ -476,12 +521,7 @@ sal_Bool SAL_CALL OResultSet::isAfterLast()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->isAfterLast();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ return m_nCurrentField >= static_cast<sal_Int32>(fieldCount);
}
sal_Bool SAL_CALL OResultSet::isFirst()
@@ -489,12 +529,7 @@ sal_Bool SAL_CALL OResultSet::isFirst()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->isFirst();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ return m_nCurrentField == 1 && !isAfterLast();
}
sal_Bool SAL_CALL OResultSet::isLast()
@@ -502,12 +537,7 @@ sal_Bool SAL_CALL OResultSet::isLast()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->isLast();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ return mysql_field_tell(m_pResult) == fieldCount;
}
void SAL_CALL OResultSet::beforeFirst()
@@ -515,11 +545,7 @@ void SAL_CALL OResultSet::beforeFirst()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- m_result->beforeFirst();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::beforeFirst", *this);
}
void SAL_CALL OResultSet::afterLast()
@@ -527,11 +553,7 @@ void SAL_CALL OResultSet::afterLast()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- m_result->afterLast();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
+ mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::afterLast", *this);
}
void SAL_CALL OResultSet::close()
@@ -539,12 +561,7 @@ void SAL_CALL OResultSet::close()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- m_result->close();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
-
+ mysql_free_result(m_pResult);
dispose();
}
@@ -553,12 +570,10 @@ sal_Bool SAL_CALL OResultSet::first()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->first();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ mysql_data_seek(m_pResult, 0);
+ next();
+
+ return true;
}
sal_Bool SAL_CALL OResultSet::last()
@@ -566,12 +581,10 @@ sal_Bool SAL_CALL OResultSet::last()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->last();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ mysql_data_seek(m_pResult, fieldCount-1);
+ next();
+
+ return true;
}
sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 row)
@@ -579,12 +592,18 @@ sal_Bool SAL_CALL OResultSet::absolute(sal_Int32 row)
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->absolute(row);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ sal_Int32 nFields = static_cast<sal_Int32>(fieldCount);
+ sal_Int32 nToGo = row < 0 ? nFields - row : row-1;
+
+ if(nToGo >= nFields)
+ nToGo = nFields - 1;
+ if(nToGo < 0)
+ nToGo = 0;
+
+ mysql_data_seek(m_pResult, nToGo);
+ next();
+
+ return true;
}
sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row)
@@ -592,12 +611,20 @@ sal_Bool SAL_CALL OResultSet::relative(sal_Int32 row)
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->relative(row);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ sal_Int32 nFields = static_cast<sal_Int32>(fieldCount);
+ if(row == 0)
+ return true;
+
+ sal_Int32 nToGo = m_nCurrentField + row;
+ if(nToGo >= nFields)
+ nToGo = nFields - 1;
+ if(nToGo < 0)
+ nToGo = 0;
+
+ mysql_data_seek(m_pResult, nToGo);
+ next();
+
+ return true;
}
sal_Bool SAL_CALL OResultSet::previous()
@@ -605,15 +632,15 @@ sal_Bool SAL_CALL OResultSet::previous()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->previous();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ if(m_nCurrentField <= 1)
+ return false;
+
+ mysql_data_seek(m_pResult, m_nCurrentField-2);
+ next();
+ return true;
}
-Reference< XInterface > SAL_CALL OResultSet::getStatement()
+uno::Reference< uno::XInterface > SAL_CALL OResultSet::getStatement()
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -650,12 +677,16 @@ sal_Bool SAL_CALL OResultSet::next()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->next();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ m_aRow = mysql_fetch_row(m_pResult);
+ m_aLengths = mysql_fetch_lengths(m_pResult);
+ m_nCurrentField = mysql_field_tell(m_pResult);
+
+ unsigned errorNum = mysql_errno(m_pMysql);
+ if(errorNum)
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(m_pMysql),
+ errorNum, *this, m_encoding);
+
+ return m_aRow != nullptr;
}
sal_Bool SAL_CALL OResultSet::wasNull()
@@ -663,12 +694,7 @@ sal_Bool SAL_CALL OResultSet::wasNull()
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- try {
- return m_result->wasNull();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; //fool
+ return m_bWasNull;
}
void SAL_CALL OResultSet::cancel()
@@ -805,7 +831,7 @@ void SAL_CALL OResultSet::updateString(sal_Int32 column, const rtl::OUString& /*
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateString", *this);
}
-void SAL_CALL OResultSet::updateBytes(sal_Int32 column, const Sequence< sal_Int8 >& /* x */)
+void SAL_CALL OResultSet::updateBytes(sal_Int32 column, const uno::Sequence< sal_Int8 >& /* x */)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
@@ -837,7 +863,7 @@ void SAL_CALL OResultSet::updateTimestamp(sal_Int32 column, const DateTime& /* x
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateTimestamp", *this);
}
-void SAL_CALL OResultSet::updateBinaryStream(sal_Int32 column, const Reference< XInputStream >& /* x */,
+void SAL_CALL OResultSet::updateBinaryStream(sal_Int32 column, const uno::Reference< XInputStream >& /* x */,
sal_Int32 /* length */)
{
MutexGuard aGuard(m_aMutex);
@@ -846,7 +872,7 @@ void SAL_CALL OResultSet::updateBinaryStream(sal_Int32 column, const Reference<
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::updateBinaryStream", *this);
}
-void SAL_CALL OResultSet::updateCharacterStream(sal_Int32 column, const Reference< XInputStream >& /* x */,
+void SAL_CALL OResultSet::updateCharacterStream(sal_Int32 column, const uno::Reference< XInputStream >& /* x */,
sal_Int32 /* length */)
{
MutexGuard aGuard(m_aMutex);
@@ -930,11 +956,11 @@ sal_Int32 SAL_CALL OResultSet::hashBookmark(const Any& /* bookmark */)
}
// XDeleteRows
-Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows(const Sequence< Any >& /* rows */)
+uno::Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows(const uno::Sequence< Any >& /* rows */)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
- Sequence< sal_Int32 > aRet = Sequence< sal_Int32 >();
+ uno::Sequence< sal_Int32 > aRet = uno::Sequence< sal_Int32 >();
mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSet::deleteRows", *this);
return aRet;
@@ -942,7 +968,7 @@ Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows(const Sequence< Any >& /*
IPropertyArrayHelper * OResultSet::createArrayHelper() const
{
- Sequence< Property > aProps(5);
+ uno::Sequence< Property > aProps(5);
Property* pProperties = aProps.getArray();
sal_Int32 nPos = 0;
pProperties[nPos++] = Property("FetchDirection", PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0);
@@ -988,7 +1014,7 @@ void OResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any&
case PROPERTY_ID_CURSORNAME:
case PROPERTY_ID_RESULTSETCONCURRENCY:
case PROPERTY_ID_RESULTSETTYPE:
- throw Exception("cannot set prop " + rtl::OUString::number(nHandle), nullptr);
+ throw uno::Exception("cannot set prop " + rtl::OUString::number(nHandle), nullptr);
case PROPERTY_ID_FETCHDIRECTION:
break;
case PROPERTY_ID_FETCHSIZE:
@@ -1049,13 +1075,4 @@ void OResultSet::checkColumnIndex(sal_Int32 index)
}
}
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_resultset.hxx b/mysqlc/source/mysqlc_resultset.hxx
index a05cbb88cef6..407798c9cc96 100644
--- a/mysqlc/source/mysqlc_resultset.hxx
+++ b/mysqlc/source/mysqlc_resultset.hxx
@@ -23,6 +23,7 @@
#include "mysqlc_preparedstatement.hxx"
#include "mysqlc_statement.hxx"
#include "mysqlc_subcomponent.hxx"
+#include "mysqlc_connection.hxx"
#include <com/sun/star/sdbc/XCloseable.hpp>
#include <com/sun/star/sdbc/XColumnLocate.hpp>
@@ -68,11 +69,17 @@ namespace connectivity
public ::cppu::OPropertySetHelper,
public OPropertyArrayUsageHelper<OResultSet>
{
+ OConnection &m_rConnection;
+ MYSQL_ROW m_aRow;
+ unsigned long *m_aLengths = nullptr;
+ MYSQL *m_pMysql = nullptr;
css::uno::WeakReferenceHelper m_aStatement;
css::uno::Reference< css::sdbc::XResultSetMetaData> m_xMetaData;
- sql::ResultSet *m_result;
+ MYSQL_RES *m_pResult;
unsigned int fieldCount;
rtl_TextEncoding m_encoding;
+ sal_Int32 m_nCurrentField = 0;
+ bool m_bWasNull = false; // did the last getXXX result null?
// OPropertyArrayUsageHelper
::cppu::IPropertyArrayHelper* createArrayHelper() const SAL_OVERRIDE;
// OPropertySetHelper
@@ -98,7 +105,7 @@ namespace connectivity
getSupportedServiceNames()
SAL_OVERRIDE;
- OResultSet( OCommonStatement* pStmt, sql::ResultSet *result, rtl_TextEncoding _encoding );
+ OResultSet(OConnection& rConn, OCommonStatement* pStmt, MYSQL_RES *pResult, rtl_TextEncoding _encoding );
// ::cppu::OComponentHelper
void SAL_CALL disposing() SAL_OVERRIDE;
@@ -237,13 +244,4 @@ namespace connectivity
} /* connectivity */
#endif // CONNECTIVITY_SRESULTSET_HXX
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_resultsetmetadata.cxx b/mysqlc/source/mysqlc_resultsetmetadata.cxx
index d7a7054ea100..0c54ec5021ed 100644
--- a/mysqlc/source/mysqlc_resultsetmetadata.cxx
+++ b/mysqlc/source/mysqlc_resultsetmetadata.cxx
@@ -18,9 +18,11 @@
*/
#include "mysqlc_resultsetmetadata.hxx"
+#include "mysqlc_resultset.hxx"
#include "mysqlc_general.hxx"
#include <cppconn/exception.h>
+#include <com/sun/star/sdbc/XRow.hpp>
#include <rtl/ustrbuf.hxx>
using namespace connectivity::mysqlc;
@@ -28,150 +30,92 @@ using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::sdbc;
-
-OResultSetMetaData::~OResultSetMetaData()
+MYSQL_FIELD* OResultSetMetaData::getField(sal_Int32 column) const
{
+ return mysql_fetch_field_direct(m_pRes, column - 1);
}
sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize(sal_Int32 column)
{
- try {
- meta->getColumnDisplaySize(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getColumnDisplaySize", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return 0; // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return pField->length;
}
sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
{
checkColumnIndex(column);
+ MYSQL_FIELD* pField = getField(column);
- try {
- return mysqlc_sdbc_driver::mysqlToOOOType(meta->getColumnType(column));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return 0; // fool compiler
+ return mysqlc_sdbc_driver::mysqlToOOOType(pField->type, pField->charsetnr);
}
-/*
- XXX: This method doesn't throw exceptions at all.
- Should it declare that it throws ?? What if throw() is removed?
- Does it change the API, the open-close principle?
-*/
sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount()
{
- try {
- return meta->getColumnCount();
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return 0; // fool compiler
+ return mysql_num_fields(m_pRes);
}
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);
+ rtl::OUStringBuffer sql{"SHOW COLLATION WHERE Id ="};
+ sql.append(rtl::OUString::number(pField->charsetnr));
- try {
- return meta->isCaseSensitive(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ Reference< XStatement > stmt = m_rConnection.createStatement();
+ Reference< XResultSet > rs = stmt->executeQuery(sql.makeStringAndClear());
+ Reference< XRow > xRow( rs, UNO_QUERY_THROW );
+
+ rs->next(); // fetch first and only row
+ rtl::OUString sColName = xRow->getString(1); // first column is Collation name
+
+ return !sColName.isEmpty() && !sColName.endsWith("_ci");
}
rtl::OUString SAL_CALL OResultSetMetaData::getSchemaName(sal_Int32 column)
{
checkColumnIndex(column);
+ MYSQL_FIELD* pField = getField(column);
- try {
- return convert(meta->getSchemaName(column));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return rtl::OUString(); // fool compiler
+ return rtl::OStringToOUString(pField->db, m_rConnection.getConnectionEncoding());
}
rtl::OUString SAL_CALL OResultSetMetaData::getColumnName(sal_Int32 column)
{
checkColumnIndex(column);
- try {
- return convert( meta->getColumnName( column ) );
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return rtl::OUString(); // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return rtl::OStringToOUString(pField->name, m_rConnection.getConnectionEncoding());
}
rtl::OUString SAL_CALL OResultSetMetaData::getTableName(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return convert(meta->getTableName(column));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return rtl::OUString(); // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return rtl::OStringToOUString(pField->table, m_rConnection.getConnectionEncoding());
}
rtl::OUString SAL_CALL OResultSetMetaData::getCatalogName(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return convert(meta->getCatalogName(column));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return rtl::OUString(); // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return rtl::OStringToOUString(pField->catalog, m_rConnection.getConnectionEncoding());
}
rtl::OUString SAL_CALL OResultSetMetaData::getColumnTypeName(sal_Int32 column)
{
checkColumnIndex(column);
+ MYSQL_FIELD* pField = getField(column);
- try {
- return convert(meta->getColumnTypeName(column));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return rtl::OUString(); // fool compiler
+ return mysqlc_sdbc_driver::mysqlTypeToStr(pField);
}
rtl::OUString SAL_CALL OResultSetMetaData::getColumnLabel(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return convert(meta->getColumnLabel(column));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return rtl::OUString(); // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return rtl::OStringToOUString(pField->name, m_rConnection.getConnectionEncoding());
}
rtl::OUString SAL_CALL OResultSetMetaData::getColumnServiceName(sal_Int32 column)
@@ -182,152 +126,80 @@ rtl::OUString SAL_CALL OResultSetMetaData::getColumnServiceName(sal_Int32 column
return aRet;
}
-sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32 column)
+sal_Bool SAL_CALL OResultSetMetaData::isCurrency(sal_Int32 /*column*/)
{
- checkColumnIndex(column);
-
- try {
- return meta->isCurrency(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ return false; // TODO
}
sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement(sal_Int32 column)
{
checkColumnIndex(column);
- try {
- return meta->isAutoIncrement(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return pField->flags & AUTO_INCREMENT_FLAG;
}
sal_Bool SAL_CALL OResultSetMetaData::isSigned(sal_Int32 column)
{
checkColumnIndex(column);
- try {
- return meta->isSigned(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return !(pField->flags & UNSIGNED_FLAG);
}
sal_Int32 SAL_CALL OResultSetMetaData::getPrecision(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return meta->getPrecision(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getPrecision", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return 0; // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return pField->max_length - pField->decimals;
}
sal_Int32 SAL_CALL OResultSetMetaData::getScale(sal_Int32 column)
{
checkColumnIndex(column);
- try {
- return meta->getScale(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getScale", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return 0; // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return pField->decimals;
}
sal_Int32 SAL_CALL OResultSetMetaData::isNullable(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return sal_Int32(bool(meta->isNullable(column)));
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return sal_Int32(false); // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return !(pField->flags & NOT_NULL_FLAG);
}
-sal_Bool SAL_CALL OResultSetMetaData::isSearchable(sal_Int32 column)
+sal_Bool SAL_CALL OResultSetMetaData::isSearchable(sal_Int32 /*column*/)
{
- checkColumnIndex(column);
-
- try {
- return meta->isSearchable(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ return true;
}
sal_Bool SAL_CALL OResultSetMetaData::isReadOnly(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return meta->isReadOnly(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ MYSQL_FIELD* pField = getField(column);
+ return !(pField->db && strlen(pField->db));
}
sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return meta->isDefinitelyWritable(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ return !isReadOnly(column);
}
sal_Bool SAL_CALL OResultSetMetaData::isWritable(sal_Int32 column)
{
checkColumnIndex(column);
-
- try {
- return meta->isWritable(column);
- } catch (const sql::MethodNotImplementedException &) {
- mysqlc_sdbc_driver::throwFeatureNotImplementedException("OResultSetMetaData::getMetaData", *this);
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_encoding);
- }
- return false; // fool compiler
+ return !isReadOnly(column);
}
void OResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex)
{
- if (columnIndex < 1 || columnIndex > static_cast<sal_Int32>(meta->getColumnCount())) {
+ unsigned nColCount = mysql_num_fields(m_pRes);
+ if (columnIndex < 1 || columnIndex > static_cast<sal_Int32>(nColCount)) {
rtl::OUStringBuffer buf;
buf.appendAscii( "Column index out of range (expected 1 to " );
- buf.append( sal_Int32( meta->getColumnCount() ) );
+ buf.append( sal_Int32( nColCount ) );
buf.appendAscii( ", got " );
buf.append( columnIndex );
buf.append( '.' );
@@ -335,13 +207,4 @@ void OResultSetMetaData::checkColumnIndex(sal_Int32 columnIndex)
}
}
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_resultsetmetadata.hxx b/mysqlc/source/mysqlc_resultsetmetadata.hxx
index d8ad1217e00b..ff6ed092bfe1 100644
--- a/mysqlc/source/mysqlc_resultsetmetadata.hxx
+++ b/mysqlc/source/mysqlc_resultsetmetadata.hxx
@@ -23,9 +23,12 @@
#include "mysqlc_connection.hxx"
#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
#include <cppuhelper/implbase1.hxx>
#include <cppconn/resultset_metadata.h>
+#include <mysql.h>
namespace connectivity
{
@@ -33,6 +36,7 @@ namespace connectivity
{
using ::com::sun::star::sdbc::SQLException;
using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::RuntimeException;
//************ Class: ResultSetMetaData
@@ -40,13 +44,18 @@ namespace connectivity
class OResultSetMetaData final : public OResultSetMetaData_BASE
{
- sql::ResultSetMetaData * meta;
+ private:
+ OConnection& m_rConnection;
+ MYSQL_RES * m_pRes;
rtl_TextEncoding m_encoding;
- virtual ~OResultSetMetaData();
+ virtual ~OResultSetMetaData() = default;
+ MYSQL_FIELD* getField(sal_Int32 column) const;
public:
- OResultSetMetaData( sql::ResultSetMetaData * _meta, rtl_TextEncoding _encoding )
- :meta(_meta)
+ OResultSetMetaData(OConnection& rConn,
+ MYSQL_RES * pResult, rtl_TextEncoding _encoding )
+ :m_rConnection(rConn)
+ ,m_pRes(pResult)
,m_encoding( _encoding )
{
}
diff --git a/mysqlc/source/mysqlc_statement.cxx b/mysqlc/source/mysqlc_statement.cxx
index dc032fdc238d..cf13fd0a30af 100644
--- a/mysqlc/source/mysqlc_statement.cxx
+++ b/mysqlc/source/mysqlc_statement.cxx
@@ -52,11 +52,10 @@ using namespace com::sun::star::io;
using namespace com::sun::star::util;
using ::osl::MutexGuard;
-OCommonStatement::OCommonStatement(OConnection* _pConnection, sql::Statement *_cppStatement)
+OCommonStatement::OCommonStatement(OConnection* _pConnection)
:OCommonStatement_IBase(m_aMutex)
,OPropertySetHelper(OCommonStatement_IBase::rBHelper)
,m_xConnection(_pConnection)
- ,cppStatement(_cppStatement)
{
}
@@ -67,18 +66,18 @@ OCommonStatement::~OCommonStatement()
void OCommonStatement::disposeResultSet()
{
// free the cursor if alive
- cppStatement.reset();
+ if(m_pMysqlResult != nullptr)
+ {
+ mysql_free_result(m_pMysqlResult);
+ m_pMysqlResult = nullptr;
+ }
}
void OCommonStatement::disposing()
{
MutexGuard aGuard(m_aMutex);
- disposeResultSet();
-
m_xConnection.clear();
- cppStatement.reset();
-
OCommonStatement_IBase::disposing();
}
@@ -118,6 +117,7 @@ void SAL_CALL OCommonStatement::close()
checkDisposed(rBHelper.bDisposed);
}
dispose();
+ disposeResultSet();
}
void SAL_CALL OStatement::clearBatch()
@@ -131,30 +131,49 @@ sal_Bool SAL_CALL OCommonStatement::execute(const rtl::OUString& sql)
checkDisposed(rBHelper.bDisposed);
const rtl::OUString sSqlStatement = m_xConnection->transFormPreparedStatement( sql );
- bool success = false;
- try {
- success = cppStatement->execute(rtl::OUStringToOString(sSqlStatement, m_xConnection->getConnectionSettings().encoding).getStr());
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
- return success;
+ rtl::OString toExec = rtl::OUStringToOString(sSqlStatement,
+ m_xConnection->getConnectionSettings().encoding);
+
+ MYSQL* pMySql = m_xConnection->getMysqlConnection();
+
+ // NOTE: differs from mysql c API, wehere mysql_real_escape_string_quote()
+ // should be used.
+ // 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_errno(pMySql), *this, m_xConnection->getConnectionEncoding());
+ m_nAffectedRows = mysql_affected_rows(pMySql);
+
+ return !failure;
}
Reference< XResultSet > SAL_CALL OCommonStatement::executeQuery(const rtl::OUString& sql)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(rBHelper.bDisposed);
- const rtl::OUString sSqlStatement = m_xConnection->transFormPreparedStatement(sql);
-
- Reference< XResultSet > xResultSet;
- try {
- std::unique_ptr< sql::ResultSet > rset(cppStatement->executeQuery(rtl::OUStringToOString(sSqlStatement, m_xConnection->getConnectionEncoding()).getStr()));
- xResultSet = new OResultSet(this, rset.get(), m_xConnection->getConnectionEncoding());
- rset.release();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
+ const rtl::OUString sSqlStatement = sql; // TODO m_xConnection->transFormPreparedStatement( sql );
+ rtl::OString toExec = rtl::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_errno(pMySql), *this, m_xConnection->getConnectionEncoding());
+
+ m_pMysqlResult = mysql_store_result(pMySql);
+ if(m_pMysqlResult == nullptr)
+ {
+ mysqlc_sdbc_driver::throwSQLExceptionWithMsg(mysql_error(pMySql),
+ mysql_errno(pMySql), *this, m_xConnection->getConnectionEncoding());
}
- return xResultSet;
+
+ m_xResultSet = new OResultSet(*getOwnConnection(),this, m_pMysqlResult,
+ m_xConnection->getConnectionEncoding());
+ return m_xResultSet;
}
Reference< XConnection > SAL_CALL OCommonStatement::getConnection()
@@ -168,7 +187,7 @@ Reference< XConnection > SAL_CALL OCommonStatement::getConnection()
sal_Int32 SAL_CALL OCommonStatement::getUpdateCount()
{
- return cppStatement->getUpdateCount();
+ return m_nAffectedRows;
}
Any SAL_CALL OStatement::queryInterface(const Type & rType)
@@ -199,15 +218,9 @@ sal_Int32 SAL_CALL OCommonStatement::executeUpdate(const rtl::OUString& sql)
{
MutexGuard aGuard(m_aMutex);
checkDisposed(rBHelper.bDisposed);
- const rtl::OUString sSqlStatement = m_xConnection->transFormPreparedStatement(sql);
- sal_Int32 affectedRows = 0;
- try {
- affectedRows = cppStatement->executeUpdate(rtl::OUStringToOString(sSqlStatement, m_xConnection->getConnectionEncoding()).getStr());
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
- return affectedRows;
+ execute(sql);
+ return m_nAffectedRows;
}
Reference< XResultSet > SAL_CALL OCommonStatement::getResultSet()
@@ -215,23 +228,12 @@ Reference< XResultSet > SAL_CALL OCommonStatement::getResultSet()
MutexGuard aGuard(m_aMutex);
checkDisposed(rBHelper.bDisposed);
- Reference< XResultSet > xResultSet;
- try {
- std::unique_ptr< sql::ResultSet > rset(cppStatement->getResultSet());
- xResultSet = new OResultSet(this, rset.get(), m_xConnection->getConnectionEncoding());
- rset.release();
- } catch (const sql::SQLException &e) {
- mysqlc_sdbc_driver::translateAndThrow(e, *this, m_xConnection->getConnectionEncoding());
- }
- return xResultSet;
+ return m_xResultSet;
}
sal_Bool SAL_CALL OCommonStatement::getMoreResults()
{
- MutexGuard aGuard(m_aMutex);
- checkDisposed(rBHelper.bDisposed);
-
- return cppStatement->getMoreResults();
+ return false; // TODO IMPL
}
Any SAL_CALL OCommonStatement::getWarnings()
@@ -370,13 +372,4 @@ Reference< css::beans::XPropertySetInfo > SAL_CALL OCommonStatement::getProperty
return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
}
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/mysqlc/source/mysqlc_statement.hxx b/mysqlc/source/mysqlc_statement.hxx
index 6ac561f1e447..a26988a5a9ac 100644
--- a/mysqlc/source/mysqlc_statement.hxx
+++ b/mysqlc/source/mysqlc_statement.hxx
@@ -66,7 +66,11 @@ namespace connectivity
protected:
rtl::Reference<OConnection> m_xConnection; // The owning Connection object
- std::unique_ptr<sql::Statement> cppStatement;
+ css::uno::Reference<css::sdbc::XResultSet> m_xResultSet;
+ MYSQL_RES* m_pMysqlResult = nullptr;
+
+ // number of rows affected by an UPDATE, DELETE or INSERT statement.
+ sal_Int32 m_nAffectedRows = 0;
protected:
void disposeResultSet();
@@ -85,7 +89,7 @@ namespace connectivity
virtual ~OCommonStatement();
protected:
- OCommonStatement(OConnection* _pConnection, sql::Statement *_cppStatement);
+ OCommonStatement(OConnection* _pConnection);
public:
using OCommonStatement_IBase::rBHelper;
@@ -152,8 +156,8 @@ namespace connectivity
public:
// A constructor which is required for the return of the objects
- OStatement(OConnection* _pConnection, sql::Statement *_cppStatement) :
- OCommonStatement(_pConnection, _cppStatement) {}
+ OStatement(OConnection* _pConnection) :
+ OCommonStatement(_pConnection) {}
virtual rtl::OUString SAL_CALL getImplementationName() SAL_OVERRIDE;