Update ooo320-m1
[ooovba.git] / ucbhelper / source / provider / resultsetmetadata.cxx
blob38c857100cc688df73cd9c5d33f8f518b3a41908
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: resultsetmetadata.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucbhelper.hxx"
34 /**************************************************************************
35 TODO
36 **************************************************************************
38 *************************************************************************/
40 #include "osl/diagnose.h"
41 #include <com/sun/star/beans/Property.hpp>
42 #include <com/sun/star/beans/XPropertySetInfo.hpp>
43 #include <com/sun/star/io/XInputStream.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 #include <com/sun/star/sdbc/DataType.hpp>
46 #include <com/sun/star/sdbc/XArray.hpp>
47 #include <com/sun/star/sdbc/XBlob.hpp>
48 #include <com/sun/star/sdbc/XClob.hpp>
49 #include <com/sun/star/sdbc/XRef.hpp>
50 #include <com/sun/star/util/Date.hpp>
51 #include <com/sun/star/util/Time.hpp>
52 #include <com/sun/star/util/DateTime.hpp>
53 #include <ucbhelper/resultsetmetadata.hxx>
55 using namespace com::sun::star::beans;
56 using namespace com::sun::star::io;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::sdbc;
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star::util;
61 using namespace rtl;
63 namespace ucbhelper_impl {
65 struct ResultSetMetaData_Impl
67 osl::Mutex m_aMutex;
68 std::vector< ::ucbhelper::ResultSetColumnData > m_aColumnData;
69 sal_Bool m_bObtainedTypes;
70 sal_Bool m_bGlobalReadOnlyValue;
72 ResultSetMetaData_Impl( sal_Int32 nSize )
73 : m_aColumnData( nSize ), m_bObtainedTypes( sal_False ),
74 m_bGlobalReadOnlyValue( sal_True ) {}
76 ResultSetMetaData_Impl(
77 const std::vector< ::ucbhelper::ResultSetColumnData >& rColumnData )
78 : m_aColumnData( rColumnData ), m_bObtainedTypes( sal_False ),
79 m_bGlobalReadOnlyValue( sal_False ) {}
84 using namespace ucbhelper_impl;
86 namespace ucbhelper {
88 //=========================================================================
89 //=========================================================================
91 // ResultSetMetaData Implementation.
93 //=========================================================================
94 //=========================================================================
96 ResultSetMetaData::ResultSetMetaData(
97 const Reference< XMultiServiceFactory >& rxSMgr,
98 const Sequence< Property >& rProps,
99 sal_Bool bReadOnly )
100 : m_pImpl( new ResultSetMetaData_Impl( rProps.getLength() ) ),
101 m_xSMgr( rxSMgr ),
102 m_aProps( rProps ),
103 m_bReadOnly( bReadOnly )
107 //=========================================================================
108 ResultSetMetaData::ResultSetMetaData(
109 const Reference< XMultiServiceFactory >& rxSMgr,
110 const Sequence< Property >& rProps,
111 const std::vector< ResultSetColumnData >& rColumnData )
112 : m_pImpl( new ResultSetMetaData_Impl( rColumnData ) ),
113 m_xSMgr( rxSMgr ),
114 m_aProps( rProps ),
115 m_bReadOnly( sal_True )
117 OSL_ENSURE( rColumnData.size() == sal_uInt32( rProps.getLength() ),
118 "ResultSetMetaData ctor - different array sizes!" );
121 //=========================================================================
122 // virtual
123 ResultSetMetaData::~ResultSetMetaData()
125 delete m_pImpl;
128 //=========================================================================
130 // XInterface methods.
132 //=========================================================================
134 XINTERFACE_IMPL_2( ResultSetMetaData,
135 XTypeProvider,
136 XResultSetMetaData );
138 //=========================================================================
140 // XTypeProvider methods.
142 //=========================================================================
144 XTYPEPROVIDER_IMPL_2( ResultSetMetaData,
145 XTypeProvider,
146 XResultSetMetaData );
148 //=========================================================================
150 // XResultSetMetaData methods.
152 //=========================================================================
154 // virtual
155 sal_Int32 SAL_CALL ResultSetMetaData::getColumnCount()
156 throw( SQLException, RuntimeException )
158 return m_aProps.getLength();
161 //=========================================================================
162 // virtual
163 sal_Bool SAL_CALL ResultSetMetaData::isAutoIncrement( sal_Int32 column )
164 throw( SQLException, RuntimeException )
167 Checks whether column is automatically numbered, which makes it
168 read-only.
171 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
172 return sal_False;
174 return m_pImpl->m_aColumnData[ column - 1 ].isAutoIncrement;
177 //=========================================================================
178 // virtual
179 sal_Bool SAL_CALL ResultSetMetaData::isCaseSensitive( sal_Int32 column )
180 throw( SQLException, RuntimeException )
182 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
183 return sal_False;
185 return m_pImpl->m_aColumnData[ column - 1 ].isCaseSensitive;
188 //=========================================================================
189 // virtual
190 sal_Bool SAL_CALL ResultSetMetaData::isSearchable( sal_Int32 column )
191 throw( SQLException, RuntimeException )
194 Checks whether the value stored in column can be used in a
195 WHERE clause.
198 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
199 return sal_False;
201 return m_pImpl->m_aColumnData[ column - 1 ].isSearchable;
204 //=========================================================================
205 // virtual
206 sal_Bool SAL_CALL ResultSetMetaData::isCurrency( sal_Int32 column )
207 throw( SQLException, RuntimeException )
210 Checks whether column is a cash value.
213 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
214 return sal_False;
216 return m_pImpl->m_aColumnData[ column - 1 ].isCurrency;
219 //=========================================================================
220 // virtual
221 sal_Int32 SAL_CALL ResultSetMetaData::isNullable( sal_Int32 column )
222 throw( SQLException, RuntimeException )
225 Checks whether a NULL can be stored in column.
226 Possible values: see com/sun/star/sdbc/ColumnValue.idl
229 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
230 return ColumnValue::NULLABLE;
232 return m_pImpl->m_aColumnData[ column - 1 ].isNullable;
235 //=========================================================================
236 // virtual
237 sal_Bool SAL_CALL ResultSetMetaData::isSigned( sal_Int32 column )
238 throw( SQLException, RuntimeException )
241 Checks whether the value stored in column is a signed number.
244 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
245 return sal_False;
247 return m_pImpl->m_aColumnData[ column - 1 ].isSigned;
250 //=========================================================================
251 // virtual
252 sal_Int32 SAL_CALL ResultSetMetaData::getColumnDisplaySize( sal_Int32 column )
253 throw( SQLException, RuntimeException )
256 Gets the normal maximum width in characters for column.
259 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
260 return 16;
262 return m_pImpl->m_aColumnData[ column - 1 ].columnDisplaySize;
265 //=========================================================================
266 // virtual
267 OUString SAL_CALL ResultSetMetaData::getColumnLabel( sal_Int32 column )
268 throw( SQLException, RuntimeException )
271 Gets the suggested column title for column, to be used in print-
272 outs and displays.
275 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
276 return OUString();
278 OUString aLabel = m_pImpl->m_aColumnData[ column - 1 ].columnLabel;
279 if ( aLabel.getLength() )
280 return aLabel;
282 return m_aProps.getConstArray()[ column - 1 ].Name;
285 //=========================================================================
286 // virtual
287 OUString SAL_CALL ResultSetMetaData::getColumnName( sal_Int32 column )
288 throw( SQLException, RuntimeException )
291 Gets the name of column.
294 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
295 return OUString();
297 return m_aProps.getConstArray()[ column - 1 ].Name;
300 //=========================================================================
301 // virtual
302 OUString SAL_CALL ResultSetMetaData::getSchemaName( sal_Int32 column )
303 throw( SQLException, RuntimeException )
306 Gets the schema name for the table from which column of this
307 result set was derived.
308 Because this feature is not widely supported, the return value
309 for many DBMSs will be an empty string.
312 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
313 return OUString();
315 return m_pImpl->m_aColumnData[ column - 1 ].schemaName;
318 //=========================================================================
319 // virtual
320 sal_Int32 SAL_CALL ResultSetMetaData::getPrecision( sal_Int32 column )
321 throw( SQLException, RuntimeException )
324 For number types, getprecision gets the number of decimal digits
325 in column.
326 For character types, it gets the maximum length in characters for
327 column.
328 For binary types, it gets the maximum length in bytes for column.
331 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
332 return -1;
334 return m_pImpl->m_aColumnData[ column - 1 ].precision;
337 //=========================================================================
338 // virtual
339 sal_Int32 SAL_CALL ResultSetMetaData::getScale( sal_Int32 column )
340 throw( SQLException, RuntimeException )
343 Gets the number of digits to the right of the decimal point for
344 values in column.
347 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
348 return 0;
350 return m_pImpl->m_aColumnData[ column - 1 ].scale;
353 //=========================================================================
354 // virtual
355 OUString SAL_CALL ResultSetMetaData::getTableName( sal_Int32 column )
356 throw( SQLException, RuntimeException )
359 Gets the name of the table from which column of this result set
360 was derived or "" if there is none (for example, for a join).
361 Because this feature is not widely supported, the return value
362 for many DBMSs will be an empty string.
365 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
366 return OUString();
368 return m_pImpl->m_aColumnData[ column - 1 ].tableName;
371 //=========================================================================
372 // virtual
373 OUString SAL_CALL ResultSetMetaData::getCatalogName( sal_Int32 column )
374 throw( SQLException, RuntimeException )
377 Gets the catalog name for the table from which column of this
378 result set was derived.
379 Because this feature is not widely supported, the return value
380 for many DBMSs will be an empty string.
383 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
384 return OUString();
386 return m_pImpl->m_aColumnData[ column - 1 ].catalogName;
389 //=========================================================================
390 // virtual
391 sal_Int32 SAL_CALL ResultSetMetaData::getColumnType( sal_Int32 column )
392 throw( SQLException, RuntimeException )
395 Gets the JDBC type for the value stored in column. ... The STRUCT
396 and DISTINCT type codes are always returned for structured and
397 distinct types, regardless of whether the value will be mapped
398 according to the standard mapping or be a custom mapping.
401 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
402 return DataType::SQLNULL;
404 if ( m_aProps.getConstArray()[ column - 1 ].Type
405 == getCppuVoidType() )
407 // No type given. Try UCB's Properties Manager...
409 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
411 if ( !m_pImpl->m_bObtainedTypes )
415 Reference< XPropertySetInfo > xInfo(
416 m_xSMgr->createInstance(
417 OUString::createFromAscii(
418 "com.sun.star.ucb.PropertiesManager" ) ),
419 UNO_QUERY );
420 if ( xInfo.is() )
422 #if 0
423 // Convenient...
425 sal_Int32 nCount = m_pImpl->m_aProps.getLength();
426 Property* pProps = m_pImpl->m_aProps.getArray();
427 for ( sal_Int32 n = 0; n < nCount; ++n )
429 Property& rProp = pProps[ n ];
433 Property aProp
434 = xInfo->getPropertyByName( rProp.Name );
435 rProp.Type = aProp.Type;
437 catch ( UnknownPropertyException& )
439 // getPropertyByName
442 #else
443 // Less (remote) calls...
445 Sequence< Property > aProps = xInfo->getProperties();
446 const Property* pProps1 = aProps.getConstArray();
447 sal_Int32 nCount1 = aProps.getLength();
449 sal_Int32 nCount = m_aProps.getLength();
450 Property* pProps = m_aProps.getArray();
451 for ( sal_Int32 n = 0; n < nCount; ++n )
453 Property& rProp = pProps[ n ];
455 for ( sal_Int32 m = 0; m < nCount1; ++m )
457 const Property& rProp1 = pProps1[ m ];
458 if ( rProp.Name == rProp1.Name )
460 // Found...
461 rProp.Type = rProp1.Type;
462 break;
466 #endif
469 catch ( RuntimeException& )
471 throw;
473 catch ( Exception& )
475 // createInstance
478 m_pImpl->m_bObtainedTypes = sal_True;
482 const Type& rType = m_aProps.getConstArray()[ column - 1 ].Type;
483 sal_Int32 nType = DataType::OTHER;
485 if ( rType == getCppuType( static_cast< const rtl::OUString * >( 0 ) ) )
486 nType = DataType::VARCHAR; // XRow::getString
487 else if ( rType == getCppuBooleanType() )
488 nType = DataType::BIT; // XRow::getBoolean
489 else if ( rType == getCppuType( static_cast< const sal_Int32 * >( 0 ) ) )
490 nType = DataType::INTEGER; // XRow::getInt
491 else if ( rType == getCppuType( static_cast< const sal_Int64 * >( 0 ) ) )
492 nType = DataType::BIGINT; // XRow::getLong
493 else if ( rType == getCppuType( static_cast< const sal_Int16 * >( 0 ) ) )
494 nType = DataType::SMALLINT; // XRow::getShort
495 else if ( rType == getCppuType( static_cast< const sal_Int8 * >( 0 ) ) )
496 nType = DataType::TINYINT; // XRow::getByte
497 else if ( rType == getCppuType( static_cast< const float * >( 0 ) ) )
498 nType = DataType::REAL; // XRow::getFloat
499 else if ( rType == getCppuType( static_cast< const double * >( 0 ) ) )
500 nType = DataType::DOUBLE; // XRow::getDouble
501 else if ( rType == getCppuType( static_cast< const Sequence< sal_Int8 > * >( 0 ) ) )
502 nType = DataType::VARBINARY;// XRow::getBytes
503 else if ( rType == getCppuType( static_cast< const Date * >( 0 ) ) )
504 nType = DataType::DATE; // XRow::getDate
505 else if ( rType == getCppuType( static_cast< const Time * >( 0 ) ) )
506 nType = DataType::TIME; // XRow::getTime
507 else if ( rType == getCppuType( static_cast< const DateTime * >( 0 ) ) )
508 nType = DataType::TIMESTAMP;// XRow::getTimestamp
509 else if ( rType == getCppuType( static_cast< Reference< XInputStream > * >( 0 ) ) )
510 nType = DataType::LONGVARBINARY; // XRow::getBinaryStream
511 // nType = DataType::LONGVARCHAR; // XRow::getCharacterStream
512 else if ( rType == getCppuType( static_cast< Reference< XClob > * >( 0 ) ) )
513 nType = DataType::CLOB; // XRow::getClob
514 else if ( rType == getCppuType( static_cast< Reference< XBlob > * >( 0 ) ) )
515 nType = DataType::BLOB; // XRow::getBlob
516 else if ( rType == getCppuType( static_cast< Reference< XArray > * >( 0 ) ) )
517 nType = DataType::ARRAY;// XRow::getArray
518 else if ( rType == getCppuType( static_cast< Reference< XRef > * >( 0 ) ) )
519 nType = DataType::REF;// XRow::getRef
520 else
521 nType = DataType::OBJECT;// XRow::getObject
523 return nType;
526 //=========================================================================
527 // virtual
528 OUString SAL_CALL ResultSetMetaData::getColumnTypeName( sal_Int32 column )
529 throw( SQLException, RuntimeException )
532 Gets the type name used by this particular data source for the
533 values stored in column. If the type code for the type of value
534 stored in column is STRUCT, DISTINCT or JAVA_OBJECT, this method
535 returns a fully-qualified SQL type name.
538 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
539 return OUString();
541 return m_pImpl->m_aColumnData[ column - 1 ].columnTypeName;
544 //=========================================================================
545 // virtual
546 sal_Bool SAL_CALL ResultSetMetaData::isReadOnly( sal_Int32 column )
547 throw( SQLException, RuntimeException )
549 if ( m_pImpl->m_bGlobalReadOnlyValue )
550 return m_bReadOnly;
552 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
553 return sal_True;
555 // autoincrement==true => readonly
556 return m_pImpl->m_aColumnData[ column - 1 ].isAutoIncrement ||
557 m_pImpl->m_aColumnData[ column - 1 ].isReadOnly;
560 //=========================================================================
561 // virtual
562 sal_Bool SAL_CALL ResultSetMetaData::isWritable( sal_Int32 column )
563 throw( SQLException, RuntimeException )
565 if ( m_pImpl->m_bGlobalReadOnlyValue )
566 return !m_bReadOnly;
568 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
569 return sal_False;
571 return m_pImpl->m_aColumnData[ column - 1 ].isWritable;
574 //=========================================================================
575 // virtual
576 sal_Bool SAL_CALL ResultSetMetaData::isDefinitelyWritable( sal_Int32 column )
577 throw( SQLException, RuntimeException )
579 if ( m_pImpl->m_bGlobalReadOnlyValue )
580 return !m_bReadOnly;
582 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
583 return sal_False;
585 return m_pImpl->m_aColumnData[ column - 1 ].isDefinitelyWritable;
588 //=========================================================================
589 // virtual
590 OUString SAL_CALL ResultSetMetaData::getColumnServiceName( sal_Int32 column )
591 throw( SQLException, RuntimeException )
594 Returns the fully-qualified name of the service whose instances
595 are manufactured if XResultSet::getObject is called to retrieve
596 a value from the column.
599 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
600 return OUString();
602 return m_pImpl->m_aColumnData[ column - 1 ].columnServiceName;
605 } // namespace ucbhelper