1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include <cppuhelper/typeprovider.hxx> 31 #include "adabas/BConnection.hxx" 32 #include "adabas/BDriver.hxx" 33 #include "adabas/BCatalog.hxx" 34 #include "odbc/OFunctions.hxx" 35 #include "odbc/OTools.hxx" 36 #ifndef _CONNECTIVITY_ODBC_ODATABASEMETADATA_HXX_ 37 #include "adabas/BDatabaseMetaData.hxx" 38 #endif 39 #include "adabas/BStatement.hxx" 40 #include "adabas/BPreparedStatement.hxx" 41 #include <com/sun/star/lang/DisposedException.hpp> 42 #include <connectivity/dbcharset.hxx> 43 #include "connectivity/sqliterator.hxx" 44 #include <connectivity/sqlparse.hxx> 45 46 #include <string.h> 47 48 using namespace connectivity::adabas; 49 using namespace connectivity; 50 using namespace ::com::sun::star::uno; 51 using namespace ::com::sun::star::beans; 52 using namespace ::com::sun::star::sdbcx; 53 using namespace ::com::sun::star::sdbc; 54 using namespace ::com::sun::star::container; 55 using namespace ::com::sun::star::lang; 56 57 58 //------------------------------------------------------------------------------ 59 namespace starlang = ::com::sun::star::lang; 60 // -------------------------------------------------------------------------------- 61 OAdabasConnection::OAdabasConnection(const SQLHANDLE _pDriverHandle, connectivity::odbc::ODBCDriver* _pDriver) 62 : OConnection_BASE2(_pDriverHandle,_pDriver) 63 { 64 m_bUseOldDateFormat = sal_True; 65 } 66 //----------------------------------------------------------------------------- 67 SQLRETURN OAdabasConnection::Construct( const ::rtl::OUString& url,const Sequence< PropertyValue >& info) throw(SQLException) 68 { 69 ::osl::MutexGuard aGuard( m_aMutex ); 70 71 m_aConnectionHandle = SQL_NULL_HANDLE; 72 setURL(url); 73 setConnectionInfo(info); 74 75 // Connection allozieren 76 N3SQLAllocHandle(SQL_HANDLE_DBC,m_pDriverHandleCopy,&m_aConnectionHandle); 77 if(m_aConnectionHandle == SQL_NULL_HANDLE) 78 throw SQLException(); 79 80 const PropertyValue *pBegin = info.getConstArray(); 81 const PropertyValue *pEnd = pBegin + info.getLength(); 82 ::rtl::OUString sHostName; 83 84 sal_Int32 nLen = url.indexOf(':'); 85 nLen = url.indexOf(':',nLen+1); 86 ::rtl::OUString aDSN(url.copy(nLen+1)),aUID,aPWD; 87 sal_Int32 nTimeout = 20; 88 for(;pBegin != pEnd;++pBegin) 89 { 90 if ( !pBegin->Name.compareToAscii("Timeout") ) 91 pBegin->Value >>= nTimeout; 92 else if(!pBegin->Name.compareToAscii("user")) 93 pBegin->Value >>= aUID; 94 else if(!pBegin->Name.compareToAscii("password")) 95 pBegin->Value >>= aPWD; 96 else if(!pBegin->Name.compareToAscii("HostName")) 97 pBegin->Value >>= sHostName; 98 else if(0 == pBegin->Name.compareToAscii("CharSet")) 99 { 100 ::rtl::OUString sIanaName; 101 OSL_VERIFY( pBegin->Value >>= sIanaName ); 102 103 ::dbtools::OCharsetMap aLookupIanaName; 104 ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.find(sIanaName, ::dbtools::OCharsetMap::IANA()); 105 if (aLookup != aLookupIanaName.end()) 106 m_nTextEncoding = (*aLookup).getEncoding(); 107 else 108 m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW; 109 if(m_nTextEncoding == RTL_TEXTENCODING_DONTKNOW) 110 m_nTextEncoding = osl_getThreadTextEncoding(); 111 } 112 } 113 m_sUser = aUID; 114 115 if ( sHostName.getLength() ) 116 aDSN = sHostName + ':' + aDSN; 117 SQLRETURN nSQLRETURN = openConnectionWithAuth(aDSN,nTimeout, aUID,aPWD); 118 119 return nSQLRETURN; 120 } 121 //----------------------------------------------------------------------------- 122 SQLRETURN OAdabasConnection::openConnectionWithAuth(const ::rtl::OUString& aConnectStr,sal_Int32 nTimeOut, const ::rtl::OUString& _uid,const ::rtl::OUString& _pwd) 123 { 124 if (m_aConnectionHandle == SQL_NULL_HANDLE) 125 return -1; 126 127 SQLRETURN nSQLRETURN = 0; 128 SDB_ODBC_CHAR szDSN[4096]; 129 SDB_ODBC_CHAR szUID[20]; 130 SDB_ODBC_CHAR szPWD[20]; 131 132 memset(szDSN,'\0',4096); 133 memset(szUID,'\0',20); 134 memset(szPWD,'\0',20); 135 136 ::rtl::OString aConStr(::rtl::OUStringToOString(aConnectStr,getTextEncoding())); 137 ::rtl::OString aUID(::rtl::OUStringToOString(_uid,getTextEncoding())); 138 ::rtl::OString aPWD(::rtl::OUStringToOString(_pwd,getTextEncoding())); 139 memcpy(szDSN, (SDB_ODBC_CHAR*) aConStr.getStr(), ::std::min<sal_Int32>((sal_Int32)2048,aConStr.getLength())); 140 memcpy(szUID, (SDB_ODBC_CHAR*) aUID.getStr(), ::std::min<sal_Int32>((sal_Int32)20,aUID.getLength())); 141 memcpy(szPWD, (SDB_ODBC_CHAR*) aPWD.getStr(), ::std::min<sal_Int32>((sal_Int32)20,aPWD.getLength())); 142 143 144 145 N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_LOGIN_TIMEOUT,(SQLPOINTER)nTimeOut,SQL_IS_INTEGER); 146 // Verbindung aufbauen 147 148 nSQLRETURN = N3SQLConnect(m_aConnectionHandle, 149 szDSN, 150 (SQLSMALLINT) ::std::min<sal_Int32>((sal_Int32)2048,aConStr.getLength()), 151 szUID, 152 (SQLSMALLINT) ::std::min<sal_Int32>((sal_Int32)20,aUID.getLength()), 153 szPWD, 154 (SQLSMALLINT) ::std::min<sal_Int32>((sal_Int32)20,aPWD.getLength())); 155 if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA) 156 return nSQLRETURN; 157 158 m_bClosed = sal_False; 159 160 // autocoomit ist immer default 161 162 N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON,SQL_IS_INTEGER); 163 164 return nSQLRETURN; 165 } 166 167 //------------------------------------------------------------------------------ 168 void OAdabasConnection::disposing() 169 { 170 ::osl::MutexGuard aGuard(m_aMutex); 171 172 Reference< XTablesSupplier > xTableSupplier(m_xCatalog); 173 ::comphelper::disposeComponent(xTableSupplier); 174 175 m_xCatalog = WeakReference< XTablesSupplier >(); 176 177 OConnection_BASE2::disposing(); 178 } 179 //------------------------------------------------------------------------------ 180 Reference< XTablesSupplier > OAdabasConnection::createCatalog() 181 { 182 ::osl::MutexGuard aGuard( m_aMutex ); 183 Reference< XTablesSupplier > xTab = m_xCatalog; 184 if(!xTab.is()) 185 { 186 xTab = new OAdabasCatalog(m_aConnectionHandle,this); 187 m_xCatalog = xTab; 188 } 189 return xTab; 190 } 191 // -------------------------------------------------------------------------------- 192 Reference< XDatabaseMetaData > SAL_CALL OAdabasConnection::getMetaData( ) throw(SQLException, RuntimeException) 193 { 194 ::osl::MutexGuard aGuard( m_aMutex ); 195 checkDisposed(OConnection_BASE2::rBHelper.bDisposed); 196 197 198 Reference< XDatabaseMetaData > xMetaData = m_xMetaData; 199 if(!xMetaData.is()) 200 { 201 xMetaData = new OAdabasDatabaseMetaData(m_aConnectionHandle,this); 202 m_xMetaData = xMetaData; 203 } 204 205 return xMetaData; 206 } 207 // -------------------------------------------------------------------------------- 208 Reference< XStatement > SAL_CALL OAdabasConnection::createStatement( ) throw(SQLException, RuntimeException) 209 { 210 ::osl::MutexGuard aGuard( m_aMutex ); 211 checkDisposed(OConnection_BASE2::rBHelper.bDisposed); 212 213 Reference< XStatement > xReturn = new OAdabasStatement(this); 214 m_aStatements.push_back(WeakReferenceHelper(xReturn)); 215 return xReturn; 216 } 217 // -------------------------------------------------------------------------------- 218 Reference< XPreparedStatement > SAL_CALL OAdabasConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException) 219 { 220 ::osl::MutexGuard aGuard( m_aMutex ); 221 checkDisposed(OConnection_BASE2::rBHelper.bDisposed); 222 223 Reference< XPreparedStatement > xReturn = new OAdabasPreparedStatement(this,sql); 224 m_aStatements.push_back(WeakReferenceHelper(xReturn)); 225 return xReturn; 226 } 227 // ----------------------------------------------------------------------------- 228 sal_Int64 SAL_CALL OAdabasConnection::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException) 229 { 230 return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 231 ? reinterpret_cast< sal_Int64 >( this ) 232 : OConnection_BASE2::getSomething(rId); 233 } 234 // ----------------------------------------------------------------------------- 235 Sequence< sal_Int8 > OAdabasConnection::getUnoTunnelImplementationId() 236 { 237 static ::cppu::OImplementationId * pId = 0; 238 if (! pId) 239 { 240 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 241 if (! pId) 242 { 243 static ::cppu::OImplementationId aId; 244 pId = &aId; 245 } 246 } 247 return pId->getImplementationId(); 248 } 249 // ----------------------------------------------------------------------------- 250 ::connectivity::odbc::OConnection* OAdabasConnection::cloneConnection() 251 { 252 return new OAdabasConnection(m_pDriverHandleCopy,m_pDriver); 253 } 254 // ----------------------------------------------------------------------------- 255 ::vos::ORef<OSQLColumns> OAdabasConnection::createSelectColumns(const ::rtl::OUString& _rSql) 256 { 257 ::vos::ORef<OSQLColumns> aRet; 258 OSQLParser aParser(getDriver()->getORB()); 259 ::rtl::OUString sErrorMessage; 260 OSQLParseNode* pNode = aParser.parseTree(sErrorMessage,_rSql); 261 if(pNode) 262 { 263 Reference< XTablesSupplier> xCata = createCatalog(); 264 OSQLParseTreeIterator aParseIter(this, xCata->getTables(), 265 aParser, pNode); 266 aParseIter.traverseAll(); 267 aRet = aParseIter.getSelectColumns(); 268 } 269 return aRet; 270 } 271 // ----------------------------------------------------------------------------- 272 273 274 275