Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / ucbhelper / source / provider / resultsetmetadata.cxx
blob13e94ed2cc928c110c3fc8802d03bff9bf28ed58
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 /**************************************************************************
22 TODO
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
57 osl::Mutex m_aMutex;
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;
76 namespace ucbhelper {
78 //=========================================================================
79 //=========================================================================
81 // ResultSetMetaData Implementation.
83 //=========================================================================
84 //=========================================================================
86 ResultSetMetaData::ResultSetMetaData(
87 const Reference< XComponentContext >& rxContext,
88 const Sequence< Property >& rProps,
89 sal_Bool bReadOnly )
90 : m_pImpl( new ResultSetMetaData_Impl( rProps.getLength() ) ),
91 m_xContext( rxContext ),
92 m_aProps( rProps ),
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 ),
104 m_aProps( rProps ),
105 m_bReadOnly( sal_True )
107 OSL_ENSURE( rColumnData.size() == sal_uInt32( rProps.getLength() ),
108 "ResultSetMetaData ctor - different array sizes!" );
111 //=========================================================================
112 // virtual
113 ResultSetMetaData::~ResultSetMetaData()
115 delete m_pImpl;
118 //=========================================================================
120 // XInterface methods.
122 //=========================================================================
124 XINTERFACE_IMPL_2( ResultSetMetaData,
125 XTypeProvider,
126 XResultSetMetaData );
128 //=========================================================================
130 // XTypeProvider methods.
132 //=========================================================================
134 XTYPEPROVIDER_IMPL_2( ResultSetMetaData,
135 XTypeProvider,
136 XResultSetMetaData );
138 //=========================================================================
140 // XResultSetMetaData methods.
142 //=========================================================================
144 // virtual
145 sal_Int32 SAL_CALL ResultSetMetaData::getColumnCount()
146 throw( SQLException, RuntimeException )
148 return m_aProps.getLength();
151 //=========================================================================
152 // virtual
153 sal_Bool SAL_CALL ResultSetMetaData::isAutoIncrement( sal_Int32 column )
154 throw( SQLException, RuntimeException )
157 Checks whether column is automatically numbered, which makes it
158 read-only.
161 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
162 return sal_False;
164 return m_pImpl->m_aColumnData[ column - 1 ].isAutoIncrement;
167 //=========================================================================
168 // virtual
169 sal_Bool SAL_CALL ResultSetMetaData::isCaseSensitive( sal_Int32 column )
170 throw( SQLException, RuntimeException )
172 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
173 return sal_False;
175 return m_pImpl->m_aColumnData[ column - 1 ].isCaseSensitive;
178 //=========================================================================
179 // virtual
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
185 WHERE clause.
188 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
189 return sal_False;
191 return m_pImpl->m_aColumnData[ column - 1 ].isSearchable;
194 //=========================================================================
195 // virtual
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() ) )
204 return sal_False;
206 return m_pImpl->m_aColumnData[ column - 1 ].isCurrency;
209 //=========================================================================
210 // virtual
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 //=========================================================================
226 // virtual
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() ) )
235 return sal_False;
237 return m_pImpl->m_aColumnData[ column - 1 ].isSigned;
240 //=========================================================================
241 // virtual
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() ) )
250 return 16;
252 return m_pImpl->m_aColumnData[ column - 1 ].columnDisplaySize;
255 //=========================================================================
256 // virtual
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-
262 outs and displays.
265 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
266 return OUString();
268 OUString aLabel = m_pImpl->m_aColumnData[ column - 1 ].columnLabel;
269 if ( !aLabel.isEmpty() )
270 return aLabel;
272 return m_aProps.getConstArray()[ column - 1 ].Name;
275 //=========================================================================
276 // virtual
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() ) )
285 return OUString();
287 return m_aProps.getConstArray()[ column - 1 ].Name;
290 //=========================================================================
291 // virtual
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() ) )
303 return OUString();
305 return m_pImpl->m_aColumnData[ column - 1 ].schemaName;
308 //=========================================================================
309 // virtual
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
315 in column.
316 For character types, it gets the maximum length in characters for
317 column.
318 For binary types, it gets the maximum length in bytes for column.
321 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
322 return -1;
324 return m_pImpl->m_aColumnData[ column - 1 ].precision;
327 //=========================================================================
328 // virtual
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
334 values in column.
337 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
338 return 0;
340 return m_pImpl->m_aColumnData[ column - 1 ].scale;
343 //=========================================================================
344 // virtual
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() ) )
356 return OUString();
358 return m_pImpl->m_aColumnData[ column - 1 ].tableName;
361 //=========================================================================
362 // virtual
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() ) )
374 return OUString();
376 return m_pImpl->m_aColumnData[ column - 1 ].catalogName;
379 //=========================================================================
380 // virtual
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 )
423 // Found...
424 rProp.Type = rProp1.Type;
425 break;
430 catch ( RuntimeException& )
432 throw;
434 catch ( Exception& )
436 // createInstance
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
481 else
482 nType = DataType::OBJECT;// XRow::getObject
484 return nType;
487 //=========================================================================
488 // virtual
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() ) )
500 return OUString();
502 return m_pImpl->m_aColumnData[ column - 1 ].columnTypeName;
505 //=========================================================================
506 // virtual
507 sal_Bool SAL_CALL ResultSetMetaData::isReadOnly( sal_Int32 column )
508 throw( SQLException, RuntimeException )
510 if ( m_pImpl->m_bGlobalReadOnlyValue )
511 return m_bReadOnly;
513 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
514 return sal_True;
516 // autoincrement==true => readonly
517 return m_pImpl->m_aColumnData[ column - 1 ].isAutoIncrement ||
518 m_pImpl->m_aColumnData[ column - 1 ].isReadOnly;
521 //=========================================================================
522 // virtual
523 sal_Bool SAL_CALL ResultSetMetaData::isWritable( sal_Int32 column )
524 throw( SQLException, RuntimeException )
526 if ( m_pImpl->m_bGlobalReadOnlyValue )
527 return !m_bReadOnly;
529 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
530 return sal_False;
532 return m_pImpl->m_aColumnData[ column - 1 ].isWritable;
535 //=========================================================================
536 // virtual
537 sal_Bool SAL_CALL ResultSetMetaData::isDefinitelyWritable( sal_Int32 column )
538 throw( SQLException, RuntimeException )
540 if ( m_pImpl->m_bGlobalReadOnlyValue )
541 return !m_bReadOnly;
543 if ( ( column < 1 ) || ( column > m_aProps.getLength() ) )
544 return sal_False;
546 return m_pImpl->m_aColumnData[ column - 1 ].isDefinitelyWritable;
549 //=========================================================================
550 // virtual
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() ) )
561 return OUString();
563 return m_pImpl->m_aColumnData[ column - 1 ].columnServiceName;
566 } // namespace ucbhelper
568 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */