1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
27 #include "osl/diagnose.h"
28 #include <com/sun/star/beans/Property.hpp>
29 #include <com/sun/star/beans/XPropertySetInfo.hpp>
30 #include <com/sun/star/io/XInputStream.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/sdbc/DataType.hpp>
33 #include <com/sun/star/sdbc/XArray.hpp>
34 #include <com/sun/star/sdbc/XBlob.hpp>
35 #include <com/sun/star/sdbc/XClob.hpp>
36 #include <com/sun/star/sdbc/XRef.hpp>
37 #include <com/sun/star/util/Date.hpp>
38 #include <com/sun/star/util/Time.hpp>
39 #include <com/sun/star/util/DateTime.hpp>
40 #include <com/sun/star/ucb/PropertiesManager.hpp>
41 #include <ucbhelper/resultsetmetadata.hxx>
43 using namespace com::sun::star::beans
;
44 using namespace com::sun::star::io
;
45 using namespace com::sun::star::lang
;
46 using namespace com::sun::star::sdbc
;
47 using namespace com::sun::star::ucb
;
48 using namespace com::sun::star::uno
;
49 using namespace com::sun::star::util
;
52 namespace ucbhelper_impl
{
54 struct ResultSetMetaData_Impl
57 std::vector
< ::ucbhelper::ResultSetColumnData
> m_aColumnData
;
58 bool m_bObtainedTypes
;
59 bool m_bGlobalReadOnlyValue
;
61 ResultSetMetaData_Impl( sal_Int32 nSize
)
62 : m_aColumnData( nSize
), m_bObtainedTypes( false ),
63 m_bGlobalReadOnlyValue( true ) {}
65 ResultSetMetaData_Impl(
66 const std::vector
< ::ucbhelper::ResultSetColumnData
>& rColumnData
)
67 : m_aColumnData( rColumnData
), m_bObtainedTypes( false ),
68 m_bGlobalReadOnlyValue( false ) {}
73 using namespace ucbhelper_impl
;
80 // ResultSetMetaData Implementation.
85 ResultSetMetaData::ResultSetMetaData(
86 const Reference
< XComponentContext
>& rxContext
,
87 const Sequence
< Property
>& rProps
,
89 : m_pImpl( new ResultSetMetaData_Impl( rProps
.getLength() ) ),
90 m_xContext( rxContext
),
92 m_bReadOnly( bReadOnly
)
97 ResultSetMetaData::ResultSetMetaData(
98 const Reference
< XComponentContext
>& rxContext
,
99 const Sequence
< Property
>& rProps
,
100 const std::vector
< ResultSetColumnData
>& rColumnData
)
101 : m_pImpl( new ResultSetMetaData_Impl( rColumnData
) ),
102 m_xContext( rxContext
),
106 OSL_ENSURE( rColumnData
.size() == sal_uInt32( rProps
.getLength() ),
107 "ResultSetMetaData ctor - different array sizes!" );
112 ResultSetMetaData::~ResultSetMetaData()
119 // XInterface methods.
121 void SAL_CALL
ResultSetMetaData::acquire()
124 OWeakObject::acquire();
127 void SAL_CALL
ResultSetMetaData::release()
130 OWeakObject::release();
133 css::uno::Any SAL_CALL
ResultSetMetaData::queryInterface( const css::uno::Type
& rType
)
134 throw( css::uno::RuntimeException
, std::exception
)
136 css::uno::Any aRet
= cppu::queryInterface( rType
,
137 (static_cast< XTypeProvider
* >(this)),
138 (static_cast< XResultSetMetaData
* >(this))
140 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
143 // XTypeProvider methods.
147 XTYPEPROVIDER_IMPL_2( ResultSetMetaData
,
149 XResultSetMetaData
);
153 // XResultSetMetaData methods.
158 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnCount()
159 throw( SQLException
, RuntimeException
, std::exception
)
161 return m_aProps
.getLength();
166 sal_Bool SAL_CALL
ResultSetMetaData::isAutoIncrement( sal_Int32 column
)
167 throw( SQLException
, RuntimeException
, std::exception
)
170 Checks whether column is automatically numbered, which makes it
174 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
177 return m_pImpl
->m_aColumnData
[ column
- 1 ].isAutoIncrement
;
182 sal_Bool SAL_CALL
ResultSetMetaData::isCaseSensitive( sal_Int32 column
)
183 throw( SQLException
, RuntimeException
, std::exception
)
185 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
188 return m_pImpl
->m_aColumnData
[ column
- 1 ].isCaseSensitive
;
193 sal_Bool SAL_CALL
ResultSetMetaData::isSearchable( sal_Int32 column
)
194 throw( SQLException
, RuntimeException
, std::exception
)
197 Checks whether the value stored in column can be used in a
201 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
204 return m_pImpl
->m_aColumnData
[ column
- 1 ].isSearchable
;
209 sal_Bool SAL_CALL
ResultSetMetaData::isCurrency( sal_Int32 column
)
210 throw( SQLException
, RuntimeException
, std::exception
)
213 Checks whether column is a cash value.
216 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
219 return m_pImpl
->m_aColumnData
[ column
- 1 ].isCurrency
;
224 sal_Int32 SAL_CALL
ResultSetMetaData::isNullable( sal_Int32 column
)
225 throw( SQLException
, RuntimeException
, std::exception
)
228 Checks whether a NULL can be stored in column.
229 Possible values: see com/sun/star/sdbc/ColumnValue.idl
232 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
233 return ColumnValue::NULLABLE
;
235 return m_pImpl
->m_aColumnData
[ column
- 1 ].isNullable
;
240 sal_Bool SAL_CALL
ResultSetMetaData::isSigned( sal_Int32 column
)
241 throw( SQLException
, RuntimeException
, std::exception
)
244 Checks whether the value stored in column is a signed number.
247 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
250 return m_pImpl
->m_aColumnData
[ column
- 1 ].isSigned
;
255 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnDisplaySize( sal_Int32 column
)
256 throw( SQLException
, RuntimeException
, std::exception
)
259 Gets the normal maximum width in characters for column.
262 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
265 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnDisplaySize
;
270 OUString SAL_CALL
ResultSetMetaData::getColumnLabel( sal_Int32 column
)
271 throw( SQLException
, RuntimeException
, std::exception
)
274 Gets the suggested column title for column, to be used in print-
278 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
281 OUString aLabel
= m_pImpl
->m_aColumnData
[ column
- 1 ].columnLabel
;
282 if ( !aLabel
.isEmpty() )
285 return m_aProps
.getConstArray()[ column
- 1 ].Name
;
290 OUString SAL_CALL
ResultSetMetaData::getColumnName( sal_Int32 column
)
291 throw( SQLException
, RuntimeException
, std::exception
)
294 Gets the name of column.
297 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
300 return m_aProps
.getConstArray()[ column
- 1 ].Name
;
305 OUString SAL_CALL
ResultSetMetaData::getSchemaName( sal_Int32 column
)
306 throw( SQLException
, RuntimeException
, std::exception
)
309 Gets the schema name for the table from which column of this
310 result set was derived.
311 Because this feature is not widely supported, the return value
312 for many DBMSs will be an empty string.
315 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
318 return m_pImpl
->m_aColumnData
[ column
- 1 ].schemaName
;
323 sal_Int32 SAL_CALL
ResultSetMetaData::getPrecision( sal_Int32 column
)
324 throw( SQLException
, RuntimeException
, std::exception
)
327 For number types, getprecision gets the number of decimal digits
329 For character types, it gets the maximum length in characters for
331 For binary types, it gets the maximum length in bytes for column.
334 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
337 return m_pImpl
->m_aColumnData
[ column
- 1 ].precision
;
342 sal_Int32 SAL_CALL
ResultSetMetaData::getScale( sal_Int32 column
)
343 throw( SQLException
, RuntimeException
, std::exception
)
346 Gets the number of digits to the right of the decimal point for
350 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
353 return m_pImpl
->m_aColumnData
[ column
- 1 ].scale
;
358 OUString SAL_CALL
ResultSetMetaData::getTableName( sal_Int32 column
)
359 throw( SQLException
, RuntimeException
, std::exception
)
362 Gets the name of the table from which column of this result set
363 was derived or "" if there is none (for example, for a join).
364 Because this feature is not widely supported, the return value
365 for many DBMSs will be an empty string.
368 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
371 return m_pImpl
->m_aColumnData
[ column
- 1 ].tableName
;
376 OUString SAL_CALL
ResultSetMetaData::getCatalogName( sal_Int32 column
)
377 throw( SQLException
, RuntimeException
, std::exception
)
380 Gets the catalog name for the table from which column of this
381 result set was derived.
382 Because this feature is not widely supported, the return value
383 for many DBMSs will be an empty string.
386 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
389 return m_pImpl
->m_aColumnData
[ column
- 1 ].catalogName
;
394 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnType( sal_Int32 column
)
395 throw( SQLException
, RuntimeException
, std::exception
)
398 Gets the JDBC type for the value stored in column. ... The STRUCT
399 and DISTINCT type codes are always returned for structured and
400 distinct types, regardless of whether the value will be mapped
401 according to the standard mapping or be a custom mapping.
404 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
405 return DataType::SQLNULL
;
407 if ( m_aProps
.getConstArray()[ column
- 1 ].Type
408 == cppu::UnoType
<void>::get() )
410 // No type given. Try UCB's Properties Manager...
412 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
414 if ( !m_pImpl
->m_bObtainedTypes
)
418 Reference
< XPropertySetInfo
> xInfo
= PropertiesManager::create( m_xContext
);
419 // Less (remote) calls...
421 Sequence
< Property
> aProps
= xInfo
->getProperties();
422 const Property
* pProps1
= aProps
.getConstArray();
423 sal_Int32 nCount1
= aProps
.getLength();
425 sal_Int32 nCount
= m_aProps
.getLength();
426 Property
* pProps
= m_aProps
.getArray();
427 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
429 Property
& rProp
= pProps
[ n
];
431 for ( sal_Int32 m
= 0; m
< nCount1
; ++m
)
433 const Property
& rProp1
= pProps1
[ m
];
434 if ( rProp
.Name
== rProp1
.Name
)
437 rProp
.Type
= rProp1
.Type
;
443 catch ( RuntimeException
& )
452 m_pImpl
->m_bObtainedTypes
= true;
456 const Type
& rType
= m_aProps
.getConstArray()[ column
- 1 ].Type
;
457 sal_Int32 nType
= DataType::OTHER
;
459 if ( rType
== cppu::UnoType
<OUString
>::get() )
460 nType
= DataType::VARCHAR
; // XRow::getString
461 else if ( rType
== cppu::UnoType
<bool>::get() )
462 nType
= DataType::BIT
; // XRow::getBoolean
463 else if ( rType
== cppu::UnoType
<sal_Int32
>::get() )
464 nType
= DataType::INTEGER
; // XRow::getInt
465 else if ( rType
== cppu::UnoType
<sal_Int64
>::get() )
466 nType
= DataType::BIGINT
; // XRow::getLong
467 else if ( rType
== cppu::UnoType
<sal_Int16
>::get() )
468 nType
= DataType::SMALLINT
; // XRow::getShort
469 else if ( rType
== cppu::UnoType
<sal_Int8
>::get() )
470 nType
= DataType::TINYINT
; // XRow::getByte
471 else if ( rType
== cppu::UnoType
<float>::get() )
472 nType
= DataType::REAL
; // XRow::getFloat
473 else if ( rType
== cppu::UnoType
<double>::get() )
474 nType
= DataType::DOUBLE
; // XRow::getDouble
475 else if ( rType
== cppu::UnoType
<Sequence
<sal_Int8
>>::get() )
476 nType
= DataType::VARBINARY
;// XRow::getBytes
477 else if ( rType
== cppu::UnoType
<Date
>::get() )
478 nType
= DataType::DATE
; // XRow::getDate
479 else if ( rType
== cppu::UnoType
<Time
>::get() )
480 nType
= DataType::TIME
; // XRow::getTime
481 else if ( rType
== cppu::UnoType
<DateTime
>::get() )
482 nType
= DataType::TIMESTAMP
;// XRow::getTimestamp
483 else if ( rType
== cppu::UnoType
<XInputStream
>::get() )
484 nType
= DataType::LONGVARBINARY
; // XRow::getBinaryStream
485 // nType = DataType::LONGVARCHAR; // XRow::getCharacterStream
486 else if ( rType
== cppu::UnoType
<XClob
>::get() )
487 nType
= DataType::CLOB
; // XRow::getClob
488 else if ( rType
== cppu::UnoType
<XBlob
>::get() )
489 nType
= DataType::BLOB
; // XRow::getBlob
490 else if ( rType
== cppu::UnoType
<XArray
>::get() )
491 nType
= DataType::ARRAY
;// XRow::getArray
492 else if ( rType
== cppu::UnoType
<XRef
>::get() )
493 nType
= DataType::REF
;// XRow::getRef
495 nType
= DataType::OBJECT
;// XRow::getObject
502 OUString SAL_CALL
ResultSetMetaData::getColumnTypeName( sal_Int32 column
)
503 throw( SQLException
, RuntimeException
, std::exception
)
506 Gets the type name used by this particular data source for the
507 values stored in column. If the type code for the type of value
508 stored in column is STRUCT, DISTINCT or JAVA_OBJECT, this method
509 returns a fully-qualified SQL type name.
512 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
515 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnTypeName
;
520 sal_Bool SAL_CALL
ResultSetMetaData::isReadOnly( sal_Int32 column
)
521 throw( SQLException
, RuntimeException
, std::exception
)
523 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
526 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
529 // autoincrement==true => readonly
530 return m_pImpl
->m_aColumnData
[ column
- 1 ].isAutoIncrement
||
531 m_pImpl
->m_aColumnData
[ column
- 1 ].isReadOnly
;
536 sal_Bool SAL_CALL
ResultSetMetaData::isWritable( sal_Int32 column
)
537 throw( SQLException
, RuntimeException
, std::exception
)
539 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
542 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
545 return m_pImpl
->m_aColumnData
[ column
- 1 ].isWritable
;
550 sal_Bool SAL_CALL
ResultSetMetaData::isDefinitelyWritable( sal_Int32 column
)
551 throw( SQLException
, RuntimeException
, std::exception
)
553 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
556 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
559 return m_pImpl
->m_aColumnData
[ column
- 1 ].isDefinitelyWritable
;
564 OUString SAL_CALL
ResultSetMetaData::getColumnServiceName( sal_Int32 column
)
565 throw( SQLException
, RuntimeException
, std::exception
)
568 Returns the fully-qualified name of the service whose instances
569 are manufactured if XResultSet::getObject is called to retrieve
570 a value from the column.
573 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
576 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnServiceName
;
579 } // namespace ucbhelper
581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */