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
;
51 using ::rtl::OUString
;
53 namespace ucbhelper_impl
{
55 struct ResultSetMetaData_Impl
58 std::vector
< ::ucbhelper::ResultSetColumnData
> m_aColumnData
;
59 sal_Bool m_bObtainedTypes
;
60 sal_Bool m_bGlobalReadOnlyValue
;
62 ResultSetMetaData_Impl( sal_Int32 nSize
)
63 : m_aColumnData( nSize
), m_bObtainedTypes( sal_False
),
64 m_bGlobalReadOnlyValue( sal_True
) {}
66 ResultSetMetaData_Impl(
67 const std::vector
< ::ucbhelper::ResultSetColumnData
>& rColumnData
)
68 : m_aColumnData( rColumnData
), m_bObtainedTypes( sal_False
),
69 m_bGlobalReadOnlyValue( sal_False
) {}
74 using namespace ucbhelper_impl
;
78 //=========================================================================
79 //=========================================================================
81 // ResultSetMetaData Implementation.
83 //=========================================================================
84 //=========================================================================
86 ResultSetMetaData::ResultSetMetaData(
87 const Reference
< XComponentContext
>& rxContext
,
88 const Sequence
< Property
>& rProps
,
90 : m_pImpl( new ResultSetMetaData_Impl( rProps
.getLength() ) ),
91 m_xContext( rxContext
),
93 m_bReadOnly( bReadOnly
)
97 //=========================================================================
98 ResultSetMetaData::ResultSetMetaData(
99 const Reference
< XComponentContext
>& rxContext
,
100 const Sequence
< Property
>& rProps
,
101 const std::vector
< ResultSetColumnData
>& rColumnData
)
102 : m_pImpl( new ResultSetMetaData_Impl( rColumnData
) ),
103 m_xContext( rxContext
),
105 m_bReadOnly( sal_True
)
107 OSL_ENSURE( rColumnData
.size() == sal_uInt32( rProps
.getLength() ),
108 "ResultSetMetaData ctor - different array sizes!" );
111 //=========================================================================
113 ResultSetMetaData::~ResultSetMetaData()
118 //=========================================================================
120 // XInterface methods.
122 //=========================================================================
124 XINTERFACE_IMPL_2( ResultSetMetaData
,
126 XResultSetMetaData
);
128 //=========================================================================
130 // XTypeProvider methods.
132 //=========================================================================
134 XTYPEPROVIDER_IMPL_2( ResultSetMetaData
,
136 XResultSetMetaData
);
138 //=========================================================================
140 // XResultSetMetaData methods.
142 //=========================================================================
145 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnCount()
146 throw( SQLException
, RuntimeException
)
148 return m_aProps
.getLength();
151 //=========================================================================
153 sal_Bool SAL_CALL
ResultSetMetaData::isAutoIncrement( sal_Int32 column
)
154 throw( SQLException
, RuntimeException
)
157 Checks whether column is automatically numbered, which makes it
161 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
164 return m_pImpl
->m_aColumnData
[ column
- 1 ].isAutoIncrement
;
167 //=========================================================================
169 sal_Bool SAL_CALL
ResultSetMetaData::isCaseSensitive( sal_Int32 column
)
170 throw( SQLException
, RuntimeException
)
172 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
175 return m_pImpl
->m_aColumnData
[ column
- 1 ].isCaseSensitive
;
178 //=========================================================================
180 sal_Bool SAL_CALL
ResultSetMetaData::isSearchable( sal_Int32 column
)
181 throw( SQLException
, RuntimeException
)
184 Checks whether the value stored in column can be used in a
188 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
191 return m_pImpl
->m_aColumnData
[ column
- 1 ].isSearchable
;
194 //=========================================================================
196 sal_Bool SAL_CALL
ResultSetMetaData::isCurrency( sal_Int32 column
)
197 throw( SQLException
, RuntimeException
)
200 Checks whether column is a cash value.
203 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
206 return m_pImpl
->m_aColumnData
[ column
- 1 ].isCurrency
;
209 //=========================================================================
211 sal_Int32 SAL_CALL
ResultSetMetaData::isNullable( sal_Int32 column
)
212 throw( SQLException
, RuntimeException
)
215 Checks whether a NULL can be stored in column.
216 Possible values: see com/sun/star/sdbc/ColumnValue.idl
219 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
220 return ColumnValue::NULLABLE
;
222 return m_pImpl
->m_aColumnData
[ column
- 1 ].isNullable
;
225 //=========================================================================
227 sal_Bool SAL_CALL
ResultSetMetaData::isSigned( sal_Int32 column
)
228 throw( SQLException
, RuntimeException
)
231 Checks whether the value stored in column is a signed number.
234 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
237 return m_pImpl
->m_aColumnData
[ column
- 1 ].isSigned
;
240 //=========================================================================
242 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnDisplaySize( sal_Int32 column
)
243 throw( SQLException
, RuntimeException
)
246 Gets the normal maximum width in characters for column.
249 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
252 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnDisplaySize
;
255 //=========================================================================
257 OUString SAL_CALL
ResultSetMetaData::getColumnLabel( sal_Int32 column
)
258 throw( SQLException
, RuntimeException
)
261 Gets the suggested column title for column, to be used in print-
265 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
268 OUString aLabel
= m_pImpl
->m_aColumnData
[ column
- 1 ].columnLabel
;
269 if ( !aLabel
.isEmpty() )
272 return m_aProps
.getConstArray()[ column
- 1 ].Name
;
275 //=========================================================================
277 OUString SAL_CALL
ResultSetMetaData::getColumnName( sal_Int32 column
)
278 throw( SQLException
, RuntimeException
)
281 Gets the name of column.
284 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
287 return m_aProps
.getConstArray()[ column
- 1 ].Name
;
290 //=========================================================================
292 OUString SAL_CALL
ResultSetMetaData::getSchemaName( sal_Int32 column
)
293 throw( SQLException
, RuntimeException
)
296 Gets the schema name for the table from which column of this
297 result set was derived.
298 Because this feature is not widely supported, the return value
299 for many DBMSs will be an empty string.
302 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
305 return m_pImpl
->m_aColumnData
[ column
- 1 ].schemaName
;
308 //=========================================================================
310 sal_Int32 SAL_CALL
ResultSetMetaData::getPrecision( sal_Int32 column
)
311 throw( SQLException
, RuntimeException
)
314 For number types, getprecision gets the number of decimal digits
316 For character types, it gets the maximum length in characters for
318 For binary types, it gets the maximum length in bytes for column.
321 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
324 return m_pImpl
->m_aColumnData
[ column
- 1 ].precision
;
327 //=========================================================================
329 sal_Int32 SAL_CALL
ResultSetMetaData::getScale( sal_Int32 column
)
330 throw( SQLException
, RuntimeException
)
333 Gets the number of digits to the right of the decimal point for
337 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
340 return m_pImpl
->m_aColumnData
[ column
- 1 ].scale
;
343 //=========================================================================
345 OUString SAL_CALL
ResultSetMetaData::getTableName( sal_Int32 column
)
346 throw( SQLException
, RuntimeException
)
349 Gets the name of the table from which column of this result set
350 was derived or "" if there is none (for example, for a join).
351 Because this feature is not widely supported, the return value
352 for many DBMSs will be an empty string.
355 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
358 return m_pImpl
->m_aColumnData
[ column
- 1 ].tableName
;
361 //=========================================================================
363 OUString SAL_CALL
ResultSetMetaData::getCatalogName( sal_Int32 column
)
364 throw( SQLException
, RuntimeException
)
367 Gets the catalog name for the table from which column of this
368 result set was derived.
369 Because this feature is not widely supported, the return value
370 for many DBMSs will be an empty string.
373 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
376 return m_pImpl
->m_aColumnData
[ column
- 1 ].catalogName
;
379 //=========================================================================
381 sal_Int32 SAL_CALL
ResultSetMetaData::getColumnType( sal_Int32 column
)
382 throw( SQLException
, RuntimeException
)
385 Gets the JDBC type for the value stored in column. ... The STRUCT
386 and DISTINCT type codes are always returned for structured and
387 distinct types, regardless of whether the value will be mapped
388 according to the standard mapping or be a custom mapping.
391 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
392 return DataType::SQLNULL
;
394 if ( m_aProps
.getConstArray()[ column
- 1 ].Type
395 == getCppuVoidType() )
397 // No type given. Try UCB's Properties Manager...
399 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
401 if ( !m_pImpl
->m_bObtainedTypes
)
405 Reference
< XPropertySetInfo
> xInfo
= PropertiesManager::create( m_xContext
);
406 // Less (remote) calls...
408 Sequence
< Property
> aProps
= xInfo
->getProperties();
409 const Property
* pProps1
= aProps
.getConstArray();
410 sal_Int32 nCount1
= aProps
.getLength();
412 sal_Int32 nCount
= m_aProps
.getLength();
413 Property
* pProps
= m_aProps
.getArray();
414 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
416 Property
& rProp
= pProps
[ n
];
418 for ( sal_Int32 m
= 0; m
< nCount1
; ++m
)
420 const Property
& rProp1
= pProps1
[ m
];
421 if ( rProp
.Name
== rProp1
.Name
)
424 rProp
.Type
= rProp1
.Type
;
430 catch ( RuntimeException
& )
439 m_pImpl
->m_bObtainedTypes
= sal_True
;
443 const Type
& rType
= m_aProps
.getConstArray()[ column
- 1 ].Type
;
444 sal_Int32 nType
= DataType::OTHER
;
446 if ( rType
== getCppuType( static_cast< const rtl::OUString
* >( 0 ) ) )
447 nType
= DataType::VARCHAR
; // XRow::getString
448 else if ( rType
== getCppuBooleanType() )
449 nType
= DataType::BIT
; // XRow::getBoolean
450 else if ( rType
== getCppuType( static_cast< const sal_Int32
* >( 0 ) ) )
451 nType
= DataType::INTEGER
; // XRow::getInt
452 else if ( rType
== getCppuType( static_cast< const sal_Int64
* >( 0 ) ) )
453 nType
= DataType::BIGINT
; // XRow::getLong
454 else if ( rType
== getCppuType( static_cast< const sal_Int16
* >( 0 ) ) )
455 nType
= DataType::SMALLINT
; // XRow::getShort
456 else if ( rType
== getCppuType( static_cast< const sal_Int8
* >( 0 ) ) )
457 nType
= DataType::TINYINT
; // XRow::getByte
458 else if ( rType
== getCppuType( static_cast< const float * >( 0 ) ) )
459 nType
= DataType::REAL
; // XRow::getFloat
460 else if ( rType
== getCppuType( static_cast< const double * >( 0 ) ) )
461 nType
= DataType::DOUBLE
; // XRow::getDouble
462 else if ( rType
== getCppuType( static_cast< const Sequence
< sal_Int8
> * >( 0 ) ) )
463 nType
= DataType::VARBINARY
;// XRow::getBytes
464 else if ( rType
== getCppuType( static_cast< const Date
* >( 0 ) ) )
465 nType
= DataType::DATE
; // XRow::getDate
466 else if ( rType
== getCppuType( static_cast< const Time
* >( 0 ) ) )
467 nType
= DataType::TIME
; // XRow::getTime
468 else if ( rType
== getCppuType( static_cast< const DateTime
* >( 0 ) ) )
469 nType
= DataType::TIMESTAMP
;// XRow::getTimestamp
470 else if ( rType
== getCppuType( static_cast< Reference
< XInputStream
> * >( 0 ) ) )
471 nType
= DataType::LONGVARBINARY
; // XRow::getBinaryStream
472 // nType = DataType::LONGVARCHAR; // XRow::getCharacterStream
473 else if ( rType
== getCppuType( static_cast< Reference
< XClob
> * >( 0 ) ) )
474 nType
= DataType::CLOB
; // XRow::getClob
475 else if ( rType
== getCppuType( static_cast< Reference
< XBlob
> * >( 0 ) ) )
476 nType
= DataType::BLOB
; // XRow::getBlob
477 else if ( rType
== getCppuType( static_cast< Reference
< XArray
> * >( 0 ) ) )
478 nType
= DataType::ARRAY
;// XRow::getArray
479 else if ( rType
== getCppuType( static_cast< Reference
< XRef
> * >( 0 ) ) )
480 nType
= DataType::REF
;// XRow::getRef
482 nType
= DataType::OBJECT
;// XRow::getObject
487 //=========================================================================
489 OUString SAL_CALL
ResultSetMetaData::getColumnTypeName( sal_Int32 column
)
490 throw( SQLException
, RuntimeException
)
493 Gets the type name used by this particular data source for the
494 values stored in column. If the type code for the type of value
495 stored in column is STRUCT, DISTINCT or JAVA_OBJECT, this method
496 returns a fully-qualified SQL type name.
499 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
502 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnTypeName
;
505 //=========================================================================
507 sal_Bool SAL_CALL
ResultSetMetaData::isReadOnly( sal_Int32 column
)
508 throw( SQLException
, RuntimeException
)
510 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
513 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
516 // autoincrement==true => readonly
517 return m_pImpl
->m_aColumnData
[ column
- 1 ].isAutoIncrement
||
518 m_pImpl
->m_aColumnData
[ column
- 1 ].isReadOnly
;
521 //=========================================================================
523 sal_Bool SAL_CALL
ResultSetMetaData::isWritable( sal_Int32 column
)
524 throw( SQLException
, RuntimeException
)
526 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
529 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
532 return m_pImpl
->m_aColumnData
[ column
- 1 ].isWritable
;
535 //=========================================================================
537 sal_Bool SAL_CALL
ResultSetMetaData::isDefinitelyWritable( sal_Int32 column
)
538 throw( SQLException
, RuntimeException
)
540 if ( m_pImpl
->m_bGlobalReadOnlyValue
)
543 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
546 return m_pImpl
->m_aColumnData
[ column
- 1 ].isDefinitelyWritable
;
549 //=========================================================================
551 OUString SAL_CALL
ResultSetMetaData::getColumnServiceName( sal_Int32 column
)
552 throw( SQLException
, RuntimeException
)
555 Returns the fully-qualified name of the service whose instances
556 are manufactured if XResultSet::getObject is called to retrieve
557 a value from the column.
560 if ( ( column
< 1 ) || ( column
> m_aProps
.getLength() ) )
563 return m_pImpl
->m_aColumnData
[ column
- 1 ].columnServiceName
;
566 } // namespace ucbhelper
568 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */