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