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