fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dbaccess / source / ui / dlg / odbcconfig.cxx
blobace45b3f387500337c63fb4e2e9e494cf2a136ba
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_folders.h>
21 #include "odbcconfig.hxx"
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>
32 #ifdef HAVE_ODBC_SUPPORT
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
46 #include <connectivity/odbc.hxx>
48 #else
50 #define ODBC_LIBRARY ""
52 #endif // HAVE_ODBC_SUPPORT
54 namespace dbaui
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);
65 #define NSQLAllocHandle(a,b,c) (*reinterpret_cast<TSQLAllocHandle>(m_pAllocHandle))(a,b,c)
66 #define NSQLFreeHandle(a,b) (*reinterpret_cast<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) (*reinterpret_cast<TSQLDataSources>(m_pDataSources))(a,b,c,d,e,f,g,h)
69 #endif
71 // OOdbcLibWrapper
72 #ifdef HAVE_ODBC_SUPPORT
73 OOdbcLibWrapper::OOdbcLibWrapper()
74 :m_pOdbcLib(NULL)
79 #endif
81 bool OOdbcLibWrapper::load(const sal_Char* _pLibPath)
83 m_sLibPath = OUString::createFromAscii(_pLibPath);
84 #ifdef HAVE_ODBC_SUPPORT
85 // load the module
86 m_pOdbcLib = osl_loadModule(m_sLibPath.pData, SAL_LOADMODULE_NOW);
87 return (NULL != m_pOdbcLib);
88 #else
89 return sal_False;
90 #endif
93 void OOdbcLibWrapper::unload()
95 #ifdef HAVE_ODBC_SUPPORT
96 if (isLoaded())
98 osl_unloadModule(m_pOdbcLib);
99 m_pOdbcLib = NULL;
101 #endif
104 oslGenericFunction OOdbcLibWrapper::loadSymbol(const sal_Char* _pFunctionName)
106 return osl_getFunctionSymbol(m_pOdbcLib, OUString::createFromAscii(_pFunctionName).pData);
109 OOdbcLibWrapper::~OOdbcLibWrapper()
111 unload();
115 // OOdbcEnumeration
116 struct OdbcTypesImpl
118 #ifdef HAVE_ODBC_SUPPORT
119 SQLHANDLE hEnvironment;
120 OdbcTypesImpl() : hEnvironment(0) { }
121 #else
122 void* pDummy;
123 #endif
126 OOdbcEnumeration::OOdbcEnumeration()
127 #ifdef HAVE_ODBC_SUPPORT
128 :m_pAllocHandle(NULL)
129 ,m_pFreeHandle(NULL)
130 ,m_pSetEnvAttr(NULL)
131 ,m_pDataSources(NULL)
132 ,m_pImpl(new OdbcTypesImpl)
133 #endif
135 bool bLoaded = load(ODBC_LIBRARY);
136 #ifdef ODBC_LIBRARY_1
137 if ( !bLoaded )
138 bLoaded = load(ODBC_LIBRARY_1);
139 #endif
141 if ( bLoaded )
143 #ifdef HAVE_ODBC_SUPPORT
144 // load the generic functions
145 m_pAllocHandle = loadSymbol("SQLAllocHandle");
146 m_pFreeHandle = loadSymbol("SQLFreeHandle");
147 m_pSetEnvAttr = loadSymbol("SQLSetEnvAttr");
148 m_pDataSources = loadSymbol("SQLDataSources");
150 // all or nothing
151 if (!m_pAllocHandle || !m_pSetEnvAttr || !m_pDataSources || !m_pFreeHandle)
153 unload();
154 m_pAllocHandle = m_pFreeHandle = m_pSetEnvAttr = m_pDataSources = NULL;
156 #endif
160 OOdbcEnumeration::~OOdbcEnumeration()
162 freeEnv();
163 delete m_pImpl;
167 bool OOdbcEnumeration::allocEnv()
169 OSL_ENSURE(isLoaded(), "OOdbcEnumeration::allocEnv: not loaded!");
170 if (!isLoaded())
171 return false;
173 #ifdef HAVE_ODBC_SUPPORT
174 if (m_pImpl->hEnvironment)
175 // nothing to do
176 return true;
177 SQLRETURN nResult = NSQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_pImpl->hEnvironment);
178 if (SQL_SUCCESS != nResult)
179 // can't do anything without environment
180 return false;
182 NSQLSetEnvAttr(m_pImpl->hEnvironment, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3), SQL_IS_INTEGER);
183 return true;
184 #else
185 return sal_False;
186 #endif
189 void OOdbcEnumeration::freeEnv()
191 #ifdef HAVE_ODBC_SUPPORT
192 if (m_pImpl->hEnvironment)
193 NSQLFreeHandle(SQL_HANDLE_ENV, m_pImpl->hEnvironment);
194 m_pImpl->hEnvironment = 0;
195 #endif
198 void OOdbcEnumeration::getDatasourceNames(StringBag& _rNames)
200 OSL_ENSURE(isLoaded(), "OOdbcEnumeration::getDatasourceNames: not loaded!");
201 if (!isLoaded())
202 return;
204 if (!allocEnv())
206 OSL_FAIL("OOdbcEnumeration::getDatasourceNames: could not allocate an ODBC environment!");
207 return;
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 SQLRETURN nResult = SQL_SUCCESS;
217 rtl_TextEncoding nTextEncoding = osl_getThreadTextEncoding();
219 for ( nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_FIRST, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription)-1, &pcbDescription);
221 nResult = NSQLDataSources(m_pImpl->hEnvironment, SQL_FETCH_NEXT, szDSN, sizeof(szDSN), &pcbDSN, szDescription, sizeof(szDescription)-1, &pcbDescription)
224 if (nResult != SQL_SUCCESS)
225 // no further error handling
226 break;
227 else
229 OUString aCurrentDsn(reinterpret_cast<const char*>(szDSN),pcbDSN, nTextEncoding);
230 _rNames.insert(aCurrentDsn);
233 #else
234 (void) _rNames;
235 #endif
238 #ifdef HAVE_ODBC_ADMINISTRATION
240 // ProcessTerminationWait
241 class ProcessTerminationWait : public ::osl::Thread
243 oslProcess m_hProcessHandle;
244 Link<> m_aFinishHdl;
246 public:
247 ProcessTerminationWait( oslProcess _hProcessHandle, const Link<>& _rFinishHdl )
248 :m_hProcessHandle( _hProcessHandle )
249 ,m_aFinishHdl( _rFinishHdl )
253 protected:
254 virtual void SAL_CALL run()
256 osl_setThreadName("dbaui::ProcessTerminationWait");
258 osl_joinProcess( m_hProcessHandle );
259 osl_freeProcessHandle( m_hProcessHandle );
260 Application::PostUserEvent( m_aFinishHdl );
264 // OOdbcManagement
265 OOdbcManagement::OOdbcManagement(const Link<>& rAsyncFinishCallback)
266 : m_aAsyncFinishCallback(rAsyncFinishCallback)
270 OOdbcManagement::~OOdbcManagement()
272 // wait for our thread to be finished
273 if ( m_pProcessWait.get() )
274 m_pProcessWait->join();
277 bool OOdbcManagement::manageDataSources_async()
279 OSL_PRECOND( !isRunning(), "OOdbcManagement::manageDataSources_async: still running from the previous call!" );
280 if ( isRunning() )
281 return false;
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;
292 m_pProcessWait.reset( new ProcessTerminationWait( hProcessHandle, m_aAsyncFinishCallback ) );
293 m_pProcessWait->create();
294 return true;
297 bool OOdbcManagement::isRunning() const
299 return ( m_pProcessWait.get() && m_pProcessWait->isRunning() );
302 #endif // HAVE_ODBC_ADMINISTRATION
304 } // namespace dbaui
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */