Kaydet (Commit) 031009ef authored tarafından Andrzej J.R. Hunt's avatar Andrzej J.R. Hunt

Implement DocumentEventListener in firebird_sdbc driver.

Change-Id: I7e0c9abcb9822e673ba1e93c1d8bf4d177baae0f
üst 07532dd1
......@@ -39,20 +39,47 @@
#include "FDriver.hxx"
#include "FStatement.hxx"
#include "FPreparedStatement.hxx"
#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XFrames.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/io/TempFile.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/EventObject.hpp>
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/TransactionIsolation.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
#include "connectivity/dbexception.hxx"
#include "resource/common_res.hrc"
#include "resource/hsqldb_res.hrc"
#include "resource/sharedresources.hxx"
#include <comphelper/processfactory.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/ucbstreamhelper.hxx>
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<OConnection, OConnection_BASE>((::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<frame::XFrame> > 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<XDocumentEventBroadcaster> 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();
}
// -----------------------------------------------------------------------------
......
......@@ -38,6 +38,9 @@
#include <com/sun/star/sdbc/SQLWarning.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/document/DocumentEvent.hpp>
#include <com/sun/star/document/XDocumentEventListener.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include "OSubComponent.hxx"
#include "OTypeInfo.hxx"
#include <com/sun/star/lang/DisposedException.hpp>
......@@ -45,7 +48,7 @@
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <cppuhelper/compbase3.hxx>
#include <cppuhelper/compbase4.hxx>
#include <cppuhelper/weakref.hxx>
#include <map>
......@@ -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; }
......
......@@ -40,21 +40,9 @@
#include "resource/hsqldb_res.hrc"
#include "resource/sharedresources.hxx"
#include <unotools/tempfile.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/io/TempFile.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
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> 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;
......
......@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment