LCOV - code coverage report
Current view: top level - libreoffice/connectivity/source/drivers/mork - MConnection.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 73 157 46.5 %
Date: 2012-12-27 Functions: 10 33 30.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "diagnose_ex.h"
      11             : #include "MNSProfileDiscover.hxx"
      12             : #include "MConnection.hxx"
      13             : #include "MDriver.hxx"
      14             : #include "MDatabaseMetaData.hxx"
      15             : #include "MCatalog.hxx"
      16             : #include "MPreparedStatement.hxx"
      17             : #include "MorkParser.hxx"
      18             : 
      19             : #include <connectivity/dbcharset.hxx>
      20             : #include <connectivity/dbexception.hxx>
      21             : #include <connectivity/sqlerror.hxx>
      22             : 
      23             : #include "resource/mork_res.hrc"
      24             : #include "resource/common_res.hrc"
      25             : 
      26             : #include <com/sun/star/sdbc/ColumnValue.hpp>
      27             : #include <com/sun/star/sdbc/XRow.hpp>
      28             : #include <com/sun/star/sdbc/TransactionIsolation.hpp>
      29             : 
      30             : #include <comphelper/officeresourcebundle.hxx>
      31             : #include <comphelper/processfactory.hxx>
      32             : 
      33             : using namespace dbtools;
      34             : 
      35             : //------------------------------------------------------------------------------
      36             : using namespace com::sun::star::uno;
      37             : using namespace com::sun::star::lang;
      38             : using namespace com::sun::star::beans;
      39             : using namespace com::sun::star::sdbc;
      40             : using namespace com::sun::star::sdbcx;
      41             : // --------------------------------------------------------------------------------
      42             : 
      43             : namespace connectivity { namespace mork {
      44             : 
      45             : static const int defaultScope = 0x80;
      46             : 
      47             : // -----------------------------------------------------------------------------
      48             : 
      49           3 : OConnection::OConnection(MorkDriver* _pDriver)
      50             :     :OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)_pDriver, this)
      51             :     ,m_pDriver(_pDriver)
      52           3 :     ,m_aColumnAlias( _pDriver->getFactory() )
      53             : {
      54           3 :     m_pDriver->acquire();
      55           3 :     m_pProfileAccess = new ProfileAccess();
      56           3 :     m_pMork = new MorkParser();
      57           3 : }
      58             : //-----------------------------------------------------------------------------
      59           3 : OConnection::~OConnection()
      60             : {
      61           1 :     acquire();
      62           1 :     if(!isClosed())
      63           0 :         close();
      64           1 :     m_pDriver->release();
      65           1 :     m_pDriver = NULL;
      66           1 :     delete m_pProfileAccess;
      67           1 :     delete m_pMork;
      68           2 : }
      69             : //-----------------------------------------------------------------------------
      70          27 : void SAL_CALL OConnection::release() throw()
      71             : {
      72          27 :     relase_ChildImpl();
      73          27 : }
      74             : // -----------------------------------------------------------------------------
      75             : //-----------------------------------------------------------------------------
      76           3 : void OConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info)  throw(SQLException)
      77             : {
      78             :     (void) info; // avoid warnings
      79             :     SAL_INFO("connectivity.mork", "=> OConnection::construct()" );
      80             :     //  open file
      81           3 :     setURL(url);
      82             :     //
      83             :     // Skip 'sdbc:mozab: part of URL
      84             :     //
      85           3 :     sal_Int32 nLen = url.indexOf(':');
      86           3 :     nLen = url.indexOf(':',nLen+1);
      87             :     OSL_ENSURE( url.copy( 0, nLen ) == "sdbc:address", "OConnection::construct: invalid start of the URI - should never have survived XDriver::acceptsURL!" );
      88             : 
      89           3 :     OUString aAddrbookURI(url.copy(nLen+1));
      90             :     // Get Scheme
      91           3 :     nLen = aAddrbookURI.indexOf(':');
      92           3 :     OUString aAddrbookScheme;
      93           3 :     OUString sAdditionalInfo;
      94           3 :     if ( nLen == -1 )
      95             :     {
      96             :         // There isn't any subschema: - but could be just subschema
      97           0 :         if ( !aAddrbookURI.isEmpty() )
      98             :         {
      99           0 :             aAddrbookScheme= aAddrbookURI;
     100             :         }
     101             :         else
     102             :         {
     103             :             SAL_WARN("connectivity.mork", "No subschema given!!!");
     104           0 :             throwGenericSQLException( STR_URI_SYNTAX_ERROR, *this );
     105             :         }
     106             :     }
     107             :     else
     108             :     {
     109           3 :         aAddrbookScheme = aAddrbookURI.copy(0, nLen);
     110           3 :         sAdditionalInfo = aAddrbookURI.copy( nLen + 1 );
     111             :     }
     112             : 
     113             :     SAL_INFO("connectivity.mork", "URI = " << aAddrbookURI );
     114             :     SAL_INFO("connectivity.mork", "Scheme = " << aAddrbookScheme );
     115             : 
     116           3 :     OUString path;
     117           3 :     const OUString UNITTEST_URL = "thunderbird:unittest:";
     118           3 :     sal_Int32 unittestIndex = url.indexOf(UNITTEST_URL);
     119             : 
     120             :     // production?
     121           3 :     if (unittestIndex == -1)
     122             :     {
     123           0 :         OUString defaultProfile = m_pProfileAccess->getDefaultProfile(::com::sun::star::mozilla::MozillaProductType_Thunderbird);
     124           0 :         path = m_pProfileAccess->getProfilePath(::com::sun::star::mozilla::MozillaProductType_Thunderbird, defaultProfile);
     125             :         SAL_INFO("connectivity.mork", "DefaultProfile: " << defaultProfile);
     126             :         SAL_INFO("connectivity.mork", "ProfilePath: " << path);
     127           0 :         path += rtl::OUString( "/abook.mab" );
     128             :     }
     129             :     else
     130             :     {
     131           3 :         path = aAddrbookURI.replaceFirst(UNITTEST_URL, "");
     132             :     }
     133             : 
     134             :     SAL_INFO("connectivity.mork", "AdressbookPath: " << path);
     135             : 
     136           3 :     rtl::OString strPath = ::rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8 );
     137             : 
     138             :     // Open and parse mork file
     139           3 :     if (!m_pMork->open(strPath.getStr()))
     140             :     {
     141             :         SAL_WARN("connectivity.mork", "Can not parse mork file!");
     142           0 :         throwGenericSQLException( STR_COULD_NOT_LOAD_FILE, *this );
     143             :     }
     144             : 
     145             :     // check that we can retrieve the tables:
     146           3 :     MorkTableMap *Tables = m_pMork->getTables( defaultScope );
     147           3 :     MorkTableMap::iterator tableIter;
     148           3 :     if (Tables)
     149             :     {
     150             :         // Iterate all tables
     151           6 :         for ( tableIter = Tables->begin(); tableIter != Tables->end(); ++tableIter )
     152             :         {
     153           3 :             if ( 0 == tableIter->first ) continue;
     154             :             SAL_INFO("connectivity.mork", "table->first : " << tableIter->first);
     155             :         }
     156           3 :     }
     157           3 : }
     158             : 
     159             : // XServiceInfo
     160             : // --------------------------------------------------------------------------------
     161           0 : IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.mork.OConnection", "com.sun.star.sdbc.Connection")
     162             : 
     163             : // --------------------------------------------------------------------------------
     164           0 : Reference< XStatement > SAL_CALL OConnection::createStatement(  ) throw(SQLException, RuntimeException)
     165             : {
     166             :     SAL_INFO("connectivity.mork", "=> OConnection::createStatement()" );
     167             : 
     168           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     169           0 :     checkDisposed(OConnection_BASE::rBHelper.bDisposed);
     170             : 
     171             :     // create a statement
     172             :     // the statement can only be executed once
     173           0 :     Reference< XStatement > xReturn = new OStatement(this);
     174           0 :     m_aStatements.push_back(WeakReferenceHelper(xReturn));
     175           0 :     return xReturn;
     176             : }
     177             : // --------------------------------------------------------------------------------
     178           2 : Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException)
     179             : {
     180             :     SAL_INFO("connectivity.mork", "=> OConnection::prepareStatement()" );
     181             :     SAL_INFO("connectivity.mork", "OConnection::prepareStatement( " << _sSql << " )");
     182             : 
     183             :     OSL_UNUSED( _sSql );
     184           2 :     ::osl::MutexGuard aGuard( m_aMutex );
     185           2 :     checkDisposed(OConnection_BASE::rBHelper.bDisposed);
     186             : 
     187             :     // the pre
     188             :     // create a statement
     189             :     // the statement can only be executed more than once
     190           2 :     OPreparedStatement* pPrepared = new OPreparedStatement(this,_sSql);
     191           2 :     Reference< XPreparedStatement > xReturn = pPrepared;
     192           2 :     pPrepared->lateInit();
     193             : 
     194           2 :     m_aStatements.push_back(WeakReferenceHelper(xReturn));
     195           2 :     return xReturn;
     196             : }
     197             : // --------------------------------------------------------------------------------
     198           0 : Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException)
     199             : {
     200             :     SAL_INFO("connectivity.mork", "=> OConnection::prepareCall()" );
     201             :     SAL_INFO("connectivity.mork", "sql: " << _sSql);
     202             :     OSL_UNUSED( _sSql );
     203           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
     204             :     SAL_INFO("connectivity.mork", "OConnection::prepareCall( " << _sSql << " )");
     205           0 :     return NULL;
     206             : }
     207             : // --------------------------------------------------------------------------------
     208           0 : ::rtl::OUString SAL_CALL OConnection::nativeSQL( const ::rtl::OUString& _sSql ) throw(SQLException, RuntimeException)
     209             : {
     210             :     SAL_INFO("connectivity.mork", "=> OConnection::nativeSQL()" );
     211             :     SAL_INFO("connectivity.mork", "sql: " << _sSql);
     212             : 
     213           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     214             :     // when you need to transform SQL92 to you driver specific you can do it here
     215             :     SAL_INFO("connectivity.mork", "OConnection::nativeSQL(" << _sSql << " )" );
     216             : 
     217           0 :     return _sSql;
     218             : }
     219             : // --------------------------------------------------------------------------------
     220           0 : void SAL_CALL OConnection::setAutoCommit( sal_Bool /*autoCommit*/ ) throw(SQLException, RuntimeException)
     221             : {
     222           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setAutoCommit", *this );
     223           0 : }
     224             : // --------------------------------------------------------------------------------
     225           0 : sal_Bool SAL_CALL OConnection::getAutoCommit(  ) throw(SQLException, RuntimeException)
     226             : {
     227             :     // you have to distinguish which if you are in autocommit mode or not
     228             :     // at normal case true should be fine here
     229             : 
     230           0 :     return sal_True;
     231             : }
     232             : // --------------------------------------------------------------------------------
     233           0 : void SAL_CALL OConnection::commit(  ) throw(SQLException, RuntimeException)
     234             : {
     235             :     // when you database does support transactions you should commit here
     236           0 : }
     237             : // --------------------------------------------------------------------------------
     238           0 : void SAL_CALL OConnection::rollback(  ) throw(SQLException, RuntimeException)
     239             : {
     240             :     // same as commit but for the other case
     241           0 : }
     242             : // --------------------------------------------------------------------------------
     243           1 : sal_Bool SAL_CALL OConnection::isClosed(  ) throw(SQLException, RuntimeException)
     244             : {
     245           1 :     ::osl::MutexGuard aGuard( m_aMutex );
     246             : 
     247             :     // just simple -> we are close when we are disposed taht means someone called dispose(); (XComponent)
     248           1 :     return OConnection_BASE::rBHelper.bDisposed;
     249             : }
     250             : // --------------------------------------------------------------------------------
     251          87 : Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData(  ) throw(SQLException, RuntimeException)
     252             : {
     253             :     SAL_INFO("connectivity.mork", "=> OConnection::getMetaData()" );
     254             : 
     255          87 :     ::osl::MutexGuard aGuard( m_aMutex );
     256          87 :     checkDisposed(OConnection_BASE::rBHelper.bDisposed);
     257             : 
     258             :     // here we have to create the class with biggest interface
     259             :     // The answer is 42 :-)
     260          87 :     Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
     261          87 :     if(!xMetaData.is())
     262             :     {
     263           3 :         xMetaData = new ODatabaseMetaData(this); // need the connection because it can return it
     264           3 :         m_xMetaData = xMetaData;
     265             :     }
     266             : 
     267          87 :     return xMetaData;
     268             : }
     269             : // --------------------------------------------------------------------------------
     270           0 : void SAL_CALL OConnection::setReadOnly( sal_Bool /*readOnly*/ ) throw(SQLException, RuntimeException)
     271             : {
     272           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setReadOnly", *this );
     273           0 : }
     274             : // --------------------------------------------------------------------------------
     275           0 : sal_Bool SAL_CALL OConnection::isReadOnly(  ) throw(SQLException, RuntimeException)
     276             : {
     277             :     // return if your connection to readonly
     278           0 :     return sal_False;
     279             : }
     280             : // --------------------------------------------------------------------------------
     281           0 : void SAL_CALL OConnection::setCatalog( const ::rtl::OUString& /*catalog*/ ) throw(SQLException, RuntimeException)
     282             : {
     283           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setCatalog", *this );
     284           0 : }
     285             : // --------------------------------------------------------------------------------
     286           0 : ::rtl::OUString SAL_CALL OConnection::getCatalog(  ) throw(SQLException, RuntimeException)
     287             : {
     288           0 :     return ::rtl::OUString();
     289             : }
     290             : // --------------------------------------------------------------------------------
     291           0 : void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 /*level*/ ) throw(SQLException, RuntimeException)
     292             : {
     293           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setTransactionIsolation", *this );
     294           0 : }
     295             : // --------------------------------------------------------------------------------
     296           0 : sal_Int32 SAL_CALL OConnection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
     297             : {
     298             :     // please have a look at @see com.sun.star.sdbc.TransactionIsolation
     299           0 :     return TransactionIsolation::NONE;
     300             : }
     301             : // --------------------------------------------------------------------------------
     302           0 : Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getTypeMap(  ) throw(SQLException, RuntimeException)
     303             : {
     304             :     // if your driver has special database types you can return it here
     305           0 :     return NULL;
     306             : }
     307             : // --------------------------------------------------------------------------------
     308           0 : void SAL_CALL OConnection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
     309             : {
     310           0 :     ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
     311           0 : }
     312             : // --------------------------------------------------------------------------------
     313             : // XCloseable
     314           0 : void SAL_CALL OConnection::close(  ) throw(SQLException, RuntimeException)
     315             : {
     316             :     // we just dispose us
     317             :     {
     318           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     319           0 :         checkDisposed(OConnection_BASE::rBHelper.bDisposed);
     320             : 
     321             :     }
     322           0 :     dispose();
     323           0 : }
     324             : // --------------------------------------------------------------------------------
     325             : // XWarningsSupplier
     326           0 : Any SAL_CALL OConnection::getWarnings(  ) throw(SQLException, RuntimeException)
     327             : {
     328             :     // when you collected some warnings -> return it
     329           0 :     return Any();
     330             : }
     331             : // --------------------------------------------------------------------------------
     332           0 : void SAL_CALL OConnection::clearWarnings(  ) throw(SQLException, RuntimeException)
     333             : {
     334             :     // you should clear your collected warnings here
     335           0 : }
     336             : //------------------------------------------------------------------------------
     337           1 : void OConnection::disposing()
     338             : {
     339             :     // we noticed that we should be destroied in near future so we have to dispose our statements
     340           1 :     ::osl::MutexGuard aGuard(m_aMutex);
     341           1 :     dispose_ChildImpl();
     342           1 : }
     343             : // -----------------------------------------------------------------------------
     344             : 
     345           2 : Reference< XTablesSupplier > SAL_CALL OConnection::createCatalog()
     346             : {
     347             :     OSL_TRACE("IN OConnection::createCatalog()" );
     348           2 :     ::osl::MutexGuard aGuard( m_aMutex );
     349           2 :     Reference< XTablesSupplier > xTab = m_xCatalog;
     350           2 :     if(!m_xCatalog.is())
     351             :     {
     352           2 :         OCatalog *pCat = new OCatalog(this);
     353           2 :         xTab = pCat;
     354           2 :         m_xCatalog = xTab;
     355             :     }
     356             :     OSL_TRACE( "\tOUT OConnection::createCatalog()" );
     357           2 :     return xTab;
     358             : }
     359             : // -----------------------------------------------------------------------------
     360             : 
     361             : // -----------------------------------------------------------------------------
     362           0 : void OConnection::throwSQLException( const ErrorDescriptor& _rError, const Reference< XInterface >& _rxContext )
     363             : {
     364           0 :     if ( _rError.getResId() != 0 )
     365             :     {
     366             :         OSL_ENSURE( ( _rError.getErrorCondition() == 0 ),
     367             :             "OConnection::throwSQLException: unsupported error code combination!" );
     368             : 
     369           0 :         ::rtl::OUString sParameter( _rError.getParameter() );
     370           0 :         if ( !sParameter.isEmpty() )
     371             :         {
     372           0 :             const ::rtl::OUString sError( getResources().getResourceStringWithSubstitution(
     373           0 :                 _rError.getResId(),
     374             :                 "$1$", sParameter
     375           0 :              ) );
     376           0 :             ::dbtools::throwGenericSQLException( sError, _rxContext );
     377           0 :             OSL_FAIL( "OConnection::throwSQLException: unreachable (1)!" );
     378             :         }
     379             : 
     380           0 :         throwGenericSQLException( _rError.getResId(), _rxContext );
     381           0 :         OSL_FAIL( "OConnection::throwSQLException: unreachable (2)!" );
     382             :     }
     383             : 
     384           0 :     if ( _rError.getErrorCondition() != 0 )
     385             :     {
     386           0 :         SQLError aErrorHelper( comphelper::getComponentContext(getDriver()->getFactory()) );
     387           0 :         ::rtl::OUString sParameter( _rError.getParameter() );
     388           0 :         if ( !sParameter.isEmpty() )
     389           0 :             aErrorHelper.raiseException( _rError.getErrorCondition(), _rxContext, sParameter );
     390             :         else
     391           0 :             aErrorHelper.raiseException( _rError.getErrorCondition(), _rxContext);
     392           0 :         OSL_FAIL( "OConnection::throwSQLException: unreachable (3)!" );
     393             :     }
     394             : 
     395           0 :     throwGenericSQLException( STR_UNSPECIFIED_ERROR, _rxContext );
     396           0 : }
     397             : 
     398             : // -----------------------------------------------------------------------------
     399           0 : void OConnection::throwSQLException( const sal_uInt16 _nErrorResourceId, const Reference< XInterface >& _rxContext )
     400             : {
     401           0 :     ErrorDescriptor aError;
     402           0 :     aError.setResId( _nErrorResourceId );
     403           0 :     throwSQLException( aError, _rxContext );
     404           0 : }
     405             : 
     406             : } } // namespace connectivity::mork
     407             : 
     408             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10