From 031009ef27b3dccbb97c9f22f6c59b8808aef34c Mon Sep 17 00:00:00 2001 From: "Andrzej J.R. Hunt" Date: Thu, 11 Jul 2013 15:26:48 +0100 Subject: [PATCH] Implement DocumentEventListener in firebird_sdbc driver. Change-Id: I7e0c9abcb9822e673ba1e93c1d8bf4d177baae0f --- .../source/drivers/firebird/FConnection.cxx | 171 ++++++++++++++++-- .../source/drivers/firebird/FConnection.hxx | 22 ++- .../source/drivers/firebird/FDriver.cxx | 91 +--------- .../source/drivers/firebird/FDriver.hxx | 3 - 4 files changed, 177 insertions(+), 110 deletions(-) diff --git a/connectivity/source/drivers/firebird/FConnection.cxx b/connectivity/source/drivers/firebird/FConnection.cxx index e72b87e42da3..e9594f9b3b7d 100644 --- a/connectivity/source/drivers/firebird/FConnection.cxx +++ b/connectivity/source/drivers/firebird/FConnection.cxx @@ -39,20 +39,47 @@ #include "FDriver.hxx" #include "FStatement.hxx" #include "FPreparedStatement.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include +#include +#include + +#include "connectivity/dbexception.hxx" +#include "resource/common_res.hrc" +#include "resource/hsqldb_res.hrc" +#include "resource/sharedresources.hxx" + +#include +#include +#include using namespace connectivity::firebird; using namespace connectivity; -//------------------------------------------------------------------------------ -using namespace com::sun::star::uno; -using namespace com::sun::star::lang; +using namespace com::sun::star; using namespace com::sun::star::beans; +using namespace com::sun::star::document; +using namespace com::sun::star::embed; +using namespace com::sun::star::frame; +using namespace com::sun::star::io; +using namespace com::sun::star::lang; using namespace com::sun::star::sdbc; -// -------------------------------------------------------------------------------- +using namespace com::sun::star::uno; + OConnection::OConnection(FirebirdDriver* _pDriver) : OSubComponent((::cppu::OWeakObject*)_pDriver, this), OMetaConnection_BASE(m_aMutex), @@ -103,21 +130,92 @@ static int pr_error(const ISC_STATUS* status, char* operation) return 1; } -void OConnection::construct(const ::rtl::OUString& url, const Sequence< PropertyValue >& info, - const bool constructNewDatabase) +void OConnection::construct(const ::rtl::OUString& url, const Sequence< PropertyValue >& info) throw(SQLException) { SAL_INFO("connectivity.firebird", "=> OConnection::construct()."); osl_atomic_increment( &m_refCount ); - // some example code how to get the information out of the sequence + bool bIsNewDatabase = false; + OUString aStorageURL; + if (url.equals("sdbc:embedded:firebird")) + { + m_bIsEmbedded = true; + const PropertyValue* pIter = info.getConstArray(); + const PropertyValue* pEnd = pIter + info.getLength(); + + for (;pIter != pEnd; ++pIter) + { + if ( pIter->Name == "Storage" ) + { + m_xEmbeddedStorage.set(pIter->Value,UNO_QUERY); + } + else if ( pIter->Name == "URL" ) + { + pIter->Value >>= aStorageURL; + } + } + + if ( !m_xEmbeddedStorage.is() ) + { + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_NO_STROAGE); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); + + const OUString sDBName( "firebird.fdb" ); // Location within .odb container + m_aURL = utl::TempFile::CreateTempName() + ".fdb"; + + SAL_INFO("connectivity.firebird", "Temporary .fdb location: " + << OUStringToOString(m_aURL,RTL_TEXTENCODING_UTF8 ).getStr()); + if (!bIsNewDatabase) + { + SAL_INFO("connectivity.firebird", "Extracting .fdb from .odb" ); + if (!m_xEmbeddedStorage->isStreamElement(sDBName)) + { + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + Reference< XStream > xDBStream(m_xEmbeddedStorage->openStreamElement(sDBName, + ElementModes::READ)); + + uno::Reference< ucb::XSimpleFileAccess2 > xFileAccess( + ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), + uno::UNO_QUERY ); + if ( !xFileAccess.is() ) + { + // TODO: Error + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + try { + xFileAccess->writeFile(m_aURL,xDBStream->getInputStream()); + } + catch (...) + { + // TODO + } + } + + if (bIsNewDatabase) + { + } + // Get DB properties from XML + + } + // else if url.begins(sdbc:firebird...) ISC_STATUS_ARRAY status; /* status vector */ - if (constructNewDatabase) + if (bIsNewDatabase) { - if (isc_create_database(status, url.getLength(), OUStringToOString(url, RTL_TEXTENCODING_UTF8).getStr(), + if (isc_create_database(status, m_aURL.getLength(), OUStringToOString(m_aURL, RTL_TEXTENCODING_UTF8).getStr(), &m_DBHandler, 0, NULL, 0)) { if(pr_error(status, "create new database")) @@ -126,11 +224,46 @@ void OConnection::construct(const ::rtl::OUString& url, const Sequence< Property } else { - if (isc_attach_database(status, url.getLength(), OUStringToOString(url, RTL_TEXTENCODING_UTF8).getStr(), + if (isc_attach_database(status, m_aURL.getLength(), OUStringToOString(m_aURL, RTL_TEXTENCODING_UTF8).getStr(), &m_DBHandler, 0, NULL)) if (pr_error(status, "attach database")) return; } + + if (m_bIsEmbedded) + { + uno::Reference< frame::XDesktop2 > xFramesSupplier = + frame::Desktop::create(::comphelper::getProcessComponentContext()); + uno::Reference< frame::XFrames > xFrames( xFramesSupplier->getFrames(), + uno::UNO_QUERY); + uno::Sequence< uno::Reference > xFrameList = + xFrames->queryFrames( frame::FrameSearchFlag::ALL ); + for (sal_Int32 i = 0; i < xFrameList.getLength(); i++) + { + uno::Reference< frame::XFrame > xf = xFrameList[i]; + + uno::Reference< XController > xc; + if (xf.is()) + xc = xf->getController(); + + uno::Reference< XModel > xm; + if (xc.is()) + xm = xc->getModel(); + + OUString aURL; + + if (xm.is()) + aURL = xm->getURL(); + if (aURL == aStorageURL) + { + uno::Reference xBroadcaster( xm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->addDocumentEventListener( this ); + //TODO: remove in the disposing? + } + } + } + osl_atomic_decrement( &m_refCount ); } // XServiceInfo @@ -360,6 +493,20 @@ void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeExceptio { // you should clear your collected warnings here } +// -------------------------------------------------------------------------------- +// XDocumentEventListener +void SAL_CALL OConnection::documentEventOccured( const DocumentEvent& _Event ) + throw(RuntimeException) +{ + if (_Event.EventName == "onSave" || _Event.EventName == "onSaveAs") + { + // TODO: write to storage + } +} +// XEventListener +void SAL_CALL OConnection::disposing( const EventObject& Source ) throw (RuntimeException) +{ +} //-------------------------------------------------------------------- void OConnection::buildTypeInfo() throw( SQLException) { @@ -438,7 +585,7 @@ void OConnection::disposing() return; dispose_ChildImpl(); - OConnection_BASE::disposing(); + cppu::WeakComponentImplHelperBase::disposing(); } // ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/firebird/FConnection.hxx b/connectivity/source/drivers/firebird/FConnection.hxx index af2ff6601d62..d6f284b686c3 100644 --- a/connectivity/source/drivers/firebird/FConnection.hxx +++ b/connectivity/source/drivers/firebird/FConnection.hxx @@ -38,6 +38,9 @@ #include #include +#include +#include +#include #include "OSubComponent.hxx" #include "OTypeInfo.hxx" #include @@ -45,7 +48,7 @@ #include #include #include -#include +#include #include #include @@ -57,9 +60,10 @@ namespace connectivity namespace firebird { - typedef ::cppu::WeakComponentImplHelper3< ::com::sun::star::sdbc::XConnection, + typedef ::cppu::WeakComponentImplHelper4< ::com::sun::star::sdbc::XConnection, ::com::sun::star::sdbc::XWarningsSupplier, - ::com::sun::star::lang::XServiceInfo + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::document::XDocumentEventListener > OMetaConnection_BASE; class OStatement_Base; @@ -94,11 +98,15 @@ namespace connectivity ::com::sun::star::sdbc::SQLWarning m_aLastWarning; // Last SQLWarning generated by // an operation + bool m_bIsEmbedded; ::rtl::OUString m_aURL; // URL of connection + // or file path ::rtl::OUString m_sUser; // the user name FirebirdDriver* m_pDriver; // Pointer to the owning // driver object + ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xEmbeddedStorage; + sal_Bool m_bClosed; sal_Bool m_bUseCatalog; // should we use the catalog on filebased databases sal_Bool m_bUseOldDateFormat; @@ -108,8 +116,7 @@ namespace connectivity public: virtual void construct( const ::rtl::OUString& url, - const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info, - const bool constructNewDatabase) + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info) throw(::com::sun::star::sdbc::SQLException); OConnection(FirebirdDriver* _pDriver); @@ -148,7 +155,10 @@ namespace connectivity // XWarningsSupplier virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL clearWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); - // + // XDocumentEventListener + virtual void SAL_CALL documentEventOccured( const ::com::sun::star::document::DocumentEvent& Event ) throw(::com::sun::star::uno::RuntimeException); + // css.lang.XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); // should we use the catalog on filebased databases inline sal_Bool isCatalogUsed() const { return m_bUseCatalog; } diff --git a/connectivity/source/drivers/firebird/FDriver.cxx b/connectivity/source/drivers/firebird/FDriver.cxx index 78280da4749c..112a5d5411fa 100644 --- a/connectivity/source/drivers/firebird/FDriver.cxx +++ b/connectivity/source/drivers/firebird/FDriver.cxx @@ -40,21 +40,9 @@ #include "resource/hsqldb_res.hrc" #include "resource/sharedresources.hxx" -#include - #include -#include - -#include -#include -#include -#include -#include -#include using namespace com::sun::star; -using namespace com::sun::star::embed; -using namespace com::sun::star::io; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::beans; @@ -77,9 +65,7 @@ namespace connectivity } // -------------------------------------------------------------------------------- FirebirdDriver::FirebirdDriver() - : ODriver_BASE(m_aMutex), - mbIsEmbedded(false), - mFilePath() + : ODriver_BASE(m_aMutex) { } // -------------------------------------------------------------------------------- @@ -145,77 +131,6 @@ Sequence< ::rtl::OUString > SAL_CALL FirebirdDriver::getSupportedServiceNames( Reference< XConnection > SAL_CALL FirebirdDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException) { Reference< XConnection > xConnection; - bool bIsNewDatabase = false; - if (url.equals("sdbc:embedded:firebird")) - { - mbIsEmbedded = true; - Reference xStorage; - const PropertyValue* pIter = info.getConstArray(); - const PropertyValue* pEnd = pIter + info.getLength(); - - for (;pIter != pEnd; ++pIter) - { - if ( pIter->Name == "Storage" ) - { - xStorage.set(pIter->Value,UNO_QUERY); - } - } - - if ( !xStorage.is() ) - { - ::connectivity::SharedResources aResources; - const OUString sMessage = aResources.getResourceString(STR_NO_STROAGE); - ::dbtools::throwGenericSQLException(sMessage ,*this); - } - - bIsNewDatabase = !xStorage->hasElements(); - - const OUString sDBName( "firebird.fdb" ); // Location within .odb container - mFilePath = utl::TempFile::CreateTempName() + ".fdb"; - - SAL_INFO("connectivity.firebird", "Temporary .fdb location: " - << OUStringToOString(mFilePath,RTL_TEXTENCODING_UTF8 ).getStr()); - if (!bIsNewDatabase) - { - SAL_INFO("connectivity.firebird", "Extracting .fdb from .odb" ); - if (!xStorage->isStreamElement(sDBName)) - { - ::connectivity::SharedResources aResources; - const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); - ::dbtools::throwGenericSQLException(sMessage ,*this); - } - - Reference< XStream > xDBStream(xStorage->openStreamElement(sDBName, - ElementModes::READ)); - - SAL_INFO("connectivity.firebird", ".fdb being written to " - << OUStringToOString(mFilePath,RTL_TEXTENCODING_UTF8 ).getStr()); - - uno::Reference< ucb::XSimpleFileAccess2 > xFileAccess( - ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), - uno::UNO_QUERY ); - if ( !xFileAccess.is() ) - { - // TODO: Error - ::connectivity::SharedResources aResources; - const OUString sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); - ::dbtools::throwGenericSQLException(sMessage ,*this); - } - try { - xFileAccess->writeFile(mFilePath,xDBStream->getInputStream()); - } - catch (...) - { - // TODO - } - } - - if (bIsNewDatabase) - { - } - // Get DB properties from XML - - } SAL_INFO("connectivity.firebird", "=> ODriver_BASE::connect(), URL: " << url ); @@ -226,12 +141,10 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect( const ::rtl::OUString if ( ! acceptsURL(url) ) return NULL; - bool bCreateNewFile = mbIsEmbedded&&bIsNewDatabase; - // create a new connection with the given properties and append it to our vector OConnection* pCon = new OConnection(this); Reference< XConnection > xCon = pCon; // important here because otherwise the connection could be deleted inside (refcount goes -> 0) - pCon->construct(mFilePath,info,bCreateNewFile); // late constructor call which can throw exception and allows a correct dtor call when so + pCon->construct(url,info); // late constructor call which can throw exception and allows a correct dtor call when so m_xConnections.push_back(WeakReferenceHelper(*pCon)); return xCon; diff --git a/connectivity/source/drivers/firebird/FDriver.hxx b/connectivity/source/drivers/firebird/FDriver.hxx index 1a259c0baf91..307ecddcaf61 100644 --- a/connectivity/source/drivers/firebird/FDriver.hxx +++ b/connectivity/source/drivers/firebird/FDriver.hxx @@ -57,9 +57,6 @@ namespace connectivity OWeakRefArray m_xConnections; // vector containing a list // of all the Connection objects // for this Driver - private: - bool mbIsEmbedded; - OUString mFilePath; public: