Bump for 3.6-28
[LibreOffice.git] / connectivity / source / drivers / mozab / MPreparedStatement.cxx
blobcb1fd13068ec5f9690e2d65f46203e26cd9e8761
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <stdio.h>
30 #include <osl/diagnose.h>
31 #include "connectivity/sdbcx/VColumn.hxx"
32 #include "MPreparedStatement.hxx"
33 #include <com/sun/star/sdbc/DataType.hpp>
34 #include "MResultSetMetaData.hxx"
35 #include <cppuhelper/typeprovider.hxx>
36 #include <comphelper/sequence.hxx>
37 #include <com/sun/star/lang/DisposedException.hpp>
38 #include "connectivity/dbexception.hxx"
39 #include "connectivity/dbtools.hxx"
40 #include <comphelper/types.hxx>
41 #include <com/sun/star/sdbc/ColumnValue.hpp>
42 #include "diagnose_ex.h"
44 #if OSL_DEBUG_LEVEL > 0
45 # define OUtoCStr( x ) ( ::rtl::OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
46 #else /* OSL_DEBUG_LEVEL */
47 # define OUtoCStr( x ) ("dummy")
48 #endif /* OSL_DEBUG_LEVEL */
50 using namespace ::comphelper;
51 using namespace connectivity;
52 using namespace connectivity::mozab;
53 using namespace com::sun::star::uno;
54 using namespace com::sun::star::lang;
55 using namespace com::sun::star::beans;
56 using namespace com::sun::star::sdbc;
57 using namespace com::sun::star::sdbcx;
58 using namespace com::sun::star::container;
59 using namespace com::sun::star::io;
60 using namespace com::sun::star::util;
62 IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.mozab.PreparedStatement","com.sun.star.sdbc.PreparedStatement");
65 OPreparedStatement::OPreparedStatement( OConnection* _pConnection,const ::rtl::OUString& sql)
66 :OCommonStatement(_pConnection)
67 ,m_nNumParams(0)
68 ,m_sSqlStatement(sql)
69 ,m_bPrepared(sal_False)
70 ,m_pResultSet()
73 // -----------------------------------------------------------------------------
74 OPreparedStatement::~OPreparedStatement()
77 // -----------------------------------------------------------------------------
78 void OPreparedStatement::lateInit()
80 if ( eSelect != parseSql( m_sSqlStatement ) )
81 throw SQLException();
83 // -------------------------------------------------------------------------
84 void SAL_CALL OPreparedStatement::disposing()
86 ::osl::MutexGuard aGuard(m_aMutex);
88 OCommonStatement::disposing();
90 m_xMetaData.clear();
91 if(m_aParameterRow.is())
93 m_aParameterRow->get().clear();
94 m_aParameterRow = NULL;
96 m_xParamColumns = NULL;
98 // -----------------------------------------------------------------------------
100 OCommonStatement::StatementType OPreparedStatement::parseSql( const ::rtl::OUString& sql , sal_Bool bAdjusted )
101 throw ( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException )
103 StatementType eStatementType = OCommonStatement::parseSql( sql, bAdjusted );
104 if ( eStatementType != eSelect )
105 return eStatementType;
107 m_xParamColumns = new OSQLColumns();
109 // describe all parameters need for the resultset
110 describeParameter();
112 Reference<XIndexAccess> xNames(m_xColNames,UNO_QUERY);
113 OResultSet::setBoundedColumns( m_aRow, m_xParamColumns, xNames, sal_False, m_xDBMetaData, m_aColMapping );
115 return eStatementType;
118 // -----------------------------------------------------------------------------
119 void OPreparedStatement::initializeResultSet( OResultSet* _pResult )
121 OCommonStatement::initializeResultSet( _pResult );
122 _pResult->setParameterColumns( m_xParamColumns );
123 _pResult->setParameterRow( m_aParameterRow );
126 // -----------------------------------------------------------------------------
127 void OPreparedStatement::clearCachedResultSet()
129 OCommonStatement::clearCachedResultSet();
130 m_pResultSet.clear();
131 m_xMetaData.clear();
133 // -----------------------------------------------------------------------------
134 void OPreparedStatement::cacheResultSet( const ::rtl::Reference< OResultSet >& _pResult )
136 OCommonStatement::cacheResultSet( _pResult );
137 OSL_PRECOND( m_pResultSet == NULL, "OPreparedStatement::parseSql: you should call clearCachedResultSet before!" );
138 m_pResultSet = _pResult;
141 // -----------------------------------------------------------------------------
142 void SAL_CALL OPreparedStatement::acquire() throw()
144 OCommonStatement::acquire();
146 // -----------------------------------------------------------------------------
147 void SAL_CALL OPreparedStatement::release() throw()
149 OCommonStatement::release();
151 // -----------------------------------------------------------------------------
152 Any SAL_CALL OPreparedStatement::queryInterface( const Type & rType ) throw(RuntimeException)
154 Any aRet = OCommonStatement::queryInterface(rType);
155 if(!aRet.hasValue())
156 aRet = OPreparedStatement_BASE::queryInterface(rType);
157 return aRet;
159 // -------------------------------------------------------------------------
160 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL OPreparedStatement::getTypes( ) throw(::com::sun::star::uno::RuntimeException)
162 return ::comphelper::concatSequences(OPreparedStatement_BASE::getTypes(),OCommonStatement::getTypes());
164 // -------------------------------------------------------------------------
166 Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData( ) throw(SQLException, RuntimeException)
168 ::osl::MutexGuard aGuard( m_aMutex );
169 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
171 sal_Bool bReadOnly = sal_True;
172 if ( m_pResultSet.is() )
173 bReadOnly = m_pResultSet->determineReadOnly();
174 // if we do not have a result set, then we have not been executed, yet. In this case, assuming readonly=true is
175 // okay, /me thinks.
177 if ( !m_xMetaData.is() )
178 m_xMetaData = new OResultSetMetaData( m_pSQLIterator->getSelectColumns(), m_pSQLIterator->getTables().begin()->first ,m_pTable,bReadOnly );
180 return m_xMetaData;
183 // -------------------------------------------------------------------------
184 sal_Bool SAL_CALL OPreparedStatement::execute( ) throw(SQLException, RuntimeException)
186 ::osl::MutexGuard aGuard( m_aMutex );
187 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
189 Reference< XResultSet> xResult = executeQuery();
190 return xResult.is();
192 // -------------------------------------------------------------------------
194 sal_Int32 SAL_CALL OPreparedStatement::executeUpdate( ) throw(SQLException, RuntimeException)
196 ::dbtools::throwFeatureNotImplementedException( "XStatement::executeUpdate", *this );
197 return 0;
199 // -------------------------------------------------------------------------
201 void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
203 ::osl::MutexGuard aGuard( m_aMutex );
204 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
206 OSL_TRACE("prepStmt::setString( %s )", OUtoCStr( x ) );
207 setParameter( parameterIndex, x );
209 // -------------------------------------------------------------------------
211 Reference< XConnection > SAL_CALL OPreparedStatement::getConnection( ) throw(SQLException, RuntimeException)
213 ::osl::MutexGuard aGuard( m_aMutex );
214 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
216 return (Reference< XConnection >)m_pConnection;
218 // -------------------------------------------------------------------------
220 Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery( ) throw(SQLException, RuntimeException)
222 ::osl::MutexGuard aGuard( m_aMutex );
223 OSL_TRACE("In: OPreparedStatement::executeQuery" );
224 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
226 // our statement has already been parsed in lateInit, no need to do all this (potentially expensive)
227 // stuff again. Just execute.
228 return impl_executeCurrentQuery();
230 // -------------------------------------------------------------------------
232 void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 /*parameterIndex*/, sal_Bool /*x*/ ) throw(SQLException, RuntimeException)
234 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBoolean", *this );
236 // -------------------------------------------------------------------------
237 void SAL_CALL OPreparedStatement::setByte( sal_Int32 /*parameterIndex*/, sal_Int8 /*x*/ ) throw(SQLException, RuntimeException)
239 ::dbtools::throwFeatureNotImplementedException( "XParameters::setByte", *this );
241 // -------------------------------------------------------------------------
243 void SAL_CALL OPreparedStatement::setDate( sal_Int32 /*parameterIndex*/, const Date& /*aData*/ ) throw(SQLException, RuntimeException)
245 ::dbtools::throwFeatureNotImplementedException( "XParameters::setDate", *this );
247 // -------------------------------------------------------------------------
250 void SAL_CALL OPreparedStatement::setTime( sal_Int32 /*parameterIndex*/, const Time& /*aVal*/ ) throw(SQLException, RuntimeException)
252 ::dbtools::throwFeatureNotImplementedException( "XParameters::setTime", *this );
254 // -------------------------------------------------------------------------
256 void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 /*parameterIndex*/, const DateTime& /*aVal*/ ) throw(SQLException, RuntimeException)
258 ::dbtools::throwFeatureNotImplementedException( "XParameters::setTimestamp", *this );
260 // -------------------------------------------------------------------------
262 void SAL_CALL OPreparedStatement::setDouble( sal_Int32 /*parameterIndex*/, double /*x*/ ) throw(SQLException, RuntimeException)
264 ::dbtools::throwFeatureNotImplementedException( "XParameters::setDouble", *this );
267 // -------------------------------------------------------------------------
269 void SAL_CALL OPreparedStatement::setFloat( sal_Int32 /*parameterIndex*/, float /*x*/ ) throw(SQLException, RuntimeException)
271 ::dbtools::throwFeatureNotImplementedException( "XParameters::setFloat", *this );
273 // -------------------------------------------------------------------------
275 void SAL_CALL OPreparedStatement::setInt( sal_Int32 /*parameterIndex*/, sal_Int32 /*x*/ ) throw(SQLException, RuntimeException)
277 ::dbtools::throwFeatureNotImplementedException( "XParameters::setInt", *this );
279 // -------------------------------------------------------------------------
281 void SAL_CALL OPreparedStatement::setLong( sal_Int32 /*parameterIndex*/, sal_Int64 /*aVal*/ ) throw(SQLException, RuntimeException)
283 ::dbtools::throwFeatureNotImplementedException( "XParameters::setLong", *this );
285 // -------------------------------------------------------------------------
287 void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/ ) throw(SQLException, RuntimeException)
289 ::osl::MutexGuard aGuard( m_aMutex );
290 checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
292 checkAndResizeParameters(parameterIndex);
294 (m_aParameterRow->get())[parameterIndex].setNull();
296 // -------------------------------------------------------------------------
298 void SAL_CALL OPreparedStatement::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) throw(SQLException, RuntimeException)
300 ::dbtools::throwFeatureNotImplementedException( "XParameters::setClob", *this );
302 // -------------------------------------------------------------------------
304 void SAL_CALL OPreparedStatement::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) throw(SQLException, RuntimeException)
306 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBlob", *this );
308 // -------------------------------------------------------------------------
310 void SAL_CALL OPreparedStatement::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException)
312 ::dbtools::throwFeatureNotImplementedException( "XParameters::setArray", *this );
314 // -------------------------------------------------------------------------
316 void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException)
318 ::dbtools::throwFeatureNotImplementedException( "XParameters::setRef", *this );
320 // -------------------------------------------------------------------------
322 void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 /*parameterIndex*/, const Any& /*x*/, sal_Int32 /*sqlType*/, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException)
324 ::dbtools::throwFeatureNotImplementedException( "XParameters::setObjectWithInfo", *this );
326 // -------------------------------------------------------------------------
328 void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& /*typeName*/ ) throw(SQLException, RuntimeException)
330 setNull(parameterIndex,sqlType);
332 // -------------------------------------------------------------------------
334 void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException)
336 ::dbtools::implSetObject(this,parameterIndex,x);
338 // -------------------------------------------------------------------------
340 void SAL_CALL OPreparedStatement::setShort( sal_Int32 /*parameterIndex*/, sal_Int16 /*x*/ ) throw(SQLException, RuntimeException)
342 ::dbtools::throwFeatureNotImplementedException( "XParameters::setShort", *this );
344 // -------------------------------------------------------------------------
346 void SAL_CALL OPreparedStatement::setBytes( sal_Int32 /*parameterIndex*/, const Sequence< sal_Int8 >& /*x*/ ) throw(SQLException, RuntimeException)
348 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBytes", *this );
350 // -------------------------------------------------------------------------
353 void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 /*parameterIndex*/, const Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(SQLException, RuntimeException)
355 ::dbtools::throwFeatureNotImplementedException( "XParameters::setCharacterStream", *this );
357 // -------------------------------------------------------------------------
359 void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 /*parameterIndex*/, const Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(SQLException, RuntimeException)
361 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBinaryStream", *this );
363 // -------------------------------------------------------------------------
365 void SAL_CALL OPreparedStatement::clearParameters( ) throw(SQLException, RuntimeException)
368 // -------------------------------------------------------------------------
369 void OPreparedStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
371 switch(nHandle)
373 case PROPERTY_ID_RESULTSETCONCURRENCY:
374 break;
375 case PROPERTY_ID_RESULTSETTYPE:
376 break;
377 case PROPERTY_ID_FETCHDIRECTION:
378 break;
379 case PROPERTY_ID_USEBOOKMARKS:
380 break;
381 default:
382 OCommonStatement::setFastPropertyValue_NoBroadcast(nHandle,rValue);
386 // -----------------------------------------------------------------------------
387 void OPreparedStatement::checkAndResizeParameters(sal_Int32 parameterIndex)
389 ::connectivity::checkDisposed(OCommonStatement_IBASE::rBHelper.bDisposed);
391 if ( !m_aParameterRow.is() ) {
392 m_aParameterRow = new OValueVector();
393 m_aParameterRow->get().push_back(sal_Int32(0));
396 if ((sal_Int32)(m_aParameterRow->get()).size() <= parameterIndex)
397 (m_aParameterRow->get()).resize(parameterIndex+1);
399 // -----------------------------------------------------------------------------
400 void OPreparedStatement::setParameter(sal_Int32 parameterIndex, const
401 ORowSetValue& x)
403 ::osl::MutexGuard aGuard( m_aMutex );
404 checkAndResizeParameters(parameterIndex);
406 OSL_TRACE("setParameter( %d, '%s')", parameterIndex, OUtoCStr(x) );
407 (m_aParameterRow->get())[parameterIndex] = x;
410 //------------------------------------------------------------------
411 size_t OPreparedStatement::AddParameter(OSQLParseNode * pParameter, const Reference<XPropertySet>& _xCol)
413 OSL_UNUSED( pParameter );
414 // Count of the newly added Parameters
415 size_t nParameter = m_xParamColumns->get().size()+1;
417 OSL_ENSURE(SQL_ISRULE(pParameter,parameter),"OResultSet::AddParameter: Argument is not a Parameter");
418 OSL_ENSURE(pParameter->count() > 0,"OResultSet: error in parse tree");
419 #if OSL_DEBUG_LEVEL > 0
420 OSQLParseNode * pMark = pParameter->getChild(0);
421 OSL_UNUSED( pMark );
422 #endif
424 ::rtl::OUString sParameterName;
426 // set up Parameter-Column:
427 sal_Int32 eType = DataType::VARCHAR;
428 sal_uInt32 nPrecision = 255;
429 sal_Int32 nScale = 0;
430 sal_Int32 nNullable = ColumnValue::NULLABLE;
432 if (_xCol.is())
434 // Type, Precision, Scale ... utilize the selected Columns,
435 // then this Column will get the value assigned or with this
436 // Column will the value be compared.
437 eType = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)));
438 nPrecision = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)));
439 nScale = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)));
440 nNullable = getINT32(_xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE)));
441 _xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sParameterName;
444 Reference<XPropertySet> xParaColumn = new connectivity::sdbcx::OColumn(sParameterName
445 ,::rtl::OUString()
446 ,::rtl::OUString()
447 ,::rtl::OUString()
448 ,nNullable
449 ,nPrecision
450 ,nScale
451 ,eType
452 ,sal_False
453 ,sal_False
454 ,sal_False
455 ,m_pSQLIterator->isCaseSensitive());
456 m_xParamColumns->get().push_back(xParaColumn);
457 return nParameter;
459 // -----------------------------------------------------------------------------
460 void OPreparedStatement::describeColumn(OSQLParseNode*
461 _pParameter,OSQLParseNode* _pNode,const OSQLTable& _xTable)
463 Reference<XPropertySet> xProp;
464 if(SQL_ISRULE(_pNode,column_ref))
466 ::rtl::OUString sColumnName,sTableRange;
467 m_pSQLIterator->getColumnRange(_pNode,sColumnName,sTableRange);
468 if(!sColumnName.isEmpty())
470 Reference<XNameAccess> xNameAccess = _xTable->getColumns();
471 if(xNameAccess->hasByName(sColumnName))
472 xNameAccess->getByName(sColumnName) >>= xProp;
473 AddParameter(_pParameter,xProp);
476 // else
477 // AddParameter(_pParameter,xProp);
479 // -------------------------------------------------------------------------
480 void OPreparedStatement::describeParameter()
482 ::std::vector< OSQLParseNode*> aParseNodes;
483 scanParameter(m_pParseTree,aParseNodes);
484 if(!aParseNodes.empty())
486 m_xParamColumns = new OSQLColumns();
487 const OSQLTables& xTabs = m_pSQLIterator->getTables();
488 if(xTabs.size())
490 OSQLTable xTable = xTabs.begin()->second;
491 ::std::vector< OSQLParseNode*>::const_iterator aIter =
492 aParseNodes.begin();
493 for (;aIter != aParseNodes.end();++aIter )
495 describeColumn(*aIter,(*aIter)->getParent()->getChild(0),xTable);
501 // -----------------------------------------------------------------------------
502 void OPreparedStatement::scanParameter(OSQLParseNode* pParseNode,::std::vector< OSQLParseNode*>& _rParaNodes)
504 OSL_ENSURE(pParseNode != NULL,"OResultSet: internal error: invalid ParseNode");
506 // Parameter Name-Row found?
507 if (SQL_ISRULE(pParseNode,parameter))
509 OSL_ENSURE(pParseNode->count() >= 1,"OResultSet: Faulty Parse Tree");
510 OSL_ENSURE(pParseNode->getChild(0)->getNodeType() == SQL_NODE_PUNCTUATION,"OResultSet: Faulty Parse Tree");
512 _rParaNodes.push_back(pParseNode);
513 // further search isn't necessary
514 return;
517 // Search on in Parse Tree
518 for (sal_uInt32 i = 0; i < pParseNode->count(); i++)
519 scanParameter(pParseNode->getChild(i),_rParaNodes);
521 // -----------------------------------------------------------------------------
522 ::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)
524 return NULL;
526 // -----------------------------------------------------------------------------
527 sal_Int32 SAL_CALL OPreparedStatement::getUpdateCount( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
529 return 0;
531 // -----------------------------------------------------------------------------
532 sal_Bool SAL_CALL OPreparedStatement::getMoreResults( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
534 return sal_False;
536 // -----------------------------------------------------------------------------
539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */