User: rt      
Date: 05/10/24 01:28:38

Modified:
 /dba/dbaccess/source/core/dataaccess/
  datasource.cxx

Log:
 INTEGRATION: CWS dba201d (1.63.2); FILE MERGED
 2005/10/05 10:18:56 fs 1.63.2.1: #i55493# be an XFlushListener at an embedded 
connection

File Changes:

Directory: /dba/dbaccess/source/core/dataaccess/
================================================

File [changed]: datasource.cxx
Url: 
http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/dataaccess/datasource.cxx?r1=1.63&r2=1.64
Delta lines:  +150 -4
---------------------
--- datasource.cxx      23 Sep 2005 12:05:24 -0000      1.63
+++ datasource.cxx      24 Oct 2005 08:28:36 -0000      1.64
@@ -150,9 +150,111 @@
 {
 //........................................................................
 
-//============================================================
-//= OAuthenticationContinuation
-//============================================================
+    //============================================================
+    //= FlushNotificationAdapter
+    //============================================================
+    typedef ::cppu::WeakImplHelper1< XFlushListener > 
FlushNotificationAdapter_Base;
+    /** helper class which implements a XFlushListener, and forwards all
+        notification events to another XFlushListener
+
+        The speciality is that the foreign XFlushListener instance, to which
+        the notifications are forwarded, is held weak.
+
+        Thus, the class can be used with XFlushable instance which hold
+        their listeners with a hard reference, if you simply do not *want*
+        to be held hard-ref-wise.
+    */
+    class FlushNotificationAdapter : public FlushNotificationAdapter_Base
+    {
+    private:
+        WeakReference< XFlushable >     m_aBroadcaster;
+        WeakReference< XFlushListener > m_aListener;
+
+    public:
+        static void installAdapter( const Reference< XFlushable >& 
_rxBroadcaster, const Reference< XFlushListener >& _rxListener )
+        {
+            Reference< XFlushListener > xAdapter( new 
FlushNotificationAdapter( _rxBroadcaster, _rxListener ) );
+        }
+
+    protected:
+        FlushNotificationAdapter( const Reference< XFlushable >& 
_rxBroadcaster, const Reference< XFlushListener >& _rxListener );
+        ~FlushNotificationAdapter();
+
+        void SAL_CALL impl_dispose( bool _bRevokeListener );
+
+    protected:
+        // XFlushListener
+        virtual void SAL_CALL flushed( const 
::com::sun::star::lang::EventObject& rEvent ) throw 
(::com::sun::star::uno::RuntimeException);
+        // XEventListener
+        virtual void SAL_CALL disposing( const 
::com::sun::star::lang::EventObject& Source ) throw 
(::com::sun::star::uno::RuntimeException);
+    };
+
+    //------------------------------------------------------------
+    DBG_NAME( FlushNotificationAdapter )
+    //------------------------------------------------------------
+    FlushNotificationAdapter::FlushNotificationAdapter( const Reference< 
XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
+        :m_aBroadcaster( _rxBroadcaster )
+        ,m_aListener( _rxListener )
+    {
+        DBG_CTOR( FlushNotificationAdapter, NULL );
+        DBG_ASSERT( _rxBroadcaster.is(), 
"FlushNotificationAdapter::FlushNotificationAdapter: invalid flushable!" );
+
+        osl_incrementInterlockedCount( &m_refCount );
+        {
+            if ( _rxBroadcaster.is() )
+                _rxBroadcaster->addFlushListener( this );
+        }
+        osl_decrementInterlockedCount( &m_refCount );
+        DBG_ASSERT( m_refCount == 1, 
"FlushNotificationAdapter::FlushNotificationAdapter: broadcaster isn't holding 
by hard ref!?" );
+    }
+
+    //------------------------------------------------------------
+    FlushNotificationAdapter::~FlushNotificationAdapter()
+    {
+        DBG_DTOR( FlushNotificationAdapter, NULL );
+    }
+
+    //--------------------------------------------------------------------
+    void SAL_CALL FlushNotificationAdapter::impl_dispose( bool 
_bRevokeListener )
+    {
+        Reference< XFlushListener > xKeepAlive( this );
+
+        if ( _bRevokeListener )
+        {
+            Reference< XFlushable > xFlushable( m_aBroadcaster );
+            if ( xFlushable.is() )
+                xFlushable->removeFlushListener( this );
+        }
+
+        m_aListener = Reference< XFlushListener >();
+        m_aBroadcaster = Reference< XFlushable >();
+    }
+
+    //--------------------------------------------------------------------
+    void SAL_CALL FlushNotificationAdapter::flushed( const EventObject& rEvent 
) throw (RuntimeException)
+    {
+        Reference< XFlushListener > xListener( m_aListener );
+        if ( xListener.is() )
+            xListener->flushed( rEvent );
+        else
+            impl_dispose( true );
+    }
+
+    //--------------------------------------------------------------------
+    void SAL_CALL FlushNotificationAdapter::disposing( const EventObject& 
Source ) throw (RuntimeException)
+    {
+        DBG_ASSERT( Source.Source == m_aBroadcaster.get(), 
"FlushNotificationAdapter::disposing: where did this come from?" );
+
+        Reference< XFlushListener > xListener( m_aListener );
+        if ( xListener.is() )
+            xListener->disposing( Source );
+
+        impl_dispose( false );
+    }
+
+    //============================================================
+    //= OAuthenticationContinuation
+    //============================================================
        class OAuthenticationContinuation : public OInteraction< 
XInteractionSupplyAuthentication >
        {
                sal_Bool        m_bDatasourceReadonly : 1;      // if sal_True, 
the data source using this continuation
@@ -718,6 +820,15 @@
                                xReturn = 
xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL, 
::comphelper::concatSequences(aUserPwd,aDriverInfo));
                        else
                                xReturn = 
xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL,aDriverInfo);
+
+            if ( m_pImpl->isEmbeddedDatabase() )
+            {
+                // see ODatabaseSource::flushed for comment on why we register 
as FlushListener
+                // at the connection
+                Reference< XFlushable > xFlushable( xReturn, UNO_QUERY );
+                if ( xFlushable.is() )
+                    FlushNotificationAdapter::installAdapter( xFlushable, this 
);
+            }
                }
        }
        else
@@ -1094,7 +1205,7 @@
        {
                Reference< XComponent> xComp(xConn,UNO_QUERY);
                if ( xComp.is() )
-                       xComp->addEventListener(static_cast< 
css::lang::XEventListener* >(this));
+                       xComp->addEventListener( static_cast< 
XContainerListener* >( this ) );
                m_pImpl->m_aConnections.push_back(OWeakConnection(xConn));
        }
 
@@ -1182,6 +1293,41 @@
        {
        }
 }
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseSource::flushed( const EventObject& rEvent ) throw 
(RuntimeException)
+{
+       ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+       MutexGuard aGuard(m_aMutex);
+
+    // Okay, this is some hack.
+    //
+    // In general, we have the problem that embedded databases write into 
their underlying storage, which
+    // logically is one of our sub storage, and practically is a temporary 
file maintained by the
+    // package implementation. As long as we did not commit this storage and 
our main storage,
+    // the changes made by the embedded database engine is not really 
reflected in the database document
+    // file. This is Bad (TM) for a "real" database application - imagine 
somebody entering some
+    // data, and then crashing: For a database application, you would expect 
that the data still is present
+    // when you connect to the database next time.
+    //
+    // Since this is a conceptual problem as long as we do use those ZIP 
packages (in fact, we *cannot*
+    // provide the desired functionality as long as we do not have a package 
format which allows O(1) writes),
+    // we cannot completely fix this. However, we can relax the problem by 
commiting more often - often
+    // enough so that data loss is more seldom, and seldom enough so that 
there's no noticable performance
+    // decrease.
+    //
+    // For this, we introduced a few places which XFlushable::flush their 
connections, and register as
+    // XFlushListener at the embedded connection (which needs to provide the 
XFlushable functionality).
+    // Then, when the connection is flushed, we commit both the database 
storage and our main storage.
+    //
+    // #i55274# / 2005-09-30 / [EMAIL PROTECTED]
+
+    OSL_ENSURE( m_pImpl->isEmbeddedDatabase(), "ODatabaseSource::flushed: no 
embedded database?!" );
+    sal_Bool bWasModified = m_pImpl->m_bModified;
+    m_pImpl->commitEmbeddedStorage();
+    m_pImpl->setModified( bWasModified );
+}
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseSource::addFlushListener( const Reference< 
::com::sun::star::util::XFlushListener >& _xListener ) throw (RuntimeException)
 {




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to