1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FConnection.cxx,v $
10 * $Revision: 1.51.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include <cppuhelper/typeprovider.hxx>
34 #include "file/FConnection.hxx"
35 #include "file/FDatabaseMetaData.hxx"
36 #include "file/FDriver.hxx"
37 #include "file/FStatement.hxx"
38 #include "file/FPreparedStatement.hxx"
39 #include <com/sun/star/sdbc/ColumnValue.hpp>
40 #include <com/sun/star/sdbc/XRow.hpp>
41 #include <com/sun/star/lang/DisposedException.hpp>
42 #include <com/sun/star/container/XChild.hpp>
43 #include <com/sun/star/ucb/XContent.hpp>
44 #include <com/sun/star/ucb/XContentIdentifier.hpp>
45 #include <tools/urlobj.hxx>
46 #include "file/FCatalog.hxx"
47 #include <svtools/pathoptions.hxx>
48 #include <ucbhelper/content.hxx>
49 #include <connectivity/dbcharset.hxx>
50 #include <connectivity/dbexception.hxx>
51 #include <osl/thread.h>
52 #include <osl/nlsupport.h>
53 #include "resource/file_res.hrc"
55 using namespace connectivity::file
;
56 using namespace dbtools
;
57 //------------------------------------------------------------------------------
58 using namespace com::sun::star::uno
;
59 using namespace com::sun::star::lang
;
60 using namespace com::sun::star::beans
;
61 using namespace com::sun::star::sdbc
;
62 using namespace com::sun::star::sdbcx
;
63 using namespace com::sun::star::container
;
64 using namespace com::sun::star::ucb
;
65 using namespace ::ucbhelper
;
67 typedef connectivity::OMetaConnection OConnection_BASE
;
68 // --------------------------------------------------------------------------------
69 OConnection::OConnection(OFileDriver
* _pDriver
)
70 : OSubComponent
<OConnection
, OConnection_BASE
>((::cppu::OWeakObject
*)_pDriver
, this)
73 ,m_bShowDeleted(sal_False
)
74 ,m_bCaseSensitiveExtension( sal_True
)
75 ,m_bCheckSQL92(sal_False
)
76 ,m_bDefaultTextEncoding(false)
78 m_nTextEncoding
= RTL_TEXTENCODING_DONTKNOW
;
80 //-----------------------------------------------------------------------------
81 OConnection::~OConnection()
86 //-----------------------------------------------------------------------------
87 void SAL_CALL
OConnection::release() throw()
92 //-----------------------------------------------------------------------------
93 sal_Bool
OConnection::matchesExtension( const String
& _rExt
) const
95 if ( isCaseSensitveExtension() )
96 return ( getExtension() == _rExt
);
98 String
sMyExtension( getExtension() );
99 sMyExtension
.ToLowerAscii();
100 String
sExt( _rExt
);
103 return sMyExtension
== sExt
;
106 //-----------------------------------------------------------------------------
107 void OConnection::construct(const ::rtl::OUString
& url
,const Sequence
< PropertyValue
>& info
) throw(SQLException
)
109 osl_incrementInterlockedCount( &m_refCount
);
111 ::rtl::OUString aExt
;
112 const PropertyValue
*pIter
= info
.getConstArray();
113 const PropertyValue
*pEnd
= pIter
+ info
.getLength();
114 for(;pIter
!= pEnd
;++pIter
)
116 if(0 == pIter
->Name
.compareToAscii("Extension"))
117 OSL_VERIFY( pIter
->Value
>>= aExt
);
118 else if(0 == pIter
->Name
.compareToAscii("CharSet"))
120 ::rtl::OUString sIanaName
;
121 OSL_VERIFY( pIter
->Value
>>= sIanaName
);
123 ::dbtools::OCharsetMap aLookupIanaName
;
124 ::dbtools::OCharsetMap::const_iterator aLookup
= aLookupIanaName
.find(sIanaName
, ::dbtools::OCharsetMap::IANA());
125 if (aLookup
!= aLookupIanaName
.end())
126 m_nTextEncoding
= (*aLookup
).getEncoding();
128 m_nTextEncoding
= RTL_TEXTENCODING_DONTKNOW
;
130 else if (0 == pIter
->Name
.compareToAscii("ShowDeleted"))
132 OSL_VERIFY( pIter
->Value
>>= m_bShowDeleted
);
134 else if (0 == pIter
->Name
.compareToAscii("EnableSQL92Check"))
136 pIter
->Value
>>= m_bCheckSQL92
;
138 } // for(;pIter != pEnd;++pIter)
141 sal_Int32 nLen
= url
.indexOf(':');
142 nLen
= url
.indexOf(':',nLen
+1);
143 ::rtl::OUString
aDSN(url
.copy(nLen
+1)),aUID
,aPWD
;
145 String aFileName
= aDSN
;
147 aURL
.SetSmartProtocol(INET_PROT_FILE
);
149 SvtPathOptions aPathOptions
;
150 aFileName
= aPathOptions
.SubstituteVariable(aFileName
);
153 aURL
.SetSmartURL(aFileName
);
155 setURL(aURL
.GetMainURL(INetURLObject::NO_DECODE
));
158 if ( m_nTextEncoding
== RTL_TEXTENCODING_DONTKNOW
)
160 //m_nTextEncoding = osl_getTextEncodingFromLocale(NULL);
161 m_nTextEncoding
= osl_getThreadTextEncoding();
162 m_bDefaultTextEncoding
= true;
165 if ( aExt
.getLength() )
166 m_aFilenameExtension
= aExt
;
170 ::ucbhelper::Content aFile
;
173 aFile
= ::ucbhelper::Content(getURL(),Reference
< XCommandEnvironment
>());
175 catch(ContentCreationException
& e
)
177 throwUrlNotValid(getURL(),e
.Message
);
180 // set fields to fetch
181 Sequence
< OUString
> aProps(1);
182 OUString
* pProps
= aProps
.getArray();
183 pProps
[ 0 ] = OUString::createFromAscii( "Title" );
187 if (aFile
.isFolder())
189 m_xDir
= aFile
.createDynamicCursor(aProps
, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY
);
190 m_xContent
= aFile
.get();
192 else if (aFile
.isDocument())
194 Reference
<XContent
> xParent(Reference
<XChild
>(aFile
.get(),UNO_QUERY
)->getParent(),UNO_QUERY
);
195 Reference
<XContentIdentifier
> xIdent
= xParent
->getIdentifier();
196 m_xContent
= xParent
;
198 ::ucbhelper::Content
aParent(xIdent
->getContentIdentifier(),Reference
< XCommandEnvironment
>());
199 m_xDir
= aParent
.createDynamicCursor(aProps
, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY
);
203 OSL_ENSURE(0,"OConnection::construct: ::ucbhelper::Content isn't a folde nor a document! How that?!");
204 throw SQLException();
207 catch(Exception
& e
) // a execption is thrown when no file exists
209 throwUrlNotValid(getURL(),e
.Message
);
211 if(!m_xDir
.is() || !m_xContent
.is())
212 throwUrlNotValid(getURL(),::rtl::OUString());
214 if (m_aFilenameExtension
.Search('*') != STRING_NOTFOUND
|| m_aFilenameExtension
.Search('?') != STRING_NOTFOUND
)
215 throw SQLException();
217 catch(const Exception
&)
219 osl_decrementInterlockedCount( &m_refCount
);
223 osl_decrementInterlockedCount( &m_refCount
);
226 // --------------------------------------------------------------------------------
227 IMPLEMENT_SERVICE_INFO(OConnection
, "com.sun.star.sdbc.drivers.file.Connection", "com.sun.star.sdbc.Connection")
229 // --------------------------------------------------------------------------------
230 Reference
< XStatement
> SAL_CALL
OConnection::createStatement( ) throw(SQLException
, RuntimeException
)
232 ::osl::MutexGuard
aGuard( m_aMutex
);
233 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
236 Reference
< XStatement
> xReturn
= new OStatement(this);
237 m_aStatements
.push_back(WeakReferenceHelper(xReturn
));
240 // --------------------------------------------------------------------------------
241 Reference
< XPreparedStatement
> SAL_CALL
OConnection::prepareStatement( const ::rtl::OUString
& sql
) throw(SQLException
, RuntimeException
)
243 ::osl::MutexGuard
aGuard( m_aMutex
);
244 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
247 OPreparedStatement
* pStmt
= new OPreparedStatement(this);
248 Reference
< XPreparedStatement
> xHoldAlive
= pStmt
;
249 pStmt
->construct(sql
);
250 m_aStatements
.push_back(WeakReferenceHelper(*pStmt
));
253 // --------------------------------------------------------------------------------
254 Reference
< XPreparedStatement
> SAL_CALL
OConnection::prepareCall( const ::rtl::OUString
& /*sql*/ ) throw(SQLException
, RuntimeException
)
256 throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
259 // --------------------------------------------------------------------------------
260 ::rtl::OUString SAL_CALL
OConnection::nativeSQL( const ::rtl::OUString
& sql
) throw(SQLException
, RuntimeException
)
264 // --------------------------------------------------------------------------------
265 void SAL_CALL
OConnection::setAutoCommit( sal_Bool autoCommit
) throw(SQLException
, RuntimeException
)
267 ::osl::MutexGuard
aGuard( m_aMutex
);
268 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
270 m_bAutoCommit
= autoCommit
;
272 // --------------------------------------------------------------------------------
273 sal_Bool SAL_CALL
OConnection::getAutoCommit( ) throw(SQLException
, RuntimeException
)
275 ::osl::MutexGuard
aGuard( m_aMutex
);
276 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
278 return m_bAutoCommit
;
280 // --------------------------------------------------------------------------------
281 void SAL_CALL
OConnection::commit( ) throw(SQLException
, RuntimeException
)
284 // --------------------------------------------------------------------------------
285 void SAL_CALL
OConnection::rollback( ) throw(SQLException
, RuntimeException
)
288 // --------------------------------------------------------------------------------
289 sal_Bool SAL_CALL
OConnection::isClosed( ) throw(SQLException
, RuntimeException
)
291 ::osl::MutexGuard
aGuard( m_aMutex
);
293 return OConnection_BASE::rBHelper
.bDisposed
;
295 // --------------------------------------------------------------------------------
296 Reference
< XDatabaseMetaData
> SAL_CALL
OConnection::getMetaData( ) throw(SQLException
, RuntimeException
)
298 ::osl::MutexGuard
aGuard( m_aMutex
);
299 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
302 Reference
< XDatabaseMetaData
> xMetaData
= m_xMetaData
;
305 xMetaData
= new ODatabaseMetaData(this);
306 m_xMetaData
= xMetaData
;
311 // --------------------------------------------------------------------------------
312 void SAL_CALL
OConnection::setReadOnly( sal_Bool readOnly
) throw(SQLException
, RuntimeException
)
314 ::osl::MutexGuard
aGuard( m_aMutex
);
315 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
318 m_bReadOnly
= readOnly
;
320 // --------------------------------------------------------------------------------
321 sal_Bool SAL_CALL
OConnection::isReadOnly( ) throw(SQLException
, RuntimeException
)
323 ::osl::MutexGuard
aGuard( m_aMutex
);
324 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
329 // --------------------------------------------------------------------------------
330 void SAL_CALL
OConnection::setCatalog( const ::rtl::OUString
& /*catalog*/ ) throw(SQLException
, RuntimeException
)
332 throwFeatureNotImplementedException( "XConnection::setCatalog", *this );
334 // --------------------------------------------------------------------------------
335 ::rtl::OUString SAL_CALL
OConnection::getCatalog( ) throw(SQLException
, RuntimeException
)
337 return ::rtl::OUString();
339 // --------------------------------------------------------------------------------
340 void SAL_CALL
OConnection::setTransactionIsolation( sal_Int32
/*level*/ ) throw(SQLException
, RuntimeException
)
342 throwFeatureNotImplementedException( "XConnection::setTransactionIsolation", *this );
344 // --------------------------------------------------------------------------------
345 sal_Int32 SAL_CALL
OConnection::getTransactionIsolation( ) throw(SQLException
, RuntimeException
)
349 // --------------------------------------------------------------------------------
350 Reference
< XNameAccess
> SAL_CALL
OConnection::getTypeMap( ) throw(SQLException
, RuntimeException
)
354 // --------------------------------------------------------------------------------
355 void SAL_CALL
OConnection::setTypeMap( const Reference
< XNameAccess
>& /*typeMap*/ ) throw(SQLException
, RuntimeException
)
358 // --------------------------------------------------------------------------------
360 void SAL_CALL
OConnection::close( ) throw(SQLException
, RuntimeException
)
363 ::osl::MutexGuard
aGuard( m_aMutex
);
364 checkDisposed(OConnection_BASE::rBHelper
.bDisposed
);
369 // --------------------------------------------------------------------------------
371 Any SAL_CALL
OConnection::getWarnings( ) throw(SQLException
, RuntimeException
)
375 // --------------------------------------------------------------------------------
376 void SAL_CALL
OConnection::clearWarnings( ) throw(SQLException
, RuntimeException
)
379 //------------------------------------------------------------------------------
380 void OConnection::disposing()
382 ::osl::MutexGuard
aGuard(m_aMutex
);
383 OConnection_BASE::disposing();
385 m_bClosed
= sal_True
;
388 m_xCatalog
= WeakReference
< XTablesSupplier
>();
392 //------------------------------------------------------------------------------
393 Reference
< XTablesSupplier
> OConnection::createCatalog()
395 ::osl::MutexGuard
aGuard( m_aMutex
);
396 Reference
< XTablesSupplier
> xTab
= m_xCatalog
;
399 xTab
= new OFileCatalog(this);
404 // -----------------------------------------------------------------------------
405 Reference
< XDynamicResultSet
> OConnection::getDir() const
407 Reference
<XDynamicResultSet
> xContent
;
408 Sequence
< ::rtl::OUString
> aProps(1);
409 ::rtl::OUString
* pProps
= aProps
.getArray();
410 pProps
[ 0 ] = ::rtl::OUString::createFromAscii( "Title" );
413 Reference
<XContentIdentifier
> xIdent
= getContent()->getIdentifier();
414 ::ucbhelper::Content
aParent(xIdent
->getContentIdentifier(),Reference
< XCommandEnvironment
>());
415 xContent
= aParent
.createDynamicCursor(aProps
, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY
);
422 // -----------------------------------------------------------------------------
423 sal_Int64 SAL_CALL
OConnection::getSomething( const Sequence
< sal_Int8
>& rId
) throw (RuntimeException
)
425 return (rId
.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId
.getConstArray(), 16 ) )
426 ? reinterpret_cast< sal_Int64
>( this )
429 // -----------------------------------------------------------------------------
430 Sequence
< sal_Int8
> OConnection::getUnoTunnelImplementationId()
432 static ::cppu::OImplementationId
* pId
= 0;
435 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
438 static ::cppu::OImplementationId aId
;
442 return pId
->getImplementationId();
444 // -----------------------------------------------------------------------------
445 void OConnection::throwUrlNotValid(const ::rtl::OUString
& _rsUrl
,const ::rtl::OUString
& _rsMessage
)
448 aError
.Message
= getResources().getResourceStringWithSubstitution(
449 STR_NO_VALID_FILE_URL
,
453 aError
.SQLState
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000"));
454 aError
.ErrorCode
= 0;
455 aError
.Context
= static_cast< XConnection
* >(this);
456 if (_rsMessage
.getLength())
457 aError
.NextException
<<= SQLException(_rsMessage
, aError
.Context
, ::rtl::OUString(), 0, Any());
461 // -----------------------------------------------------------------------------