1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 #ifndef _DBACORE_RESULTCOLUMN_HXX_
27 #include "resultcolumn.hxx"
28 #endif
29 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
30 #include <com/sun/star/lang/DisposedException.hpp>
31 #endif
32 #ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
33 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
34 #endif
35 #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
36 #include <com/sun/star/sdbc/DataType.hpp>
37 #endif
38 #ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
39 #include <com/sun/star/sdbc/ColumnValue.hpp>
40 #endif
41 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
42 #include <cppuhelper/typeprovider.hxx>
43 #endif
44 #ifndef _TOOLS_DEBUG_HXX
45 #include <tools/debug.hxx>
46 #endif
47 #ifndef TOOLS_DIAGNOSE_EX_H
48 #include <tools/diagnose_ex.h>
49 #endif
50 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
51 #include "dbastrings.hrc"
52 #endif
53 #ifndef _DBASHARED_APITOOLS_HXX_
54 #include "apitools.hxx"
55 #endif
56 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
57 #include <com/sun/star/beans/PropertyAttribute.hpp>
58 #endif
59 #ifndef _CPPUHELPER_EXC_HLP_HXX_
60 #include <cppuhelper/exc_hlp.hxx>
61 #endif
62 #ifndef _OSL_THREAD_H_
63 #include <osl/thread.h>
64 #endif
65 
66 using namespace ::com::sun::star::sdbc;
67 using namespace ::com::sun::star::beans;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::lang;
70 using namespace ::com::sun::star::container;
71 using namespace ::osl;
72 using namespace ::comphelper;
73 using namespace ::cppu;
74 using namespace dbaccess;
75 
DBG_NAME(OResultColumn)76 DBG_NAME(OResultColumn)
77 //--------------------------------------------------------------------------
78 OResultColumn::OResultColumn( const Reference < XResultSetMetaData >& _xMetaData, sal_Int32 _nPos,
79         const Reference< XDatabaseMetaData >& _rxDBMeta )
80     :OColumn( true )
81     ,m_xMetaData( _xMetaData )
82     ,m_xDBMetaData( _rxDBMeta )
83     ,m_nPos( _nPos )
84 {
85 	DBG_CTOR(OResultColumn,NULL);
86 }
87 // -----------------------------------------------------------------------------
impl_determineIsRowVersion_nothrow()88 void OResultColumn::impl_determineIsRowVersion_nothrow()
89 {
90     if ( m_aIsRowVersion.hasValue() )
91         return;
92     m_aIsRowVersion <<= (sal_Bool)(sal_False);
93 
94     OSL_ENSURE( m_xDBMetaData.is(), "OResultColumn::impl_determineIsRowVersion_nothrow: no DBMetaData!" );
95     if ( !m_xDBMetaData.is() )
96         return;
97 
98     try
99     {
100         ::rtl::OUString sCatalog, sSchema, sTable, sColumnName;
101         getPropertyValue( PROPERTY_CATALOGNAME ) >>= sCatalog;
102         getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema;
103         getPropertyValue( PROPERTY_TABLENAME ) >>= sTable;
104         getPropertyValue( PROPERTY_NAME ) >>= sColumnName;
105 
106         try
107         {
108             Reference< XResultSet > xVersionColumns = m_xDBMetaData->getVersionColumns(
109                 makeAny( sCatalog ), sSchema, sTable );
110             if ( xVersionColumns.is() ) // allowed to be NULL
111             {
112                 Reference< XRow > xResultRow( xVersionColumns, UNO_QUERY_THROW );
113                 while ( xVersionColumns->next() )
114                 {
115                     if ( xResultRow->getString( 2 ) == sColumnName )
116                     {
117                         m_aIsRowVersion <<= (sal_Bool)(sal_True);
118                         break;
119                     }
120                 }
121             }
122         }
123         catch(const SQLException&)
124         {
125         }
126     }
127     catch( const Exception& )
128     {
129         DBG_UNHANDLED_EXCEPTION();
130     }
131 }
132 // -----------------------------------------------------------------------------
~OResultColumn()133 OResultColumn::~OResultColumn()
134 {
135 	DBG_DTOR(OResultColumn,NULL);
136 }
137 // com::sun::star::lang::XTypeProvider
138 //--------------------------------------------------------------------------
getImplementationId()139 Sequence< sal_Int8 > OResultColumn::getImplementationId() throw (RuntimeException)
140 {
141 	static OImplementationId * pId = 0;
142 	if (! pId)
143 	{
144 		MutexGuard aGuard( Mutex::getGlobalMutex() );
145 		if (! pId)
146 		{
147 			static OImplementationId aId;
148 			pId = &aId;
149 		}
150 	}
151 	return pId->getImplementationId();
152 }
153 
154 // XServiceInfo
155 //------------------------------------------------------------------------------
getImplementationName()156 rtl::OUString OResultColumn::getImplementationName(  ) throw(RuntimeException)
157 {
158 	return rtl::OUString::createFromAscii("com.sun.star.sdb.OResultColumn");
159 }
160 
161 //------------------------------------------------------------------------------
getSupportedServiceNames()162 Sequence< ::rtl::OUString > OResultColumn::getSupportedServiceNames(  ) throw (RuntimeException)
163 {
164 	Sequence< ::rtl::OUString > aSNS( 2 );
165 	aSNS[0] = SERVICE_SDBCX_COLUMN;
166 	aSNS[1] = SERVICE_SDB_RESULTCOLUMN;
167 	return aSNS;
168 }
169 
170 // OComponentHelper
171 //------------------------------------------------------------------------------
disposing()172 void OResultColumn::disposing()
173 {
174 	OColumn::disposing();
175 
176 	MutexGuard aGuard(m_aMutex);
177 	m_xMetaData = NULL;
178 }
179 
180 // comphelper::OPropertyArrayUsageHelper
181 //------------------------------------------------------------------------------
createArrayHelper() const182 ::cppu::IPropertyArrayHelper* OResultColumn::createArrayHelper( ) const
183 {
184 	BEGIN_PROPERTY_HELPER(21)
185 		DECL_PROP1(CATALOGNAME,				::rtl::OUString,	READONLY);
186 		DECL_PROP1(DISPLAYSIZE,				sal_Int32,			READONLY);
187 		DECL_PROP1_BOOL(ISAUTOINCREMENT,						READONLY);
188 		DECL_PROP1_BOOL(ISCASESENSITIVE,						READONLY);
189 		DECL_PROP1_BOOL(ISCURRENCY,								READONLY);
190 		DECL_PROP1_BOOL(ISDEFINITELYWRITABLE,					READONLY);
191 		DECL_PROP1(ISNULLABLE,				sal_Int32,			READONLY);
192 		DECL_PROP1_BOOL(ISREADONLY,								READONLY);
193 		DECL_PROP1_BOOL(ISROWVERSION,                           READONLY);
194 		DECL_PROP1_BOOL(ISSEARCHABLE,							READONLY);
195 		DECL_PROP1_BOOL(ISSIGNED,								READONLY);
196 		DECL_PROP1_BOOL(ISWRITABLE,								READONLY);
197 		DECL_PROP1(LABEL,					::rtl::OUString,	READONLY);
198 		DECL_PROP1(NAME,					::rtl::OUString,	READONLY);
199 		DECL_PROP1(PRECISION,				sal_Int32,			READONLY);
200 		DECL_PROP1(SCALE,					sal_Int32,			READONLY);
201 		DECL_PROP1(SCHEMANAME,				::rtl::OUString,	READONLY);
202 		DECL_PROP1(SERVICENAME,				::rtl::OUString,	READONLY);
203 		DECL_PROP1(TABLENAME,				::rtl::OUString,	READONLY);
204 		DECL_PROP1(TYPE,					sal_Int32,			READONLY);
205 		DECL_PROP1(TYPENAME,				::rtl::OUString,	READONLY);
206 	END_PROPERTY_HELPER();
207 }
208 
209 // cppu::OPropertySetHelper
210 //------------------------------------------------------------------------------
getInfoHelper()211 ::cppu::IPropertyArrayHelper& OResultColumn::getInfoHelper()
212 {
213 	return *static_cast< ::comphelper::OPropertyArrayUsageHelper< OResultColumn >* >(this)->getArrayHelper();
214 }
215 
216 //------------------------------------------------------------------------------
217 namespace
218 {
219     template< typename TYPE >
obtain(Any & _out_rValue,::boost::optional<TYPE> _rCache,const sal_Int32 _nPos,const Reference<XResultSetMetaData> & _rxResultMeta,TYPE (SAL_CALL XResultSetMetaData::* Getter)(sal_Int32))220     void obtain( Any& _out_rValue, ::boost::optional< TYPE > _rCache, const sal_Int32 _nPos, const Reference < XResultSetMetaData >& _rxResultMeta, TYPE (SAL_CALL XResultSetMetaData::*Getter)( sal_Int32 ) )
221     {
222         if ( !_rCache )
223             _rCache.reset( (_rxResultMeta.get()->*Getter)( _nPos ) );
224         _out_rValue <<= *_rCache;
225     }
226 }
227 
228 //------------------------------------------------------------------------------
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const229 void OResultColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
230 {
231 	try
232 	{
233         if ( OColumn::isRegisteredProperty( nHandle ) )
234         {
235             OColumn::getFastPropertyValue( rValue, nHandle );
236         }
237         else
238         {
239 		    switch (nHandle)
240 		    {
241                 case PROPERTY_ID_ISROWVERSION:
242                     const_cast< OResultColumn* >( this )->impl_determineIsRowVersion_nothrow();
243                     rValue = m_aIsRowVersion;
244                     break;
245 			    case PROPERTY_ID_TABLENAME:
246 				    rValue <<= m_xMetaData->getTableName(m_nPos);
247 				    break;
248 			    case PROPERTY_ID_SCHEMANAME:
249 				    rValue <<= m_xMetaData->getSchemaName(m_nPos);
250 				    break;
251 			    case PROPERTY_ID_CATALOGNAME:
252 				    rValue <<= m_xMetaData->getCatalogName(m_nPos);
253 				    break;
254 			    case PROPERTY_ID_ISSIGNED:
255                     obtain( rValue, m_isSigned, m_nPos, m_xMetaData, &XResultSetMetaData::isSigned );
256 			        break;
257 			    case PROPERTY_ID_ISCURRENCY:
258                     obtain( rValue, m_isCurrency, m_nPos, m_xMetaData, &XResultSetMetaData::isCurrency );
259 			        break;
260 			    case PROPERTY_ID_ISSEARCHABLE:
261                     obtain( rValue, m_bSearchable, m_nPos, m_xMetaData, &XResultSetMetaData::isSearchable );
262 			        break;
263 			    case PROPERTY_ID_ISCASESENSITIVE:
264                     obtain( rValue, m_isCaseSensitive, m_nPos, m_xMetaData, &XResultSetMetaData::isCaseSensitive );
265 			        break;
266 			    case PROPERTY_ID_ISREADONLY:
267                     obtain( rValue, m_isReadOnly, m_nPos, m_xMetaData, &XResultSetMetaData::isReadOnly );
268 			        break;
269 			    case PROPERTY_ID_ISWRITABLE:
270                     obtain( rValue, m_isWritable, m_nPos, m_xMetaData, &XResultSetMetaData::isWritable );
271 			        break;
272 			    case PROPERTY_ID_ISDEFINITELYWRITABLE:
273                     obtain( rValue, m_isDefinitelyWritable, m_nPos, m_xMetaData, &XResultSetMetaData::isDefinitelyWritable );
274 			        break;
275 			    case PROPERTY_ID_ISAUTOINCREMENT:
276                     obtain( rValue, m_isAutoIncrement, m_nPos, m_xMetaData, &XResultSetMetaData::isAutoIncrement );
277 			        break;
278 			    case PROPERTY_ID_SERVICENAME:
279 				    rValue <<= m_xMetaData->getColumnServiceName(m_nPos);
280 				    break;
281 			    case PROPERTY_ID_LABEL:
282                     obtain( rValue, m_sColumnLabel, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnLabel );
283 				    break;
284 			    case PROPERTY_ID_DISPLAYSIZE:
285                     obtain( rValue, m_nColumnDisplaySize, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnDisplaySize );
286 				    break;
287 			    case PROPERTY_ID_TYPE:
288                     obtain( rValue, m_nColumnType, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnType );
289 				    break;
290 			    case PROPERTY_ID_PRECISION:
291                     obtain( rValue, m_nPrecision, m_nPos, m_xMetaData, &XResultSetMetaData::getPrecision );
292 				    break;
293 			    case PROPERTY_ID_SCALE:
294                     obtain( rValue, m_nScale, m_nPos, m_xMetaData, &XResultSetMetaData::getScale );
295 				    break;
296 			    case PROPERTY_ID_ISNULLABLE:
297                     obtain( rValue, m_isNullable, m_nPos, m_xMetaData, &XResultSetMetaData::isNullable );
298 				    break;
299 			    case PROPERTY_ID_TYPENAME:
300 				    rValue <<= m_xMetaData->getColumnTypeName(m_nPos);
301 				    break;
302                 default:
303                     OSL_ENSURE( false, "OResultColumn::getFastPropertyValue: unknown property handle!" );
304                     break;
305             }
306 		}
307 	}
308 	catch (SQLException& )
309 	{
310 		// default handling if we caught an exception
311 		switch (nHandle)
312 		{
313 			case PROPERTY_ID_LABEL:
314 			case PROPERTY_ID_TYPENAME:
315 			case PROPERTY_ID_SERVICENAME:
316 			case PROPERTY_ID_TABLENAME:
317 			case PROPERTY_ID_SCHEMANAME:
318 			case PROPERTY_ID_CATALOGNAME:
319 				// empty string'S
320 				rValue <<= rtl::OUString();
321 				break;
322             case PROPERTY_ID_ISROWVERSION:
323 			case PROPERTY_ID_ISAUTOINCREMENT:
324 			case PROPERTY_ID_ISWRITABLE:
325 			case PROPERTY_ID_ISDEFINITELYWRITABLE:
326 			case PROPERTY_ID_ISCASESENSITIVE:
327 			case PROPERTY_ID_ISSEARCHABLE:
328 			case PROPERTY_ID_ISCURRENCY:
329 			case PROPERTY_ID_ISSIGNED:
330 			{
331 				sal_Bool bVal = sal_False;
332 				rValue.setValue(&bVal, getBooleanCppuType());
333 			}	break;
334 			case PROPERTY_ID_ISREADONLY:
335 			{
336 				sal_Bool bVal = sal_True;
337 				rValue.setValue(&bVal, getBooleanCppuType());
338 			}	break;
339 			case PROPERTY_ID_SCALE:
340 			case PROPERTY_ID_PRECISION:
341 			case PROPERTY_ID_DISPLAYSIZE:
342 				rValue <<= sal_Int32(0);
343 				break;
344 			case PROPERTY_ID_TYPE:
345 				rValue <<= sal_Int32(DataType::SQLNULL);
346 				break;
347 			case PROPERTY_ID_ISNULLABLE:
348 				rValue <<= ColumnValue::NULLABLE_UNKNOWN;
349 				break;
350 		}
351 	}
352 }
353 
354