1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #ifndef _DBACORE_DATACOLUMN_HXX_
32 #include "CRowSetDataColumn.hxx"
33 #endif
34 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
35 #include "dbastrings.hrc"
36 #endif
37 #ifndef _DBASHARED_APITOOLS_HXX_
38 #include "apitools.hxx"
39 #endif
40 #ifndef _COMPHELPER_TYPES_HXX_
41 #include <comphelper/types.hxx>
42 #endif
43 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
44 #include <cppuhelper/typeprovider.hxx>
45 #endif
46 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
47 #include <com/sun/star/beans/PropertyAttribute.hpp>
48 #endif
49 #ifndef _TOOLS_DEBUG_HXX
50 #include <tools/debug.hxx>
51 #endif
52 
53 using namespace dbaccess;
54 using namespace comphelper;
55 using namespace connectivity;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::beans;
58 //	using namespace ::com::sun::star::sdbcx;
59 using namespace ::com::sun::star::sdbc;
60 using namespace ::com::sun::star::container;
61 using namespace ::com::sun::star::lang;
62 using namespace ::com::sun::star::util;
63 using namespace cppu;
64 using namespace osl;
65 
66 DBG_NAME(ORowSetDataColumn)
67 // -------------------------------------------------------------------------
68 ORowSetDataColumn::ORowSetDataColumn(	const Reference < XResultSetMetaData >& _xMetaData,
69 									  const Reference < XRow >& _xRow,
70 									  const Reference < XRowUpdate >& _xRowUpdate,
71 									  sal_Int32 _nPos,
72                                       const Reference< XDatabaseMetaData >& _rxDBMeta,
73 									  const ::rtl::OUString& _rDescription,
74                                       const ::rtl::OUString& i_sLabel,
75 									  const ORowSetCacheIterator& _rColumnValue)
76 	:ODataColumn(_xMetaData,_xRow,_xRowUpdate,_nPos,_rxDBMeta)
77 	,m_aColumnValue(_rColumnValue)
78     ,m_sLabel(i_sLabel)
79 	,m_aDescription(_rDescription)
80 {
81 	DBG_CTOR(ORowSetDataColumn,NULL);
82     OColumnSettings::registerProperties( *this );
83     registerProperty( PROPERTY_DESCRIPTION, PROPERTY_ID_DESCRIPTION, PropertyAttribute::READONLY, &m_aDescription, ::getCppuType( &m_aDescription ) );
84 }
85 // -------------------------------------------------------------------------
86 ORowSetDataColumn::~ORowSetDataColumn()
87 {
88 	DBG_DTOR(ORowSetDataColumn,NULL);
89 }
90 // -------------------------------------------------------------------------
91 // comphelper::OPropertyArrayUsageHelper
92 //------------------------------------------------------------------------------
93 ::cppu::IPropertyArrayHelper* ORowSetDataColumn::createArrayHelper( ) const
94 {
95     const sal_Int32 nDerivedProperties = 21;
96 	Sequence< Property> aDerivedProperties( nDerivedProperties );
97 	Property* pDesc = aDerivedProperties.getArray();
98 	sal_Int32 nPos = 0;
99 
100     DECL_PROP1( CATALOGNAME,                ::rtl::OUString,    READONLY );
101     DECL_PROP1( DISPLAYSIZE,                sal_Int32,          READONLY );
102     DECL_PROP1_BOOL( ISAUTOINCREMENT,                           READONLY );
103     DECL_PROP1_BOOL( ISCASESENSITIVE,                           READONLY );
104     DECL_PROP1_BOOL( ISCURRENCY,                                READONLY );
105     DECL_PROP1_BOOL( ISDEFINITELYWRITABLE,                      READONLY );
106     DECL_PROP1( ISNULLABLE,                 sal_Int32,          READONLY );
107     DECL_PROP1_BOOL( ISREADONLY,                                BOUND );
108     DECL_PROP1_BOOL( ISROWVERSION,                              READONLY );
109     DECL_PROP1_BOOL( ISSEARCHABLE,                              READONLY );
110     DECL_PROP1_BOOL( ISSIGNED,                                  READONLY );
111     DECL_PROP1_BOOL( ISWRITABLE,                                READONLY );
112     DECL_PROP1( LABEL,                      ::rtl::OUString,    READONLY );
113     DECL_PROP1( PRECISION,                  sal_Int32,          READONLY );
114     DECL_PROP1( SCALE,                      sal_Int32,          READONLY );
115     DECL_PROP1( SCHEMANAME,                 ::rtl::OUString,    READONLY );
116     DECL_PROP1( SERVICENAME,                ::rtl::OUString,    READONLY );
117     DECL_PROP1( TABLENAME,                  ::rtl::OUString,    READONLY );
118     DECL_PROP1( TYPE,                       sal_Int32,          READONLY );
119     DECL_PROP1( TYPENAME,                   ::rtl::OUString,    READONLY );
120     DECL_PROP1( VALUE,                      Any,                BOUND );
121     OSL_ENSURE( nPos == nDerivedProperties, "ORowSetDataColumn::createArrayHelper: inconsistency!" );
122 
123     Sequence< Property > aRegisteredProperties;
124     describeProperties( aRegisteredProperties );
125 
126     return new ::cppu::OPropertyArrayHelper( ::comphelper::concatSequences( aDerivedProperties, aRegisteredProperties ), sal_False );
127 }
128 
129 // cppu::OPropertySetHelper
130 //------------------------------------------------------------------------------
131 ::cppu::IPropertyArrayHelper& ORowSetDataColumn::getInfoHelper()
132 {
133 	return *static_cast< ::comphelper::OPropertyArrayUsageHelper< ORowSetDataColumn >* >(this)->getArrayHelper();
134 }
135 // -------------------------------------------------------------------------
136 void SAL_CALL ORowSetDataColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
137 {
138     if ( PROPERTY_ID_VALUE == nHandle )
139     {
140 		if ( !m_aColumnValue.isNull() && m_aColumnValue->isValid() )
141 		{
142 			::osl::Mutex* pMutex = m_aColumnValue.getMutex();
143 			::osl::MutexGuard aGuard( *pMutex );
144 #if OSL_DEBUG_LEVEL > 0
145 			ORowSetRow aRow = *m_aColumnValue;
146 #endif
147 			OSL_ENSURE((sal_Int32)aRow->get().size() > m_nPos,"Pos is greater than size of vector");
148 			rValue = ((*m_aColumnValue)->get())[m_nPos].makeAny();
149 		}
150     }
151     else if ( PROPERTY_ID_LABEL == nHandle && m_sLabel.getLength() )
152         rValue <<= m_sLabel;
153     else
154         ODataColumn::getFastPropertyValue( rValue, nHandle );
155 }
156 
157 // -------------------------------------------------------------------------
158 void SAL_CALL ORowSetDataColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue )throw (Exception)
159 {
160     switch( nHandle )
161     {
162         case PROPERTY_ID_VALUE:
163             updateObject(rValue);
164             break;
165         case PROPERTY_ID_ISREADONLY:
166             {
167                 sal_Bool bVal = sal_False;
168                 rValue >>= bVal;
169                 m_isReadOnly.reset(bVal);
170             }
171             break;
172         default:
173             ODataColumn::setFastPropertyValue_NoBroadcast( nHandle,rValue );
174             break;
175     }
176 }
177 // -------------------------------------------------------------------------
178 sal_Bool SAL_CALL ORowSetDataColumn::convertFastPropertyValue( Any & rConvertedValue,
179 															Any & rOldValue,
180 															sal_Int32 nHandle,
181 															const Any& rValue ) throw (IllegalArgumentException)
182 {
183     sal_Bool bModified = sal_False;
184     switch( nHandle )
185     {
186         case PROPERTY_ID_VALUE:
187             {
188 		        rConvertedValue = rValue;
189 		        getFastPropertyValue(rOldValue, PROPERTY_ID_VALUE);
190 		        bModified = rConvertedValue != rOldValue;
191             }
192             break;
193         case PROPERTY_ID_ISREADONLY:
194             {
195 		        rConvertedValue = rValue;
196 		        getFastPropertyValue(rOldValue, PROPERTY_ID_ISREADONLY);
197 		        bModified = rConvertedValue != rOldValue;
198             }
199             break;
200         default:
201             bModified = ODataColumn::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
202             break;
203     }
204 
205 	return bModified;
206 }
207 //--------------------------------------------------------------------------
208 Sequence< sal_Int8 > ORowSetDataColumn::getImplementationId() throw (RuntimeException)
209 {
210 	static OImplementationId * pId = 0;
211 	if (! pId)
212 	{
213 		MutexGuard aGuard( Mutex::getGlobalMutex() );
214 		if (! pId)
215 		{
216 			static OImplementationId aId;
217 			pId = &aId;
218 		}
219 	}
220 	return pId->getImplementationId();
221 }
222 // -------------------------------------------------------------------------
223 void ORowSetDataColumn::fireValueChange(const ORowSetValue& _rOldValue)
224 {
225 	if ( !m_aColumnValue.isNull() && m_aColumnValue->isValid() && (!(((*m_aColumnValue)->get())[m_nPos] == _rOldValue)) )
226 	{
227 		sal_Int32 nHandle = PROPERTY_ID_VALUE;
228 		m_aOldValue = _rOldValue.makeAny();
229 		Any aNew = ((*m_aColumnValue)->get())[m_nPos].makeAny();
230 
231 		fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
232 	}
233     else if ( !m_aColumnValue.isNull() && !_rOldValue.isNull() )
234     {
235         sal_Int32 nHandle = PROPERTY_ID_VALUE;
236 		m_aOldValue = _rOldValue.makeAny();
237 		Any aNew;
238 
239 		fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
240     }
241 }
242 // -----------------------------------------------------------------------------
243 DBG_NAME(ORowSetDataColumns )
244 ORowSetDataColumns::ORowSetDataColumns(
245 				sal_Bool _bCase,
246 				const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
247 				::cppu::OWeakObject& _rParent,
248 				::osl::Mutex& _rMutex,
249 				const ::std::vector< ::rtl::OUString> &_rVector
250 				) : connectivity::sdbcx::OCollection(_rParent,_bCase,_rMutex,_rVector)
251 				,m_aColumns(_rColumns)
252 {
253 	DBG_CTOR(ORowSetDataColumns ,NULL);
254 }
255 // -----------------------------------------------------------------------------
256 ORowSetDataColumns::~ORowSetDataColumns()
257 {
258 	DBG_DTOR(ORowSetDataColumns ,NULL);
259 }
260 // -----------------------------------------------------------------------------
261 sdbcx::ObjectType ORowSetDataColumns::createObject(const ::rtl::OUString& _rName)
262 {
263 	connectivity::sdbcx::ObjectType xNamed;
264 
265 	::comphelper::UStringMixEqual aCase(isCaseSensitive());
266 	::connectivity::OSQLColumns::Vector::const_iterator first =  ::connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),_rName,aCase);
267 	if(first != m_aColumns->get().end())
268 		xNamed.set(*first,UNO_QUERY);
269 
270 	return xNamed;
271 }
272 // -----------------------------------------------------------------------------
273 void SAL_CALL ORowSetDataColumns::disposing(void)
274 {
275 	//	clear_NoDispose();
276 	ORowSetDataColumns_BASE::disposing();
277 	m_aColumns = NULL;
278 	//	m_aColumns.clear();
279 }
280 // -----------------------------------------------------------------------------
281 void ORowSetDataColumns::assign(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,const ::std::vector< ::rtl::OUString> &_rVector)
282 {
283 	m_aColumns = _rColumns;
284 	reFill(_rVector);
285 }
286 // -----------------------------------------------------------------------------
287 void ORowSetDataColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
288 {
289 }
290 // -----------------------------------------------------------------------------
291 
292 
293