Branch data 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: 200? 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 <rtl/ustrbuf.hxx>
59 : : #include <rtl/strbuf.hxx>
60 : :
61 : : #include <cppuhelper/queryinterface.hxx>
62 : : #include <cppuhelper/typeprovider.hxx>
63 : :
64 : : #include <com/sun/star/sdbc/XGeneratedResultSet.hpp>
65 : :
66 : : #include "pq_updateableresultset.hxx"
67 : : #include "pq_resultsetmetadata.hxx"
68 : : #include "pq_tools.hxx"
69 : : #include "pq_statics.hxx"
70 : :
71 : : #include <string.h>
72 : :
73 : : using osl::MutexGuard;
74 : :
75 : : using rtl::OUString;
76 : : using rtl::OUStringBuffer;
77 : : using rtl::OStringBuffer;
78 : : using rtl::OString;
79 : :
80 : : using com::sun::star::uno::Reference;
81 : : using com::sun::star::uno::makeAny;
82 : : using com::sun::star::uno::Sequence;
83 : : using com::sun::star::uno::UNO_QUERY;
84 : : using com::sun::star::uno::Any;
85 : : using com::sun::star::uno::Type;
86 : : using com::sun::star::uno::RuntimeException;
87 : :
88 : : using com::sun::star::sdbc::XGeneratedResultSet;
89 : : using com::sun::star::sdbc::XResultSetMetaDataSupplier;
90 : : using com::sun::star::sdbc::SQLException;
91 : : using com::sun::star::sdbc::XResultSet;
92 : : using com::sun::star::sdbc::XCloseable;
93 : : using com::sun::star::sdbc::XColumnLocate;
94 : : using com::sun::star::sdbc::XResultSetUpdate;
95 : : using com::sun::star::sdbc::XRowUpdate;
96 : : using com::sun::star::sdbc::XRow;
97 : : using com::sun::star::sdbc::XStatement;
98 : :
99 : : using com::sun::star::beans::XFastPropertySet;
100 : : using com::sun::star::beans::XPropertySet;
101 : : using com::sun::star::beans::XMultiPropertySet;
102 : :
103 : : #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
104 : :
105 : : namespace pq_sdbc_driver
106 : : {
107 : :
108 : :
109 : 0 : com::sun::star::uno::Reference< com::sun::star::sdbc::XCloseable > UpdateableResultSet::createFromPGResultSet(
110 : : const ::rtl::Reference< RefCountedMutex > & mutex,
111 : : const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &owner,
112 : : ConnectionSettings **ppSettings,
113 : : PGresult *result,
114 : : const rtl::OUString &schema,
115 : : const rtl::OUString &table,
116 : : const com::sun::star::uno::Sequence< ::rtl::OUString > &primaryKey )
117 : : {
118 : 0 : ConnectionSettings *pSettings = *ppSettings;
119 : 0 : sal_Int32 columnCount = PQnfields( result );
120 : 0 : sal_Int32 rowCount = PQntuples( result );
121 : 0 : Sequence< OUString > columnNames( columnCount );
122 : 0 : for( int i = 0 ; i < columnCount ; i ++ )
123 : : {
124 : 0 : char * name = PQfname( result, i );
125 : 0 : columnNames[i] = rtl::OUString( name, strlen(name), pSettings->encoding );
126 : : }
127 : 0 : Sequence< Sequence< Any > > data( rowCount );
128 : :
129 : : // copy all the data into unicode strings (also binaries, as we yet
130 : : // don't know, what a binary is and what not!)
131 : 0 : for( int row = 0 ; row < rowCount ; row ++ )
132 : : {
133 : 0 : Sequence< Any > aRow( columnCount );
134 : 0 : for( int col = 0 ; col < columnCount ; col ++ )
135 : : {
136 : 0 : if( ! PQgetisnull( result, row, col ) )
137 : : {
138 : 0 : char * val = PQgetvalue( result, row, col );
139 : :
140 : 0 : aRow[col] = makeAny(
141 : 0 : rtl::OUString( val, strlen( val ) , (*ppSettings)->encoding ) );
142 : : }
143 : : }
144 : 0 : data[row] = aRow;
145 : 0 : }
146 : :
147 : : UpdateableResultSet *pRS = new UpdateableResultSet(
148 : 0 : mutex, owner, columnNames, data, ppSettings, schema, table , primaryKey );
149 : :
150 : 0 : Reference <XCloseable > ret = pRS; // give it an refcount
151 : :
152 : 0 : pRS->m_meta = new ResultSetMetaData( mutex, pRS,0, ppSettings, result, schema, table );
153 : :
154 : 0 : PQclear( result ); // we don't need it anymore
155 : :
156 : 0 : return ret;
157 : : }
158 : :
159 : 0 : com::sun::star::uno::Any UpdateableResultSet::queryInterface(
160 : : const com::sun::star::uno::Type & reqType )
161 : : throw (com::sun::star::uno::RuntimeException)
162 : : {
163 : 0 : Any ret = SequenceResultSet::queryInterface( reqType );
164 : 0 : if( ! ret.hasValue() )
165 : : ret = ::cppu::queryInterface(
166 : : reqType,
167 : : static_cast< XResultSetUpdate * > ( this ),
168 : 0 : static_cast< XRowUpdate * > ( this ) );
169 : 0 : return ret;
170 : : }
171 : :
172 : :
173 : 0 : com::sun::star::uno::Sequence< com::sun::star::uno::Type > UpdateableResultSet::getTypes()
174 : : throw( com::sun::star::uno::RuntimeException )
175 : : {
176 : : static cppu::OTypeCollection *pCollection;
177 : 0 : if( ! pCollection )
178 : : {
179 : 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
180 : 0 : if( !pCollection )
181 : : {
182 : : static cppu::OTypeCollection collection(
183 : 0 : getCppuType( (Reference< XResultSetUpdate> *) 0 ),
184 : 0 : getCppuType( (Reference< XRowUpdate> *) 0 ),
185 : 0 : SequenceResultSet::getTypes());
186 : 0 : pCollection = &collection;
187 : 0 : }
188 : : }
189 : 0 : return pCollection->getTypes();
190 : :
191 : : }
192 : :
193 : 0 : com::sun::star::uno::Sequence< sal_Int8> UpdateableResultSet::getImplementationId()
194 : : throw( com::sun::star::uno::RuntimeException )
195 : : {
196 : : static cppu::OImplementationId *pId;
197 : 0 : if( ! pId )
198 : : {
199 : 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
200 : 0 : if( ! pId )
201 : : {
202 : 0 : static cppu::OImplementationId id(sal_False);
203 : 0 : pId = &id;
204 : 0 : }
205 : : }
206 : 0 : return pId->getImplementationId();
207 : : }
208 : :
209 : 0 : OUString UpdateableResultSet::buildWhereClause()
210 : : {
211 : 0 : OUString ret;
212 : 0 : if( m_primaryKey.getLength() )
213 : : {
214 : 0 : OUStringBuffer buf( 128 );
215 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " WHERE " ) );
216 : 0 : for( int i = 0 ; i < m_primaryKey.getLength() ; i ++ )
217 : : {
218 : 0 : if( i > 0 )
219 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " AND " ) );
220 : 0 : sal_Int32 index = findColumn( m_primaryKey[i] );
221 : 0 : bufferQuoteIdentifier( buf, m_primaryKey[i], *m_ppSettings );
222 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) );
223 : 0 : bufferQuoteConstant( buf, getString( index ), *m_ppSettings );
224 : : }
225 : 0 : ret = buf.makeStringAndClear();
226 : : }
227 : 0 : return ret;
228 : : }
229 : :
230 : :
231 : 0 : void UpdateableResultSet::insertRow( ) throw (SQLException, RuntimeException)
232 : : {
233 : 0 : MutexGuard guard( m_refMutex->mutex );
234 : 0 : if( isLog( *m_ppSettings, LogLevel::INFO ) )
235 : : {
236 : 0 : log( *m_ppSettings, LogLevel::INFO,"UpdateableResultSet::insertRow got called" );
237 : : }
238 : 0 : if( ! m_insertRow )
239 : : throw SQLException(
240 : : ASCII_STR("pq_resultset.insertRow: moveToInsertRow has not been called !" ),
241 : 0 : *this, OUString(), 1, Any() );
242 : :
243 : 0 : OUStringBuffer buf( 128 );
244 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "INSERT INTO " ) );
245 : 0 : bufferQuoteQualifiedIdentifier( buf, m_schema, m_table, *m_ppSettings );
246 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ( " ) );
247 : :
248 : 0 : int columns = 0;
249 : 0 : for( UpdateableFieldVector::size_type i = 0 ; i < m_updateableField.size() ; i++ )
250 : : {
251 : 0 : if( m_updateableField[i].isTouched )
252 : : {
253 : 0 : if( columns > 0 )
254 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) );
255 : 0 : columns ++;
256 : 0 : bufferQuoteIdentifier( buf, m_columnNames[i], *m_ppSettings);
257 : : }
258 : : }
259 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ) VALUES ( " ) );
260 : :
261 : 0 : columns = 0;
262 : 0 : for( UpdateableFieldVector::size_type i = 0 ; i < m_updateableField.size() ; i ++ )
263 : : {
264 : 0 : if( m_updateableField[i].isTouched )
265 : : {
266 : 0 : if( columns > 0 )
267 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " , " ) );
268 : 0 : columns ++;
269 : 0 : bufferQuoteAnyConstant( buf, m_updateableField[i].value, *m_ppSettings );
270 : :
271 : : // OUString val;
272 : : // m_updateableField[i].value >>= val;
273 : : // buf.append( val );
274 : : // rtl::OStringToOUString(val, (*m_ppSettings)->encoding ) );
275 : : }
276 : : }
277 : :
278 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " )" ) );
279 : :
280 : : Reference< XStatement > stmt =
281 : 0 : extractConnectionFromStatement(m_owner)->createStatement();
282 : 0 : DisposeGuard dispGuard( stmt );
283 : 0 : stmt->executeUpdate( buf.makeStringAndClear() );
284 : :
285 : : // reflect the changes !
286 : 0 : m_rowCount ++;
287 : 0 : m_data.realloc( m_rowCount );
288 : 0 : m_data[m_rowCount-1] = Sequence< Any > ( m_fieldCount );
289 : 0 : Reference< XGeneratedResultSet > result( stmt, UNO_QUERY );
290 : 0 : if( result.is() )
291 : : {
292 : 0 : Reference< XResultSet > rs = result->getGeneratedValues();
293 : 0 : if( rs.is() && rs->next() )
294 : : {
295 : 0 : Reference< XColumnLocate > columnLocate( rs, UNO_QUERY );
296 : 0 : Reference< XRow> xRow ( rs, UNO_QUERY );
297 : 0 : for( int i = 0 ; i < m_fieldCount ; i++ )
298 : : {
299 : 0 : int field = columnLocate->findColumn( m_columnNames[i] );
300 : 0 : if( field >= 1 )
301 : : {
302 : 0 : m_data[m_rowCount-1][i] <<= xRow->getString( field );
303 : : // printf( "adding %s %s\n" ,
304 : : // OUStringToOString( m_columnNames[i], RTL_TEXTENCODING_ASCII_US).getStr(),
305 : : // OUStringToOString( xRow->getString( field ), RTL_TEXTENCODING_ASCII_US).getStr() );
306 : :
307 : : }
308 : 0 : }
309 : : }
310 : : else
311 : : {
312 : : // do the best we can ( DEFAULT and AUTO increment values fail ! )
313 : 0 : for( int i = 0 ; i < m_fieldCount ; i ++ )
314 : : {
315 : 0 : if( m_updateableField[i].isTouched )
316 : 0 : m_data[m_rowCount-1][i] = m_updateableField[i].value;
317 : : }
318 : 0 : }
319 : : }
320 : :
321 : : // cleanup
322 : 0 : m_updateableField = UpdateableFieldVector();
323 : 0 : }
324 : :
325 : 0 : void UpdateableResultSet::updateRow( ) throw (SQLException, RuntimeException)
326 : : {
327 : 0 : MutexGuard guard( m_refMutex->mutex );
328 : 0 : if( isLog( *m_ppSettings, LogLevel::INFO ) )
329 : : {
330 : 0 : log( *m_ppSettings, LogLevel::INFO,"UpdateableResultSet::updateRow got called" );
331 : : }
332 : 0 : if( m_insertRow )
333 : : throw SQLException(
334 : : ASCII_STR("pq_resultset.updateRow: moveToCurrentRow has not been called !" ),
335 : 0 : *this, OUString(), 1, Any() );
336 : :
337 : 0 : OUStringBuffer buf( 128 );
338 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "UPDATE " ) );
339 : 0 : bufferQuoteQualifiedIdentifier( buf, m_schema, m_table, *m_ppSettings );
340 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SET " ) );
341 : :
342 : 0 : int columns = 0;
343 : 0 : for( UpdateableFieldVector::size_type i = 0; i < m_updateableField.size() ; i ++ )
344 : : {
345 : 0 : if( m_updateableField[i].isTouched )
346 : : {
347 : 0 : if( columns > 0 )
348 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) );
349 : 0 : columns ++;
350 : :
351 : 0 : buf.append( m_columnNames[i] );
352 : 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = " ) );
353 : 0 : bufferQuoteAnyConstant( buf, m_updateableField[i].value, *m_ppSettings );
354 : : // OUString val;
355 : : // m_updateableField[i].value >>= val;
356 : : // bufferQuoteConstant( buf, val ):
357 : : // buf.append( val );
358 : : }
359 : : }
360 : 0 : buf.append( buildWhereClause() );
361 : :
362 : 0 : Reference< XStatement > stmt = extractConnectionFromStatement(m_owner)->createStatement();
363 : 0 : DisposeGuard dispGuard( stmt );
364 : 0 : stmt->executeUpdate( buf.makeStringAndClear() );
365 : :
366 : : // reflect the changes !
367 : 0 : for( int i = 0 ; i < m_fieldCount ; i ++ )
368 : : {
369 : 0 : if( m_updateableField[i].isTouched )
370 : 0 : m_data[m_row][i] = m_updateableField[i].value;
371 : : }
372 : 0 : m_updateableField = UpdateableFieldVector();
373 : 0 : }
374 : :
375 : 0 : void UpdateableResultSet::deleteRow( ) throw (SQLException, RuntimeException)
376 : : {
377 : 0 : if( isLog( *m_ppSettings, LogLevel::INFO ) )
378 : : {
379 : 0 : log( *m_ppSettings, LogLevel::INFO,"UpdateableResultSet::deleteRow got called" );
380 : : }
381 : 0 : if( m_insertRow )
382 : : throw SQLException(
383 : : ASCII_STR("pq_resultset.deleteRow: deleteRow cannot be called when on insert row !" ),
384 : 0 : *this, OUString(), 1, Any() );
385 : :
386 : 0 : if( m_row < 0 || m_row >= m_rowCount )
387 : : {
388 : 0 : OUStringBuffer buf( 128 );
389 : 0 : buf.appendAscii( "deleteRow cannot be called on invalid row (" );
390 : 0 : buf.append( m_row );
391 : 0 : buf.appendAscii( ")" );
392 : 0 : throw SQLException( buf.makeStringAndClear() , *this, OUString(), 0, Any() );
393 : : }
394 : :
395 : 0 : Reference< XStatement > stmt = extractConnectionFromStatement(m_owner)->createStatement();
396 : 0 : DisposeGuard dispGuard( stmt );
397 : 0 : OUStringBuffer buf( 128 );
398 : 0 : buf.appendAscii( "DELETE FROM " );
399 : 0 : bufferQuoteQualifiedIdentifier( buf, m_schema, m_table, *m_ppSettings );
400 : 0 : buf.appendAscii( " " );
401 : 0 : buf.append( buildWhereClause() );
402 : :
403 : 0 : stmt->executeUpdate( buf.makeStringAndClear() );
404 : :
405 : : // reflect the changes !
406 : 0 : for( int i = m_row + 1; i < m_row ; i ++ )
407 : : {
408 : 0 : m_data[i-1] = m_data[i];
409 : : }
410 : 0 : m_rowCount --;
411 : 0 : m_data.realloc( m_rowCount );
412 : 0 : }
413 : :
414 : 0 : void UpdateableResultSet::cancelRowUpdates( ) throw (SQLException, RuntimeException)
415 : : {
416 : 0 : MutexGuard guard( m_refMutex->mutex );
417 : 0 : m_updateableField = UpdateableFieldVector();
418 : 0 : }
419 : :
420 : 0 : void UpdateableResultSet::moveToInsertRow( ) throw (SQLException, RuntimeException)
421 : : {
422 : 0 : m_insertRow = true;
423 : 0 : }
424 : :
425 : 0 : void UpdateableResultSet::moveToCurrentRow( ) throw (SQLException, RuntimeException)
426 : : {
427 : 0 : m_insertRow = false;
428 : 0 : }
429 : :
430 : 0 : void UpdateableResultSet::checkUpdate( sal_Int32 columnIndex)
431 : : {
432 : 0 : checkColumnIndex( columnIndex );
433 : 0 : if( m_updateableField.empty() )
434 : 0 : m_updateableField = UpdateableFieldVector( m_fieldCount );
435 : 0 : m_updateableField[columnIndex-1].isTouched = true;
436 : 0 : }
437 : :
438 : 0 : void UpdateableResultSet::updateNull( sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
439 : : {
440 : 0 : MutexGuard guard( m_refMutex->mutex );
441 : 0 : checkClosed();
442 : 0 : checkUpdate( columnIndex );
443 : 0 : m_updateableField[columnIndex-1].value = Any();
444 : 0 : }
445 : :
446 : 0 : void UpdateableResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw (SQLException, RuntimeException)
447 : : {
448 : 0 : MutexGuard guard( m_refMutex->mutex );
449 : 0 : checkClosed();
450 : 0 : checkUpdate( columnIndex );
451 : :
452 : 0 : Statics &st = getStatics();
453 : 0 : if( x )
454 : 0 : m_updateableField[columnIndex-1].value <<= ( x ? st.TRUE : st.FALSE );
455 : :
456 : 0 : }
457 : :
458 : 0 : void UpdateableResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw (SQLException, RuntimeException)
459 : : {
460 : 0 : updateInt(columnIndex,x);
461 : 0 : }
462 : :
463 : 0 : void UpdateableResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw (SQLException, RuntimeException)
464 : : {
465 : 0 : updateInt( columnIndex, x );
466 : 0 : }
467 : :
468 : 0 : void UpdateableResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw (SQLException, RuntimeException)
469 : : {
470 : 0 : updateLong( columnIndex, x );
471 : : // MutexGuard guard( m_refMutex->mutex );
472 : : // checkClosed();
473 : : // checkUpdate( columnIndex );
474 : :
475 : : // m_updateableField[columnIndex-1].value <<= OUString::valueOf( x );
476 : :
477 : 0 : }
478 : :
479 : 0 : void UpdateableResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw (SQLException, RuntimeException)
480 : : {
481 : 0 : MutexGuard guard( m_refMutex->mutex );
482 : 0 : checkClosed();
483 : 0 : checkUpdate( columnIndex );
484 : :
485 : : // OStringBuffer buf( 20 );
486 : : // buf.append( "'" );
487 : : // buf.append( (sal_Int64) x );
488 : : // buf.append( "'" );
489 : 0 : m_updateableField[columnIndex-1].value <<= OUString::valueOf( x );
490 : 0 : }
491 : :
492 : 0 : void UpdateableResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw (SQLException, RuntimeException)
493 : : {
494 : :
495 : 0 : MutexGuard guard( m_refMutex->mutex );
496 : 0 : checkClosed();
497 : 0 : checkUpdate( columnIndex );
498 : :
499 : 0 : m_updateableField[columnIndex-1].value <<= OUString::valueOf( x );
500 : 0 : }
501 : :
502 : 0 : void UpdateableResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw (SQLException, RuntimeException)
503 : : {
504 : 0 : MutexGuard guard( m_refMutex->mutex );
505 : 0 : checkClosed();
506 : 0 : checkUpdate( columnIndex );
507 : :
508 : 0 : m_updateableField[columnIndex-1].value <<= OUString::valueOf( x );
509 : 0 : }
510 : :
511 : 0 : void UpdateableResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw (SQLException, RuntimeException)
512 : : {
513 : 0 : MutexGuard guard( m_refMutex->mutex );
514 : 0 : checkClosed();
515 : 0 : checkUpdate( columnIndex );
516 : :
517 : 0 : m_updateableField[columnIndex-1].value <<= x;
518 : 0 : }
519 : :
520 : 0 : void UpdateableResultSet::updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw (SQLException, RuntimeException)
521 : : {
522 : 0 : MutexGuard guard( m_refMutex->mutex );
523 : 0 : checkClosed();
524 : 0 : checkUpdate( columnIndex );
525 : :
526 : : size_t len;
527 : : unsigned char * escapedString =
528 : 0 : PQescapeBytea( (unsigned char *)x.getConstArray(), x.getLength(), &len);
529 : 0 : if( ! escapedString )
530 : : {
531 : : throw SQLException(
532 : : ASCII_STR("pq_preparedstatement.setBytes: Error during converting bytesequence to an SQL conform string" ),
533 : 0 : *this, OUString(), 1, Any() );
534 : : }
535 : : // buf.append( (const sal_Char *)escapedString, len -1 );
536 : :
537 : 0 : m_updateableField[columnIndex-1].value <<=
538 : 0 : OUString( (sal_Char*) escapedString, len, RTL_TEXTENCODING_ASCII_US );
539 : 0 : free( escapedString );
540 : 0 : }
541 : :
542 : 0 : void UpdateableResultSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw (SQLException, RuntimeException)
543 : : {
544 : 0 : updateString( columnIndex, date2String( x ) );
545 : 0 : }
546 : :
547 : 0 : void UpdateableResultSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw (SQLException, RuntimeException)
548 : : {
549 : 0 : updateString( columnIndex, time2String( x ) );
550 : 0 : }
551 : :
552 : 0 : void UpdateableResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw (SQLException, RuntimeException)
553 : : {
554 : 0 : updateString( columnIndex, dateTime2String( x ) );
555 : 0 : }
556 : :
557 : 0 : void UpdateableResultSet::updateBinaryStream( sal_Int32 /* columnIndex */, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& /* x */, sal_Int32 /* length */ ) throw (SQLException, RuntimeException)
558 : : {
559 : 0 : }
560 : :
561 : 0 : void UpdateableResultSet::updateCharacterStream( sal_Int32 /* columnIndex */, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& /* x */, sal_Int32 /* length */ ) throw (SQLException, RuntimeException)
562 : : {
563 : 0 : }
564 : :
565 : 0 : void UpdateableResultSet::updateObject( sal_Int32 /* columnIndex */, const ::com::sun::star::uno::Any& /* x */ ) throw (SQLException, RuntimeException)
566 : : {
567 : 0 : }
568 : :
569 : 0 : void UpdateableResultSet::updateNumericObject( sal_Int32 /* columnIndex */, const ::com::sun::star::uno::Any& /* x */, sal_Int32 /* scale */ ) throw (SQLException, RuntimeException)
570 : : {
571 : 0 : }
572 : :
573 : :
574 : 0 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > UpdateableResultSet::getMetaData( )
575 : : throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
576 : : {
577 : 0 : return m_meta;
578 : : }
579 : :
580 : 0 : Sequence< Type > UpdateableResultSet::getStaticTypes( bool updateable )
581 : : throw( com::sun::star::uno::RuntimeException )
582 : : {
583 : 0 : if( updateable )
584 : : {
585 : : cppu::OTypeCollection collection(
586 : 0 : getCppuType( (Reference< XResultSetUpdate> *) 0 ),
587 : 0 : getCppuType( (Reference< XRowUpdate> *) 0 ),
588 : : // getCppuType( (Reference< com::sun::star::sdbcx::XRowLocate > *) 0 ),
589 : 0 : getStaticTypes( false /* updateable */ ) );
590 : 0 : return collection.getTypes();
591 : : }
592 : : else
593 : : {
594 : : cppu::OTypeCollection collection(
595 : 0 : getCppuType( (Reference< XResultSet> *) 0 ),
596 : 0 : getCppuType( (Reference< XResultSetMetaDataSupplier> *) 0 ),
597 : 0 : getCppuType( (Reference< XRow> *) 0 ),
598 : 0 : getCppuType( (Reference< XColumnLocate> *) 0 ),
599 : 0 : getCppuType( (Reference< XCloseable> *) 0 ),
600 : 0 : getCppuType( (Reference< XPropertySet >*) 0 ),
601 : 0 : getCppuType( (Reference< XFastPropertySet > *) 0 ),
602 : 0 : getCppuType( (Reference< XMultiPropertySet > *) 0 ),
603 : 0 : getCppuType( (const Reference< com::sun::star::lang::XComponent > *)0 ), // OComponentHelper
604 : 0 : getCppuType( (const Reference< com::sun::star::lang::XTypeProvider > *)0 ),
605 : 0 : getCppuType( (const Reference< com::sun::star::uno::XAggregation > *)0 ),
606 : 0 : getCppuType( (const Reference< com::sun::star::uno::XWeak > *)0 ) );
607 : 0 : return collection.getTypes();
608 : : }
609 : : }
610 : :
611 : : }
|