1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*9b5730f6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*9b5730f6SAndrew Rist * distributed with this work for additional information
6*9b5730f6SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*9b5730f6SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*9b5730f6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*9b5730f6SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist * KIND, either express or implied. See the License for the
17*9b5730f6SAndrew Rist * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*9b5730f6SAndrew Rist *************************************************************/
21*9b5730f6SAndrew Rist
22*9b5730f6SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir #include "calc/CConnection.hxx"
27cdf0e10cSrcweir #include "calc/CDatabaseMetaData.hxx"
28cdf0e10cSrcweir #include "calc/CCatalog.hxx"
29cdf0e10cSrcweir #ifndef _CONNECTIVITY_CALC_ODRIVER_HXX_
30cdf0e10cSrcweir #include "calc/CDriver.hxx"
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #ifndef CONNECTIVITY_RESOURCE_CALC_HRC
33cdf0e10cSrcweir #include "resource/calc_res.hrc"
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #include "resource/sharedresources.hxx"
36cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
37cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
39cdf0e10cSrcweir #include <tools/urlobj.hxx>
40cdf0e10cSrcweir #include "calc/CPreparedStatement.hxx"
41cdf0e10cSrcweir #include "calc/CStatement.hxx"
42cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
43cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
44cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
45cdf0e10cSrcweir #include <rtl/logfile.hxx>
46cdf0e10cSrcweir
47cdf0e10cSrcweir using namespace connectivity::calc;
48cdf0e10cSrcweir using namespace connectivity::file;
49cdf0e10cSrcweir
50cdf0e10cSrcweir typedef connectivity::file::OConnection OConnection_BASE;
51cdf0e10cSrcweir
52cdf0e10cSrcweir //------------------------------------------------------------------------------
53cdf0e10cSrcweir
54cdf0e10cSrcweir using namespace ::com::sun::star::uno;
55cdf0e10cSrcweir using namespace ::com::sun::star::beans;
56cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
57cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
58cdf0e10cSrcweir using namespace ::com::sun::star::lang;
59cdf0e10cSrcweir using namespace ::com::sun::star::frame;
60cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
61cdf0e10cSrcweir
62cdf0e10cSrcweir // --------------------------------------------------------------------------------
63cdf0e10cSrcweir
OCalcConnection(ODriver * _pDriver)64cdf0e10cSrcweir OCalcConnection::OCalcConnection(ODriver* _pDriver) : OConnection(_pDriver),m_nDocCount(0)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::OCalcConnection" );
67cdf0e10cSrcweir // m_aFilenameExtension is not used
68cdf0e10cSrcweir }
69cdf0e10cSrcweir
~OCalcConnection()70cdf0e10cSrcweir OCalcConnection::~OCalcConnection()
71cdf0e10cSrcweir {
72cdf0e10cSrcweir }
73cdf0e10cSrcweir
construct(const::rtl::OUString & url,const Sequence<PropertyValue> & info)74cdf0e10cSrcweir void OCalcConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info)
75cdf0e10cSrcweir throw(SQLException)
76cdf0e10cSrcweir {
77cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::construct" );
78cdf0e10cSrcweir // open file
79cdf0e10cSrcweir
80cdf0e10cSrcweir sal_Int32 nLen = url.indexOf(':');
81cdf0e10cSrcweir nLen = url.indexOf(':',nLen+1);
82cdf0e10cSrcweir ::rtl::OUString aDSN(url.copy(nLen+1));
83cdf0e10cSrcweir
84cdf0e10cSrcweir m_aFileName = aDSN;
85cdf0e10cSrcweir INetURLObject aURL;
86cdf0e10cSrcweir aURL.SetSmartProtocol(INET_PROT_FILE);
87cdf0e10cSrcweir {
88cdf0e10cSrcweir SvtPathOptions aPathOptions;
89cdf0e10cSrcweir m_aFileName = aPathOptions.SubstituteVariable(m_aFileName);
90cdf0e10cSrcweir }
91cdf0e10cSrcweir aURL.SetSmartURL(m_aFileName);
92cdf0e10cSrcweir if ( aURL.GetProtocol() == INET_PROT_NOT_VALID )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir // don't pass invalid URL to loadComponentFromURL
95cdf0e10cSrcweir throw SQLException();
96cdf0e10cSrcweir }
97cdf0e10cSrcweir m_aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE);
98cdf0e10cSrcweir
99cdf0e10cSrcweir m_sPassword = ::rtl::OUString();
100cdf0e10cSrcweir const char* pPwd = "password";
101cdf0e10cSrcweir
102cdf0e10cSrcweir const PropertyValue *pIter = info.getConstArray();
103cdf0e10cSrcweir const PropertyValue *pEnd = pIter + info.getLength();
104cdf0e10cSrcweir for(;pIter != pEnd;++pIter)
105cdf0e10cSrcweir {
106cdf0e10cSrcweir if(!pIter->Name.compareToAscii(pPwd))
107cdf0e10cSrcweir {
108cdf0e10cSrcweir pIter->Value >>= m_sPassword;
109cdf0e10cSrcweir break;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir } // for(;pIter != pEnd;++pIter)
112cdf0e10cSrcweir ODocHolder aDocHodler(this); // just to test that the doc can be loaded
113cdf0e10cSrcweir acquireDoc();
114cdf0e10cSrcweir }
115cdf0e10cSrcweir // -----------------------------------------------------------------------------
acquireDoc()116cdf0e10cSrcweir Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc()
117cdf0e10cSrcweir {
118cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::acquireDoc" );
119cdf0e10cSrcweir if ( m_xDoc.is() )
120cdf0e10cSrcweir {
121cdf0e10cSrcweir osl_incrementInterlockedCount(&m_nDocCount);
122cdf0e10cSrcweir return m_xDoc;
123cdf0e10cSrcweir }
124cdf0e10cSrcweir // open read-only as long as updating isn't implemented
125cdf0e10cSrcweir Sequence<PropertyValue> aArgs(2);
126cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden");
127cdf0e10cSrcweir aArgs[0].Value <<= (sal_Bool) sal_True;
128cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly");
129cdf0e10cSrcweir aArgs[1].Value <<= (sal_Bool) sal_True;
130cdf0e10cSrcweir
131cdf0e10cSrcweir if ( m_sPassword.getLength() )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir const sal_Int32 nPos = aArgs.getLength();
134cdf0e10cSrcweir aArgs.realloc(nPos+1);
135cdf0e10cSrcweir aArgs[nPos].Name = ::rtl::OUString::createFromAscii("Password");
136cdf0e10cSrcweir aArgs[nPos].Value <<= m_sPassword;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
139cdf0e10cSrcweir Reference< XComponentLoader > xDesktop( getDriver()->getFactory()->createInstance(
140cdf0e10cSrcweir ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
141cdf0e10cSrcweir if (!xDesktop.is())
142cdf0e10cSrcweir {
143cdf0e10cSrcweir OSL_ASSERT("no desktop");
144cdf0e10cSrcweir throw SQLException();
145cdf0e10cSrcweir }
146cdf0e10cSrcweir Reference< XComponent > xComponent;
147cdf0e10cSrcweir Any aLoaderException;
148cdf0e10cSrcweir try
149cdf0e10cSrcweir {
150cdf0e10cSrcweir xComponent = xDesktop->loadComponentFromURL(
151cdf0e10cSrcweir m_aFileName, ::rtl::OUString::createFromAscii("_blank"), 0, aArgs );
152cdf0e10cSrcweir }
153cdf0e10cSrcweir catch( const Exception& )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir aLoaderException = ::cppu::getCaughtException();
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
158cdf0e10cSrcweir m_xDoc.set(xComponent, UNO_QUERY );
159cdf0e10cSrcweir
160cdf0e10cSrcweir // if the URL is not a spreadsheet document, throw the exception here
161cdf0e10cSrcweir // instead of at the first access to it
162cdf0e10cSrcweir if ( !m_xDoc.is() )
163cdf0e10cSrcweir {
164cdf0e10cSrcweir Any aErrorDetails;
165cdf0e10cSrcweir if ( aLoaderException.hasValue() )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir Exception aLoaderError;
168cdf0e10cSrcweir OSL_VERIFY( aLoaderException >>= aLoaderError );
169cdf0e10cSrcweir
170cdf0e10cSrcweir SQLException aDetailException;
171cdf0e10cSrcweir aDetailException.Message = m_aResources.getResourceStringWithSubstitution(
172cdf0e10cSrcweir STR_LOAD_FILE_ERROR_MESSAGE,
173cdf0e10cSrcweir "$exception_type$", aLoaderException.getValueTypeName(),
174cdf0e10cSrcweir "$error_message$", aLoaderError.Message
175cdf0e10cSrcweir );
176cdf0e10cSrcweir aErrorDetails <<= aDetailException;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir
179cdf0e10cSrcweir const ::rtl::OUString sError( m_aResources.getResourceStringWithSubstitution(
180cdf0e10cSrcweir STR_COULD_NOT_LOAD_FILE,
181cdf0e10cSrcweir "$filename$", m_aFileName
182cdf0e10cSrcweir ) );
183cdf0e10cSrcweir ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails );
184cdf0e10cSrcweir }
185cdf0e10cSrcweir osl_incrementInterlockedCount(&m_nDocCount);
186cdf0e10cSrcweir return m_xDoc;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir // -----------------------------------------------------------------------------
releaseDoc()189cdf0e10cSrcweir void OCalcConnection::releaseDoc()
190cdf0e10cSrcweir {
191cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::releaseDoc" );
192cdf0e10cSrcweir if ( osl_decrementInterlockedCount(&m_nDocCount) == 0 )
193cdf0e10cSrcweir ::comphelper::disposeComponent( m_xDoc );
194cdf0e10cSrcweir }
195cdf0e10cSrcweir // -----------------------------------------------------------------------------
disposing()196cdf0e10cSrcweir void OCalcConnection::disposing()
197cdf0e10cSrcweir {
198cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::disposing" );
199cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex);
200cdf0e10cSrcweir
201cdf0e10cSrcweir m_nDocCount = 0;
202cdf0e10cSrcweir ::comphelper::disposeComponent( m_xDoc );
203cdf0e10cSrcweir
204cdf0e10cSrcweir OConnection::disposing();
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
207cdf0e10cSrcweir // XServiceInfo
208cdf0e10cSrcweir // --------------------------------------------------------------------------------
209cdf0e10cSrcweir
210cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO(OCalcConnection, "com.sun.star.sdbc.drivers.calc.Connection", "com.sun.star.sdbc.Connection")
211cdf0e10cSrcweir
212cdf0e10cSrcweir // --------------------------------------------------------------------------------
213cdf0e10cSrcweir
getMetaData()214cdf0e10cSrcweir Reference< XDatabaseMetaData > SAL_CALL OCalcConnection::getMetaData( ) throw(SQLException, RuntimeException)
215cdf0e10cSrcweir {
216cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::getMetaData" );
217cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
218cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
219cdf0e10cSrcweir
220cdf0e10cSrcweir
221cdf0e10cSrcweir Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
222cdf0e10cSrcweir if(!xMetaData.is())
223cdf0e10cSrcweir {
224cdf0e10cSrcweir xMetaData = new OCalcDatabaseMetaData(this);
225cdf0e10cSrcweir m_xMetaData = xMetaData;
226cdf0e10cSrcweir }
227cdf0e10cSrcweir
228cdf0e10cSrcweir return xMetaData;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir
231cdf0e10cSrcweir //------------------------------------------------------------------------------
232cdf0e10cSrcweir
createCatalog()233cdf0e10cSrcweir ::com::sun::star::uno::Reference< XTablesSupplier > OCalcConnection::createCatalog()
234cdf0e10cSrcweir {
235cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createCatalog" );
236cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
237cdf0e10cSrcweir Reference< XTablesSupplier > xTab = m_xCatalog;
238cdf0e10cSrcweir if(!xTab.is())
239cdf0e10cSrcweir {
240cdf0e10cSrcweir OCalcCatalog *pCat = new OCalcCatalog(this);
241cdf0e10cSrcweir xTab = pCat;
242cdf0e10cSrcweir m_xCatalog = xTab;
243cdf0e10cSrcweir }
244cdf0e10cSrcweir return xTab;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir
247cdf0e10cSrcweir // --------------------------------------------------------------------------------
248cdf0e10cSrcweir
createStatement()249cdf0e10cSrcweir Reference< XStatement > SAL_CALL OCalcConnection::createStatement( ) throw(SQLException, RuntimeException)
250cdf0e10cSrcweir {
251cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createStatement" );
252cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
253cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
254cdf0e10cSrcweir
255cdf0e10cSrcweir
256cdf0e10cSrcweir Reference< XStatement > xReturn = new OCalcStatement(this);
257cdf0e10cSrcweir m_aStatements.push_back(WeakReferenceHelper(xReturn));
258cdf0e10cSrcweir return xReturn;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir
261cdf0e10cSrcweir // --------------------------------------------------------------------------------
262cdf0e10cSrcweir
prepareStatement(const::rtl::OUString & sql)263cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareStatement( const ::rtl::OUString& sql )
264cdf0e10cSrcweir throw(SQLException, RuntimeException)
265cdf0e10cSrcweir {
266cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareStatement" );
267cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
268cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
269cdf0e10cSrcweir
270cdf0e10cSrcweir
271cdf0e10cSrcweir OCalcPreparedStatement* pStmt = new OCalcPreparedStatement(this);
272cdf0e10cSrcweir Reference< XPreparedStatement > xHoldAlive = pStmt;
273cdf0e10cSrcweir pStmt->construct(sql);
274cdf0e10cSrcweir m_aStatements.push_back(WeakReferenceHelper(*pStmt));
275cdf0e10cSrcweir return pStmt;
276cdf0e10cSrcweir }
277cdf0e10cSrcweir
278cdf0e10cSrcweir // --------------------------------------------------------------------------------
279cdf0e10cSrcweir
prepareCall(const::rtl::OUString &)280cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareCall( const ::rtl::OUString& /*sql*/ )
281cdf0e10cSrcweir throw(SQLException, RuntimeException)
282cdf0e10cSrcweir {
283cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareCall" );
284cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
285cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
286cdf0e10cSrcweir
287cdf0e10cSrcweir ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
288cdf0e10cSrcweir return NULL;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir // -----------------------------------------------------------------------------
291cdf0e10cSrcweir
292