update dev300-m58
[ooovba.git] / connectivity / source / drivers / mozab / MPreparedStatement.cxx
blob07e7551a8a1a0df57ed8912f3a00ae2f9507db3c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MPreparedStatement.cxx,v $
10 * $Revision: 1.14.56.1 $
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 <stdio.h>
34 #include <osl/diagnose.h>
35 #include "connectivity/sdbcx/VColumn.hxx"
36 #include "MPreparedStatement.hxx"
37 #include <com/sun/star/sdbc/DataType.hpp>
38 #include "MResultSetMetaData.hxx"
39 #include <cppuhelper/typeprovider.hxx>
40 #include <comphelper/sequence.hxx>
41 #include <com/sun/star/lang/DisposedException.hpp>
42 #include "connectivity/dbexception.hxx"
43 #include "connectivity/dbtools.hxx"
44 #include <comphelper/types.hxx>
45 #include <com/sun/star/sdbc/ColumnValue.hpp>
46 #include "diagnose_ex.h"
48 #if OSL_DEBUG_LEVEL > 0
49 # define OUtoCStr( x ) ( ::rtl::OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
50 #else /* OSL_DEBUG_LEVEL */
51 # define OUtoCStr( x ) ("dummy")
52 #endif /* OSL_DEBUG_LEVEL */
54 using namespace ::comphelper;
55 using namespace connectivity;
56 using namespace connectivity::mozab;
57 using namespace com::sun::star::uno;
58 using namespace com::sun::star::lang;
59 using namespace com::sun::star::beans;
60 using namespace com::sun::star::sdbc;
61 using namespace com::sun::star::sdbcx;
62 using namespace com::sun::star::container;
63 using namespace com::sun::star::io;
64 using namespace com::sun::star::util;
66 IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.mozab.PreparedStatement","com.sun.star.sdbc.PreparedStatement");
69 OPreparedStatement::OPreparedStatement( OConnection* _pConnection,const ::rtl::OUString& sql)
70 :OCommonStatement(_pConnection)
71 ,m_nNumParams(0)
72 ,m_sSqlStatement(sql)
73 ,m_bPrepared(sal_False)
74 ,m_pResultSet()
77 // -----------------------------------------------------------------------------
78 OPreparedStatement::~OPreparedStatement()
81 // -----------------------------------------------------------------------------
82 void OPreparedStatement::lateInit()
84 if ( eSelect != parseSql( m_sSqlStatement ) )
85 throw SQLException();
87 // -------------------------------------------------------------------------
88 void SAL_CALL OPreparedStatement::disposing()
90 ::osl::MutexGuard aGuard(m_aMutex);
92 OCommonStatement::disposing();
94 m_xMetaData.clear();
95 if(m_aParameterRow.isValid())
97 m_aParameterRow->get().clear();
98 m_aParameterRow = NULL;
100 m_xParamColumns = NULL;
102 // -----------------------------------------------------------------------------
104 OCommonStatement::StatementType OPreparedStatement::parseSql( const ::rtl::OUString& sql , sal_Bool bAdjusted )
105 throw ( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException )
107 StatementType eStatementType = OCommonStatement::parseSql( sql, bAdjusted );
108 if ( eStatementType != eSelect )
109 return eStatementType;
111 m_xParamColumns = new OSQLColumns();
113 // describe all parameters need for the resultset
114 describeParameter();
116 Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY);
117 OResultSet::setBoundedColumns( m_aRow, m_xParamColumns, xNames, sal_False, m_xDBMetaData, m_aColMapping );
119 return eStatementType;
122 // -----------------------------------------------------------------------------
123 void OPreparedStatement::initializeResultSet( OResultSet* _pResult )
125 OCommonStatement::initializeResultSet( _pResult );
126 _pResult->setParameterColumns( m_xParamColumns );
127 _pResult->setParameterRow( m_aParameterRow );
130 // -----------------------------------------------------------------------------
131 void OPreparedStatement::clearCachedResultSet()
133 OCommonStatement::clearCachedResultSet();
134 m_pResultSet.clear();
135 m_xMetaData.clear();
137 // -----------------------------------------------------------------------------
138 void OPreparedStatement::cacheResultSet( const ::rtl::Reference< OResultSet >& _pResult )
140 OCommonStatement::cacheResultSet( _pResult );
141 OSL_PRECOND( m_pResultSet == NULL, "OPreparedStatement::parseSql: you should call clearCachedResultSet before!" );
142 m_pResultSet = _pResult;
145 // -----------------------------------------------------------------------------
146 void SAL_CALL OPreparedStatement::acquire() throw()
148 OCommonStatement::acquire();
150 // -----------------------------------------------------------------------------
151 void SAL_CALL OPreparedStatement::release() throw()
153 OCommonStatement::release();
155 // -----------------------------------------------------------------------------
156 Any SAL_CALL OPreparedStatement::queryInterface( const Type & rType ) throw(RuntimeException)
158 Any aRet = OCommonStatement::queryInterface(rType);
159 if(!aRet.hasValue())
160 aRet = OPreparedStatement_BASE::queryInterface(rType);
161 return aRet;
163 // -------------------------------------------------------------------------
164 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL OPreparedStatement::getTypes( ) throw(::com::sun::star::uno::RuntimeException)
166 return ::comphelper::concatSequences(OPreparedStatement_BASE::getTypes(),OCommonStatement::getTypes());
168 // -------------------------------------------------------------------------
170 Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData( ) throw(SQLException, RuntimeException)
172 ::osl::MutexGuard aGuard( m_aMutex );
173 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
175 sal_Bool bReadOnly = sal_True;
176 if ( m_pResultSet.is() )
177 bReadOnly = m_pResultSet->determineReadOnly();
178 // if we do not have a result set, then we have not been executed, yet. In this case, assuming readonly=true is
179 // okay, /me thinks.
181 if ( !m_xMetaData.is() )
182 m_xMetaData = new OResultSetMetaData( m_pSQLIterator->getSelectColumns(), m_pSQLIterator->getTables().begin()->first ,m_pTable,bReadOnly );
184 return m_xMetaData;
187 // -------------------------------------------------------------------------
188 sal_Bool SAL_CALL OPreparedStatement::execute( ) throw(SQLException, RuntimeException)
190 ::osl::MutexGuard aGuard( m_aMutex );
191 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
193 Reference< XResultSet> xResult = executeQuery();
194 return xResult.is();
196 // -------------------------------------------------------------------------
198 sal_Int32 SAL_CALL OPreparedStatement::executeUpdate( ) throw(SQLException, RuntimeException)
200 ::dbtools::throwFeatureNotImplementedException( "XStatement::executeUpdate", *this );
201 return 0;
203 // -------------------------------------------------------------------------
205 void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
207 ::osl::MutexGuard aGuard( m_aMutex );
208 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
210 OSL_TRACE("prepStmt::setString( %s )", OUtoCStr( x ) );
211 setParameter( parameterIndex, x );
213 // -------------------------------------------------------------------------
215 Reference< XConnection > SAL_CALL OPreparedStatement::getConnection( ) throw(SQLException, RuntimeException)
217 ::osl::MutexGuard aGuard( m_aMutex );
218 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
220 return (Reference< XConnection >)m_pConnection;
222 // -------------------------------------------------------------------------
224 Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery( ) throw(SQLException, RuntimeException)
226 ::osl::MutexGuard aGuard( m_aMutex );
227 OSL_TRACE("In: OPreparedStatement::executeQuery" );
228 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
230 // our statement has already been parsed in lateInit, no need to do all this (potentially expensive)
231 // stuff again. Just execute.
232 return impl_executeCurrentQuery();
234 // -------------------------------------------------------------------------
236 void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 /*parameterIndex*/, sal_Bool /*x*/ ) throw(SQLException, RuntimeException)
238 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBoolean", *this );
240 // -------------------------------------------------------------------------
241 void SAL_CALL OPreparedStatement::setByte( sal_Int32 /*parameterIndex*/, sal_Int8 /*x*/ ) throw(SQLException, RuntimeException)
243 ::dbtools::throwFeatureNotImplementedException( "XParameters::setByte", *this );
245 // -------------------------------------------------------------------------
247 void SAL_CALL OPreparedStatement::setDate( sal_Int32 /*parameterIndex*/, const Date& /*aData*/ ) throw(SQLException, RuntimeException)
249 ::dbtools::throwFeatureNotImplementedException( "XParameters::setDate", *this );
251 // -------------------------------------------------------------------------
254 void SAL_CALL OPreparedStatement::setTime( sal_Int32 /*parameterIndex*/, const Time& /*aVal*/ ) throw(SQLException, RuntimeException)
256 ::dbtools::throwFeatureNotImplementedException( "XParameters::setTime", *this );
258 // -------------------------------------------------------------------------
260 void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 /*parameterIndex*/, const DateTime& /*aVal*/ ) throw(SQLException, RuntimeException)
262 ::dbtools::throwFeatureNotImplementedException( "XParameters::setTimestamp", *this );
264 // -------------------------------------------------------------------------
266 void SAL_CALL OPreparedStatement::setDouble( sal_Int32 /*parameterIndex*/, double /*x*/ ) throw(SQLException, RuntimeException)
268 ::dbtools::throwFeatureNotImplementedException( "XParameters::setDouble", *this );
271 // -------------------------------------------------------------------------
273 void SAL_CALL OPreparedStatement::setFloat( sal_Int32 /*parameterIndex*/, float /*x*/ ) throw(SQLException, RuntimeException)
275 ::dbtools::throwFeatureNotImplementedException( "XParameters::setFloat", *this );
277 // -------------------------------------------------------------------------
279 void SAL_CALL OPreparedStatement::setInt( sal_Int32 /*parameterIndex*/, sal_Int32 /*x*/ ) throw(SQLException, RuntimeException)
281 ::dbtools::throwFeatureNotImplementedException( "XParameters::setInt", *this );
283 // -------------------------------------------------------------------------
285 void SAL_CALL OPreparedStatement::setLong( sal_Int32 /*parameterIndex*/, sal_Int64 /*aVal*/ ) throw(SQLException, RuntimeException)
287 ::dbtools::throwFeatureNotImplementedException( "XParameters::setLong", *this );
289 // -------------------------------------------------------------------------
291 void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/ ) throw(SQLException, RuntimeException)
293 ::osl::MutexGuard aGuard( m_aMutex );
294 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
296 checkAndResizeParameters(parameterIndex);
298 (m_aParameterRow->get())[parameterIndex].setNull();
300 // -------------------------------------------------------------------------
302 void SAL_CALL OPreparedStatement::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) throw(SQLException, RuntimeException)
304 ::dbtools::throwFeatureNotImplementedException( "XParameters::setClob", *this );
306 // -------------------------------------------------------------------------
308 void SAL_CALL OPreparedStatement::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) throw(SQLException, RuntimeException)
310 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBlob", *this );
312 // -------------------------------------------------------------------------
314 void SAL_CALL OPreparedStatement::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException)
316 ::dbtools::throwFeatureNotImplementedException( "XParameters::setArray", *this );
318 // -------------------------------------------------------------------------
320 void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException)
322 ::dbtools::throwFeatureNotImplementedException( "XParameters::setRef", *this );
324 // -------------------------------------------------------------------------
326 void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 /*parameterIndex*/, const Any& /*x*/, sal_Int32 /*sqlType*/, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException)
328 ::dbtools::throwFeatureNotImplementedException( "XParameters::setObjectWithInfo", *this );
330 // -------------------------------------------------------------------------
332 void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& /*typeName*/ ) throw(SQLException, RuntimeException)
334 setNull(parameterIndex,sqlType);
336 // -------------------------------------------------------------------------
338 void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException)
340 ::dbtools::implSetObject(this,parameterIndex,x);
342 // -------------------------------------------------------------------------
344 void SAL_CALL OPreparedStatement::setShort( sal_Int32 /*parameterIndex*/, sal_Int16 /*x*/ ) throw(SQLException, RuntimeException)
346 ::dbtools::throwFeatureNotImplementedException( "XParameters::setShort", *this );
348 // -------------------------------------------------------------------------
350 void SAL_CALL OPreparedStatement::setBytes( sal_Int32 /*parameterIndex*/, const Sequence< sal_Int8 >& /*x*/ ) throw(SQLException, RuntimeException)
352 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBytes", *this );
354 // -------------------------------------------------------------------------
357 void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 /*parameterIndex*/, const Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(SQLException, RuntimeException)
359 ::dbtools::throwFeatureNotImplementedException( "XParameters::setCharacterStream", *this );
361 // -------------------------------------------------------------------------
363 void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 /*parameterIndex*/, const Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(SQLException, RuntimeException)
365 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBinaryStream", *this );
367 // -------------------------------------------------------------------------
369 void SAL_CALL OPreparedStatement::clearParameters( ) throw(SQLException, RuntimeException)
372 // -------------------------------------------------------------------------
373 void OPreparedStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
375 switch(nHandle)
377 case PROPERTY_ID_RESULTSETCONCURRENCY:
378 break;
379 case PROPERTY_ID_RESULTSETTYPE:
380 break;
381 case PROPERTY_ID_FETCHDIRECTION:
382 break;
383 case PROPERTY_ID_USEBOOKMARKS:
384 break;
385 default:
386 OCommonStatement::setFastPropertyValue_NoBroadcast(nHandle,rValue);
389 // -----------------------------------------------------------------------------
390 void OPreparedStatement::checkParameterIndex(sal_Int32 _parameterIndex)
392 if( !_parameterIndex || _parameterIndex > m_nNumParams)
393 ::dbtools::throwInvalidIndexException(*this);
395 // -----------------------------------------------------------------------------
396 void OPreparedStatement::checkAndResizeParameters(sal_Int32 parameterIndex)
398 ::connectivity::checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
400 if ( !m_aParameterRow.isValid() ) {
401 m_aParameterRow = new OValueVector();
402 m_aParameterRow->get().push_back(sal_Int32(0));
405 if ((sal_Int32)(m_aParameterRow->get()).size() <= parameterIndex)
406 (m_aParameterRow->get()).resize(parameterIndex+1);
408 // -----------------------------------------------------------------------------
409 void OPreparedStatement::setParameter(sal_Int32 parameterIndex, const
410 ORowSetValue& x)
412 ::osl::MutexGuard aGuard( m_aMutex );
413 checkAndResizeParameters(parameterIndex);
415 OSL_TRACE("setParameter( %d, '%s')", parameterIndex, OUtoCStr(x) );
416 (m_aParameterRow->get())[parameterIndex] = x;
419 //------------------------------------------------------------------
420 sal_uInt32 OPreparedStatement::AddParameter(OSQLParseNode * pParameter, const Reference<XPropertySet>& _xCol)
422 OSL_UNUSED( pParameter );
423 // Nr. des neu hinzuzufuegenden Parameters:
424 sal_uInt32 nParameter = m_xParamColumns->get().size()+1;
426 OSL_ENSURE(SQL_ISRULE(pParameter,parameter),"OResultSet::AddParameter: Argument ist kein Parameter");
427 OSL_ENSURE(pParameter->count() > 0,"OResultSet: Fehler im Parse Tree");
428 #if OSL_DEBUG_LEVEL > 0
429 OSQLParseNode * pMark = pParameter->getChild(0);
430 OSL_UNUSED( pMark );
431 #endif
433 ::rtl::OUString sParameterName;
435 // Parameter-Column aufsetzen:
436 sal_Int32 eType = DataType::VARCHAR;
437 sal_uInt32 nPrecision = 255;
438 sal_Int32 nScale = 0;
439 sal_Int32 nNullable = ColumnValue::NULLABLE;
441 if (_xCol.is())
443 // Typ, Precision, Scale ... der angegebenen Column verwenden,
444 // denn dieser Column wird der Wert zugewiesen bzw. mit dieser
445 // Column wird der Wert verglichen.
446 eType = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)));
447 nPrecision = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)));
448 nScale = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)));
449 nNullable = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE)));
450 _xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sParameterName;
453 Reference<XPropertySet> xParaColumn = new connectivity::sdbcx::OColumn(sParameterName
454 ,::rtl::OUString()
455 ,::rtl::OUString()
456 ,nNullable
457 ,nPrecision
458 ,nScale
459 ,eType
460 ,sal_False
461 ,sal_False
462 ,sal_False
463 ,m_pSQLIterator->isCaseSensitive());
464 m_xParamColumns->get().push_back(xParaColumn);
465 return nParameter;
467 // -----------------------------------------------------------------------------
468 void OPreparedStatement::describeColumn(OSQLParseNode*
469 _pParameter,OSQLParseNode* _pNode,const OSQLTable& _xTable)
471 Reference<XPropertySet> xProp;
472 if(SQL_ISRULE(_pNode,column_ref))
474 ::rtl::OUString sColumnName,sTableRange;
475 m_pSQLIterator->getColumnRange(_pNode,sColumnName,sTableRange);
476 if(sColumnName.getLength())
478 Reference<XNameAccess> xNameAccess = _xTable->getColumns();
479 if(xNameAccess->hasByName(sColumnName))
480 xNameAccess->getByName(sColumnName) >>= xProp;
481 AddParameter(_pParameter,xProp);
484 // else
485 // AddParameter(_pParameter,xProp);
487 // -------------------------------------------------------------------------
488 void OPreparedStatement::describeParameter()
490 ::std::vector< OSQLParseNode*> aParseNodes;
491 scanParameter(m_pParseTree,aParseNodes);
492 if(aParseNodes.size())
494 m_xParamColumns = new OSQLColumns();
495 const OSQLTables& xTabs = m_pSQLIterator->getTables();
496 if(xTabs.size())
498 OSQLTable xTable = xTabs.begin()->second;
499 ::std::vector< OSQLParseNode*>::const_iterator aIter =
500 aParseNodes.begin();
501 for (;aIter != aParseNodes.end();++aIter )
503 describeColumn(*aIter,(*aIter)->getParent()->getChild(0),xTable);
509 // -----------------------------------------------------------------------------
510 void OPreparedStatement::scanParameter(OSQLParseNode* pParseNode,::std::vector< OSQLParseNode*>& _rParaNodes)
512 OSL_ENSURE(pParseNode != NULL,"OResultSet: interner Fehler: ungueltiger ParseNode");
514 // Parameter Name-Regel gefunden?
515 if (SQL_ISRULE(pParseNode,parameter))
517 OSL_ENSURE(pParseNode->count() >= 1,"OResultSet: Parse Tree fehlerhaft");
518 OSL_ENSURE(pParseNode->getChild(0)->getNodeType() == SQL_NODE_PUNCTUATION,"OResultSet: Parse Tree fehlerhaft");
520 _rParaNodes.push_back(pParseNode);
521 // Weiterer Abstieg nicht erforderlich
522 return;
525 // Weiter absteigen im Parse Tree
526 for (sal_uInt32 i = 0; i < pParseNode->count(); i++)
527 scanParameter(pParseNode->getChild(i),_rParaNodes);
529 // -----------------------------------------------------------------------------
530 ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL OPreparedStatement::getResultSet( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
532 return NULL;
534 // -----------------------------------------------------------------------------
535 sal_Int32 SAL_CALL OPreparedStatement::getUpdateCount( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
537 return 0;
539 // -----------------------------------------------------------------------------
540 sal_Bool SAL_CALL OPreparedStatement::getMoreResults( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
542 return sal_False;
544 // -----------------------------------------------------------------------------