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