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_connectivity.hxx"
30 #include "ado/AColumn.hxx"
31 #include "ado/AConnection.hxx"
32 #include "ado/Awrapado.hxx"
33 #include <cppuhelper/typeprovider.hxx>
34 #include <comphelper/sequence.hxx>
35 #include <com/sun/star/sdbc/ColumnValue.hpp>
36 #include <comphelper/extract.hxx>
37 #include <comphelper/types.hxx>
38 #include "ado/ACatalog.hxx"
39 
40 using namespace ::comphelper;
41 
42 using namespace connectivity::ado;
43 using namespace com::sun::star::uno;
44 using namespace com::sun::star::lang;
45 using namespace com::sun::star::beans;
46 using namespace com::sun::star::sdbc;
47 
48 void WpADOColumn::Create()
49 {
50 	HRESULT         hr = -1;
51 
52 	_ADOColumn* pColumn = NULL;
53 	hr = CoCreateInstance(ADOS::CLSID_ADOCOLUMN_25,
54 						  NULL,
55 						  CLSCTX_INPROC_SERVER,
56 						  ADOS::IID_ADOCOLUMN_25,
57 						  (void**)&pColumn );
58 
59 
60 	if( !FAILED( hr ) )
61 	{
62 		operator=( pColumn );
63 		pColumn->Release( );
64 	}
65 }
66 // -------------------------------------------------------------------------
67 OAdoColumn::OAdoColumn(sal_Bool _bCase,OConnection* _pConnection,_ADOColumn* _pColumn)
68 	: connectivity::sdbcx::OColumn(::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),0,0,0,0,sal_False,sal_False,sal_False,_bCase)
69 	,m_pConnection(_pConnection)
70 {
71 	construct();
72 	OSL_ENSURE(_pColumn,"Column can not be null!");
73 	m_aColumn = WpADOColumn(_pColumn);
74 	//	m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog());
75 	fillPropertyValues();
76 }
77 // -------------------------------------------------------------------------
78 OAdoColumn::OAdoColumn(sal_Bool _bCase,OConnection* _pConnection)
79 	: connectivity::sdbcx::OColumn(_bCase)
80 	,m_pConnection(_pConnection)
81 {
82 	m_aColumn.Create();
83 	m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog());
84 	construct();
85 	fillPropertyValues();
86 	m_Type = DataType::OTHER;
87 }
88 
89 //--------------------------------------------------------------------------
90 Sequence< sal_Int8 > OAdoColumn::getUnoTunnelImplementationId()
91 {
92 	static ::cppu::OImplementationId * pId = 0;
93 	if (! pId)
94 	{
95 		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
96 		if (! pId)
97 		{
98 			static ::cppu::OImplementationId aId;
99 			pId = &aId;
100 		}
101 	}
102 	return pId->getImplementationId();
103 }
104 
105 // com::sun::star::lang::XUnoTunnel
106 //------------------------------------------------------------------
107 sal_Int64 OAdoColumn::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
108 {
109 	return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
110 				? reinterpret_cast< sal_Int64 >( this )
111 				: OColumn_ADO::getSomething(rId);
112 }
113 // -------------------------------------------------------------------------
114 void OAdoColumn::construct()
115 {
116 	sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY;
117 
118 	registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISASCENDING),		PROPERTY_ID_ISASCENDING,	nAttrib,&m_IsAscending,	::getBooleanCppuType());
119 	registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RELATEDCOLUMN),	PROPERTY_ID_RELATEDCOLUMN,	nAttrib,&m_ReferencedColumn,	::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
120 }
121 // -----------------------------------------------------------------------------
122 void OAdoColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)throw (Exception)
123 {
124 	if(m_aColumn.IsValid())
125 	{
126 		const sal_Char* pAdoPropertyName = NULL;
127 
128 		switch(nHandle)
129 		{
130 			case PROPERTY_ID_ISASCENDING:
131 				m_aColumn.put_SortOrder(::cppu::any2bool(rValue) ? adSortAscending : adSortDescending);
132 				break;
133 			case PROPERTY_ID_RELATEDCOLUMN:
134 				{
135 					::rtl::OUString aVal;
136 					rValue >>= aVal;
137 					m_aColumn.put_RelatedColumn(aVal);
138 				}
139 				break;
140 			case PROPERTY_ID_NAME:
141 				{
142 					::rtl::OUString aVal;
143 					rValue >>= aVal;
144 					m_aColumn.put_Name(aVal);
145 				}
146 				break;
147 			case PROPERTY_ID_TYPE:
148 				{
149 					sal_Int32 nVal=0;
150 					rValue >>= nVal;
151 					m_aColumn.put_Type(ADOS::MapJdbc2ADOType(nVal,m_pConnection->getEngineType()));
152 				}
153 				break;
154 			case PROPERTY_ID_TYPENAME:
155 				//	rValue <<= m_pTable->getCatalog()->getConnection()->getTypeInfo()->find();
156 				break;
157 			case PROPERTY_ID_PRECISION:
158 				{
159 					sal_Int32 nVal=0;
160 					rValue >>= nVal;
161 					m_aColumn.put_Precision(nVal);
162 				}
163 				break;
164 			case PROPERTY_ID_SCALE:
165 				{
166 					sal_Int32 nVal=0;
167 					rValue >>= nVal;
168                     if ( !m_IsCurrency )
169 					    m_aColumn.put_NumericScale((sal_Int8)nVal);
170 				}
171 				break;
172 			case PROPERTY_ID_ISNULLABLE:
173 				{
174 					sal_Int32 nVal=0;
175 					rValue >>= nVal;
176 					if ( nVal == ColumnValue::NULLABLE )
177 						m_aColumn.put_Attributes( adColNullable );
178 				}
179 				break;
180 			case PROPERTY_ID_ISROWVERSION:
181 				break;
182 
183 			case PROPERTY_ID_ISAUTOINCREMENT:
184 				OTools::putValue( m_aColumn.get_Properties(), ::rtl::OUString::createFromAscii( "Autoincrement" ), getBOOL( rValue ) );
185 				break;
186 
187             case PROPERTY_ID_IM001:
188 			case PROPERTY_ID_DESCRIPTION:
189                 pAdoPropertyName = "Description";
190 				break;
191 
192 			case PROPERTY_ID_DEFAULTVALUE:
193 				pAdoPropertyName = "Default";
194 				break;
195 		}
196 
197 		if ( pAdoPropertyName )
198 			OTools::putValue( m_aColumn.get_Properties(), ::rtl::OUString::createFromAscii( pAdoPropertyName ), getString( rValue ) );
199 	}
200 	OColumn_ADO::setFastPropertyValue_NoBroadcast(nHandle,rValue);
201 }
202 // -----------------------------------------------------------------------------
203 void OAdoColumn::fillPropertyValues()
204 {
205 	if(m_aColumn.IsValid())
206 	{
207 		m_IsAscending		= m_aColumn.get_SortOrder() == adSortAscending;
208 		m_ReferencedColumn	= m_aColumn.get_RelatedColumn();
209 		m_Name				= m_aColumn.get_Name();
210 		m_Precision			= m_aColumn.get_Precision();
211 		m_Scale				= m_aColumn.get_NumericScale();
212 		m_IsNullable		= ((m_aColumn.get_Attributes() & adColNullable) == adColNullable) ? ColumnValue::NULLABLE : ColumnValue::NO_NULLS;
213 
214 		DataTypeEnum eType	= m_aColumn.get_Type();
215 		m_IsCurrency		= (eType == adCurrency);
216         if ( m_IsCurrency && !m_Scale)
217             m_Scale = 4;
218 		m_Type				= ADOS::MapADOType2Jdbc(eType);
219 
220 		sal_Bool bForceTo = sal_True;
221 		const OTypeInfoMap* pTypeInfoMap = m_pConnection->getTypeInfo();
222 		const OExtendedTypeInfo* pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),eType,::rtl::OUString(),m_Precision,m_Scale,bForceTo);
223 		if ( pTypeInfo )
224 			m_TypeName = pTypeInfo->aSimpleType.aTypeName;
225 		else if ( eType == adVarBinary && ADOS::isJetEngine(m_pConnection->getEngineType()) )
226 		{
227 			::comphelper::TStringMixEqualFunctor aCase(sal_False);
228 			OTypeInfoMap::const_iterator aFind = ::std::find_if(pTypeInfoMap->begin(),
229 															pTypeInfoMap->end(),
230 															::std::compose1(
231 															::std::bind2nd(aCase, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VarBinary"))),
232 																::std::compose1(
233 																	::std::mem_fun(&OExtendedTypeInfo::getDBName),
234 																	::std::select2nd<OTypeInfoMap::value_type>())
235 																)
236 
237 													);
238 
239 			if ( aFind != pTypeInfoMap->end() ) // change column type if necessary
240 			{
241 				eType = aFind->first;
242 				pTypeInfo = aFind->second;
243 			}
244 
245 			if ( !pTypeInfo )
246 			{
247 				pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),adBinary,::rtl::OUString(),m_Precision,m_Scale,bForceTo);
248 				eType = adBinary;
249 			}
250 
251 			if ( pTypeInfo )
252 			{
253 				m_TypeName = pTypeInfo->aSimpleType.aTypeName;
254 				m_Type	= ADOS::MapADOType2Jdbc(eType);
255 			}
256 		}
257 
258 
259 		// fill some specific props
260 		{
261 			WpADOProperties aProps( m_aColumn.get_Properties() );
262 
263 			if ( aProps.IsValid() )
264 			{
265 				m_IsAutoIncrement = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Autoincrement")) );
266 
267 				m_Description = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Description")) );
268 
269 				m_DefaultValue = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Default")) );
270 
271 #if OSL_DEBUG_LEVEL > 0
272 				sal_Int32 nCount = aProps.GetItemCount();
273 				for (sal_Int32 i = 0; i<nCount; ++i)
274 				{
275 					WpADOProperty aProp = aProps.GetItem(i);
276 					::rtl::OUString sName = aProp.GetName();
277 					::rtl::OUString sVal = aProp.GetValue();
278 				}
279 #endif
280 			}
281 		}
282 	}
283 }
284 // -----------------------------------------------------------------------------
285 WpADOColumn	OAdoColumn::getColumnImpl() const
286 {
287 	return m_aColumn;
288 }
289 // -----------------------------------------------------------------------------
290 // -----------------------------------------------------------------------------
291 void SAL_CALL OAdoColumn::acquire() throw()
292 {
293 	OColumn_ADO::acquire();
294 }
295 // -----------------------------------------------------------------------------
296 void SAL_CALL OAdoColumn::release() throw()
297 {
298 	OColumn_ADO::release();
299 }
300 // -----------------------------------------------------------------------------
301 
302 
303 
304