LCOV - code coverage report
Current view: top level - dbaccess/source/ui/dlg - odbcconfig.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 66 1.5 %
Date: 2014-11-03 Functions: 2 13 15.4 %
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             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_folders.h>
      21             : #include "odbcconfig.hxx"
      22             : 
      23             : #include <rtl/bootstrap.hxx>
      24             : #include <rtl/ustring.hxx>
      25             : #include <rtl/ustrbuf.hxx>
      26             : #include <osl/diagnose.h>
      27             : #include <osl/process.h>
      28             : #include <osl/thread.hxx>
      29             : #include <tools/debug.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : 
      32             : #ifdef HAVE_ODBC_SUPPORT
      33             : 
      34             : #if defined WNT
      35             : #define ODBC_LIBRARY    "ODBC32.DLL"
      36             : #endif
      37             : #ifdef UNX
      38             : #ifdef MACOSX
      39             : #define ODBC_LIBRARY        "libiodbc.dylib"
      40             : #else
      41             : #define ODBC_LIBRARY_1      "libodbc.so.1"
      42             : #define ODBC_LIBRARY        "libodbc.so"
      43             : #endif
      44             : #endif
      45             : 
      46             : #include <connectivity/odbc.hxx>
      47             : 
      48             : #else
      49             : 
      50             : #define ODBC_LIBRARY    ""
      51             : 
      52             : #endif  // HAVE_ODBC_SUPPORT
      53             : 
      54             : namespace dbaui
      55             : {
      56             : 
      57             : #ifdef HAVE_ODBC_SUPPORT
      58             : typedef SQLRETURN (SQL_API* TSQLManageDataSource) (SQLHWND hwndParent);
      59             : typedef SQLRETURN (SQL_API* TSQLAllocHandle) (SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE* OutputHandlePtr);
      60             : typedef SQLRETURN (SQL_API* TSQLFreeHandle) (SQLSMALLINT HandleType, SQLHANDLE Handle);
      61             : typedef SQLRETURN (SQL_API* TSQLSetEnvAttr) (SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
      62             : typedef SQLRETURN (SQL_API* TSQLDataSources) (SQLHENV EnvironmentHandle, SQLUSMALLINT   Direction, SQLCHAR* ServerName,
      63             :                                 SQLSMALLINT BufferLength1, SQLSMALLINT* NameLength1Ptr, SQLCHAR* Description, SQLSMALLINT BufferLength2, SQLSMALLINT* NameLength2Ptr);
      64             : 
      65             : #define NSQLAllocHandle(a,b,c) (*(TSQLAllocHandle)(m_pAllocHandle))(a,b,c)
      66             : #define NSQLFreeHandle(a,b) (*(TSQLFreeHandle)(m_pFreeHandle))(a,b)
      67             : #define NSQLSetEnvAttr(a,b,c,d) (*reinterpret_cast<TSQLSetEnvAttr>(m_pSetEnvAttr))(a,b,c,d)
      68             : #define NSQLDataSources(a,b,c,d,e,f,g,h) (*(TSQLDataSources)(m_pDataSources))(a,b,c,d,e,f,g,h)
      69             : #endif
      70             : 
      71             : // OOdbcLibWrapper
      72             : #ifdef HAVE_ODBC_SUPPORT
      73           0 : OOdbcLibWrapper::OOdbcLibWrapper()
      74           0 :     :m_pOdbcLib(NULL)
      75             : {
      76             : 
      77           0 : }
      78             : 
      79             : #endif
      80             : 
      81           0 : bool OOdbcLibWrapper::load(const sal_Char* _pLibPath)
      82             : {
      83           0 :     m_sLibPath = OUString::createFromAscii(_pLibPath);
      84             : #ifdef HAVE_ODBC_SUPPORT
      85             :     // load the module
      86           0 :     m_pOdbcLib = osl_loadModule(m_sLibPath.pData, SAL_LOADMODULE_NOW);
      87           0 :     return (NULL != m_pOdbcLib);
      88             : #else
      89             :     return sal_False;
      90             : #endif
      91             : }
      92             : 
      93           0 : void OOdbcLibWrapper::unload()
      94             : {
      95             : #ifdef HAVE_ODBC_SUPPORT
      96           0 :     if (isLoaded())
      97             :     {
      98           0 :         osl_unloadModule(m_pOdbcLib);
      99           0 :         m_pOdbcLib = NULL;
     100             :     }
     101             : #endif
     102           0 : }
     103             : 
     104           0 : oslGenericFunction OOdbcLibWrapper::loadSymbol(const sal_Char* _pFunctionName)
     105             : {
     106           0 :     return osl_getFunctionSymbol(m_pOdbcLib, OUString::createFromAscii(_pFunctionName).pData);
     107             : }
     108             : 
     109           0 : OOdbcLibWrapper::~OOdbcLibWrapper()
     110             : {
     111           0 :     unload();
     112             : 
     113           0 : }
     114             : 
     115             : // OOdbcEnumeration
     116             : struct OdbcTypesImpl
     117             : {
     118             : #ifdef HAVE_ODBC_SUPPORT
     119             :     SQLHANDLE   hEnvironment;
     120           0 :     OdbcTypesImpl() : hEnvironment(0) { }
     121             : #else
     122             :     void*       pDummy;
     123             : #endif
     124             : };
     125             : 
     126           0 : OOdbcEnumeration::OOdbcEnumeration()
     127             : #ifdef HAVE_ODBC_SUPPORT
     128             :     :m_pAllocHandle(NULL)
     129             :     ,m_pFreeHandle(NULL)
     130             :     ,m_pSetEnvAttr(NULL)
     131             :     ,m_pDataSources(NULL)
     132           0 :     ,m_pImpl(new OdbcTypesImpl)
     133             : #endif
     134             : {
     135           0 :     bool bLoaded = load(ODBC_LIBRARY);
     136             : #ifdef ODBC_LIBRARY_1
     137           0 :     if ( !bLoaded )
     138           0 :         bLoaded = load(ODBC_LIBRARY_1);
     139             : #endif
     140             : 
     141           0 :     if ( bLoaded )
     142             :     {
     143             : #ifdef HAVE_ODBC_SUPPORT
     144             :         // load the generic functions
     145           0 :         m_pAllocHandle = loadSymbol("SQLAllocHandle");
     146           0 :         m_pFreeHandle = loadSymbol("SQLFreeHandle");
     147           0 :         m_pSetEnvAttr = loadSymbol("SQLSetEnvAttr");
     148           0 :         m_pDataSources = loadSymbol("SQLDataSources");
     149             : 
     150             :         // all or nothing
     151           0 :         if (!m_pAllocHandle || !m_pSetEnvAttr || !m_pDataSources || !m_pFreeHandle)
     152             :         {
     153           0 :             unload();
     154           0 :             m_pAllocHandle = m_pFreeHandle = m_pSetEnvAttr = m_pDataSources = NULL;
     155             :         }
     156             : #endif
     157             :     }
     158           0 : }
     159             : 
     160           0 : OOdbcEnumeration::~OOdbcEnumeration()
     161             : {
     162           0 :     freeEnv();
     163           0 :     delete m_pImpl;
     164             : 
     165           0 : }
     166             : 
     167           0 : bool OOdbcEnumeration::allocEnv()
     168             : {
     169             :     OSL_ENSURE(isLoaded(), "OOdbcEnumeration::allocEnv: not loaded!");
     170           0 :     if (!isLoaded())
     171           0 :         return false;
     172             : 
     173             : #ifdef HAVE_ODBC_SUPPORT
     174           0 :     if (m_pImpl->hEnvironment)
     175             :         // nothing to do
     176           0 :         return true;
     177           0 :     SQLRETURN nResult = NSQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_pImpl->hEnvironment);
     178           0 :     if (SQL_SUCCESS != nResult)
     179             :         // can't do anything without environment
     180           0 :         return false;
     181             : 
     182           0 :     NSQLSetEnvAttr(m_pImpl->hEnvironment, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3), SQL_IS_INTEGER);
     183           0 :     return true;
     184             : #else
     185             :     return sal_False;
     186             : #endif
     187             : }
     188             : 
     189           0 : void OOdbcEnumeration::freeEnv()
     190             : {
     191             : #ifdef HAVE_ODBC_SUPPORT
     192           0 :     if (m_pImpl->hEnvironment)
     193           0 :         NSQLFreeHandle(SQL_HANDLE_ENV, m_pImpl->hEnvironment);
     194           0 :     m_pImpl->hEnvironment  = 0;
     195             : #endif
     196           0 : }
     197             : 
     198           0 : void OOdbcEnumeration::getDatasourceNames(StringBag& _rNames)
     199             : {
     200             :     OSL_ENSURE(isLoaded(), "OOdbcEnumeration::getDatasourceNames: not loaded!");
     201           0 :     if (!isLoaded())
     202           0 :         return;
     203             : 
     204           0 :     if (!allocEnv())
     205             :     {
     206             :         OSL_FAIL("OOdbcEnumeration::getDatasourceNames: could not allocate an ODBC environment!");
     207           0 :         return;
     208             :     }
     209             : 
     210             : #ifdef HAVE_ODBC_SUPPORT
     211             :     // now that we have an environment collect the data source names
     212             :     UCHAR szDSN[SQL_MAX_DSN_LENGTH+1];
     213             :     SWORD pcbDSN;
     214             :     UCHAR szDescription[1024+1];
     215             :     SWORD pcbDescription;
     216           0 :     SQLRETURN nResult = SQL_SUCCESS;
     217           0 :     rtl_TextEncoding nTextEncoding = osl_getThreadTextEncoding();
     218             : 
     219           0 :     for (   nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_FIRST, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription)-1, &pcbDescription);
     220             :             ;
     221           0 :             nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_NEXT, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription)-1, &pcbDescription)
     222             :         )
     223             :     {
     224           0 :         if (nResult != SQL_SUCCESS)
     225             :             // no further error handling
     226           0 :             break;
     227             :         else
     228             :         {
     229           0 :             OUString aCurrentDsn(reinterpret_cast<const char*>(szDSN),pcbDSN, nTextEncoding);
     230           0 :             _rNames.insert(aCurrentDsn);
     231             :         }
     232           0 :     }
     233             : #else
     234             :     (void) _rNames;
     235             : #endif
     236             : }
     237             : 
     238             : #ifdef HAVE_ODBC_ADMINISTRATION
     239             : 
     240             : // ProcessTerminationWait
     241             : class ProcessTerminationWait : public ::osl::Thread
     242             : {
     243             :     oslProcess  m_hProcessHandle;
     244             :     Link        m_aFinishHdl;
     245             : 
     246             : public:
     247             :     ProcessTerminationWait( oslProcess _hProcessHandle, const Link& _rFinishHdl )
     248             :         :m_hProcessHandle( _hProcessHandle )
     249             :         ,m_aFinishHdl( _rFinishHdl )
     250             :     {
     251             :     }
     252             : 
     253             : protected:
     254             :     virtual void SAL_CALL run()
     255             :     {
     256             :         osl_setThreadName("dbaui::ProcessTerminationWait");
     257             : 
     258             :         osl_joinProcess( m_hProcessHandle );
     259             :         osl_freeProcessHandle( m_hProcessHandle );
     260             :         Application::PostUserEvent( m_aFinishHdl );
     261             :     }
     262             : };
     263             : 
     264             : // OOdbcManagement
     265             : OOdbcManagement::OOdbcManagement(const Link& rAsyncFinishCallback)
     266             :     : m_aAsyncFinishCallback(rAsyncFinishCallback)
     267             : {
     268             : }
     269             : 
     270             : OOdbcManagement::~OOdbcManagement()
     271             : {
     272             :     // wait for our thread to be finished
     273             :     if ( m_pProcessWait.get() )
     274             :         m_pProcessWait->join();
     275             : }
     276             : 
     277             : bool OOdbcManagement::manageDataSources_async()
     278             : {
     279             :     OSL_PRECOND( !isRunning(), "OOdbcManagement::manageDataSources_async: still running from the previous call!" );
     280             :     if ( isRunning() )
     281             :         return false;
     282             : 
     283             :     // this is done in an external process, due to #i78733#
     284             :     // (and note this whole functionality is supported on Windows only, ATM)
     285             :     OUString sExecutableName( "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER "/odbcconfig.exe" );
     286             :     ::rtl::Bootstrap::expandMacros( sExecutableName ); //TODO: detect failure
     287             :     oslProcess hProcessHandle(0);
     288             :     oslProcessError eError = osl_executeProcess( sExecutableName.pData, NULL, 0, 0, NULL, NULL, NULL, 0, &hProcessHandle );
     289             :     if ( eError != osl_Process_E_None )
     290             :         return false;
     291             : 
     292             :     m_pProcessWait.reset( new ProcessTerminationWait( hProcessHandle, m_aAsyncFinishCallback ) );
     293             :     m_pProcessWait->create();
     294             :     return true;
     295             : }
     296             : 
     297             : bool OOdbcManagement::isRunning() const
     298             : {
     299             :     return ( m_pProcessWait.get() && m_pProcessWait->isRunning() );
     300             : }
     301             : 
     302             : #endif // HAVE_ODBC_ADMINISTRATION
     303             : 
     304          72 : }   // namespace dbaui
     305             : 
     306             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10