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

Generated by: LCOV version 1.10