xref: /AOO41X/main/connectivity/source/drivers/adabas/BConnection.cxx (revision 24c56ab9f1bd1305754aa2f564704f38ff57627e)
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 // --------------------------------------------------------------------------------
OAdabasConnection(const SQLHANDLE _pDriverHandle,connectivity::odbc::ODBCDriver * _pDriver)57 OAdabasConnection::OAdabasConnection(const SQLHANDLE _pDriverHandle, connectivity::odbc::ODBCDriver*        _pDriver)
58                                                  : OConnection_BASE2(_pDriverHandle,_pDriver)
59 {
60     m_bUseOldDateFormat = sal_True;
61 }
62 //-----------------------------------------------------------------------------
Construct(const::rtl::OUString & url,const Sequence<PropertyValue> & info)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.isEmpty() )
112         aDSN = sHostName + ::rtl::OUString::createFromAscii(":") + aDSN;
113     SQLRETURN nSQLRETURN = openConnectionWithAuth(aDSN,nTimeout, aUID,aPWD);
114 
115     return nSQLRETURN;
116 }
117 //-----------------------------------------------------------------------------
openConnectionWithAuth(const::rtl::OUString & aConnectStr,sal_Int32 nTimeOut,const::rtl::OUString & _uid,const::rtl::OUString & _pwd)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 //------------------------------------------------------------------------------
disposing()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 //------------------------------------------------------------------------------
createCatalog()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 // --------------------------------------------------------------------------------
getMetaData()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 // --------------------------------------------------------------------------------
createStatement()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 // --------------------------------------------------------------------------------
prepareStatement(const::rtl::OUString & sql)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 // -----------------------------------------------------------------------------
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & rId)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 // -----------------------------------------------------------------------------
getUnoTunnelImplementationId()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 // -----------------------------------------------------------------------------
cloneConnection()246 ::connectivity::odbc::OConnection* OAdabasConnection::cloneConnection()
247 {
248     return new OAdabasConnection(m_pDriverHandleCopy,m_pDriver);
249 }
250 // -----------------------------------------------------------------------------
createSelectColumns(const::rtl::OUString & _rSql)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