diff options
Diffstat (limited to 'connectivity/source/drivers/firebird/Connection.cxx')
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.cxx | 213 |
1 files changed, 112 insertions, 101 deletions
diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx index 05c24e9f73be..5a2be8872485 100644 --- a/connectivity/source/drivers/firebird/Connection.cxx +++ b/connectivity/source/drivers/firebird/Connection.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -22,7 +22,6 @@ #include "Clob.hxx" #include "Connection.hxx" #include "DatabaseMetaData.hxx" -#include "Driver.hxx" #include "PreparedStatement.hxx" #include "Statement.hxx" #include "Util.hxx" @@ -44,11 +43,12 @@ #include <resource/sharedresources.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/servicehelper.hxx> #include <comphelper/storagehelper.hxx> #include <cppuhelper/exc_hlp.hxx> #include <unotools/tempfile.hxx> -#include <unotools/localfilehelper.hxx> +#include <osl/file.hxx> #include <rtl/strbuf.hxx> #include <sal/log.hxx> @@ -72,16 +72,14 @@ using namespace ::com::sun::star::uno; * Location within the .odb that an embedded .fdb will be stored. * Only relevant for embedded dbs. */ -constexpr OUStringLiteral our_sFDBLocation( u"firebird.fdb" ); +constexpr OUString our_sFDBLocation( u"firebird.fdb"_ustr ); /** * Older version of LO may store the database in a .fdb file */ -constexpr OUStringLiteral our_sFBKLocation( u"firebird.fbk" ); +constexpr OUString our_sFBKLocation( u"firebird.fbk"_ustr ); Connection::Connection() : Connection_BASE(m_aMutex) - , m_sConnectionURL() - , m_sFirebirdURL() , m_bIsEmbedded(false) , m_bIsFile(false) , m_bIsAutoCommit(true) @@ -96,7 +94,6 @@ Connection::Connection() #endif , m_xCatalog(nullptr) , m_xMetaData(nullptr) - , m_aStatements() { } @@ -164,7 +161,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); - m_pDatabaseFileDir.reset(new ::utl::TempFile(nullptr, true)); + m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(nullptr, true)); m_pDatabaseFileDir->EnableKillingFile(); m_sFirebirdURL = m_pDatabaseFileDir->GetFileName() + "/firebird.fdb"; m_sFBKPath = m_pDatabaseFileDir->GetFileName() + "/firebird.fbk"; @@ -199,7 +196,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& // External file AND/OR remote connection else if (url.startsWith("sdbc:firebird:")) { - m_sFirebirdURL = url.copy(OUString("sdbc:firebird:").getLength()); + m_sFirebirdURL = url.copy(strlen("sdbc:firebird:")); if (m_sFirebirdURL.startsWith("file://")) { m_bIsFile = true; @@ -208,19 +205,19 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& if (!xFileAccess->exists(m_sFirebirdURL)) bIsNewDatabase = true; - m_sFirebirdURL = m_sFirebirdURL.copy(OUString("file://").getLength()); + osl::FileBase::getSystemPathFromFileURL(m_sFirebirdURL, m_sFirebirdURL); } } std::string dpbBuffer; { - char userName[256] = ""; - char userPassword[256] = ""; + OString userName; + OString userPassword; dpbBuffer.push_back(isc_dpb_version1); dpbBuffer.push_back(isc_dpb_sql_dialect); dpbBuffer.push_back(1); // 1 byte long - dpbBuffer.push_back(FIREBIRD_SQL_DIALECT); + dpbBuffer.push_back(SQL_DIALECT_CURRENT); // set UTF8 as default character set of the database const char sCharset[] = "UTF8"; @@ -236,45 +233,64 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& if (m_bIsEmbedded || m_bIsFile) { - strcpy(userName,"sysdba"); - strcpy(userPassword,"masterkey"); + userName = "sysdba"_ostr; + userPassword = "masterkey"_ostr; } else { - // TODO: parse password from connection string as needed? + for (const auto& rIter : info) + { + if (rIter.Name == "user") + { + if (OUString value; rIter.Value >>= value) + userName = OUStringToOString(value, RTL_TEXTENCODING_UTF8); + } + else if (rIter.Name == "password") + { + if (OUString value; rIter.Value >>= value) + userPassword = OUStringToOString(value, RTL_TEXTENCODING_UTF8); + } + } } - if (strlen(userName)) + if (!userName.isEmpty()) { - int nUsernameLength = strlen(userName); + const sal_Int32 nMaxUsername = 255; //max size + int nUsernameLength = std::min(userName.getLength(), nMaxUsername); dpbBuffer.push_back(isc_dpb_user_name); dpbBuffer.push_back(nUsernameLength); - dpbBuffer.append(userName); + dpbBuffer.append(userName.getStr(), nUsernameLength); } - if (strlen(userPassword)) + if (!userPassword.isEmpty()) { - int nPasswordLength = strlen(userPassword); + const sal_Int32 nMaxPassword = 255; //max size + int nPasswordLength = std::min(userPassword.getLength(), nMaxPassword); dpbBuffer.push_back(isc_dpb_password); dpbBuffer.push_back(nPasswordLength); - dpbBuffer.append(userPassword); + dpbBuffer.append(userPassword.getStr(), nPasswordLength); } } + // use isc_dpb_utf8_filename to identify encoding of filenames + dpbBuffer.push_back(isc_dpb_utf8_filename); + dpbBuffer.push_back(0); // no filename here, it is passed to functions directly + ISC_STATUS_ARRAY status; /* status vector */ ISC_STATUS aErr; + const OString sFirebirdURL = OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8); if (bIsNewDatabase) { aErr = isc_create_database(status, - m_sFirebirdURL.getLength(), - OUStringToOString(m_sFirebirdURL,RTL_TEXTENCODING_UTF8).getStr(), + sFirebirdURL.getLength(), + sFirebirdURL.getStr(), &m_aDBHandle, dpbBuffer.size(), dpbBuffer.c_str(), 0); if (aErr) { - evaluateStatusVector(status, "isc_create_database", *this); + evaluateStatusVector(status, u"isc_create_database", *this); } } else @@ -285,14 +301,14 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& } aErr = isc_attach_database(status, - m_sFirebirdURL.getLength(), - OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8).getStr(), + sFirebirdURL.getLength(), + sFirebirdURL.getStr(), &m_aDBHandle, dpbBuffer.size(), dpbBuffer.c_str()); if (aErr) { - evaluateStatusVector(status, "isc_attach_database", *this); + evaluateStatusVector(status, u"isc_attach_database", *this); } } @@ -323,12 +339,6 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& } } -void Connection::notifyDatabaseModified() -{ - if (m_xParentDocument.is()) // Only true in embedded mode - m_xParentDocument->setModified(true); -} - //----- XServiceInfo --------------------------------------------------------- IMPLEMENT_SERVICE_INFO(Connection, "com.sun.star.sdbc.drivers.firebird.Connection", "com.sun.star.sdbc.Connection") @@ -342,7 +352,7 @@ Reference< XBlob> Connection::createBlob(ISC_QUAD const * pBlobId) &m_aTransactionHandle, *pBlobId); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } @@ -355,10 +365,23 @@ Reference< XClob> Connection::createClob(ISC_QUAD const * pBlobId) &m_aTransactionHandle, *pBlobId); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } +//----- XUnoTunnel ---------------------------------------------------------- +// virtual +sal_Int64 SAL_CALL Connection::getSomething(const css::uno::Sequence<sal_Int8>& rId) +{ + return comphelper::getSomethingImpl(rId, this); +} + +// static +const css::uno::Sequence<sal_Int8> & Connection::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} //----- XConnection ---------------------------------------------------------- Reference< XStatement > SAL_CALL Connection::createStatement( ) @@ -373,7 +396,7 @@ Reference< XStatement > SAL_CALL Connection::createStatement( ) // create a statement // the statement can only be executed once Reference< XStatement > xReturn = new OStatement(this); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } @@ -389,7 +412,7 @@ Reference< XPreparedStatement > SAL_CALL Connection::prepareStatement( buildTypeInfo(); Reference< XPreparedStatement > xReturn = new OPreparedStatement(this, _sSql); - m_aStatements.push_back(WeakReferenceHelper(xReturn)); + m_aStatements.emplace_back(xReturn); return xReturn; } @@ -411,7 +434,6 @@ Reference< XPreparedStatement > SAL_CALL Connection::prepareCall( OUString SAL_CALL Connection::nativeSQL( const OUString& _sSql ) { - MutexGuard aGuard( m_aMutex ); // We do not need to adapt the SQL for Firebird atm. return _sSql; } @@ -490,7 +512,7 @@ void Connection::setupTransaction() aTPB); evaluateStatusVector(status_vector, - "isc_start_transaction", + u"isc_start_transaction", *this); } @@ -516,7 +538,7 @@ void SAL_CALL Connection::commit() disposeStatements(); isc_commit_transaction(status_vector, &m_aTransactionHandle); evaluateStatusVector(status_vector, - "isc_commit_transaction", + u"isc_commit_transaction", *this); } } @@ -569,7 +591,7 @@ isc_svc_handle Connection::attachServiceManager() aSPBBuffer)) { evaluateStatusVector(aStatusVector, - "isc_service_attach", + u"isc_service_attach", *this); } @@ -583,7 +605,7 @@ void Connection::detachServiceManager(isc_svc_handle aServiceHandle) &aServiceHandle)) { evaluateStatusVector(aStatusVector, - "isc_service_detach", + u"isc_service_detach", *this); } } @@ -600,22 +622,18 @@ void Connection::runBackupService(const short nAction) OString sFBKPath = OUStringToOString(m_sFBKPath, RTL_TEXTENCODING_UTF8); - OStringBuffer aRequest; // byte array - - - aRequest.append(static_cast<char>(nAction)); - - aRequest.append(char(isc_spb_dbname)); // .fdb sal_uInt16 nFDBLength = sFDBPath.getLength(); - aRequest.append(static_cast<char>(nFDBLength & 0xFF)); // least significant byte first - aRequest.append(static_cast<char>((nFDBLength >> 8) & 0xFF)); - aRequest.append(sFDBPath); - - aRequest.append(char(isc_spb_bkp_file)); // .fbk sal_uInt16 nFBKLength = sFBKPath.getLength(); - aRequest.append(static_cast<char>(nFBKLength & 0xFF)); - aRequest.append(static_cast<char>((nFBKLength >> 8) & 0xFF)); - aRequest.append(sFBKPath); + OStringBuffer aRequest( // byte array + OStringChar(static_cast<char>(nAction)) + + OStringChar(char(isc_spb_dbname)) // .fdb + + OStringChar(static_cast<char>(nFDBLength & 0xFF)) // least significant byte first + + OStringChar(static_cast<char>((nFDBLength >> 8) & 0xFF)) + + sFDBPath + + OStringChar(char(isc_spb_bkp_file)) // .fbk + + OStringChar(static_cast<char>(nFBKLength & 0xFF)) + + OStringChar(static_cast<char>((nFBKLength >> 8) & 0xFF)) + + sFBKPath); if (nAction == isc_action_svc_restore) { @@ -642,7 +660,7 @@ void Connection::runBackupService(const short nAction) aRequest.getLength(), aRequest.getStr())) { - evaluateStatusVector(aStatusVector, "isc_service_start", *this); + evaluateStatusVector(aStatusVector, u"isc_service_start", *this); } char aInfoSPB = isc_info_svc_line; @@ -658,7 +676,7 @@ void Connection::runBackupService(const short nAction) sizeof(aResults), aResults)) { - evaluateStatusVector(aStatusVector, "isc_service_query", *this); + evaluateStatusVector(aStatusVector, u"isc_service_query", *this); } detachServiceManager(aServiceHandle); @@ -798,42 +816,9 @@ void SAL_CALL Connection::documentEventOccured( const DocumentEvent& Event ) if ( !(m_bIsEmbedded && m_xEmbeddedStorage.is()) ) return; - SAL_INFO("connectivity.firebird", "Writing .fbk from running db"); - try - { - runBackupService(isc_action_svc_backup); - } - catch (const SQLException& e) - { - auto a = cppu::getCaughtException(); - throw WrappedTargetRuntimeException(e.Message, e.Context, a); - } - - - Reference< XStream > xDBStream(m_xEmbeddedStorage->openStreamElement(our_sFBKLocation, - ElementModes::WRITE)); - - // TODO: verify the backup actually exists -- the backup service - // can fail without giving any sane error messages / telling us - // that it failed. - using namespace ::comphelper; - Reference< XComponentContext > xContext = comphelper::getProcessComponentContext(); - Reference< XInputStream > xInputStream; - if (!xContext.is()) - return; - - xInputStream = - OStorageHelper::GetInputStreamFromURL(m_sFBKPath, xContext); - if (xInputStream.is()) - OStorageHelper::CopyInputToOutput( xInputStream, - xDBStream->getOutputStream()); - - // remove old fdb file if exists - uno::Reference< ucb::XSimpleFileAccess > xFileAccess = - ucb::SimpleFileAccess::create(xContext); - if (xFileAccess->exists(m_sFirebirdURL)) - xFileAccess->kill(m_sFirebirdURL); + storeDatabase(); } + // XEventListener void SAL_CALL Connection::disposing(const EventObject& /*rSource*/) { @@ -911,20 +896,46 @@ void Connection::disposing() { if (isc_detach_database(status, &m_aDBHandle)) { - evaluateStatusVector(status, "isc_detach_database", *this); + evaluateStatusVector(status, u"isc_detach_database", *this); } } - // TODO: write to storage again? + + storeDatabase(); cppu::WeakComponentImplHelperBase::disposing(); - if (m_pDatabaseFileDir) + m_pDatabaseFileDir.reset(); +} + +void Connection::storeDatabase() +{ + MutexGuard aGuard(m_aMutex); + if (m_bIsEmbedded && m_xEmbeddedStorage.is()) { - ::utl::removeTree(m_pDatabaseFileDir->GetURL()); - m_pDatabaseFileDir.reset(); + SAL_INFO("connectivity.firebird", "Writing .fbk from running db"); + try + { + runBackupService(isc_action_svc_backup); + } + catch (const SQLException& e) + { + auto a = cppu::getCaughtException(); + throw WrappedTargetRuntimeException(e.Message, e.Context, a); + } + Reference<XStream> xDBStream( + m_xEmbeddedStorage->openStreamElement(our_sFBKLocation, ElementModes::WRITE)); + using namespace ::comphelper; + Reference<XComponentContext> xContext = comphelper::getProcessComponentContext(); + Reference<XInputStream> xInputStream; + if (!xContext.is()) + return; + xInputStream = OStorageHelper::GetInputStreamFromURL(m_sFBKPath, xContext); + if (xInputStream.is()) + OStorageHelper::CopyInputToOutput(xInputStream, xDBStream->getOutputStream()); } } + void Connection::disposeStatements() { MutexGuard aGuard(m_aMutex); @@ -956,4 +967,4 @@ uno::Reference< XTablesSupplier > Connection::createCatalog() } - +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |