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