LibreOffice Module connectivity (master) 1
FConnection.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
24#include <file/FConnection.hxx>
26#include <file/FDriver.hxx>
27#include <file/FStatement.hxx>
29#include <com/sun/star/container/XChild.hpp>
30#include <com/sun/star/ucb/ContentCreationException.hpp>
31#include <com/sun/star/ucb/XContent.hpp>
32#include <com/sun/star/ucb/XContentIdentifier.hpp>
33#include <tools/urlobj.hxx>
34#include <file/FCatalog.hxx>
37#include <ucbhelper/content.hxx>
40#include <o3tl/any.hxx>
41#include <osl/thread.h>
42#include <strings.hrc>
43
44using namespace connectivity::file;
45using namespace dbtools;
46
47using namespace com::sun::star::uno;
48using namespace com::sun::star::lang;
49using namespace com::sun::star::beans;
50using namespace com::sun::star::sdbc;
51using namespace com::sun::star::sdbcx;
52using namespace com::sun::star::container;
53using namespace com::sun::star::ucb;
54using namespace ::ucbhelper;
56
57OConnection::OConnection(OFileDriver* _pDriver)
58 : m_pDriver(_pDriver)
59 , m_bAutoCommit(false)
60 , m_bReadOnly(false)
61 , m_bShowDeleted(false)
62 , m_bCaseSensitiveExtension( true )
63 , m_bCheckSQL92(false)
64 , m_bDefaultTextEncoding(false)
65{
66 m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW;
67}
68
70{
71 if(!isClosed( ))
72 close();
73}
74
75bool OConnection::matchesExtension( const OUString& _rExt ) const
76{
78 return ( getExtension() == _rExt );
79
80 OUString sMyExtension( getExtension().toAsciiLowerCase() );
81 OUString sExt( _rExt.toAsciiLowerCase() );
82
83 return sMyExtension == sExt;
84}
85
86
87void OConnection::construct(const OUString& url,const Sequence< PropertyValue >& info)
88{
89 osl_atomic_increment( &m_refCount );
90
91 OUString aExt;
92 const PropertyValue *pIter = info.getConstArray();
93 const PropertyValue *pEnd = pIter + info.getLength();
94 for(;pIter != pEnd;++pIter)
95 {
96 if( pIter->Name == "Extension" )
97 OSL_VERIFY( pIter->Value >>= aExt );
98 else if( pIter->Name == "CharSet" )
99 {
100 if (auto const numeric = o3tl::tryAccess<sal_uInt16>(pIter->Value))
101 {
102 m_nTextEncoding = *numeric;
103 }
104 else
105 {
106 OUString sIanaName;
107 OSL_VERIFY( pIter->Value >>= sIanaName );
108
109 ::dbtools::OCharsetMap aLookupIanaName;
110 ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.findIanaName(sIanaName);
111 if (aLookup != aLookupIanaName.end())
112 m_nTextEncoding = (*aLookup).getEncoding();
113 else
114 m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW;
115 }
116 }
117 else if( pIter->Name == "ShowDeleted" )
118 {
119 OSL_VERIFY( pIter->Value >>= m_bShowDeleted );
120 }
121 else if( pIter->Name == "EnableSQL92Check" )
122 {
123 pIter->Value >>= m_bCheckSQL92;
124 }
125 } // for(;pIter != pEnd;++pIter)
126
127 {
128 sal_Int32 nLen = url.indexOf(':');
129 nLen = url.indexOf(':',nLen+1);
130 OUString aDSN(url.copy(nLen+1));
131
132 OUString aFileName = aDSN;
134 aURL.SetSmartProtocol(INetProtocol::File);
136 {
137 SvtPathOptions aPathOptions;
138 aFileName = aPathOptions.SubstituteVariable(aFileName);
139 }
140
141 aURL.SetSmartURL(aFileName);
142
144 }
145
146 if ( m_nTextEncoding == RTL_TEXTENCODING_DONTKNOW )
147 {
148 //m_nTextEncoding = osl_getTextEncodingFromLocale(NULL);
149 m_nTextEncoding = osl_getThreadTextEncoding();
151 }
152
153 if ( !aExt.isEmpty() )
155
156 try
157 {
159 try
160 {
162 }
163 catch(ContentCreationException& e)
164 {
165 throwUrlNotValid(getURL(),e.Message);
166 }
167
168 // set fields to fetch
169 Sequence< OUString > aProps { "Title" };
170
171 try
172 {
173 if (aFile.isFolder())
174 {
175 m_xDir = aFile.createDynamicCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY );
176 m_xContent = aFile.get();
177 }
178 else if (aFile.isDocument())
179 {
180 Reference<XContent> xParent(Reference<XChild>(aFile.get(),UNO_QUERY_THROW)->getParent(),UNO_QUERY_THROW);
181 Reference<XContentIdentifier> xIdent = xParent->getIdentifier();
182 m_xContent = xParent;
183
185 m_xDir = aParent.createDynamicCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY );
186 }
187 else
188 {
189 OSL_FAIL("OConnection::construct: ::ucbhelper::Content is neither a folder nor a document! How's that?!");
190 throw SQLException();
191 }
192 }
193 catch(Exception& e) // an exception is thrown when no file exists
194 {
195 throwUrlNotValid(getURL(),e.Message);
196 }
197 if(!m_xDir.is() || !m_xContent.is())
198 throwUrlNotValid(getURL(),OUString());
199
200 if (m_aFilenameExtension.indexOf('*') >= 0 || m_aFilenameExtension.indexOf('?') >= 0)
201 throw SQLException();
202 }
203 catch(const Exception&)
204 {
205 osl_atomic_decrement( &m_refCount );
206 throw;
207 }
208
209 osl_atomic_decrement( &m_refCount );
210}
211// XServiceInfo
212
213IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.file.Connection", "com.sun.star.sdbc.Connection")
214
215
216Reference< XStatement > SAL_CALL OConnection::createStatement( )
217{
218 ::osl::MutexGuard aGuard( m_aMutex );
219 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
220
221
222 Reference< XStatement > xReturn = new OStatement(this);
223 m_aStatements.push_back(WeakReferenceHelper(xReturn));
224 return xReturn;
225}
226
228{
229 ::osl::MutexGuard aGuard( m_aMutex );
230 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
231
232
234 pStmt->construct(sql);
235 m_aStatements.push_back(WeakReferenceHelper(*pStmt));
236 return pStmt;
237}
238
240{
241 throwFeatureNotImplementedSQLException( "XConnection::prepareCall", *this );
242 return nullptr;
243}
244
245OUString SAL_CALL OConnection::nativeSQL( const OUString& sql )
246{
247 return sql;
248}
249
250void SAL_CALL OConnection::setAutoCommit( sal_Bool autoCommit )
251{
252 ::osl::MutexGuard aGuard( m_aMutex );
253 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
254
255 m_bAutoCommit = autoCommit;
256}
257
259{
260 ::osl::MutexGuard aGuard( m_aMutex );
261 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
262
263 return m_bAutoCommit;
264}
265
266void SAL_CALL OConnection::commit( )
267{
268}
269
270void SAL_CALL OConnection::rollback( )
271{
272}
273
275{
276 ::osl::MutexGuard aGuard( m_aMutex );
277
278 return OConnection_BASE::rBHelper.bDisposed;
279}
280
282{
283 ::osl::MutexGuard aGuard( m_aMutex );
284 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
285
286
288 if(!xMetaData.is())
289 {
290 xMetaData = new ODatabaseMetaData(this);
291 m_xMetaData = xMetaData;
292 }
293
294 return xMetaData;
295}
296
297void SAL_CALL OConnection::setReadOnly( sal_Bool readOnly )
298{
299 ::osl::MutexGuard aGuard( m_aMutex );
300 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
301
302
303 m_bReadOnly = readOnly;
304}
305
307{
308 ::osl::MutexGuard aGuard( m_aMutex );
309 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
310
311
312 return m_bReadOnly;
313}
314
315void SAL_CALL OConnection::setCatalog( const OUString& /*catalog*/ )
316{
317 throwFeatureNotImplementedSQLException( "XConnection::setCatalog", *this );
318}
319
320OUString SAL_CALL OConnection::getCatalog( )
321{
322 return OUString();
323}
324
325void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 /*level*/ )
326{
327 throwFeatureNotImplementedSQLException( "XConnection::setTransactionIsolation", *this );
328}
329
331{
332 return 0;
333}
334
336{
337 return nullptr;
338}
339
340void SAL_CALL OConnection::setTypeMap( const Reference< XNameAccess >& /*typeMap*/ )
341{
342}
343
344// XCloseable
345void SAL_CALL OConnection::close( )
346{
347 {
348 ::osl::MutexGuard aGuard( m_aMutex );
349 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
350
351 }
352 dispose();
353}
354
355// XWarningsSupplier
357{
358 return Any();
359}
360
362{
363}
364
366{
367 ::osl::MutexGuard aGuard(m_aMutex);
369
370 m_xDir.clear();
371 m_xContent.clear();
373}
374
376{
377 ::osl::MutexGuard aGuard( m_aMutex );
379 if(!xTab.is())
380 {
381 xTab = new OFileCatalog(this);
382 m_xCatalog = xTab;
383 }
384 return xTab;
385}
386
388{
390 Sequence< OUString > aProps { "Title" };
391 try
392 {
393 Reference<XContentIdentifier> xIdent = getContent()->getIdentifier();
395 xContent = aParent.createDynamicCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY );
396 }
397 catch(Exception&)
398 {
399 }
400 return xContent;
401}
402
403sal_Int64 SAL_CALL OConnection::getSomething( const Sequence< sal_Int8 >& rId )
404{
405 return comphelper::getSomethingImpl(rId, this);
406}
407
409{
410 static const comphelper::UnoIdInit implId;
411 return implId.getSeq();
412}
413
414void OConnection::throwUrlNotValid(const OUString & _rsUrl,const OUString & _rsMessage)
415{
416 SQLException aError;
418 STR_NO_VALID_FILE_URL,
419 "$URL$", _rsUrl
420 );
421
422 aError.SQLState = "S1000";
423 aError.ErrorCode = 0;
424 aError.Context = static_cast< XConnection* >(this);
425 if (!_rsMessage.isEmpty())
426 aError.NextException <<= SQLException(_rsMessage, aError.Context, OUString(), 0, Any());
427
428 throw aError;
429}
430
431
432/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
connectivity::OMetaConnection OConnection_BASE
Definition: FConnection.cxx:55
OUString SubstituteVariable(const OUString &rVar) const
const css::uno::Sequence< sal_Int8 > & getSeq() const
void setURL(const OUString &_rsUrl)
Definition: TConnection.hxx:63
connectivity::OWeakRefArray m_aStatements
Definition: TConnection.hxx:47
css::uno::WeakReference< css::sdbc::XDatabaseMetaData > m_xMetaData
Definition: TConnection.hxx:53
const OUString & getURL() const
Definition: TConnection.hxx:62
rtl_TextEncoding m_nTextEncoding
Definition: TConnection.hxx:51
const SharedResources & getResources() const
Definition: TConnection.hxx:65
OUString getResourceStringWithSubstitution(TranslateId pResId, const char *_pAsciiPatternToReplace, const OUString &_rStringToSubstitute) const
loads a string from the shared resource file, and replaces a given ASCII pattern with a given string
css::uno::WeakReference< css::sdbcx::XTablesSupplier > m_xCatalog
Definition: FConnection.hxx:41
css::uno::Reference< css::ucb::XContent > m_xContent
Definition: FConnection.hxx:47
virtual sal_Int32 SAL_CALL getTransactionIsolation() override
void throwUrlNotValid(const OUString &_rsUrl, const OUString &_rsMessage)
virtual void SAL_CALL setCatalog(const OUString &catalog) override
bool matchesExtension(const OUString &_rExt) const
Definition: FConnection.cxx:75
virtual void SAL_CALL setAutoCommit(sal_Bool autoCommit) override
virtual void SAL_CALL setTransactionIsolation(sal_Int32 level) override
virtual void SAL_CALL disposing() override
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > SAL_CALL getMetaData() override
virtual css::uno::Reference< css::sdbcx::XTablesSupplier > createCatalog()
const css::uno::Reference< css::ucb::XContent > & getContent() const
virtual void SAL_CALL rollback() override
virtual OUString SAL_CALL nativeSQL(const OUString &sql) override
virtual void SAL_CALL close() override final
css::uno::Reference< css::ucb::XDynamicResultSet > m_xDir
Definition: FConnection.hxx:46
virtual css::uno::Reference< css::sdbc::XPreparedStatement > SAL_CALL prepareCall(const OUString &sql) override
virtual void construct(const OUString &_rUrl, const css::uno::Sequence< css::beans::PropertyValue > &_rInfo)
virtual sal_Bool SAL_CALL isClosed() override final
virtual ~OConnection() override
Definition: FConnection.cxx:69
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
virtual void SAL_CALL clearWarnings() override
virtual css::uno::Reference< css::sdbc::XPreparedStatement > SAL_CALL prepareStatement(const OUString &sql) override
virtual sal_Bool SAL_CALL getAutoCommit() override
virtual void SAL_CALL setTypeMap(const css::uno::Reference< css::container::XNameAccess > &typeMap) override
virtual void SAL_CALL setReadOnly(sal_Bool readOnly) override
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL getTypeMap() override
virtual sal_Bool SAL_CALL isReadOnly() override
virtual OUString SAL_CALL getCatalog() override
css::uno::Reference< css::ucb::XDynamicResultSet > getDir() const
virtual css::uno::Any SAL_CALL getWarnings() override
const OUString & getExtension() const
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
virtual void SAL_CALL commit() override
is a class which translates between different charset representations.
Definition: dbcharset.hxx:54
CharsetIterator const_iterator
Definition: dbcharset.hxx:64
CharsetIterator findIanaName(std::u16string_view _rIanaName) const
find the given IANA name in the map.
Definition: dbcharset.cxx:96
CharsetIterator end() const
get access to the (last + 1st) element of the charset collection
Definition: dbcharset.cxx:118
css::uno::Reference< css::ucb::XContent > get() const
css::uno::Reference< css::ucb::XDynamicResultSet > createDynamicCursor(const css::uno::Sequence< OUString > &rPropertyNames, ResultSetInclude eMode=INCLUDE_FOLDERS_AND_DOCUMENTS)
static bool IsFuzzing()
URL aURL
std::mutex m_aMutex
bool m_bReadOnly
@ Exception
sal_Int64 getSomethingImpl(const css::uno::Sequence< sal_Int8 > &rId, T *pThis, FallbackToGetSomethingOf< Base >={})
Reference< XComponentContext > getProcessComponentContext()
IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbc.driver.file.Statement","com.sun.star.sdbc.Statement")
void checkDisposed(bool _bThrow)
Definition: dbtools.cxx:1951
void throwFeatureNotImplementedSQLException(const OUString &_rFeatureName, const Reference< XInterface > &_rxContext, const Any &_rNextException)
detail::Optional< sal_uInt16 >::type tryAccess< sal_uInt16 >(css::uno::Any const &any)
void dispose()
unsigned char sal_Bool