1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 #include <stdio.h>
36 #include <osl/diagnose.h>
37 #include "SStatement.hxx"
38 #include "SConnection.hxx"
39 #include "SResultSet.hxx"
40 #include <osl/thread.h>
41 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
42 #include <com/sun/star/sdbc/ResultSetType.hpp>
43 #include <com/sun/star/sdbc/FetchDirection.hpp>
44 #include <com/sun/star/lang/DisposedException.hpp>
45 #include <cppuhelper/typeprovider.hxx>
46 #include "propertyids.hxx"
47 
48 using namespace connectivity::skeleton;
49 //------------------------------------------------------------------------------
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::beans;
53 using namespace com::sun::star::sdbc;
54 using namespace com::sun::star::sdbcx;
55 using namespace com::sun::star::container;
56 using namespace com::sun::star::io;
57 using namespace com::sun::star::util;
58 //------------------------------------------------------------------------------
59 OStatement_Base::OStatement_Base(OConnection* _pConnection )
60 	: OStatement_BASE(m_aMutex),
61 	OPropertySetHelper(OStatement_BASE::rBHelper),
62 	rBHelper(OStatement_BASE::rBHelper),
63 	m_pConnection(_pConnection)
64 {
65 	m_pConnection->acquire();
66 }
67 // -----------------------------------------------------------------------------
68 OStatement_Base::~OStatement_Base()
69 {
70 }
71 //------------------------------------------------------------------------------
72 void OStatement_Base::disposeResultSet()
73 {
74 	// free the cursor if alive
75 	Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
76 	if (xComp.is())
77 		xComp->dispose();
78 	m_xResultSet = Reference< XResultSet>();
79 }
80 //------------------------------------------------------------------------------
81 void OStatement_BASE2::disposing()
82 {
83 	::osl::MutexGuard aGuard(m_aMutex);
84 
85 	disposeResultSet();
86 
87 	if (m_pConnection)
88 		m_pConnection->release();
89 	m_pConnection = NULL;
90 
91 	dispose_ChildImpl();
92 	OStatement_Base::disposing();
93 }
94 //-----------------------------------------------------------------------------
95 void SAL_CALL OStatement_BASE2::release() throw()
96 {
97 	relase_ChildImpl();
98 }
99 //-----------------------------------------------------------------------------
100 Any SAL_CALL OStatement_Base::queryInterface( const Type & rType ) throw(RuntimeException)
101 {
102 	Any aRet = OStatement_BASE::queryInterface(rType);
103 	if(!aRet.hasValue())
104 		aRet = OPropertySetHelper::queryInterface(rType);
105 	return aRet;
106 }
107 // -------------------------------------------------------------------------
108 Sequence< Type > SAL_CALL OStatement_Base::getTypes(  ) throw(RuntimeException)
109 {
110 	::cppu::OTypeCollection aTypes(
111         ::cppu::UnoType< Reference< XMultiPropertySet > >::get(),
112         ::cppu::UnoType< Reference< XFastPropertySet > >::get(),
113         ::cppu::UnoType< Reference< XPropertySet > >::get());
114 
115 	return concatSequences(aTypes.getTypes(),OStatement_BASE::getTypes());
116 }
117 // -------------------------------------------------------------------------
118 
119 void SAL_CALL OStatement_Base::cancel(  ) throw(RuntimeException)
120 {
121 	::osl::MutexGuard aGuard( m_aMutex );
122 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
123 	// cancel the current sql statement
124 }
125 // -------------------------------------------------------------------------
126 
127 void SAL_CALL OStatement_Base::close(  ) throw(SQLException, RuntimeException)
128 {
129 	{
130 		::osl::MutexGuard aGuard( m_aMutex );
131 		checkDisposed(OStatement_BASE::rBHelper.bDisposed);
132 
133 	}
134 	dispose();
135 }
136 // -------------------------------------------------------------------------
137 
138 void SAL_CALL OStatement::clearBatch(  ) throw(SQLException, RuntimeException)
139 {
140 	// if you support batches clear it here
141 }
142 // -------------------------------------------------------------------------
143 sal_Bool SAL_CALL OStatement_Base::execute( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
144 {
145 	::osl::MutexGuard aGuard( m_aMutex );
146 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
147 
148 	// returns true when a resultset is available
149 	return sal_False;
150 }
151 // -------------------------------------------------------------------------
152 
153 Reference< XResultSet > SAL_CALL OStatement_Base::executeQuery( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
154 {
155 	::osl::MutexGuard aGuard( m_aMutex );
156 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
157 
158 
159 	Reference< XResultSet > xRS = NULL;
160 	// create a resultset as result of executing the sql statement
161 	// you have to here something :-)
162 	m_xResultSet = xRS; // we nedd a reference to it for later use
163 	return xRS;
164 }
165 // -------------------------------------------------------------------------
166 
167 Reference< XConnection > SAL_CALL OStatement_Base::getConnection(  ) throw(SQLException, RuntimeException)
168 {
169 	::osl::MutexGuard aGuard( m_aMutex );
170 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
171 
172 	// just return our connection here
173 	return (Reference< XConnection >)m_pConnection;
174 }
175 // -----------------------------------------------------------------------------
176 sal_Int32 SAL_CALL OStatement_Base::getUpdateCount(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
177 {
178 	return 0;
179 }
180 // -------------------------------------------------------------------------
181 
182 Any SAL_CALL OStatement::queryInterface( const Type & rType ) throw(RuntimeException)
183 {
184 	Any aRet = ::cppu::queryInterface(rType,static_cast< XBatchExecution*> (this));
185 	if(!aRet.hasValue())
186 		aRet = OStatement_Base::queryInterface(rType);
187 	return aRet;
188 }
189 // -------------------------------------------------------------------------
190 
191 void SAL_CALL OStatement::addBatch( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
192 {
193 	::osl::MutexGuard aGuard( m_aMutex );
194 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
195 
196 
197 	m_aBatchList.push_back(sql);
198 }
199 // -------------------------------------------------------------------------
200 Sequence< sal_Int32 > SAL_CALL OStatement::executeBatch(  ) throw(SQLException, RuntimeException)
201 {
202 	::osl::MutexGuard aGuard( m_aMutex );
203 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
204 
205 	return Sequence< sal_Int32 >();
206 }
207 // -------------------------------------------------------------------------
208 
209 
210 sal_Int32 SAL_CALL OStatement_Base::executeUpdate( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
211 {
212 	::osl::MutexGuard aGuard( m_aMutex );
213 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
214 
215 	// the return values gives information about how many rows are affected by executing the sql statement
216 	return 0;
217 
218 }
219 // -------------------------------------------------------------------------
220 
221 Reference< XResultSet > SAL_CALL OStatement_Base::getResultSet(  ) throw(SQLException, RuntimeException)
222 {
223 	::osl::MutexGuard aGuard( m_aMutex );
224 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
225 
226 //	return our save resultset here
227 	return m_xResultSet;
228 }
229 // -------------------------------------------------------------------------
230 
231 sal_Bool SAL_CALL OStatement_Base::getMoreResults(  ) throw(SQLException, RuntimeException)
232 {
233 	::osl::MutexGuard aGuard( m_aMutex );
234 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
235 
236 	// if your driver supports more than only one resultset
237 	// and has one more at this moment return true
238 	return sal_False;
239 }
240 // -------------------------------------------------------------------------
241 
242 // -------------------------------------------------------------------------
243 Any SAL_CALL OStatement_Base::getWarnings(  ) throw(SQLException, RuntimeException)
244 {
245 	::osl::MutexGuard aGuard( m_aMutex );
246 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
247 
248 
249 	return makeAny(m_aLastWarning);
250 }
251 // -------------------------------------------------------------------------
252 
253 // -------------------------------------------------------------------------
254 void SAL_CALL OStatement_Base::clearWarnings(  ) throw(SQLException, RuntimeException)
255 {
256 	::osl::MutexGuard aGuard( m_aMutex );
257 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
258 
259 
260 	m_aLastWarning = SQLWarning();
261 }
262 // -------------------------------------------------------------------------
263 ::cppu::IPropertyArrayHelper* OStatement_Base::createArrayHelper( ) const
264 {
265 	// this properties are define by the service statement
266 	// they must in alphabetic order
267 	Sequence< Property > aProps(10);
268 	Property* pProperties = aProps.getArray();
269 	sal_Int32 nPos = 0;
270 	DECL_PROP0(CURSORNAME,	::rtl::OUString);
271 	DECL_BOOL_PROP0(ESCAPEPROCESSING);
272 	DECL_PROP0(FETCHDIRECTION,sal_Int32);
273 	DECL_PROP0(FETCHSIZE,	sal_Int32);
274 	DECL_PROP0(MAXFIELDSIZE,sal_Int32);
275 	DECL_PROP0(MAXROWS,		sal_Int32);
276 	DECL_PROP0(QUERYTIMEOUT,sal_Int32);
277 	DECL_PROP0(RESULTSETCONCURRENCY,sal_Int32);
278 	DECL_PROP0(RESULTSETTYPE,sal_Int32);
279 	DECL_BOOL_PROP0(USEBOOKMARKS);
280 
281 	return new ::cppu::OPropertyArrayHelper(aProps);
282 }
283 
284 // -------------------------------------------------------------------------
285 ::cppu::IPropertyArrayHelper & OStatement_Base::getInfoHelper()
286 {
287 	return *const_cast<OStatement_Base*>(this)->getArrayHelper();
288 }
289 // -------------------------------------------------------------------------
290 sal_Bool OStatement_Base::convertFastPropertyValue(
291 							Any & rConvertedValue,
292 							Any & rOldValue,
293 							sal_Int32 nHandle,
294 							const Any& rValue )
295 								throw (::com::sun::star::lang::IllegalArgumentException)
296 {
297 	sal_Bool bConverted = sal_False;
298 	// here we have to try to convert
299 	return bConverted;
300 }
301 // -------------------------------------------------------------------------
302 void OStatement_Base::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
303 {
304 	// set the value to what ever is nescessary
305 	switch(nHandle)
306 	{
307 		case PROPERTY_ID_QUERYTIMEOUT:
308 		case PROPERTY_ID_MAXFIELDSIZE:
309 		case PROPERTY_ID_MAXROWS:
310 		case PROPERTY_ID_CURSORNAME:
311 		case PROPERTY_ID_RESULTSETCONCURRENCY:
312 		case PROPERTY_ID_RESULTSETTYPE:
313 		case PROPERTY_ID_FETCHDIRECTION:
314 		case PROPERTY_ID_FETCHSIZE:
315 		case PROPERTY_ID_ESCAPEPROCESSING:
316 		case PROPERTY_ID_USEBOOKMARKS:
317 		default:
318 			;
319 	}
320 }
321 // -------------------------------------------------------------------------
322 void OStatement_Base::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
323 {
324 	switch(nHandle)
325 	{
326 		case PROPERTY_ID_QUERYTIMEOUT:
327 		case PROPERTY_ID_MAXFIELDSIZE:
328 		case PROPERTY_ID_MAXROWS:
329 		case PROPERTY_ID_CURSORNAME:
330 		case PROPERTY_ID_RESULTSETCONCURRENCY:
331 		case PROPERTY_ID_RESULTSETTYPE:
332 		case PROPERTY_ID_FETCHDIRECTION:
333 		case PROPERTY_ID_FETCHSIZE:
334 		case PROPERTY_ID_ESCAPEPROCESSING:
335 		case PROPERTY_ID_USEBOOKMARKS:
336 		default:
337 			;
338 	}
339 }
340 // -------------------------------------------------------------------------
341 IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.OStatement","com.sun.star.sdbc.Statement");
342 // -----------------------------------------------------------------------------
343 void SAL_CALL OStatement_Base::acquire() throw()
344 {
345 	OStatement_BASE::acquire();
346 }
347 // -----------------------------------------------------------------------------
348 void SAL_CALL OStatement_Base::release() throw()
349 {
350 	OStatement_BASE::release();
351 }
352 // -----------------------------------------------------------------------------
353 void SAL_CALL OStatement::acquire() throw()
354 {
355 	OStatement_BASE2::acquire();
356 }
357 // -----------------------------------------------------------------------------
358 void SAL_CALL OStatement::release() throw()
359 {
360 	OStatement_BASE2::release();
361 }
362 // -----------------------------------------------------------------------------
363 Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OStatement_Base::getPropertySetInfo(  ) throw(RuntimeException)
364 {
365 	return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
366 }
367 // -----------------------------------------------------------------------------
368 
369