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

Generated by: LCOV version 1.11