1 /*************************************************************************
3 * $RCSfile: SConnection.cxx,v $
7 * last change: $Author: rt $ $Date: 2008-04-10 16:30:40 $
9 * The Contents of this file are made available subject to the terms of
12 * Copyright (c) 2003 by Sun Microsystems, Inc.
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *************************************************************************/
41 #include "SConnection.hxx"
43 #include "SDatabaseMetaData.hxx"
44 #include "SDriver.hxx"
45 #include "SStatement.hxx"
46 #include "SPreparedStatement.hxx"
47 #include <com/sun/star/sdbc/ColumnValue.hpp>
48 #include <com/sun/star/sdbc/XRow.hpp>
49 #include <com/sun/star/sdbc/TransactionIsolation.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
52 using namespace connectivity::skeleton
;
54 //------------------------------------------------------------------------------
55 using namespace com::sun::star::uno
;
56 using namespace com::sun::star::lang
;
57 using namespace com::sun::star::beans
;
58 using namespace com::sun::star::sdbc
;
59 // --------------------------------------------------------------------------------
60 OConnection::OConnection(SkeletonDriver
* _pDriver
)
61 : OSubComponent
<OConnection
, OConnection_BASE
>((::cppu::OWeakObject
*)_pDriver
, this),
62 OMetaConnection_BASE(m_aMutex
),
66 m_bUseCatalog(sal_False
),
67 m_bUseOldDateFormat(sal_False
)
71 //-----------------------------------------------------------------------------
72 OConnection::~OConnection()
79 //-----------------------------------------------------------------------------
80 void SAL_CALL
OConnection::release() throw()
84 // -----------------------------------------------------------------------------
85 //-----------------------------------------------------------------------------
86 void OConnection::construct(const ::rtl::OUString
& url
,const Sequence
< PropertyValue
>& info
) throw(SQLException
)
88 osl_incrementInterlockedCount( &m_refCount
);
90 // some example code how to get the information out of the sequence
92 sal_Int32 nLen
= url
.indexOf(':');
93 nLen
= url
.indexOf(':',nLen
+1);
94 ::rtl::OUString
aDSN(RTL_CONSTASCII_USTRINGPARAM("DSN=")), aUID
, aPWD
, aSysDrvSettings
;
95 aDSN
+= url
.copy(nLen
+1);
97 const char* pUser
= "user";
98 const char* pTimeout
= "Timeout";
99 const char* pSilent
= "Silent";
100 const char* pPwd
= "password";
101 const char* pUseCatalog
= "UseCatalog";
102 const char* pSysDrv
= "SystemDriverSettings";
104 sal_Int32 nTimeout
= 20;
105 sal_Bool bSilent
= sal_True
;
106 const PropertyValue
*pBegin
= info
.getConstArray();
107 const PropertyValue
*pEnd
= pBegin
+ info
.getLength();
108 for(;pBegin
!= pEnd
;++pBegin
)
110 if(!pBegin
->Name
.compareToAscii(pTimeout
))
111 pBegin
->Value
>>= nTimeout
;
112 else if(!pBegin
->Name
.compareToAscii(pSilent
))
113 pBegin
->Value
>>= bSilent
;
114 else if(!pBegin
->Name
.compareToAscii(pUser
))
116 pBegin
->Value
>>= aUID
;
117 aDSN
= aDSN
+ ::rtl::OUString::createFromAscii(";UID=") + aUID
;
119 else if(!pBegin
->Name
.compareToAscii(pPwd
))
121 pBegin
->Value
>>= aPWD
;
122 aDSN
= aDSN
+ ::rtl::OUString::createFromAscii(";PWD=") + aPWD
;
124 else if(!pBegin
->Name
.compareToAscii(pUseCatalog
))
126 pBegin
->Value
>>= m_bUseCatalog
;
128 else if(!pBegin
->Name
.compareToAscii(pSysDrv
))
130 pBegin
->Value
>>= aSysDrvSettings
;
131 aDSN
+= ::rtl::OUString::createFromAscii(";");
132 aDSN
+= aSysDrvSettings
;
137 osl_decrementInterlockedCount( &m_refCount
);
140 // --------------------------------------------------------------------------------
141 IMPLEMENT_SERVICE_INFO(OConnection
, "com.sun.star.sdbc.drivers.skeleton.OConnection", "com.sun.star.sdbc.Connection")
143 // --------------------------------------------------------------------------------
144 Reference
< XStatement
> SAL_CALL
OConnection::createStatement( ) throw(SQLException
, RuntimeException
)
146 ::osl::MutexGuard
aGuard( m_aMutex
);
147 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
149 // create a statement
150 // the statement can only be executed once
151 Reference
< XStatement
> xReturn
= new OStatement(this);
152 m_aStatements
.push_back(WeakReferenceHelper(xReturn
));
155 // --------------------------------------------------------------------------------
156 Reference
< XPreparedStatement
> SAL_CALL
OConnection::prepareStatement( const ::rtl::OUString
& _sSql
) throw(SQLException
, RuntimeException
)
158 ::osl::MutexGuard
aGuard( m_aMutex
);
159 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
162 if(m_aTypeInfo
.empty())
165 // create a statement
166 // the statement can only be executed more than once
167 Reference
< XPreparedStatement
> xReturn
= new OPreparedStatement(this,m_aTypeInfo
,_sSql
);
168 m_aStatements
.push_back(WeakReferenceHelper(xReturn
));
171 // --------------------------------------------------------------------------------
172 Reference
< XPreparedStatement
> SAL_CALL
OConnection::prepareCall( const ::rtl::OUString
& _sSql
) throw(SQLException
, RuntimeException
)
174 ::osl::MutexGuard
aGuard( m_aMutex
);
175 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
177 // not implemented yet :-) a task to do
180 // --------------------------------------------------------------------------------
181 ::rtl::OUString SAL_CALL
OConnection::nativeSQL( const ::rtl::OUString
& _sSql
) throw(SQLException
, RuntimeException
)
183 ::osl::MutexGuard
aGuard( m_aMutex
);
184 // when you need to transform SQL92 to you driver specific you can do it here
188 // --------------------------------------------------------------------------------
189 void SAL_CALL
OConnection::setAutoCommit( sal_Bool autoCommit
) throw(SQLException
, RuntimeException
)
191 ::osl::MutexGuard
aGuard( m_aMutex
);
192 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
193 // here you have to set your commit mode please have a look at the jdbc documentation to get a clear explanation
195 // --------------------------------------------------------------------------------
196 sal_Bool SAL_CALL
OConnection::getAutoCommit( ) throw(SQLException
, RuntimeException
)
198 ::osl::MutexGuard
aGuard( m_aMutex
);
199 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
200 // you have to distinguish which if you are in autocommit mode or not
201 // at normal case true should be fine here
205 // --------------------------------------------------------------------------------
206 void SAL_CALL
OConnection::commit( ) throw(SQLException
, RuntimeException
)
208 ::osl::MutexGuard
aGuard( m_aMutex
);
209 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
211 // when you database does support transactions you should commit here
213 // --------------------------------------------------------------------------------
214 void SAL_CALL
OConnection::rollback( ) throw(SQLException
, RuntimeException
)
216 ::osl::MutexGuard
aGuard( m_aMutex
);
217 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
220 // same as commit but for the other case
222 // --------------------------------------------------------------------------------
223 sal_Bool SAL_CALL
OConnection::isClosed( ) throw(SQLException
, RuntimeException
)
225 ::osl::MutexGuard
aGuard( m_aMutex
);
227 // just simple -> we are close when we are disposed taht means someone called dispose(); (XComponent)
228 return OConnection_BASE::rBHelper
.bDisposed
;
230 // --------------------------------------------------------------------------------
231 Reference
< XDatabaseMetaData
> SAL_CALL
OConnection::getMetaData( ) throw(SQLException
, RuntimeException
)
233 ::osl::MutexGuard
aGuard( m_aMutex
);
234 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
236 // here we have to create the class with biggest interface
237 // The answer is 42 :-)
238 Reference
< XDatabaseMetaData
> xMetaData
= m_xMetaData
;
241 xMetaData
= new ODatabaseMetaData(this); // need the connection because it can return it
242 m_xMetaData
= xMetaData
;
247 // --------------------------------------------------------------------------------
248 void SAL_CALL
OConnection::setReadOnly( sal_Bool readOnly
) throw(SQLException
, RuntimeException
)
250 ::osl::MutexGuard
aGuard( m_aMutex
);
251 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
253 // set you connection to readonly
255 // --------------------------------------------------------------------------------
256 sal_Bool SAL_CALL
OConnection::isReadOnly( ) throw(SQLException
, RuntimeException
)
258 ::osl::MutexGuard
aGuard( m_aMutex
);
259 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
261 // return if your connection to readonly
264 // --------------------------------------------------------------------------------
265 void SAL_CALL
OConnection::setCatalog( const ::rtl::OUString
& catalog
) throw(SQLException
, RuntimeException
)
267 ::osl::MutexGuard
aGuard( m_aMutex
);
268 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
270 // if your database doesn't work with catalogs you go to next method otherwise you kjnow what to do
272 // --------------------------------------------------------------------------------
273 ::rtl::OUString SAL_CALL
OConnection::getCatalog( ) throw(SQLException
, RuntimeException
)
275 ::osl::MutexGuard
aGuard( m_aMutex
);
276 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
279 // return your current catalog
280 return ::rtl::OUString();
282 // --------------------------------------------------------------------------------
283 void SAL_CALL
OConnection::setTransactionIsolation( sal_Int32 level
) throw(SQLException
, RuntimeException
)
285 ::osl::MutexGuard
aGuard( m_aMutex
);
286 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
288 // set your isolation level
289 // please have a look at @see com.sun.star.sdbc.TransactionIsolation
291 // --------------------------------------------------------------------------------
292 sal_Int32 SAL_CALL
OConnection::getTransactionIsolation( ) throw(SQLException
, RuntimeException
)
294 ::osl::MutexGuard
aGuard( m_aMutex
);
295 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
298 // please have a look at @see com.sun.star.sdbc.TransactionIsolation
299 return TransactionIsolation::NONE
;
301 // --------------------------------------------------------------------------------
302 Reference
< ::com::sun::star::container::XNameAccess
> SAL_CALL
OConnection::getTypeMap( ) throw(SQLException
, RuntimeException
)
304 ::osl::MutexGuard
aGuard( m_aMutex
);
305 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
307 // if your driver has special database types you can return it here
311 // --------------------------------------------------------------------------------
312 void SAL_CALL
OConnection::setTypeMap( const Reference
< ::com::sun::star::container::XNameAccess
>& typeMap
) throw(SQLException
, RuntimeException
)
314 // the other way around
316 // --------------------------------------------------------------------------------
318 void SAL_CALL
OConnection::close( ) throw(SQLException
, RuntimeException
)
320 // we just dispose us
322 ::osl::MutexGuard
aGuard( m_aMutex
);
323 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
328 // --------------------------------------------------------------------------------
330 Any SAL_CALL
OConnection::getWarnings( ) throw(SQLException
, RuntimeException
)
332 // when you collected some warnings -> return it
335 // --------------------------------------------------------------------------------
336 void SAL_CALL
OConnection::clearWarnings( ) throw(SQLException
, RuntimeException
)
338 // you should clear your collected warnings here
340 //--------------------------------------------------------------------
341 void OConnection::buildTypeInfo() throw( SQLException
)
343 ::osl::MutexGuard
aGuard( m_aMutex
);
345 Reference
< XResultSet
> xRs
= getMetaData ()->getTypeInfo ();
346 Reference
< XRow
> xRow(xRs
,UNO_QUERY
);
347 // Information for a single SQL type
349 // Loop on the result set until we reach end of file
354 aInfo
.aTypeName
= xRow
->getString (1);
355 aInfo
.nType
= xRow
->getShort (2);
356 aInfo
.nPrecision
= xRow
->getInt (3);
357 aInfo
.aLiteralPrefix
= xRow
->getString (4);
358 aInfo
.aLiteralSuffix
= xRow
->getString (5);
359 aInfo
.aCreateParams
= xRow
->getString (6);
360 aInfo
.bNullable
= xRow
->getBoolean (7) == ColumnValue::NULLABLE
;
361 aInfo
.bCaseSensitive
= xRow
->getBoolean (8);
362 aInfo
.nSearchType
= xRow
->getShort (9);
363 aInfo
.bUnsigned
= xRow
->getBoolean (10);
364 aInfo
.bCurrency
= xRow
->getBoolean (11);
365 aInfo
.bAutoIncrement
= xRow
->getBoolean (12);
366 aInfo
.aLocalTypeName
= xRow
->getString (13);
367 aInfo
.nMinimumScale
= xRow
->getShort (14);
368 aInfo
.nMaximumScale
= xRow
->getShort (15);
369 aInfo
.nNumPrecRadix
= (sal_Int16
)xRow
->getInt(18);
373 // Now that we have the type info, save it
374 // in the Hashtable if we don't already have an
375 // entry for this SQL type.
377 m_aTypeInfo
.push_back(aInfo
);
380 // Close the result set/statement.
382 Reference
< XCloseable
> xClose(xRs
,UNO_QUERY
);
385 //------------------------------------------------------------------------------
386 void OConnection::disposing()
388 // we noticed that we should be destroied in near future so we have to dispose our statements
389 ::osl::MutexGuard
aGuard(m_aMutex
);
391 for (OWeakRefArray::iterator i
= m_aStatements
.begin(); m_aStatements
.end() != i
; ++i
)
393 Reference
< XComponent
> xComp(i
->get(), UNO_QUERY
);
397 m_aStatements
.clear();
399 m_bClosed
= sal_True
;
400 m_xMetaData
= ::com::sun::star::uno::WeakReference
< ::com::sun::star::sdbc::XDatabaseMetaData
>();
403 OConnection_BASE::disposing();
405 // -----------------------------------------------------------------------------