1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: resultsetmetadata.cxx,v $
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 /**************************************************************************
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
;
63 namespace ucbhelper_impl
{
65 struct ResultSetMetaData_Impl
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
;
88 //=========================================================================
89 //=========================================================================
91 // ResultSetMetaData Implementation.
93 //=========================================================================
94 //=========================================================================
96 ResultSetMetaData::ResultSetMetaData(
97 const Reference
< XMultiServiceFactory
>& rxSMgr
,
98 const Sequence
< Property
>& rProps
,
100 : m_pImpl( new ResultSetMetaData_Impl( rProps
.getLength() ) ),
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
) ),
115 m_bReadOnly( sal_True
)
117 OSL_ENSURE( rColumnData
.size() == sal_uInt32( rProps
.getLength() ),
118 "ResultSetMetaData ctor - different array sizes!" );
121 //=========================================================================
123 ResultSetMetaData::~ResultSetMetaData()
128 //=========================================================================
130 // XInterface methods.
132 //=========================================================================
134 XINTERFACE_IMPL_2( ResultSetMetaData
,
136 XResultSetMetaData
);
138 //=========================================================================
140 // XTypeProvider methods.
142 //=========================================================================
144 XTYPEPROVIDER_IMPL_2( ResultSetMetaData
,
146 XResultSetMetaData
);
148 //=========================================================================
150 // XResultSetMetaData methods.
152 //=========================================================================
155 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnCount()
156 throw( SQLException
, RuntimeException
)
158 return m_aProps
.getLength();
161 //=========================================================================
163 sal_Bool SAL_CALL
ResultSetMetaData::isAutoIncrement( sal_Int32 column
)
164 throw( SQLException
, RuntimeException
)
167 Checks whether column is automatically numbered, which makes it
171 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
174 return m_pImpl
->m_aColumnData
[ column
- 1 ].isAutoIncrement
;
177 //=========================================================================
179 sal_Bool SAL_CALL
ResultSetMetaData::isCaseSensitive( sal_Int32 column
)
180 throw( SQLException
, RuntimeException
)
182 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
185 return m_pImpl
->m_aColumnData
[ column
- 1 ].isCaseSensitive
;
188 //=========================================================================
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
198 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
201 return m_pImpl
->m_aColumnData
[ column
- 1 ].isSearchable
;
204 //=========================================================================
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() ) )
216 return m_pImpl
->m_aColumnData
[ column
- 1 ].isCurrency
;
219 //=========================================================================
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 //=========================================================================
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() ) )
247 return m_pImpl
->m_aColumnData
[ column
- 1 ].isSigned
;
250 //=========================================================================
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() ) )
262 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnDisplaySize
;
265 //=========================================================================
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-
275 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
278 OUString aLabel
= m_pImpl
->m_aColumnData
[ column
- 1 ].columnLabel
;
279 if ( aLabel
.getLength() )
282 return m_aProps
.getConstArray()[ column
- 1 ].Name
;
285 //=========================================================================
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() ) )
297 return m_aProps
.getConstArray()[ column
- 1 ].Name
;
300 //=========================================================================
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() ) )
315 return m_pImpl
->m_aColumnData
[ column
- 1 ].schemaName
;
318 //=========================================================================
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
326 For character types, it gets the maximum length in characters for
328 For binary types, it gets the maximum length in bytes for column.
331 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
334 return m_pImpl
->m_aColumnData
[ column
- 1 ].precision
;
337 //=========================================================================
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
347 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
350 return m_pImpl
->m_aColumnData
[ column
- 1 ].scale
;
353 //=========================================================================
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() ) )
368 return m_pImpl
->m_aColumnData
[ column
- 1 ].tableName
;
371 //=========================================================================
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() ) )
386 return m_pImpl
->m_aColumnData
[ column
- 1 ].catalogName
;
389 //=========================================================================
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" ) ),
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
];
434 = xInfo
->getPropertyByName( rProp
.Name
);
435 rProp
.Type
= aProp
.Type
;
437 catch ( UnknownPropertyException
& )
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
)
461 rProp
.Type
= rProp1
.Type
;
469 catch ( RuntimeException
& )
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
521 nType
= DataType::OBJECT
;// XRow::getObject
526 //=========================================================================
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() ) )
541 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnTypeName
;
544 //=========================================================================
546 sal_Bool SAL_CALL
ResultSetMetaData::isReadOnly( sal_Int32 column
)
547 throw( SQLException
, RuntimeException
)
549 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
552 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
555 // autoincrement==true => readonly
556 return m_pImpl
->m_aColumnData
[ column
- 1 ].isAutoIncrement
||
557 m_pImpl
->m_aColumnData
[ column
- 1 ].isReadOnly
;
560 //=========================================================================
562 sal_Bool SAL_CALL
ResultSetMetaData::isWritable( sal_Int32 column
)
563 throw( SQLException
, RuntimeException
)
565 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
568 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
571 return m_pImpl
->m_aColumnData
[ column
- 1 ].isWritable
;
574 //=========================================================================
576 sal_Bool SAL_CALL
ResultSetMetaData::isDefinitelyWritable( sal_Int32 column
)
577 throw( SQLException
, RuntimeException
)
579 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
582 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
585 return m_pImpl
->m_aColumnData
[ column
- 1 ].isDefinitelyWritable
;
588 //=========================================================================
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() ) )
602 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnServiceName
;
605 } // namespace ucbhelper