Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * Effective License of whole file:
5 : *
6 : * This library is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public
8 : * License version 2.1, as published by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * Lesser General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public
16 : * License along with this library; if not, write to the Free Software
17 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 : * MA 02111-1307 USA
19 : *
20 : * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
21 : *
22 : * The Contents of this file are made available subject to the terms of
23 : * the GNU Lesser General Public License Version 2.1
24 : *
25 : * Copyright: 2000 by Sun Microsystems, Inc.
26 : *
27 : * Contributor(s): Joerg Budischewski
28 : *
29 : * All parts contributed on or after August 2011:
30 : *
31 : * This Source Code Form is subject to the terms of the Mozilla Public
32 : * License, v. 2.0. If a copy of the MPL was not distributed with this
33 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
34 : *
35 : ************************************************************************/
36 :
37 : #include "pq_preparedstatement.hxx"
38 : #include "pq_resultset.hxx"
39 : #include "pq_tools.hxx"
40 : #include "pq_statics.hxx"
41 : #include "pq_statement.hxx"
42 :
43 : #include <rtl/strbuf.hxx>
44 : #include <rtl/ustrbuf.hxx>
45 :
46 :
47 : #include <cppuhelper/typeprovider.hxx>
48 : #include <cppuhelper/queryinterface.hxx>
49 :
50 : #include <com/sun/star/beans/PropertyAttribute.hpp>
51 :
52 : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
53 : #include <com/sun/star/sdbc/ResultSetType.hpp>
54 :
55 : #include <string.h>
56 :
57 : #include <connectivity/dbconversion.hxx>
58 :
59 : using osl::Mutex;
60 : using osl::MutexGuard;
61 :
62 :
63 : using com::sun::star::uno::Any;
64 : using com::sun::star::uno::makeAny;
65 : using com::sun::star::uno::Type;
66 : using com::sun::star::uno::RuntimeException;
67 : using com::sun::star::uno::Exception;
68 : using com::sun::star::uno::Sequence;
69 : using com::sun::star::uno::Reference;
70 : using com::sun::star::uno::XInterface;
71 : using com::sun::star::uno::UNO_QUERY;
72 :
73 : using com::sun::star::lang::IllegalArgumentException;
74 :
75 : using com::sun::star::sdbc::XWarningsSupplier;
76 : using com::sun::star::sdbc::XCloseable;
77 : using com::sun::star::sdbc::XPreparedStatement;
78 : using com::sun::star::sdbc::XParameters;
79 : using com::sun::star::sdbc::XResultSet;
80 : using com::sun::star::sdbc::XRef;
81 : using com::sun::star::sdbc::XBlob;
82 : using com::sun::star::sdbc::XClob;
83 : using com::sun::star::sdbc::XArray;
84 : using com::sun::star::sdbc::XConnection;
85 : using com::sun::star::sdbc::XGeneratedResultSet;
86 : using com::sun::star::sdbc::SQLException;
87 :
88 : using com::sun::star::beans::Property;
89 : using com::sun::star::beans::XPropertySetInfo;
90 : using com::sun::star::beans::XPropertySet;
91 : using com::sun::star::beans::XMultiPropertySet;
92 : using com::sun::star::beans::XFastPropertySet;
93 :
94 : using namespace dbtools;
95 :
96 : namespace pq_sdbc_driver
97 : {
98 0 : static ::cppu::IPropertyArrayHelper & getPreparedStatementPropertyArrayHelper()
99 : {
100 : static ::cppu::IPropertyArrayHelper *pArrayHelper;
101 0 : if( ! pArrayHelper )
102 : {
103 0 : MutexGuard guard( Mutex::getGlobalMutex() );
104 0 : if( ! pArrayHelper )
105 : {
106 : static Property aTable[] =
107 : {
108 : Property(
109 : OUString("CursorName"), 0,
110 0 : ::cppu::UnoType<OUString>::get() , 0 ),
111 : Property(
112 : OUString("EscapeProcessing"), 1,
113 0 : ::getBooleanCppuType() , 0 ),
114 : Property(
115 : OUString("FetchDirection"), 2,
116 0 : ::cppu::UnoType<sal_Int32>::get() , 0 ),
117 : Property(
118 : OUString("FetchSize"), 3,
119 0 : ::cppu::UnoType<sal_Int32>::get() , 0 ),
120 : Property(
121 : OUString("MaxFieldSize"), 4,
122 0 : ::cppu::UnoType<sal_Int32>::get() , 0 ),
123 : Property(
124 : OUString("MaxRows"), 5,
125 0 : ::cppu::UnoType<sal_Int32>::get() , 0 ),
126 : Property(
127 : OUString("QueryTimeOut"), 6,
128 0 : ::cppu::UnoType<sal_Int32>::get() , 0 ),
129 : Property(
130 : OUString("ResultSetConcurrency"), 7,
131 0 : ::cppu::UnoType<sal_Int32>::get() , 0 ),
132 : Property(
133 : OUString("ResultSetType"), 8,
134 0 : ::cppu::UnoType<sal_Int32>::get() , 0 )
135 0 : };
136 : OSL_ASSERT( sizeof(aTable)/ sizeof(Property) == PREPARED_STATEMENT_SIZE );
137 0 : static ::cppu::OPropertyArrayHelper arrayHelper( aTable, PREPARED_STATEMENT_SIZE, sal_True );
138 0 : pArrayHelper = &arrayHelper;
139 0 : }
140 : }
141 0 : return *pArrayHelper;
142 : }
143 :
144 0 : static bool isOperator( char c )
145 : {
146 : static const char * operators = "<>=()!/&%.,;";
147 :
148 0 : const char * w = operators;
149 0 : while (*w && *w != c)
150 : {
151 0 : ++w;
152 : }
153 0 : return *w != 0;
154 : }
155 :
156 0 : static bool isNamedParameterStart( const OString & o , int index )
157 : {
158 0 : return o[index] == ':' && (
159 0 : isWhitespace( o[index-1] ) || isOperator(o[index-1]) );
160 : }
161 :
162 0 : static bool isQuoted( const OString & str )
163 : {
164 0 : return str[0] == '"' || str[0] == '\'';
165 : }
166 :
167 0 : PreparedStatement::PreparedStatement(
168 : const ::rtl::Reference< RefCountedMutex > & refMutex,
169 : const Reference< XConnection > & conn,
170 : struct ConnectionSettings *pSettings,
171 : const OString & stmt )
172 0 : : OComponentHelper(refMutex->mutex)
173 : , OPropertySetHelper(OComponentHelper::rBHelper)
174 : , m_connection(conn)
175 : , m_pSettings(pSettings)
176 : , m_stmt(stmt)
177 : , m_refMutex(refMutex)
178 : , m_multipleResultAvailable(false)
179 : , m_multipleResultUpdateCount(0)
180 0 : , m_lastOidInserted( InvalidOid )
181 : {
182 0 : m_props[PREPARED_STATEMENT_QUERY_TIME_OUT] = makeAny( (sal_Int32)0 );
183 0 : m_props[PREPARED_STATEMENT_MAX_ROWS] = makeAny( (sal_Int32)0 );
184 0 : m_props[PREPARED_STATEMENT_RESULT_SET_CONCURRENCY] = makeAny(
185 0 : com::sun::star::sdbc::ResultSetConcurrency::READ_ONLY );
186 0 : m_props[PREPARED_STATEMENT_RESULT_SET_TYPE] = makeAny(
187 0 : com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE );
188 :
189 0 : splitSQL( m_stmt, m_splittedStatement );
190 0 : int elements = 0;
191 0 : for( int i = 0, max = m_splittedStatement.size(); i < max ; i ++ )
192 : {
193 0 : const OString &str = m_splittedStatement[i];
194 : // ignore quoted strings ....
195 0 : if( ! isQuoted( str ) )
196 : {
197 : // the ':' cannot be the first or the last part of the
198 : // token,
199 : // the ? cannot be the first part of the token , so we start
200 : // at one
201 0 : for( int index = 1 ; index < str.getLength() ; index ++ )
202 : {
203 0 : if( str[index] == '?' ||
204 0 : isNamedParameterStart( str , index )
205 : )
206 : {
207 0 : elements ++;
208 : }
209 : }
210 : }
211 : }
212 0 : m_vars = OStringVector ( elements );
213 0 : }
214 :
215 0 : PreparedStatement::~PreparedStatement()
216 : {
217 : POSTGRE_TRACE( "dtor PreparedStatement" );
218 0 : }
219 :
220 0 : void PreparedStatement::checkColumnIndex( sal_Int32 parameterIndex )
221 : {
222 0 : if( parameterIndex < 1 || parameterIndex > (sal_Int32) m_vars.size() )
223 : {
224 0 : OUStringBuffer buf( 128 );
225 0 : buf.appendAscii( "pq_preparedstatement: parameter index out of range (expected 1 to " );
226 0 : buf.append( (sal_Int32 ) m_vars.size() );
227 0 : buf.appendAscii( ", got " );
228 0 : buf.append( parameterIndex );
229 0 : buf.appendAscii( ", statement '" );
230 0 : buf.append( OStringToOUString( m_stmt, m_pSettings->encoding ) );
231 0 : buf.appendAscii( "')" );
232 0 : throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any () );
233 : }
234 0 : }
235 0 : void PreparedStatement::checkClosed() throw (SQLException, RuntimeException )
236 : {
237 0 : if( ! m_pSettings || ! m_pSettings->pConnection )
238 : throw SQLException(
239 : "pq_driver: PreparedStatement or connection has already been closed !",
240 0 : *this, OUString(),1,Any());
241 0 : }
242 :
243 0 : Any PreparedStatement::queryInterface( const Type & reqType ) throw (RuntimeException, std::exception)
244 : {
245 0 : Any ret;
246 :
247 0 : ret = OComponentHelper::queryInterface( reqType );
248 0 : if( ! ret.hasValue() )
249 0 : ret = ::cppu::queryInterface( reqType,
250 : static_cast< XWarningsSupplier * > ( this ),
251 : static_cast< XPreparedStatement * > ( this ),
252 : static_cast< com::sun::star::sdbc::XResultSetMetaDataSupplier * > ( this ),
253 : static_cast< XParameters * > ( this ),
254 : static_cast< XCloseable * > ( this ),
255 : static_cast< XGeneratedResultSet * > ( this ),
256 : static_cast< XPropertySet * > ( this ),
257 : static_cast< XMultiPropertySet * > ( this ),
258 0 : static_cast< XFastPropertySet * > ( this ) );
259 0 : return ret;
260 : }
261 :
262 :
263 0 : Sequence< Type > PreparedStatement::getTypes() throw ( RuntimeException, std::exception )
264 : {
265 : static cppu::OTypeCollection *pCollection;
266 0 : if( ! pCollection )
267 : {
268 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
269 0 : if( !pCollection )
270 : {
271 : static cppu::OTypeCollection collection(
272 0 : cppu::UnoType<XWarningsSupplier>::get(),
273 0 : cppu::UnoType<XPreparedStatement>::get(),
274 0 : cppu::UnoType<com::sun::star::sdbc::XResultSetMetaDataSupplier>::get(),
275 0 : cppu::UnoType<XParameters>::get(),
276 0 : cppu::UnoType<XCloseable>::get(),
277 0 : cppu::UnoType<XGeneratedResultSet>::get(),
278 0 : cppu::UnoType<XPropertySet>::get(),
279 0 : cppu::UnoType<XFastPropertySet>::get(),
280 0 : cppu::UnoType<XMultiPropertySet>::get(),
281 0 : OComponentHelper::getTypes());
282 0 : pCollection = &collection;
283 0 : }
284 : }
285 0 : return pCollection->getTypes();
286 : }
287 :
288 0 : Sequence< sal_Int8> PreparedStatement::getImplementationId() throw ( RuntimeException, std::exception )
289 : {
290 0 : return css::uno::Sequence<sal_Int8>();
291 : }
292 :
293 0 : void PreparedStatement::close( ) throw (SQLException, RuntimeException, std::exception)
294 : {
295 : // let the connection die without acquired mutex !
296 0 : Reference< XConnection > r;
297 0 : Reference< XCloseable > resultSet;
298 : {
299 0 : MutexGuard guard( m_refMutex->mutex );
300 0 : m_pSettings = 0;
301 0 : r = m_connection;
302 0 : m_connection.clear();
303 :
304 0 : resultSet = m_lastResultset;
305 0 : m_lastResultset.clear();
306 : }
307 0 : if( resultSet.is() )
308 : {
309 0 : resultSet->close();
310 0 : }
311 0 : }
312 :
313 0 : void PreparedStatement::raiseSQLException(
314 : const char * errorMsg, const char *errorType )
315 : throw( SQLException )
316 : {
317 0 : OUStringBuffer buf(128);
318 0 : buf.appendAscii( "pq_driver: ");
319 0 : if( errorType )
320 : {
321 0 : buf.appendAscii( "[" );
322 0 : buf.appendAscii( errorType );
323 0 : buf.appendAscii( "]" );
324 : }
325 : buf.append(
326 0 : OUString( errorMsg, strlen(errorMsg) , m_pSettings->encoding ) );
327 0 : buf.appendAscii( " (caused by statement '" );
328 0 : buf.appendAscii( m_executedStatement.getStr() );
329 0 : buf.appendAscii( "')" );
330 0 : OUString error = buf.makeStringAndClear();
331 0 : log( m_pSettings, LogLevel::ERROR, error );
332 0 : throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any() );
333 : }
334 :
335 0 : Reference< XResultSet > PreparedStatement::executeQuery( )
336 : throw (SQLException, RuntimeException, std::exception)
337 : {
338 0 : Reference< XCloseable > lastResultSet = m_lastResultset;
339 0 : if( lastResultSet.is() )
340 0 : lastResultSet->close();
341 :
342 0 : if( ! execute( ) )
343 : {
344 0 : raiseSQLException( "not a query" );
345 : }
346 0 : return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY );
347 : }
348 :
349 0 : sal_Int32 PreparedStatement::executeUpdate( )
350 : throw (SQLException, RuntimeException, std::exception)
351 : {
352 0 : if( execute( ) )
353 : {
354 0 : raiseSQLException( "not a command" );
355 : }
356 0 : return m_multipleResultUpdateCount;
357 : }
358 :
359 0 : sal_Bool PreparedStatement::execute( )
360 : throw (SQLException, RuntimeException, std::exception)
361 : {
362 0 : osl::MutexGuard guard( m_refMutex->mutex );
363 :
364 0 : OStringBuffer buf( m_stmt.getLength() *2 );
365 :
366 0 : OStringVector::size_type vars = 0;
367 0 : for( OStringVector::size_type i = 0 ; i < m_splittedStatement.size() ; ++i )
368 : {
369 : // LEM TODO: instead of this manual mucking with SQL
370 : // could we use PQexecParams / PQExecPrepared / ...?
371 : // Only snafu is giving the types of the parameters and
372 : // that it needs $1, $2, etc instead of "?"
373 0 : const OString &str = m_splittedStatement[i];
374 : // printf( "Splitted %d %s\n" , i , str.getStr() );
375 0 : if( isQuoted( str ) )
376 : {
377 0 : buf.append( str );
378 : }
379 : else
380 : {
381 0 : int start = 0,index;
382 0 : for( index = 1 ; index < str.getLength() ; index ++ )
383 : {
384 0 : if( str[index] == '?' )
385 : {
386 0 : buf.append( str.getStr()+start, index - start );
387 0 : buf.append( m_vars[vars] );
388 0 : vars ++;
389 0 : start =index+1;
390 : }
391 : else
392 : {
393 0 : if ( isNamedParameterStart( str, index ) )
394 : {
395 0 : buf.append( str.getStr()+start, index -start );
396 0 : buf.append( m_vars[vars] );
397 :
398 : // skip to the end of the named parameter
399 0 : while ( index < str.getLength()
400 0 : && !( isWhitespace(str[index])
401 0 : || isOperator (str[index])))
402 : {
403 0 : ++index;
404 : }
405 0 : start = index;
406 0 : vars ++;
407 : }
408 : }
409 : }
410 : // if( index +1 >= str.getLength() )
411 : // {
412 0 : buf.append( str.getStr() + start, index -start );
413 : // }
414 : }
415 : }
416 :
417 0 : m_executedStatement = buf.makeStringAndClear();
418 :
419 0 : m_lastResultset.clear();
420 0 : m_lastTableInserted = OUString();
421 :
422 0 : struct CommandData data;
423 0 : data.refMutex = m_refMutex;
424 0 : data.ppSettings = &m_pSettings;
425 0 : data.pLastOidInserted = &m_lastOidInserted;
426 0 : data.pLastQuery = &m_lastQuery;
427 0 : data.pMultipleResultUpdateCount = &m_multipleResultUpdateCount;
428 0 : data.pMultipleResultAvailable = &m_multipleResultAvailable;
429 0 : data.pLastTableInserted = &m_lastTableInserted;
430 0 : data.pLastResultset = &m_lastResultset;
431 0 : data.owner = *this;
432 0 : data.tableSupplier = Reference< com::sun::star::sdbcx::XTablesSupplier >( m_connection, UNO_QUERY );
433 0 : data.concurrency = extractIntProperty( this, getStatics().RESULT_SET_CONCURRENCY );
434 :
435 0 : return executePostgresCommand( m_executedStatement , &data ); // see pq_statement.cxx
436 : }
437 :
438 0 : Reference< XConnection > PreparedStatement::getConnection( )
439 : throw (SQLException, RuntimeException, std::exception)
440 : {
441 0 : Reference< XConnection > ret;
442 : {
443 0 : MutexGuard guard( m_refMutex->mutex );
444 0 : checkClosed();
445 0 : ret = m_connection;
446 : }
447 0 : return ret;
448 : }
449 :
450 :
451 0 : void PreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType )
452 : throw (SQLException, RuntimeException, std::exception)
453 : {
454 : (void)sqlType;
455 0 : MutexGuard guard( m_refMutex->mutex );
456 0 : checkClosed();
457 0 : checkColumnIndex( parameterIndex );
458 0 : m_vars[parameterIndex-1] = OString( "NULL" );
459 0 : }
460 :
461 0 : void PreparedStatement::setObjectNull(
462 : sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& typeName )
463 : throw (SQLException, RuntimeException, std::exception)
464 : {
465 : (void) sqlType; (void) typeName;
466 0 : MutexGuard guard( m_refMutex->mutex );
467 0 : checkClosed();
468 0 : checkColumnIndex( parameterIndex );
469 0 : m_vars[parameterIndex-1] = OString( "NULL" );
470 0 : }
471 :
472 :
473 0 : void PreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x )
474 : throw (SQLException, RuntimeException, std::exception)
475 : {
476 0 : MutexGuard guard(m_refMutex->mutex );
477 0 : checkClosed();
478 0 : checkColumnIndex( parameterIndex );
479 0 : if( x )
480 0 : m_vars[parameterIndex-1] = OString( "'t'" );
481 : else
482 0 : m_vars[parameterIndex-1] = OString( "'f'" );
483 0 : }
484 :
485 0 : void PreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x )
486 : throw (SQLException, RuntimeException, std::exception)
487 : {
488 0 : setInt(parameterIndex,x);
489 0 : }
490 :
491 0 : void PreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x )
492 : throw (SQLException, RuntimeException, std::exception)
493 : {
494 0 : setInt(parameterIndex, x );
495 0 : }
496 :
497 0 : void PreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x )
498 : throw (SQLException, RuntimeException, std::exception)
499 : {
500 : // printf( "setString %d %d\n ", parameterIndex, x);
501 0 : MutexGuard guard(m_refMutex->mutex );
502 0 : checkClosed();
503 0 : checkColumnIndex( parameterIndex );
504 0 : OStringBuffer buf( 20 );
505 0 : buf.append( "'" );
506 0 : buf.append( (sal_Int32) x );
507 0 : buf.append( "'" );
508 0 : m_vars[parameterIndex-1] = buf.makeStringAndClear();
509 0 : }
510 :
511 0 : void PreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x )
512 : throw (SQLException, RuntimeException, std::exception)
513 : {
514 0 : MutexGuard guard(m_refMutex->mutex );
515 0 : checkClosed();
516 0 : checkColumnIndex( parameterIndex );
517 0 : OStringBuffer buf( 20 );
518 0 : buf.append( "'" );
519 0 : buf.append( (sal_Int64) x );
520 0 : buf.append( "'" );
521 0 : m_vars[parameterIndex-1] = buf.makeStringAndClear();
522 0 : }
523 :
524 0 : void PreparedStatement::setFloat( sal_Int32 parameterIndex, float x )
525 : throw (SQLException, RuntimeException, std::exception)
526 : {
527 0 : MutexGuard guard(m_refMutex->mutex );
528 0 : checkClosed();
529 0 : checkColumnIndex( parameterIndex );
530 0 : OStringBuffer buf( 20 );
531 0 : buf.append( "'" );
532 0 : buf.append( x );
533 0 : buf.append( "'" );
534 0 : m_vars[parameterIndex-1] = buf.makeStringAndClear();
535 0 : }
536 :
537 0 : void PreparedStatement::setDouble( sal_Int32 parameterIndex, double x )
538 : throw (SQLException, RuntimeException, std::exception)
539 : {
540 0 : MutexGuard guard(m_refMutex->mutex );
541 0 : checkClosed();
542 0 : checkColumnIndex( parameterIndex );
543 0 : OStringBuffer buf( 20 );
544 0 : buf.append( "'" );
545 0 : buf.append( x );
546 0 : buf.append( "'" );
547 0 : m_vars[parameterIndex-1] = buf.makeStringAndClear();
548 0 : }
549 :
550 0 : void PreparedStatement::setString( sal_Int32 parameterIndex, const OUString& x )
551 : throw (SQLException, RuntimeException, std::exception)
552 : {
553 : // printf( "setString %d %s\n ", parameterIndex,
554 : // OUStringToOString( x , RTL_TEXTENCODING_ASCII_US ).getStr());
555 0 : MutexGuard guard(m_refMutex->mutex );
556 0 : checkClosed();
557 0 : checkColumnIndex( parameterIndex );
558 0 : OStringBuffer buf( 20 );
559 0 : buf.append( "'" );
560 0 : OString y = OUStringToOString( x, m_pSettings->encoding );
561 0 : buf.ensureCapacity( y.getLength() * 2 + 2 );
562 0 : int len = PQescapeString( ((char*)buf.getStr())+1, y.getStr() , y.getLength() );
563 0 : buf.setLength( 1 + len );
564 0 : buf.append( "'" );
565 0 : m_vars[parameterIndex-1] = buf.makeStringAndClear();
566 0 : }
567 :
568 0 : void PreparedStatement::setBytes(
569 : sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x )
570 : throw (SQLException, RuntimeException, std::exception)
571 : {
572 0 : MutexGuard guard(m_refMutex->mutex );
573 0 : checkClosed();
574 0 : checkColumnIndex( parameterIndex );
575 0 : OStringBuffer buf( 20 );
576 0 : buf.append( "'" );
577 : size_t len;
578 : unsigned char * escapedString =
579 0 : PQescapeBytea( (unsigned char *)x.getConstArray(), x.getLength(), &len);
580 0 : if( ! escapedString )
581 : {
582 : throw SQLException(
583 : "pq_preparedstatement.setBytes: Error during converting bytesequence to an SQL conform string",
584 0 : *this, OUString(), 1, Any() );
585 : }
586 0 : buf.append( (const sal_Char *)escapedString, len -1 );
587 0 : free( escapedString );
588 0 : buf.append( "'" );
589 0 : m_vars[parameterIndex-1] = buf.makeStringAndClear();
590 0 : }
591 :
592 :
593 0 : void PreparedStatement::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x )
594 : throw (SQLException, RuntimeException, std::exception)
595 : {
596 0 : setString( parameterIndex, DBTypeConversion::toDateString( x ) );
597 0 : }
598 :
599 0 : void PreparedStatement::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x )
600 : throw (SQLException, RuntimeException, std::exception)
601 : {
602 0 : setString( parameterIndex, DBTypeConversion::toTimeString( x ) );
603 0 : }
604 :
605 0 : void PreparedStatement::setTimestamp(
606 : sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x )
607 : throw (SQLException, RuntimeException, std::exception)
608 : {
609 0 : setString( parameterIndex, DBTypeConversion::toDateTimeString( x ) );
610 0 : }
611 :
612 0 : void PreparedStatement::setBinaryStream(
613 : sal_Int32 parameterIndex,
614 : const Reference< ::com::sun::star::io::XInputStream >& x,
615 : sal_Int32 length )
616 : throw (SQLException, RuntimeException, std::exception)
617 : {
618 : (void) parameterIndex; (void)x; (void) length;
619 : throw SQLException(
620 : "pq_preparedstatement: setBinaryStream not implemented",
621 0 : *this, OUString(), 1, Any () );
622 : }
623 :
624 0 : void PreparedStatement::setCharacterStream(
625 : sal_Int32 parameterIndex,
626 : const Reference< ::com::sun::star::io::XInputStream >& x,
627 : sal_Int32 length )
628 : throw (SQLException, RuntimeException, std::exception)
629 : {
630 : (void) parameterIndex; (void)x; (void) length;
631 : throw SQLException(
632 : "pq_preparedstatement: setCharacterStream not implemented",
633 0 : *this, OUString(), 1, Any () );
634 : }
635 :
636 0 : void PreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x )
637 : throw (SQLException, RuntimeException, std::exception)
638 : {
639 0 : if( ! implSetObject( this, parameterIndex, x ))
640 : {
641 0 : OUStringBuffer buf;
642 0 : buf.append( "pq_preparedstatement::setObject: can't convert value of type " );
643 0 : buf.append( x.getValueTypeName() );
644 0 : throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any () );
645 : }
646 0 : }
647 :
648 0 : void PreparedStatement::setObjectWithInfo(
649 : sal_Int32 parameterIndex,
650 : const Any& x,
651 : sal_Int32 targetSqlType,
652 : sal_Int32 scale )
653 : throw (SQLException, RuntimeException, std::exception)
654 : {
655 : (void) scale;
656 0 : if( com::sun::star::sdbc::DataType::DECIMAL == targetSqlType ||
657 : com::sun::star::sdbc::DataType::NUMERIC == targetSqlType )
658 : {
659 0 : double myDouble = 0.0;
660 0 : OUString myString;
661 0 : if( x >>= myDouble )
662 : {
663 0 : myString = OUString::number( myDouble );
664 : }
665 : else
666 : {
667 0 : x >>= myString;
668 : }
669 0 : if( !myString.isEmpty() )
670 : {
671 : // printf( "setObjectWithInfo %s\n", OUStringToOString(myString,RTL_TEXTENCODING_ASCII_US).getStr());
672 0 : setString( parameterIndex, myString );
673 : }
674 : else
675 : {
676 0 : OUStringBuffer buf;
677 0 : buf.append( "pq_preparedstatement::setObjectWithInfo: can't convert value of type " );
678 0 : buf.append( x.getValueTypeName() );
679 0 : buf.append( " to type DECIMAL or NUMERIC" );
680 0 : throw SQLException( buf.makeStringAndClear(), *this, OUString(), 1, Any () );
681 0 : }
682 : }
683 : else
684 : {
685 0 : setObject( parameterIndex, x );
686 : }
687 :
688 0 : }
689 :
690 0 : void PreparedStatement::setRef(
691 : sal_Int32 parameterIndex,
692 : const Reference< XRef >& x )
693 : throw (SQLException, RuntimeException, std::exception)
694 : {
695 : (void) parameterIndex; (void)x;
696 : throw SQLException(
697 : "pq_preparedstatement: setRef not implemented",
698 0 : *this, OUString(), 1, Any () );
699 : }
700 :
701 0 : void PreparedStatement::setBlob(
702 : sal_Int32 parameterIndex,
703 : const Reference< XBlob >& x )
704 : throw (SQLException, RuntimeException, std::exception)
705 : {
706 : (void) parameterIndex; (void)x;
707 : throw SQLException(
708 : "pq_preparedstatement: setBlob not implemented",
709 0 : *this, OUString(), 1, Any () );
710 : }
711 :
712 0 : void PreparedStatement::setClob(
713 : sal_Int32 parameterIndex,
714 : const Reference< XClob >& x )
715 : throw (SQLException, RuntimeException, std::exception)
716 : {
717 : (void) parameterIndex; (void)x;
718 : throw SQLException(
719 : "pq_preparedstatement: setClob not implemented",
720 0 : *this, OUString(), 1, Any () );
721 : }
722 :
723 0 : void PreparedStatement::setArray(
724 : sal_Int32 parameterIndex,
725 : const Reference< XArray >& x )
726 : throw (SQLException, RuntimeException, std::exception)
727 : {
728 0 : setString( parameterIndex, array2String( x->getArray( 0 ) ) );
729 0 : }
730 :
731 0 : void PreparedStatement::clearParameters( )
732 : throw (SQLException, RuntimeException, std::exception)
733 : {
734 0 : MutexGuard guard(m_refMutex->mutex );
735 0 : m_vars = OStringVector ( m_vars.size() );
736 0 : }
737 :
738 0 : Any PreparedStatement::getWarnings( )
739 : throw (SQLException,RuntimeException, std::exception)
740 : {
741 0 : return Any();
742 : }
743 :
744 0 : void PreparedStatement::clearWarnings( )
745 : throw (SQLException, RuntimeException, std::exception)
746 : {
747 0 : }
748 :
749 0 : Reference< ::com::sun::star::sdbc::XResultSetMetaData > PreparedStatement::getMetaData()
750 : throw (SQLException,RuntimeException, std::exception)
751 : {
752 0 : Reference< com::sun::star::sdbc::XResultSetMetaData > ret;
753 0 : Reference< com::sun::star::sdbc::XResultSetMetaDataSupplier > supplier( m_lastResultset, UNO_QUERY );
754 0 : if( supplier.is() )
755 0 : ret = supplier->getMetaData();
756 0 : return ret;
757 : }
758 :
759 0 : ::cppu::IPropertyArrayHelper & PreparedStatement::getInfoHelper()
760 : {
761 0 : return getPreparedStatementPropertyArrayHelper();
762 : }
763 :
764 :
765 0 : sal_Bool PreparedStatement::convertFastPropertyValue(
766 : Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue )
767 : throw (IllegalArgumentException)
768 : {
769 : bool bRet;
770 0 : rOldValue = m_props[nHandle];
771 0 : switch( nHandle )
772 : {
773 : case PREPARED_STATEMENT_CURSOR_NAME:
774 : {
775 0 : OUString val;
776 0 : bRet = ( rValue >>= val );
777 0 : rConvertedValue = makeAny( val );
778 0 : break;
779 : }
780 : case PREPARED_STATEMENT_ESCAPE_PROCESSING:
781 : {
782 0 : bool val(false);
783 0 : bRet = ( rValue >>= val );
784 0 : rConvertedValue = makeAny( val );
785 0 : break;
786 : }
787 : case PREPARED_STATEMENT_FETCH_DIRECTION:
788 : case PREPARED_STATEMENT_FETCH_SIZE:
789 : case PREPARED_STATEMENT_MAX_FIELD_SIZE:
790 : case PREPARED_STATEMENT_MAX_ROWS:
791 : case PREPARED_STATEMENT_QUERY_TIME_OUT:
792 : case PREPARED_STATEMENT_RESULT_SET_CONCURRENCY:
793 : case PREPARED_STATEMENT_RESULT_SET_TYPE:
794 : {
795 : sal_Int32 val;
796 0 : bRet = ( rValue >>= val );
797 0 : rConvertedValue = makeAny( val );
798 0 : break;
799 : }
800 : default:
801 : {
802 0 : OUStringBuffer buf(128);
803 0 : buf.appendAscii( "pq_statement: Invalid property handle (" );
804 0 : buf.append( nHandle );
805 0 : buf.appendAscii( ")" );
806 0 : throw IllegalArgumentException( buf.makeStringAndClear(), *this, 2 );
807 : }
808 : }
809 0 : return bRet;
810 : }
811 :
812 :
813 0 : void PreparedStatement::setFastPropertyValue_NoBroadcast(
814 : sal_Int32 nHandle,const Any& rValue ) throw (Exception, std::exception)
815 : {
816 0 : m_props[nHandle] = rValue;
817 0 : }
818 :
819 0 : void PreparedStatement::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
820 : {
821 0 : rValue = m_props[nHandle];
822 0 : }
823 :
824 0 : Reference < XPropertySetInfo > PreparedStatement::getPropertySetInfo()
825 : throw(RuntimeException, std::exception)
826 : {
827 0 : return OPropertySetHelper::createPropertySetInfo( getPreparedStatementPropertyArrayHelper() );
828 : }
829 :
830 0 : void PreparedStatement::disposing()
831 : {
832 0 : close();
833 0 : }
834 :
835 :
836 0 : Reference< XResultSet > PreparedStatement::getResultSet( )
837 : throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
838 : {
839 0 : return Reference< XResultSet > ( m_lastResultset, com::sun::star::uno::UNO_QUERY );
840 : }
841 0 : sal_Int32 PreparedStatement::getUpdateCount( )
842 : throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
843 : {
844 0 : return m_multipleResultUpdateCount;
845 : }
846 0 : sal_Bool PreparedStatement::getMoreResults( )
847 : throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
848 : {
849 0 : return sal_False;
850 : }
851 :
852 0 : Reference< XResultSet > PreparedStatement::getGeneratedValues( )
853 : throw (SQLException, RuntimeException, std::exception)
854 : {
855 0 : osl::MutexGuard guard( m_refMutex->mutex );
856 : return getGeneratedValuesFromLastInsert(
857 0 : m_pSettings, m_connection, m_lastOidInserted, m_lastTableInserted, m_lastQuery );
858 : }
859 :
860 :
861 : }
862 :
863 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|