xref: /AOO41X/main/connectivity/source/drivers/calc/CConnection.cxx (revision 9b5730f6ddef7eb82608ca4d31dc0d7678e652cf)
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