1*9b5730f6SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9b5730f6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9b5730f6SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9b5730f6SAndrew Rist * distributed with this work for additional information 6*9b5730f6SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9b5730f6SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9b5730f6SAndrew Rist * "License"); you may not use this file except in compliance 9*9b5730f6SAndrew Rist * with the License. You may obtain a copy of the License at 10*9b5730f6SAndrew Rist * 11*9b5730f6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*9b5730f6SAndrew Rist * 13*9b5730f6SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9b5730f6SAndrew Rist * software distributed under the License is distributed on an 15*9b5730f6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9b5730f6SAndrew Rist * KIND, either express or implied. See the License for the 17*9b5730f6SAndrew Rist * specific language governing permissions and limitations 18*9b5730f6SAndrew Rist * under the License. 19*9b5730f6SAndrew Rist * 20*9b5730f6SAndrew Rist *************************************************************/ 21*9b5730f6SAndrew Rist 22*9b5730f6SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "connectivity/formattedcolumnvalue.hxx" 28cdf0e10cSrcweir #include "connectivity/dbtools.hxx" 29cdf0e10cSrcweir #include "connectivity/dbconversion.hxx" 30cdf0e10cSrcweir 31cdf0e10cSrcweir /** === begin UNO includes === **/ 32cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatter.hpp> 33cdf0e10cSrcweir #include <com/sun/star/util/Date.hpp> 34cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp> 35cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatTypes.hpp> 36cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp> 37cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp> 38cdf0e10cSrcweir /** === end UNO includes === **/ 39cdf0e10cSrcweir 40cdf0e10cSrcweir //#include <unotools/syslocale.hxx> 41cdf0e10cSrcweir #include <tools/diagnose_ex.h> 42cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 43cdf0e10cSrcweir #include <comphelper/numbers.hxx> 44cdf0e10cSrcweir #include <comphelper/componentcontext.hxx> 45cdf0e10cSrcweir #include <unotools/sharedunocomponent.hxx> 46cdf0e10cSrcweir 47cdf0e10cSrcweir //........................................................................ 48cdf0e10cSrcweir namespace dbtools 49cdf0e10cSrcweir { 50cdf0e10cSrcweir //........................................................................ 51cdf0e10cSrcweir 52cdf0e10cSrcweir /** === begin UNO using === **/ 53cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 54cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY; 55cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW; 56cdf0e10cSrcweir using ::com::sun::star::uno::UNO_SET_THROW; 57cdf0e10cSrcweir using ::com::sun::star::uno::Exception; 58cdf0e10cSrcweir using ::com::sun::star::uno::RuntimeException; 59cdf0e10cSrcweir using ::com::sun::star::uno::Any; 60cdf0e10cSrcweir using ::com::sun::star::uno::makeAny; 61cdf0e10cSrcweir using ::com::sun::star::sdbc::XRowSet; 62cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet; 63cdf0e10cSrcweir using ::com::sun::star::util::XNumberFormatter; 64cdf0e10cSrcweir using ::com::sun::star::util::Date; 65cdf0e10cSrcweir using ::com::sun::star::sdbc::XConnection; 66cdf0e10cSrcweir using ::com::sun::star::util::XNumberFormatsSupplier; 67cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySetInfo; 68cdf0e10cSrcweir using ::com::sun::star::lang::Locale; 69cdf0e10cSrcweir using ::com::sun::star::util::XNumberFormatTypes; 70cdf0e10cSrcweir using ::com::sun::star::sdb::XColumn; 71cdf0e10cSrcweir using ::com::sun::star::sdb::XColumnUpdate; 72cdf0e10cSrcweir using ::com::sun::star::lang::XComponent; 73cdf0e10cSrcweir /** === end UNO using === **/ 74cdf0e10cSrcweir namespace DataType = ::com::sun::star::sdbc::DataType; 75cdf0e10cSrcweir namespace NumberFormat = ::com::sun::star::util::NumberFormat; 76cdf0e10cSrcweir 77cdf0e10cSrcweir //==================================================================== 78cdf0e10cSrcweir //= FormattedColumnValue_Data 79cdf0e10cSrcweir //==================================================================== 80cdf0e10cSrcweir struct FormattedColumnValue_Data 81cdf0e10cSrcweir { 82cdf0e10cSrcweir Reference< XNumberFormatter > m_xFormatter; 83cdf0e10cSrcweir Date m_aNullDate; 84cdf0e10cSrcweir sal_Int32 m_nFormatKey; 85cdf0e10cSrcweir sal_Int32 m_nFieldType; 86cdf0e10cSrcweir sal_Int16 m_nKeyType; 87cdf0e10cSrcweir bool m_bNumericField; 88cdf0e10cSrcweir 89cdf0e10cSrcweir Reference< XColumn > m_xColumn; 90cdf0e10cSrcweir Reference< XColumnUpdate > m_xColumnUpdate; 91cdf0e10cSrcweir FormattedColumnValue_Datadbtools::FormattedColumnValue_Data92cdf0e10cSrcweir FormattedColumnValue_Data() 93cdf0e10cSrcweir :m_xFormatter() 94cdf0e10cSrcweir ,m_aNullDate( DBTypeConversion::getStandardDate() ) 95cdf0e10cSrcweir ,m_nFormatKey( 0 ) 96cdf0e10cSrcweir ,m_nFieldType( DataType::OTHER ) 97cdf0e10cSrcweir ,m_nKeyType( NumberFormat::UNDEFINED ) 98cdf0e10cSrcweir ,m_bNumericField( false ) 99cdf0e10cSrcweir ,m_xColumn() 100cdf0e10cSrcweir ,m_xColumnUpdate() 101cdf0e10cSrcweir { 102cdf0e10cSrcweir } 103cdf0e10cSrcweir }; 104cdf0e10cSrcweir 105cdf0e10cSrcweir //-------------------------------------------------------------------- 106cdf0e10cSrcweir namespace 107cdf0e10cSrcweir { 108cdf0e10cSrcweir //................................................................ lcl_clear_nothrow(FormattedColumnValue_Data & _rData)109cdf0e10cSrcweir void lcl_clear_nothrow( FormattedColumnValue_Data& _rData ) 110cdf0e10cSrcweir { 111cdf0e10cSrcweir _rData.m_xFormatter.clear(); 112cdf0e10cSrcweir _rData.m_nFormatKey = 0; 113cdf0e10cSrcweir _rData.m_nFieldType = DataType::OTHER; 114cdf0e10cSrcweir _rData.m_nKeyType = NumberFormat::UNDEFINED; 115cdf0e10cSrcweir _rData.m_bNumericField = false; 116cdf0e10cSrcweir 117cdf0e10cSrcweir _rData.m_xColumn.clear(); 118cdf0e10cSrcweir _rData.m_xColumnUpdate.clear(); 119cdf0e10cSrcweir } 120cdf0e10cSrcweir 121cdf0e10cSrcweir //................................................................ lcl_initColumnDataValue_nothrow(FormattedColumnValue_Data & _rData,const Reference<XNumberFormatter> & i_rNumberFormatter,const Reference<XPropertySet> & _rxColumn)122cdf0e10cSrcweir void lcl_initColumnDataValue_nothrow( FormattedColumnValue_Data& _rData, 123cdf0e10cSrcweir const Reference< XNumberFormatter >& i_rNumberFormatter, const Reference< XPropertySet >& _rxColumn ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir lcl_clear_nothrow( _rData ); 126cdf0e10cSrcweir 127cdf0e10cSrcweir OSL_PRECOND( i_rNumberFormatter.is(), "lcl_initColumnDataValue_nothrow: no number formats -> no formatted values!" ); 128cdf0e10cSrcweir if ( !i_rNumberFormatter.is() ) 129cdf0e10cSrcweir return; 130cdf0e10cSrcweir 131cdf0e10cSrcweir try 132cdf0e10cSrcweir { 133cdf0e10cSrcweir Reference< XNumberFormatsSupplier > xNumberFormatsSupp( i_rNumberFormatter->getNumberFormatsSupplier(), UNO_SET_THROW ); 134cdf0e10cSrcweir 135cdf0e10cSrcweir // remember the column 136cdf0e10cSrcweir _rData.m_xColumn.set( _rxColumn, UNO_QUERY_THROW ); 137cdf0e10cSrcweir _rData.m_xColumnUpdate.set( _rxColumn, UNO_QUERY ); 138cdf0e10cSrcweir 139cdf0e10cSrcweir // determine the field type, and whether it's a numeric field 140cdf0e10cSrcweir OSL_VERIFY( _rxColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= _rData.m_nFieldType ); 141cdf0e10cSrcweir 142cdf0e10cSrcweir switch ( _rData.m_nFieldType ) 143cdf0e10cSrcweir { 144cdf0e10cSrcweir case DataType::DATE: 145cdf0e10cSrcweir case DataType::TIME: 146cdf0e10cSrcweir case DataType::TIMESTAMP: 147cdf0e10cSrcweir case DataType::BIT: 148cdf0e10cSrcweir case DataType::BOOLEAN: 149cdf0e10cSrcweir case DataType::TINYINT: 150cdf0e10cSrcweir case DataType::SMALLINT: 151cdf0e10cSrcweir case DataType::INTEGER: 152cdf0e10cSrcweir case DataType::REAL: 153cdf0e10cSrcweir case DataType::BIGINT: 154cdf0e10cSrcweir case DataType::DOUBLE: 155cdf0e10cSrcweir case DataType::NUMERIC: 156cdf0e10cSrcweir case DataType::DECIMAL: 157cdf0e10cSrcweir _rData.m_bNumericField = true; 158cdf0e10cSrcweir break; 159cdf0e10cSrcweir default: 160cdf0e10cSrcweir _rData.m_bNumericField = false; 161cdf0e10cSrcweir break; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir // get the format key of our bound field 165cdf0e10cSrcweir Reference< XPropertySetInfo > xPSI( _rxColumn->getPropertySetInfo(), UNO_QUERY_THROW ); 166cdf0e10cSrcweir bool bHaveFieldFormat = false; 167cdf0e10cSrcweir const ::rtl::OUString sFormatKeyProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FormatKey" ) ) ); 168cdf0e10cSrcweir if ( xPSI->hasPropertyByName( sFormatKeyProperty ) ) 169cdf0e10cSrcweir { 170cdf0e10cSrcweir bHaveFieldFormat = ( _rxColumn->getPropertyValue( sFormatKeyProperty ) >>= _rData.m_nFormatKey ); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir if ( !bHaveFieldFormat ) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir // fall back to a format key as indicated by the field type 175cdf0e10cSrcweir Locale aSystemLocale; 176cdf0e10cSrcweir MsLangId::convertLanguageToLocale( MsLangId::getSystemLanguage(), aSystemLocale ); 177cdf0e10cSrcweir Reference< XNumberFormatTypes > xNumTypes( xNumberFormatsSupp->getNumberFormats(), UNO_QUERY_THROW ); 178cdf0e10cSrcweir _rData.m_nFormatKey = getDefaultNumberFormat( _rxColumn, xNumTypes, aSystemLocale ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir // some more formatter settings 182cdf0e10cSrcweir _rData.m_nKeyType = ::comphelper::getNumberFormatType( xNumberFormatsSupp->getNumberFormats(), _rData.m_nFormatKey ); 183cdf0e10cSrcweir Reference< XPropertySet > xFormatSettings( xNumberFormatsSupp->getNumberFormatSettings(), UNO_QUERY_THROW ); 184cdf0e10cSrcweir OSL_VERIFY( xFormatSettings->getPropertyValue( ::rtl::OUString::createFromAscii( "NullDate" ) ) >>= _rData.m_aNullDate ); 185cdf0e10cSrcweir 186cdf0e10cSrcweir // remember the formatter 187cdf0e10cSrcweir _rData.m_xFormatter = i_rNumberFormatter; 188cdf0e10cSrcweir } 189cdf0e10cSrcweir catch( const Exception& ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 192cdf0e10cSrcweir } 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir //................................................................ lcl_initColumnDataValue_nothrow(const::comphelper::ComponentContext & i_rContext,FormattedColumnValue_Data & i_rData,const Reference<XRowSet> & i_rRowSet,const Reference<XPropertySet> & i_rColumn)196cdf0e10cSrcweir void lcl_initColumnDataValue_nothrow( const ::comphelper::ComponentContext& i_rContext, FormattedColumnValue_Data& i_rData, 197cdf0e10cSrcweir const Reference< XRowSet >& i_rRowSet, const Reference< XPropertySet >& i_rColumn ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir OSL_PRECOND( i_rRowSet.is(), "lcl_initColumnDataValue_nothrow: no row set!" ); 200cdf0e10cSrcweir if ( !i_rRowSet.is() ) 201cdf0e10cSrcweir return; 202cdf0e10cSrcweir 203cdf0e10cSrcweir Reference< XNumberFormatter > xNumberFormatter; 204cdf0e10cSrcweir try 205cdf0e10cSrcweir { 206cdf0e10cSrcweir // get the number formats supplier of the connection of the form 207cdf0e10cSrcweir Reference< XConnection > xConnection( getConnection( i_rRowSet ), UNO_QUERY_THROW ); 208cdf0e10cSrcweir Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( xConnection, sal_True, i_rContext.getLegacyServiceFactory() ), UNO_SET_THROW ); 209cdf0e10cSrcweir 210cdf0e10cSrcweir // create a number formatter for it 211cdf0e10cSrcweir xNumberFormatter.set( i_rContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW ); 212cdf0e10cSrcweir xNumberFormatter->attachNumberFormatsSupplier( xSupplier ); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir catch( const Exception& ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 217cdf0e10cSrcweir } 218cdf0e10cSrcweir 219cdf0e10cSrcweir lcl_initColumnDataValue_nothrow( i_rData, xNumberFormatter, i_rColumn ); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir } 222cdf0e10cSrcweir 223cdf0e10cSrcweir //==================================================================== 224cdf0e10cSrcweir //= FormattedColumnValue 225cdf0e10cSrcweir //==================================================================== 226cdf0e10cSrcweir //-------------------------------------------------------------------- FormattedColumnValue(const::comphelper::ComponentContext & i_rContext,const Reference<XRowSet> & _rxRowSet,const Reference<XPropertySet> & i_rColumn)227cdf0e10cSrcweir FormattedColumnValue::FormattedColumnValue( const ::comphelper::ComponentContext& i_rContext, 228cdf0e10cSrcweir const Reference< XRowSet >& _rxRowSet, const Reference< XPropertySet >& i_rColumn ) 229cdf0e10cSrcweir :m_pData( new FormattedColumnValue_Data ) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir lcl_initColumnDataValue_nothrow( i_rContext, *m_pData, _rxRowSet, i_rColumn ); 232cdf0e10cSrcweir } 233cdf0e10cSrcweir 234cdf0e10cSrcweir //-------------------------------------------------------------------- FormattedColumnValue(const Reference<XNumberFormatter> & i_rNumberFormatter,const Reference<XPropertySet> & _rxColumn)235cdf0e10cSrcweir FormattedColumnValue::FormattedColumnValue( const Reference< XNumberFormatter >& i_rNumberFormatter, 236cdf0e10cSrcweir const Reference< XPropertySet >& _rxColumn ) 237cdf0e10cSrcweir :m_pData( new FormattedColumnValue_Data ) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir lcl_initColumnDataValue_nothrow( *m_pData, i_rNumberFormatter, _rxColumn ); 240cdf0e10cSrcweir } 241cdf0e10cSrcweir 242cdf0e10cSrcweir //-------------------------------------------------------------------- clear()243cdf0e10cSrcweir void FormattedColumnValue::clear() 244cdf0e10cSrcweir { 245cdf0e10cSrcweir lcl_clear_nothrow( *m_pData ); 246cdf0e10cSrcweir } 247cdf0e10cSrcweir 248cdf0e10cSrcweir //-------------------------------------------------------------------- ~FormattedColumnValue()249cdf0e10cSrcweir FormattedColumnValue::~FormattedColumnValue() 250cdf0e10cSrcweir { 251cdf0e10cSrcweir clear(); 252cdf0e10cSrcweir } 253cdf0e10cSrcweir 254cdf0e10cSrcweir //-------------------------------------------------------------------- getFormatKey() const255cdf0e10cSrcweir sal_Int32 FormattedColumnValue::getFormatKey() const 256cdf0e10cSrcweir { 257cdf0e10cSrcweir return m_pData->m_nFormatKey; 258cdf0e10cSrcweir } 259cdf0e10cSrcweir 260cdf0e10cSrcweir //-------------------------------------------------------------------- getFieldType() const261cdf0e10cSrcweir sal_Int32 FormattedColumnValue::getFieldType() const 262cdf0e10cSrcweir { 263cdf0e10cSrcweir return m_pData->m_nFieldType; 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir //-------------------------------------------------------------------- getKeyType() const267cdf0e10cSrcweir sal_Int16 FormattedColumnValue::getKeyType() const 268cdf0e10cSrcweir { 269cdf0e10cSrcweir return m_pData->m_nKeyType; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir 272cdf0e10cSrcweir //-------------------------------------------------------------------- isNumericField() const273cdf0e10cSrcweir bool FormattedColumnValue::isNumericField() const 274cdf0e10cSrcweir { 275cdf0e10cSrcweir return m_pData->m_bNumericField; 276cdf0e10cSrcweir } 277cdf0e10cSrcweir 278cdf0e10cSrcweir //-------------------------------------------------------------------- getColumn() const279cdf0e10cSrcweir const Reference< XColumn >& FormattedColumnValue::getColumn() const 280cdf0e10cSrcweir { 281cdf0e10cSrcweir return m_pData->m_xColumn; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir 284cdf0e10cSrcweir //-------------------------------------------------------------------- getColumnUpdate() const285cdf0e10cSrcweir const Reference< XColumnUpdate >& FormattedColumnValue::getColumnUpdate() const 286cdf0e10cSrcweir { 287cdf0e10cSrcweir return m_pData->m_xColumnUpdate; 288cdf0e10cSrcweir } 289cdf0e10cSrcweir 290cdf0e10cSrcweir //-------------------------------------------------------------------- setFormattedValue(const::rtl::OUString & _rFormattedStringValue) const291cdf0e10cSrcweir bool FormattedColumnValue::setFormattedValue( const ::rtl::OUString& _rFormattedStringValue ) const 292cdf0e10cSrcweir { 293cdf0e10cSrcweir OSL_PRECOND( m_pData->m_xColumnUpdate.is(), "FormattedColumnValue::setFormattedValue: no column!" ); 294cdf0e10cSrcweir if ( !m_pData->m_xColumnUpdate.is() ) 295cdf0e10cSrcweir return false; 296cdf0e10cSrcweir 297cdf0e10cSrcweir try 298cdf0e10cSrcweir { 299cdf0e10cSrcweir if ( m_pData->m_bNumericField ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir ::dbtools::DBTypeConversion::setValue( m_pData->m_xColumnUpdate, m_pData->m_xFormatter, m_pData->m_aNullDate, 302cdf0e10cSrcweir _rFormattedStringValue, m_pData->m_nFormatKey, ::sal::static_int_cast< sal_Int16 >( m_pData->m_nFieldType ), 303cdf0e10cSrcweir m_pData->m_nKeyType ); 304cdf0e10cSrcweir } 305cdf0e10cSrcweir else 306cdf0e10cSrcweir { 307cdf0e10cSrcweir m_pData->m_xColumnUpdate->updateString( _rFormattedStringValue ); 308cdf0e10cSrcweir } 309cdf0e10cSrcweir } 310cdf0e10cSrcweir catch( const Exception& ) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir return false; 313cdf0e10cSrcweir } 314cdf0e10cSrcweir return true; 315cdf0e10cSrcweir } 316cdf0e10cSrcweir 317cdf0e10cSrcweir //-------------------------------------------------------------------- getFormattedValue() const318cdf0e10cSrcweir ::rtl::OUString FormattedColumnValue::getFormattedValue() const 319cdf0e10cSrcweir { 320cdf0e10cSrcweir OSL_PRECOND( m_pData->m_xColumn.is(), "FormattedColumnValue::setFormattedValue: no column!" ); 321cdf0e10cSrcweir 322cdf0e10cSrcweir ::rtl::OUString sStringValue; 323cdf0e10cSrcweir if ( m_pData->m_xColumn.is() ) 324cdf0e10cSrcweir { 325cdf0e10cSrcweir if ( m_pData->m_bNumericField ) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir sStringValue = DBTypeConversion::getFormattedValue( 328cdf0e10cSrcweir m_pData->m_xColumn, m_pData->m_xFormatter, m_pData->m_aNullDate, m_pData->m_nFormatKey, m_pData->m_nKeyType 329cdf0e10cSrcweir ); 330cdf0e10cSrcweir } 331cdf0e10cSrcweir else 332cdf0e10cSrcweir { 333cdf0e10cSrcweir sStringValue = m_pData->m_xColumn->getString(); 334cdf0e10cSrcweir } 335cdf0e10cSrcweir } 336cdf0e10cSrcweir return sStringValue; 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir //........................................................................ 340cdf0e10cSrcweir } // namespace dbtools 341cdf0e10cSrcweir //........................................................................ 342