diff options
87 files changed, 4182 insertions, 1262 deletions
diff --git a/dbaccess/inc/dbaccess_helpid.hrc b/dbaccess/inc/dbaccess_helpid.hrc index 155e45906..0dcf6d624 100644 --- a/dbaccess/inc/dbaccess_helpid.hrc +++ b/dbaccess/inc/dbaccess_helpid.hrc @@ -327,7 +327,7 @@ #define HID_APP_VIEW_PREVIEW_CB (HID_DBACCESS_START + 276) #define HID_APP_VIEW_PREVIEW_1 (HID_DBACCESS_START + 277) #define HID_APP_VIEW_PREVIEW_2 (HID_DBACCESS_START + 278) -// free +#define HID_TABDESIGN_HELPTEXT (HID_DBACCESS_START + 279) #define UID_APP_VIEW_HORZ_SPLIT (HID_DBACCESS_START + 280) #define UID_APP_VIEW_PREVIEW_1 (HID_DBACCESS_START + 281) #define HID_APP_VIEW_PREVIEW_3 (HID_DBACCESS_START + 282) diff --git a/dbaccess/qa/complex/dbaccess/DatabaseDocument.java b/dbaccess/qa/complex/dbaccess/DatabaseDocument.java index 82b6aedf7..20ae86207 100644 --- a/dbaccess/qa/complex/dbaccess/DatabaseDocument.java +++ b/dbaccess/qa/complex/dbaccess/DatabaseDocument.java @@ -839,8 +839,8 @@ public class DatabaseDocument extends TestCase implements com.sun.star.document. final String otherURL = copyToTempFile(databaseDoc.getURL()); final XModel otherDoc = (XModel) UnoRuntime.queryInterface(XModel.class, loader.loadComponentFromURL(otherURL, _BLANK, 0, impl_getDefaultLoadArgs())); - impl_waitForEvent(m_globalEvents, "OnLoad", 5000, previousOnLoadEventPos + 1); impl_raise(otherDoc); + impl_waitForEvent(m_globalEvents, "OnLoad", 5000, previousOnLoadEventPos + 1); // ... and switch between the two impl_startObservingEvents(context); diff --git a/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java b/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java index 179264c46..6eb0525b9 100755 --- a/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java +++ b/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java @@ -52,6 +52,7 @@ public class SingleSelectQueryComposer extends CRMBasedTestCase { return new String[] { + "testSetCommand", "testAttributes", "testSubQueries", "testParameters", @@ -127,7 +128,32 @@ public class SingleSelectQueryComposer extends CRMBasedTestCase realValue.equals(_attributeValue)); log.println(" (results in " + (String) m_composer.getQuery() + ")"); } + + /** tests setCommand of the composer + */ + public void testSetCommand() + { + log.println("testing SingleSelectQueryComposer's setCommand"); + try + { + final String table = "SELECT * FROM \"customers\""; + m_composer.setCommand("customers",CommandType.TABLE); + assure("setCommand/getQuery TABLE inconsistent", m_composer.getQuery().equals(table)); + + m_database.getDatabase().getDataSource().createQuery("set command test", "SELECT * FROM \"orders for customer\" \"a\", \"customers\" \"b\" WHERE \"a\".\"Product Name\" = \"b\".\"Name\""); + m_composer.setCommand("set command test",CommandType.QUERY); + assure("setCommand/getQuery QUERY inconsistent", m_composer.getQuery().equals(m_database.getDatabase().getDataSource().getQueryDefinition("set command test").getCommand())); + + final String sql = "SELECT * FROM \"orders for customer\" WHERE \"Product Name\" = 'test'"; + m_composer.setCommand(sql,CommandType.COMMAND); + assure("setCommand/getQuery COMMAND inconsistent", m_composer.getQuery().equals(sql)); + } + catch (Exception e) + { + assure("Exception caught: " + e, false); + } + } /** tests accessing attributes of the composer (order, filter, group by, having) */ public void testAttributes() @@ -136,6 +162,11 @@ public class SingleSelectQueryComposer extends CRMBasedTestCase try { + log.println("check setElementaryQuery"); + final String simpleQuery2 = "SELECT * FROM \"customers\" WHERE \"Name\" = 'oranges'"; + m_composer.setElementaryQuery(simpleQuery2); + assure("setElementaryQuery/getQuery inconsistent", m_composer.getQuery().equals(simpleQuery2)); + log.println("check setQuery"); final String simpleQuery = "SELECT * FROM \"customers\""; m_composer.setQuery(simpleQuery); @@ -260,7 +291,7 @@ public class SingleSelectQueryComposer extends CRMBasedTestCase filter.addProperty("Type", PropertyAttribute.MAYBEVOID, Integer.valueOf(DataType.LONGVARCHAR)); final XPropertySet column = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,filter); - m_composer.appendFilterByColumn(column, true); + m_composer.appendFilterByColumn(column, true,SQLFilterOperator.LIKE); assure("At least one row should exist",m_database.getConnection().createStatement().executeQuery(m_composer.getQuery()).next()); } diff --git a/dbaccess/source/core/api/CRowSetColumn.cxx b/dbaccess/source/core/api/CRowSetColumn.cxx index c7b1f5e12..60c4fe1d4 100644 --- a/dbaccess/source/core/api/CRowSetColumn.cxx +++ b/dbaccess/source/core/api/CRowSetColumn.cxx @@ -50,8 +50,8 @@ namespace dbaccess //------------------------------------------------------------------------------ ORowSetColumn::ORowSetColumn( const Reference < XResultSetMetaData >& _xMetaData, const Reference < XRow >& _xRow, sal_Int32 _nPos, - const Reference< XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rDescription, ORowSetCacheIterator& _rColumnValue ) - :ORowSetDataColumn( _xMetaData, _xRow, NULL, _nPos, _rxDBMeta, _rDescription, _rColumnValue ) + const Reference< XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rDescription, const ::rtl::OUString& i_sLabel,ORowSetCacheIterator& _rColumnValue ) + :ORowSetDataColumn( _xMetaData, _xRow, NULL, _nPos, _rxDBMeta, _rDescription, i_sLabel,_rColumnValue ) { } @@ -70,7 +70,7 @@ ORowSetColumn::ORowSetColumn( const Reference < XResultSetMetaData >& _xMetaData DECL_PROP1_BOOL( ISCURRENCY, READONLY ); DECL_PROP1_BOOL( ISDEFINITELYWRITABLE, READONLY ); DECL_PROP1( ISNULLABLE, sal_Int32, READONLY ); - DECL_PROP1_BOOL( ISREADONLY, READONLY ); + DECL_PROP1_BOOL( ISREADONLY, BOUND ); DECL_PROP1_BOOL( ISROWVERSION, READONLY ); DECL_PROP1_BOOL( ISSEARCHABLE, READONLY ); DECL_PROP1_BOOL( ISSIGNED, READONLY ); diff --git a/dbaccess/source/core/api/CRowSetColumn.hxx b/dbaccess/source/core/api/CRowSetColumn.hxx index 58d50bb9b..3b16166da 100644 --- a/dbaccess/source/core/api/CRowSetColumn.hxx +++ b/dbaccess/source/core/api/CRowSetColumn.hxx @@ -53,6 +53,7 @@ namespace dbaccess sal_Int32 _nPos, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rDescription, + const ::rtl::OUString& i_sLabel, ORowSetCacheIterator& _rColumnValue); virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; diff --git a/dbaccess/source/core/api/CRowSetDataColumn.cxx b/dbaccess/source/core/api/CRowSetDataColumn.cxx index 7ef0b2167..502a0a631 100644 --- a/dbaccess/source/core/api/CRowSetDataColumn.cxx +++ b/dbaccess/source/core/api/CRowSetDataColumn.cxx @@ -71,9 +71,11 @@ ORowSetDataColumn::ORowSetDataColumn( const Reference < XResultSetMetaData >& _x sal_Int32 _nPos, const Reference< XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rDescription, + const ::rtl::OUString& i_sLabel, const ORowSetCacheIterator& _rColumnValue) :ODataColumn(_xMetaData,_xRow,_xRowUpdate,_nPos,_rxDBMeta) ,m_aColumnValue(_rColumnValue) + ,m_sLabel(i_sLabel) ,m_aDescription(_rDescription) { DBG_CTOR(ORowSetDataColumn,NULL); @@ -102,7 +104,7 @@ ORowSetDataColumn::~ORowSetDataColumn() DECL_PROP1_BOOL( ISCURRENCY, READONLY ); DECL_PROP1_BOOL( ISDEFINITELYWRITABLE, READONLY ); DECL_PROP1( ISNULLABLE, sal_Int32, READONLY ); - DECL_PROP1_BOOL( ISREADONLY, READONLY ); + DECL_PROP1_BOOL( ISREADONLY, BOUND ); DECL_PROP1_BOOL( ISROWVERSION, READONLY ); DECL_PROP1_BOOL( ISSEARCHABLE, READONLY ); DECL_PROP1_BOOL( ISSIGNED, READONLY ); @@ -146,6 +148,8 @@ void SAL_CALL ORowSetDataColumn::getFastPropertyValue( Any& rValue, sal_Int32 nH rValue = ((*m_aColumnValue)->get())[m_nPos].makeAny(); } } + else if ( PROPERTY_ID_LABEL == nHandle && m_sLabel.getLength() ) + rValue <<= m_sLabel; else ODataColumn::getFastPropertyValue( rValue, nHandle ); } @@ -153,13 +157,21 @@ void SAL_CALL ORowSetDataColumn::getFastPropertyValue( Any& rValue, sal_Int32 nH // ------------------------------------------------------------------------- void SAL_CALL ORowSetDataColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue )throw (Exception) { - if ( PROPERTY_ID_VALUE == nHandle ) - { - updateObject(rValue); - } - else + switch( nHandle ) { - ODataColumn::setFastPropertyValue_NoBroadcast( nHandle,rValue ); + case PROPERTY_ID_VALUE: + updateObject(rValue); + break; + case PROPERTY_ID_ISREADONLY: + { + sal_Bool bVal = sal_False; + rValue >>= bVal; + m_isReadOnly.reset(bVal); + } + break; + default: + ODataColumn::setFastPropertyValue_NoBroadcast( nHandle,rValue ); + break; } } // ------------------------------------------------------------------------- @@ -169,14 +181,26 @@ sal_Bool SAL_CALL ORowSetDataColumn::convertFastPropertyValue( Any & rConvertedV const Any& rValue ) throw (IllegalArgumentException) { sal_Bool bModified = sal_False; - if ( PROPERTY_ID_VALUE == nHandle ) + switch( nHandle ) { - rConvertedValue = rValue; - getFastPropertyValue(rOldValue, PROPERTY_ID_VALUE); - bModified = rConvertedValue != rOldValue; + case PROPERTY_ID_VALUE: + { + rConvertedValue = rValue; + getFastPropertyValue(rOldValue, PROPERTY_ID_VALUE); + bModified = rConvertedValue != rOldValue; + } + break; + case PROPERTY_ID_ISREADONLY: + { + rConvertedValue = rValue; + getFastPropertyValue(rOldValue, PROPERTY_ID_ISREADONLY); + bModified = rConvertedValue != rOldValue; + } + break; + default: + bModified = ODataColumn::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); + break; } - else - bModified = ODataColumn::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); return bModified; } diff --git a/dbaccess/source/core/api/CRowSetDataColumn.hxx b/dbaccess/source/core/api/CRowSetDataColumn.hxx index c3b698c5c..90677d117 100644 --- a/dbaccess/source/core/api/CRowSetDataColumn.hxx +++ b/dbaccess/source/core/api/CRowSetDataColumn.hxx @@ -48,6 +48,7 @@ namespace dbaccess ORowSetCacheIterator m_aColumnValue; ::com::sun::star::uno::Any m_aOldValue; + ::rtl::OUString m_sLabel; ::rtl::OUString m_aDescription; // description ORowSetBase* m_pRowSet; @@ -59,6 +60,7 @@ namespace dbaccess sal_Int32 _nPos, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rDescription, + const ::rtl::OUString& i_sLabel, const ORowSetCacheIterator& _rColumnValue); @@ -78,7 +80,6 @@ namespace dbaccess virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const ::com::sun::star::uno::Any& rValue )throw (::com::sun::star::uno::Exception); virtual void fireValueChange(const ::connectivity::ORowSetValue& _rOldValue); - protected: using ODataColumn::getFastPropertyValue; }; diff --git a/dbaccess/source/core/api/CacheSet.cxx b/dbaccess/source/core/api/CacheSet.cxx index 5fd214c83..7f53434b3 100644 --- a/dbaccess/source/core/api/CacheSet.cxx +++ b/dbaccess/source/core/api/CacheSet.cxx @@ -271,32 +271,8 @@ void OCacheSet::fillParameters( const ORowSetRow& _rRow RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::fillParameters" ); // use keys and indexes for excat postioning // first the keys - Reference<XKeysSupplier> xKeySup(_xTable,UNO_QUERY); - Reference<XIndexAccess> xKeys; - if(xKeySup.is()) - xKeys = xKeySup->getKeys(); - - Reference<XColumnsSupplier> xKeyColsSup; - Reference<XNameAccess> xKeyColumns; - if(xKeys.is() && xKeys->getCount()) - { - Reference<XPropertySet> xProp; - Reference<XColumnsSupplier> xColumnsSupplier; - // search the one and only primary key - for(sal_Int32 i=0;i< xKeys->getCount();++i) - { - ::cppu::extractInterface(xProp,xKeys->getByIndex(i)); - sal_Int32 nKeyType = 0; - xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; - if(KeyType::PRIMARY == nKeyType) - { - xKeyColsSup.set(xProp,UNO_QUERY); - break; - } - } - if(xKeyColsSup.is()) - xKeyColumns = xKeyColsSup->getColumns(); - } + Reference<XPropertySet> xSet(_xTable,UNO_QUERY); + const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet); // second the indexes Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY); Reference<XIndexAccess> xIndexes; @@ -311,7 +287,7 @@ void OCacheSet::fillParameters( const ORowSetRow& _rRow { for(sal_Int32 j=0;j<xIndexes->getCount();++j) { - ::cppu::extractInterface(xIndexColsSup,xIndexes->getByIndex(j)); + xIndexColsSup.set(xIndexes->getByIndex(j),UNO_QUERY); if( xIndexColsSup.is() && comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE)) && !comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX)) @@ -337,7 +313,7 @@ void OCacheSet::fillParameters( const ORowSetRow& _rRow for(; aIter != aEnd;++aIter,++nCheckCount,++i) { aColumnName = m_xSetMetaData->getColumnName(i); - if(xKeyColumns.is() && xKeyColumns->hasByName(aColumnName)) + if(xPrimaryKeyColumns.is() && xPrimaryKeyColumns->hasByName(aColumnName)) { _sCondition.append(::dbtools::quoteName( aQuote,aColumnName)); if(aIter->isNull()) @@ -347,7 +323,7 @@ void OCacheSet::fillParameters( const ORowSetRow& _rRow _sCondition.append(aAnd); _rOrgValues.push_back(nCheckCount); - } // if(xKeyColumns.is() && xKeyColumns->hasByName(aColumnName)) + } // if(xPrimaryKeyColumns.is() && xPrimaryKeyColumns->hasByName(aColumnName)) ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end(); for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin(); aIndexIter != aIndexEnd;++aIndexIter) @@ -436,32 +412,7 @@ void SAL_CALL OCacheSet::deleteRow(const ORowSetRow& _rDeleteRow ,const connecti // use keys and indexes for excat postioning // first the keys - Reference<XKeysSupplier> xKeySup(_xTable,UNO_QUERY); - Reference<XIndexAccess> xKeys; - if(xKeySup.is()) - xKeys = xKeySup->getKeys(); - - Reference<XColumnsSupplier> xKeyColsSup; - Reference<XNameAccess> xKeyColumns; - if(xKeys.is() && xKeys->getCount()) - { - Reference<XPropertySet> xProp; - Reference<XColumnsSupplier> xColumnsSupplier; - // search the one and only primary key - for(sal_Int32 i=0;i< xKeys->getCount();++i) - { - ::cppu::extractInterface(xProp,xKeys->getByIndex(i)); - sal_Int32 nKeyType = 0; - xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; - if(KeyType::PRIMARY == nKeyType) - { - xKeyColsSup.set(xProp,UNO_QUERY); - break; - } - } - if(xKeyColsSup.is()) - xKeyColumns = xKeyColsSup->getColumns(); - } + const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet); // second the indexes Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY); Reference<XIndexAccess> xIndexes; @@ -508,7 +459,7 @@ void OCacheSet::setParameter(sal_Int32 nPos ,const Reference< XParameters >& _xParameter ,const ORowSetValue& _rValue ,sal_Int32 _nType - ,sal_Int32 _nScale) + ,sal_Int32 _nScale) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::setParameter" ); sal_Int32 nType = ( _nType != DataType::OTHER ) ? _nType : _rValue.getTypeKind(); @@ -770,3 +721,33 @@ Reference< XInterface > SAL_CALL OCacheSet::getStatement( ) throw(SQLException, return m_xDriverSet->getStatement(); } // ----------------------------------------------------------------------------- +bool OCacheSet::isResultSetChanged() const +{ + return false; +} +// ----------------------------------------------------------------------------- +void OCacheSet::reset(const Reference< XResultSet>& /*_xDriverSet*/) +{ + OSL_ENSURE(0,"Illegal call!"); +} +// ----------------------------------------------------------------------------- +void OCacheSet::mergeColumnValues(sal_Int32 i_nColumnIndex,ORowSetValueVector::Vector& /*io_aInsertRow*/,ORowSetValueVector::Vector& /*io_aRow*/,::std::vector<sal_Int32>& o_aChangedColumns) +{ + o_aChangedColumns.push_back(i_nColumnIndex); +} +// ----------------------------------------------------------------------------- +bool OCacheSet::columnValuesUpdated(ORowSetValueVector::Vector& /*io_aCachedRow*/,const ORowSetValueVector::Vector& /*io_aRow*/) +{ + return false; +} +// ----------------------------------------------------------------------------- +bool OCacheSet::updateColumnValues(const ORowSetValueVector::Vector& /*io_aCachedRow*/,ORowSetValueVector::Vector& /*io_aRow*/,const ::std::vector<sal_Int32>& /*i_aChangedColumns*/) +{ + return true; +} +// ----------------------------------------------------------------------------- +void OCacheSet::fillMissingValues(ORowSetValueVector::Vector& /*io_aRow*/) const +{ +} +// ----------------------------------------------------------------------------- + diff --git a/dbaccess/source/core/api/CacheSet.hxx b/dbaccess/source/core/api/CacheSet.hxx index 0c972b0c1..59601137b 100644 --- a/dbaccess/source/core/api/CacheSet.hxx +++ b/dbaccess/source/core/api/CacheSet.hxx @@ -95,7 +95,7 @@ namespace dbaccess ,const connectivity::ORowSetValue& _rValue ,sal_Int32 _nType ,sal_Int32 _nScale - ); + ) const; void fillParameters( const ORowSetRow& _rRow ,const connectivity::OSQLTable& _xTable ,::rtl::OUStringBuffer& _sCondition @@ -166,6 +166,13 @@ namespace dbaccess virtual void SAL_CALL cancelRowUpdates( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; virtual void SAL_CALL moveToInsertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; virtual void SAL_CALL moveToCurrentRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; + + virtual bool isResultSetChanged() const; + virtual void reset(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet); + virtual void mergeColumnValues(sal_Int32 i_nColumnIndex,ORowSetValueVector::Vector& io_aInsertRow,ORowSetValueVector::Vector& io_aRow,::std::vector<sal_Int32>& o_aChangedColumns); + virtual bool columnValuesUpdated(ORowSetValueVector::Vector& o_aCachedRow,const ORowSetValueVector::Vector& i_aRow); + virtual bool updateColumnValues(const ORowSetValueVector::Vector& io_aCachedRow,ORowSetValueVector::Vector& io_aRow,const ::std::vector<sal_Int32>& i_aChangedColumns); + virtual void fillMissingValues(ORowSetValueVector::Vector& io_aRow) const; }; } #endif //DBACCESS_CORE_API_CACHESET_HXX diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx index 2ab840502..3db4acdbc 100644 --- a/dbaccess/source/core/api/KeySet.cxx +++ b/dbaccess/source/core/api/KeySet.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2010 Oracle andor its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -347,8 +347,7 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O { Reference<XPropertySet> xPara(xQueryParameters->getByIndex(i),UNO_QUERY_THROW); xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i]; - } - + } ::rtl::OUString sCatalog,sSchema,sTable; @@ -466,6 +465,7 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O } } } // if ( aSeq.getLength() > 1 ) // special handling for join + if ( i_sRowSetFilter.getLength() ) { FilterCreator aFilterCreator; @@ -781,6 +781,7 @@ void SAL_CALL OKeySet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow m_aKeyIter = m_aKeyMap.find(nBookmark); m_aKeyIter->second.second.first = 2; m_aKeyIter->second.second.second = xRow; + copyRowValue(_rInsertRow,m_aKeyIter->second.first,nBookmark); } } @@ -947,6 +948,7 @@ void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivi ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >((*m_pKeyColumnNames).size()); copyRowValue(_rInsertRow,aKeyRow,aKeyIter->first + 1); + m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(aKeyIter->first + 1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(1,NULL)))).first; // now we set the bookmark for this row (_rInsertRow->get())[0] = makeAny((sal_Int32)m_aKeyIter->first); @@ -1123,9 +1125,9 @@ Reference<XNameAccess> OKeySet::getKeyColumns() const Reference<XIndexAccess> xKeys = m_xTableKeys; if ( !xKeys.is() ) { - Reference<XKeysSupplier> xKeySup(m_xTable,UNO_QUERY); - if(xKeySup.is()) - xKeys = xKeySup->getKeys(); + Reference<XPropertySet> xSet(m_xTable,UNO_QUERY); + const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet); + return xPrimaryKeyColumns; } Reference<XColumnsSupplier> xKeyColsSup; @@ -1612,52 +1614,65 @@ namespace dbaccess { void getColumnPositions(const Reference<XNameAccess>& _rxQueryColumns, - const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rColumnNames, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _aColumnNames, const ::rtl::OUString& _rsUpdateTableName, - SelectColumnsMetaData& _rColumnAssignments) - + SelectColumnsMetaData& o_rColumnNames, + bool i_bAppendTableName) { // get the real name of the columns Sequence< ::rtl::OUString> aSelNames(_rxQueryColumns->getElementNames()); - const ::rtl::OUString* pSelBegin = aSelNames.getConstArray(); - const ::rtl::OUString* pSelEnd = pSelBegin + aSelNames.getLength(); + const ::rtl::OUString* pSelIter = aSelNames.getConstArray(); + const ::rtl::OUString* pSelEnd = pSelIter + aSelNames.getLength(); - const ::rtl::OUString* pColumnIter = _rColumnNames.getConstArray(); - const ::rtl::OUString* pColumnEnd = pColumnIter + _rColumnNames.getLength(); + const ::rtl::OUString* pTblColumnIter = _aColumnNames.getConstArray(); + const ::rtl::OUString* pTblColumnEnd = pTblColumnIter + _aColumnNames.getLength(); - ::comphelper::UStringMixLess aTmp(_rColumnAssignments.key_comp()); + + ::comphelper::UStringMixLess aTmp(o_rColumnNames.key_comp()); ::comphelper::UStringMixEqual bCase(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive()); - for(sal_Int32 nPos = 1;pSelBegin != pSelEnd;++pSelBegin,++nPos) + for(sal_Int32 nPos = 1;pSelIter != pSelEnd;++pSelIter,++nPos) { - Reference<XPropertySet> xColumnProp(_rxQueryColumns->getByName(*pSelBegin),UNO_QUERY); + Reference<XPropertySet> xQueryColumnProp(_rxQueryColumns->getByName(*pSelIter),UNO_QUERY_THROW); ::rtl::OUString sRealName,sTableName; - OSL_ENSURE(xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!"); - OSL_ENSURE(xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!"); - xColumnProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName; - xColumnProp->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName; + OSL_ENSURE(xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!"); + OSL_ENSURE(xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!"); + xQueryColumnProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName; + xQueryColumnProp->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName; - for(;pColumnIter != pColumnEnd;++pColumnIter) + for(;pTblColumnIter != pTblColumnEnd;++pTblColumnIter) { - if(bCase(sRealName,*pColumnIter) && bCase(_rsUpdateTableName,sTableName) && _rColumnAssignments.find(*pColumnIter) == _rColumnAssignments.end()) + if(bCase(sRealName,*pTblColumnIter) && bCase(_rsUpdateTableName,sTableName) && o_rColumnNames.find(*pTblColumnIter) == o_rColumnNames.end()) { sal_Int32 nType = 0; - xColumnProp->getPropertyValue(PROPERTY_TYPE) >>= nType; + xQueryColumnProp->getPropertyValue(PROPERTY_TYPE) >>= nType; sal_Int32 nScale = 0; - xColumnProp->getPropertyValue(PROPERTY_SCALE) >>= nScale; + xQueryColumnProp->getPropertyValue(PROPERTY_SCALE) >>= nScale; ::rtl::OUString sColumnDefault; - if ( xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE) ) - xColumnProp->getPropertyValue(PROPERTY_DEFAULTVALUE) >>= sColumnDefault; + if ( xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE) ) + xQueryColumnProp->getPropertyValue(PROPERTY_DEFAULTVALUE) >>= sColumnDefault; - sal_Int32 bNullable = sal_False; - xColumnProp->getPropertyValue(PROPERTY_ISNULLABLE) >>= bNullable; + sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN; + OSL_VERIFY( xQueryColumnProp->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable ); + + if ( i_bAppendTableName ) + { + ::rtl::OUStringBuffer sName; + sName.append(sTableName); + sName.appendAscii("."); + sName.append(sRealName); + SelectColumnDescription aColDesc( nPos, nType,nScale,nNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault ); + aColDesc.sRealName = sRealName; + aColDesc.sTableName = sTableName; + o_rColumnNames[sName.makeStringAndClear()] = aColDesc; + } + else + o_rColumnNames[sRealName] = SelectColumnDescription( nPos, nType,nScale,nNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault ); - - _rColumnAssignments[sRealName] = SelectColumnDescription( nPos, nType,nScale,bNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault ); break; } } - pColumnIter = _rColumnNames.getConstArray(); + pTblColumnIter = _aColumnNames.getConstArray(); } } } diff --git a/dbaccess/source/core/api/KeySet.hxx b/dbaccess/source/core/api/KeySet.hxx index 4df85d277..947f8e161 100644 --- a/dbaccess/source/core/api/KeySet.hxx +++ b/dbaccess/source/core/api/KeySet.hxx @@ -51,28 +51,30 @@ namespace dbaccess { struct SelectColumnDescription { + ::rtl::OUString sRealName; // may be empty + ::rtl::OUString sTableName; // may be empty + ::rtl::OUString sDefaultValue; sal_Int32 nPosition; sal_Int32 nType; sal_Int32 nScale; sal_Bool bNullable; - ::rtl::OUString sDefaultValue; + SelectColumnDescription() :nPosition( 0 ) ,nType( 0 ) ,nScale( 0 ) ,bNullable(sal_False) - ,sDefaultValue() { } SelectColumnDescription( sal_Int32 _nPosition, sal_Int32 _nType, sal_Int32 _nScale,sal_Bool _bNullable, const ::rtl::OUString& _rDefaultValue ) - :nPosition( _nPosition ) + :sDefaultValue( _rDefaultValue ) + ,nPosition( _nPosition ) ,nType( _nType ) ,nScale( _nScale ) ,bNullable(_bNullable) - ,sDefaultValue( _rDefaultValue ) { } }; @@ -82,7 +84,8 @@ namespace dbaccess void getColumnPositions(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxQueryColumns, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rColumnNames, const ::rtl::OUString& _rsUpdateTableName, - SelectColumnsMetaData& _rColumnAssignments /* out */); + SelectColumnsMetaData& o_rColumnNames /* out */, + bool i_bAppendTableName = false); typedef ::std::pair<ORowSetRow,::std::pair<sal_Int32,::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow> > > OKeySetValue; typedef ::std::map<sal_Int32,OKeySetValue > OKeySetMatrix; diff --git a/dbaccess/source/core/api/OptimisticSet.cxx b/dbaccess/source/core/api/OptimisticSet.cxx new file mode 100644 index 000000000..1dc198140 --- /dev/null +++ b/dbaccess/source/core/api/OptimisticSet.cxx @@ -0,0 +1,1689 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OptimisticSet.cxx,v $ + * $Revision: 1.73 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#include "OptimisticSet.hxx" +#include "core_resource.hxx" +#include "core_resource.hrc" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/sdbc/XDatabaseMetaData.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/XPreparedStatement.hpp> +#include <com/sun/star/sdbc/XParameters.hpp> +#include <com/sun/star/sdbc/XGeneratedResultSet.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/sdb/SQLFilterOperator.hpp> +#include <com/sun/star/sdbc/XColumnLocate.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include "dbastrings.hrc" +#include "apitools.hxx" +#include <com/sun/star/sdbcx/XKeysSupplier.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/sdbcx/XIndexesSupplier.hpp> +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/types.hxx> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <connectivity/dbtools.hxx> +#include <connectivity/dbexception.hxx> +#include <list> +#include <algorithm> +#include <string.h> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +#include "querycomposer.hxx" +#include "composertools.hxx" +#include <tools/debug.hxx> +#include <string.h> +#include <rtl/logfile.hxx> + +using namespace dbaccess; +using namespace ::connectivity; +using namespace ::dbtools; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star; +using namespace ::cppu; +using namespace ::osl; + +DECLARE_STL_USTRINGACCESS_MAP(::rtl::OUStringBuffer,TSQLStatements); +namespace +{ + void lcl_fillIndexColumns(const Reference<XIndexAccess>& _xIndexes, ::std::vector< Reference<XNameAccess> >& _rAllIndexColumns) + { + if ( _xIndexes.is() ) + { + Reference<XPropertySet> xIndexColsSup; + sal_Int32 nCount = _xIndexes->getCount(); + for(sal_Int32 j = 0 ; j < nCount ; ++j) + { + xIndexColsSup.set(_xIndexes->getByIndex(j),UNO_QUERY); + if( xIndexColsSup.is() + && comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE)) + && !comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX)) + ) + _rAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns()); + } + } + } + void lcl_fillKeyCondition(const ::rtl::OUString& i_sTableName,const ::rtl::OUString& i_sQuotedColumnName,const ORowSetValue& i_aValue,TSQLStatements& io_aKeyConditions) + { + ::rtl::OUStringBuffer& rKeyCondition = io_aKeyConditions[i_sTableName]; + if ( rKeyCondition.getLength() ) + rKeyCondition.appendAscii(" AND "); + rKeyCondition.append(i_sQuotedColumnName); + if ( i_aValue.isNull() ) + rKeyCondition.appendAscii(" IS NULL"); + else + rKeyCondition.appendAscii(" = ?"); + } +} + +DBG_NAME(OptimisticSet) +// ------------------------------------------------------------------------- +OptimisticSet::OptimisticSet(const ::comphelper::ComponentContext& _rContext, + const Reference< XConnection>& i_xConnection, + const Reference< XSingleSelectQueryAnalyzer >& _xComposer, + const ORowSetValueVector& _aParameterValueForCache) + :m_aSqlParser( _rContext.getLegacyServiceFactory() ) + ,m_aSqlIterator( i_xConnection, Reference<XTablesSupplier>(_xComposer,UNO_QUERY)->getTables(), m_aSqlParser, NULL ) + ,m_aParameterValueForCache(_aParameterValueForCache) + ,m_pKeyColumnNames(NULL) + ,m_pColumnNames(NULL) + ,m_pParameterNames(NULL) + ,m_xComposer(_xComposer) + ,m_bRowCountFinal(sal_False) + ,m_bResultSetChanged(false) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::OptimisticSet" ); + DBG_CTOR(OptimisticSet,NULL); +} +// ----------------------------------------------------------------------------- +OptimisticSet::~OptimisticSet() +{ + try + { + ::comphelper::disposeComponent(m_xStatement); + } + catch(Exception&) + { + m_xStatement.clear(); + } + catch(...) + { + OSL_ENSURE(0,"Unknown Exception occured"); + } + m_xComposer.clear(); + + DBG_DTOR(OptimisticSet,NULL); +} +// ----------------------------------------------------------------------------- +void OptimisticSet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::construct" ); + OCacheSet::construct(_xDriverSet,i_sRowSetFilter); + + Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); + bool bCase = (xMeta.is() && xMeta->storesMixedCaseQuotedIdentifiers()) ? true : false; + + m_pKeyColumnNames.reset( new SelectColumnsMetaData(bCase) ); + m_pColumnNames.reset( new SelectColumnsMetaData(bCase) ); + m_pParameterNames.reset( new SelectColumnsMetaData(bCase) ); + + Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY); + const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns(); + const Reference<XTablesSupplier> xTabSup(m_xComposer,UNO_QUERY); + const Reference<XNameAccess> xTables = xTabSup->getTables(); + const Sequence< ::rtl::OUString> aTableNames = xTables->getElementNames(); + const ::rtl::OUString* pTableNameIter = aTableNames.getConstArray(); + const ::rtl::OUString* pTableNameEnd = pTableNameIter + aTableNames.getLength(); + for( ; pTableNameIter != pTableNameEnd ; ++pTableNameIter) + { + findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),xMeta,xQueryColumns); + } + + // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first + // without extra variable to be set + m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,::std::pair<sal_Int32,Reference<XRow> >(0,NULL)))); + m_aKeyIter = m_aKeyMap.begin(); + + static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND "); + const ::rtl::OUString aQuote = getIdentifierQuoteString(); + ::rtl::OUStringBuffer aFilter; + static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM(".")); + static ::rtl::OUString s_sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?")); + // create the where clause + SelectColumnsMetaData::iterator aPosEnd = m_pKeyColumnNames->end(); + for(SelectColumnsMetaData::iterator aPosIter = m_pKeyColumnNames->begin();aPosIter != aPosEnd;) + { + aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sTableName)); + aFilter.append(s_sDot); + aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName)); + aFilter.append(s_sParam); + ++aPosIter; + if(aPosIter != aPosEnd) + aFilter.append(aAnd); + } + + Reference< XMultiServiceFactory > xFactory(m_xConnection, UNO_QUERY_THROW); + Reference<XSingleSelectQueryComposer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY); + Reference<XSingleSelectQueryComposer> xComp2(m_xComposer,UNO_QUERY_THROW); + ::rtl::OUString sQuery = xComp2->getQuery(); + xAnalyzer->setQuery(sQuery); + // check for joins + ::rtl::OUString aErrorMsg; + ::std::auto_ptr<OSQLParseNode> pStatementNode( m_aSqlParser.parseTree( aErrorMsg, sQuery ) ); + m_aSqlIterator.setParseTree( pStatementNode.get() ); + m_aSqlIterator.traverseAll(); + fillJoinedColumns_throw(m_aSqlIterator.getJoinConditions()); + + const ::rtl::OUString sComposerFilter = m_xComposer->getFilter(); + if ( i_sRowSetFilter.getLength() || (sComposerFilter.getLength() && sComposerFilter != i_sRowSetFilter) ) + { + FilterCreator aFilterCreator; + if ( sComposerFilter.getLength() && sComposerFilter != i_sRowSetFilter ) + aFilterCreator.append( sComposerFilter ); + aFilterCreator.append( i_sRowSetFilter ); + aFilterCreator.append( aFilter.makeStringAndClear() ); + aFilter = aFilterCreator.getComposedAndClear(); + } + xAnalyzer->setFilter(aFilter.makeStringAndClear()); + m_xStatement = m_xConnection->prepareStatement(xAnalyzer->getQueryWithSubstitution()); + ::comphelper::disposeComponent(xAnalyzer); +} +// ------------------------------------------------------------------------- +Any SAL_CALL OptimisticSet::getBookmark() throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getBookmark" ); + OSL_ENSURE(m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(), + "getBookmark is only possible when we stand on a valid row!"); + return makeAny(m_aKeyIter->first); +} + +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::moveToBookmark" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(bookmark)); + return m_aKeyIter != m_aKeyMap.end(); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::moveRelativeToBookmark" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(bookmark)); + if(m_aKeyIter != m_aKeyMap.end()) + { + relative(rows); + } + + return !isBeforeFirst() && !isAfterLast(); +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OptimisticSet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::compareBookmarks" ); + sal_Int32 nFirst = 0, nSecond = 0; + _first >>= nFirst; + _second >>= nSecond; + + return (nFirst != nSecond) ? CompareBookmark::NOT_EQUAL : CompareBookmark::EQUAL; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::hasOrderedBookmarks" ); + return sal_True; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OptimisticSet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::hashBookmark" ); + return ::comphelper::getINT32(bookmark); +} +// ------------------------------------------------------------------------- +// ::com::sun::star::sdbcx::XDeleteRows +Sequence< sal_Int32 > SAL_CALL OptimisticSet::deleteRows( const Sequence< Any >& /*rows*/ ,const connectivity::OSQLTable& /*_xTable*/) throw(SQLException, RuntimeException) +{ + Sequence< sal_Int32 > aRet; + return aRet; +} +// ------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::updateRow" ); + if ( m_aJoinedKeyColumns.empty() ) + throw SQLException(); + // list all cloumns that should be set + static ::rtl::OUString s_sPara = ::rtl::OUString::createFromAscii(" = ?"); + ::rtl::OUString aQuote = getIdentifierQuoteString(); + static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND "); + ::rtl::OUString sIsNull(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")); + ::rtl::OUString sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?")); + + ::rtl::OUString aColumnName; + ::rtl::OUStringBuffer sKeyCondition; + ::std::map< ::rtl::OUString,bool > aResultSetChanged; + TSQLStatements aKeyConditions; + TSQLStatements aIndexConditions; + TSQLStatements aSql; + + // sal_Int32 i = 1; + // here we build the condition part for the update statement + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + for(;aIter != aEnd;++aIter) + { + if ( aResultSetChanged.find( aIter->second.sTableName ) == aResultSetChanged.end() ) + aResultSetChanged[aIter->second.sTableName] = false; + const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aIter->second.sRealName); + if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() ) + { + aResultSetChanged[aIter->second.sTableName] = m_aJoinedKeyColumns.find(aIter->second.nPosition) != m_aJoinedKeyColumns.end(); + lcl_fillKeyCondition(aIter->second.sTableName,sQuotedColumnName,(_rOrginalRow->get())[aIter->second.nPosition],aKeyConditions); + } + if((_rInsertRow->get())[aIter->second.nPosition].isModified()) + { + if ( m_aJoinedKeyColumns.find(aIter->second.nPosition) != m_aJoinedKeyColumns.end() ) + throw SQLException(); + + ::std::map<sal_Int32,sal_Int32>::const_iterator aJoinIter = m_aJoinedColumns.find(aIter->second.nPosition); + if ( aJoinIter != m_aJoinedColumns.end() ) + { + (_rInsertRow->get())[aJoinIter->second] = (_rInsertRow->get())[aIter->second.nPosition]; + } + ::rtl::OUStringBuffer& rPart = aSql[aIter->second.sTableName]; + if ( rPart.getLength() ) + rPart.appendAscii(", "); + rPart.append(sQuotedColumnName); + rPart.append(s_sPara); + } + } + + if( aSql.empty() ) + ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection ); + + if( aKeyConditions.empty() ) + ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_CONDITION_FOR_PK ), SQL_GENERAL_ERROR, m_xConnection ); + + static const ::rtl::OUString s_sUPDATE(RTL_CONSTASCII_USTRINGPARAM("UPDATE ")); + static const ::rtl::OUString s_sSET(RTL_CONSTASCII_USTRINGPARAM(" SET ")); + + Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData(); + + TSQLStatements::iterator aSqlIter = aSql.begin(); + TSQLStatements::iterator aSqlEnd = aSql.end(); + for(;aSqlIter != aSqlEnd ; ++aSqlIter) + { + if ( aSqlIter->second.getLength() ) + { + m_bResultSetChanged = m_bResultSetChanged || aResultSetChanged[aSqlIter->first]; + ::rtl::OUStringBuffer sSql(s_sUPDATE); + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + sSql.append( ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ) ); + sSql.append(s_sSET); + sSql.append(aSqlIter->second); + ::rtl::OUStringBuffer& rCondition = aKeyConditions[aSqlIter->first]; + bool bAddWhere = true; + if ( rCondition.getLength() ) + { + bAddWhere = false; + sSql.appendAscii(" WHERE "); + sSql.append( rCondition ); + } + executeUpdate(_rInsertRow ,_rOrginalRow,sSql.makeStringAndClear(),aSqlIter->first); + } + } +} +// ------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::insertRow" ); + TSQLStatements aSql; + TSQLStatements aParameter; + TSQLStatements aKeyConditions; + ::std::map< ::rtl::OUString,bool > aResultSetChanged; + ::rtl::OUString aQuote = getIdentifierQuoteString(); + static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND "); + ::rtl::OUString sIsNull(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")); + ::rtl::OUString sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?")); + + // here we build the condition part for the update statement + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + for(;aIter != aEnd;++aIter) + { + if ( aResultSetChanged.find( aIter->second.sTableName ) == aResultSetChanged.end() ) + aResultSetChanged[aIter->second.sTableName] = false; + + const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aIter->second.sRealName); + if ( (_rInsertRow->get())[aIter->second.nPosition].isModified() ) + { + if ( m_aJoinedKeyColumns.find(aIter->second.nPosition) != m_aJoinedKeyColumns.end() ) + { + lcl_fillKeyCondition(aIter->second.sTableName,sQuotedColumnName,(_rInsertRow->get())[aIter->second.nPosition],aKeyConditions); + aResultSetChanged[aIter->second.sTableName] = true; + } + ::std::map<sal_Int32,sal_Int32>::const_iterator aJoinIter = m_aJoinedColumns.find(aIter->second.nPosition); + if ( aJoinIter != m_aJoinedColumns.end() ) + { + (_rInsertRow->get())[aJoinIter->second] = (_rInsertRow->get())[aIter->second.nPosition]; + } + ::rtl::OUStringBuffer& rPart = aSql[aIter->second.sTableName]; + if ( rPart.getLength() ) + rPart.appendAscii(", "); + rPart.append(sQuotedColumnName); + ::rtl::OUStringBuffer& rParam = aParameter[aIter->second.sTableName]; + if ( rParam.getLength() ) + rParam.appendAscii(", "); + rParam.appendAscii("?"); + } + } + if ( aParameter.empty() ) + ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection ); + + Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData(); + static const ::rtl::OUString s_sINSERT(RTL_CONSTASCII_USTRINGPARAM("INSERT INTO ")); + static const ::rtl::OUString s_sVALUES(RTL_CONSTASCII_USTRINGPARAM(") VALUES ( ")); + TSQLStatements::iterator aSqlIter = aSql.begin(); + TSQLStatements::iterator aSqlEnd = aSql.end(); + for(;aSqlIter != aSqlEnd ; ++aSqlIter) + { + if ( aSqlIter->second.getLength() ) + { + m_bResultSetChanged = m_bResultSetChanged || aResultSetChanged[aSqlIter->first]; + ::rtl::OUStringBuffer sSql(s_sINSERT); + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + ::rtl::OUString sComposedTableName = ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ); + sSql.append(sComposedTableName); + sSql.appendAscii(" ( "); + sSql.append(aSqlIter->second); + sSql.append(s_sVALUES); + sSql.append(aParameter[aSqlIter->first]); + sSql.appendAscii(" )"); + + ::rtl::OUStringBuffer& rCondition = aKeyConditions[aSqlIter->first]; + if ( rCondition.getLength() ) + { + ::rtl::OUStringBuffer sQuery; + sQuery.appendAscii("SELECT "); + sQuery.append(aSqlIter->second); + sQuery.appendAscii(" FROM "); + sQuery.append(sComposedTableName); + sQuery.appendAscii(" WHERE "); + sQuery.append(rCondition); + + try + { + Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(sQuery.makeStringAndClear())); + Reference< XParameters > xParameter(xPrep,UNO_QUERY); + // and then the values of the where condition + SelectColumnsMetaData::iterator aKeyCol = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::iterator aKeysEnd = m_pKeyColumnNames->end(); + sal_Int32 i = 1; + for(;aKeyCol != aKeysEnd;++aKeyCol) + { + if ( aKeyCol->second.sTableName == aSqlIter->first ) + { + setParameter(i++,xParameter,(_rInsertRow->get())[aKeyCol->second.nPosition],aKeyCol->second.nType,aKeyCol->second.nScale); + } + } + Reference<XResultSet> xRes = xPrep->executeQuery(); + Reference<XRow> xRow(xRes,UNO_QUERY); + if ( xRow.is() && xRes->next() ) + { + m_bResultSetChanged = true; + continue; + } + } + catch(const SQLException&) + { + } + } + + executeInsert(_rInsertRow,sSql.makeStringAndClear(),aSqlIter->first); + } + } +} +// ------------------------------------------------------------------------- +void OptimisticSet::executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName ) +{ + // now create,fill and execute the prepared statement + Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL)); + Reference< XParameters > xParameter(xPrep,UNO_QUERY); + + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + for(sal_Int32 i = 1;aIter != aEnd;++aIter) + { + if ( aIter->second.sTableName == i_sTableName ) + { + const sal_Int32 nPos = aIter->second.nPosition; + if((_rInsertRow->get())[nPos].isModified()) + { + if((_rInsertRow->get())[nPos].isNull()) + xParameter->setNull(i++,(_rInsertRow->get())[nPos].getTypeKind()); + else + { + impl_convertValue_throw(_rInsertRow,aIter->second); + (_rInsertRow->get())[nPos].setSigned(m_aSignedFlags[nPos-1]); + setParameter(i++,xParameter,(_rInsertRow->get())[nPos],aIter->second.nType,aIter->second.nScale); + } + } + } + } + + m_bInserted = xPrep->executeUpdate() > 0; + sal_Bool bAutoValuesFetched = sal_False; + if ( m_bInserted ) + { + // first insert the default values into the insertrow + aIter = m_pColumnNames->begin(); + for(;aIter != aEnd;++aIter) + { + if ( !(_rInsertRow->get())[aIter->second.nPosition].isModified() ) + (_rInsertRow->get())[aIter->second.nPosition] = aIter->second.sDefaultValue; + } + try + { + Reference< XGeneratedResultSet > xGRes(xPrep, UNO_QUERY); + if ( xGRes.is() ) + { + Reference< XResultSet > xRes = xGRes->getGeneratedValues(); + Reference< XRow > xRow(xRes,UNO_QUERY); + if ( xRow.is() && xRes->next() ) + { + Reference< XResultSetMetaDataSupplier > xMdSup(xRes,UNO_QUERY); + Reference< XResultSetMetaData > xMd = xMdSup->getMetaData(); + sal_Int32 nColumnCount = xMd->getColumnCount(); + ::std::vector< ::rtl::OUString >::iterator aAutoIter = m_aAutoColumns.begin(); + ::std::vector< ::rtl::OUString >::iterator aAutoEnd = m_aAutoColumns.end(); + for (sal_Int32 i = 1;aAutoIter != aAutoEnd && i <= nColumnCount; ++aAutoIter,++i) + { +#if OSL_DEBUG_LEVEL > 1 + ::rtl::OUString sColumnName( xMd->getColumnName(i) ); +#endif + SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter); + if ( aFind != m_pKeyColumnNames->end() ) + (_rInsertRow->get())[aFind->second.nPosition].fill(i,aFind->second.nType,aFind->second.bNullable,xRow); + } + bAutoValuesFetched = sal_True; + } + } + } + catch(Exception&) + { + OSL_ENSURE(0,"Could not execute GeneratedKeys() stmt"); + } + } + + ::comphelper::disposeComponent(xPrep); +/* + if ( !bAutoValuesFetched && m_bInserted ) + { + // first check if all key column values were set + const ::rtl::OUString sMax(RTL_CONSTASCII_USTRINGPARAM(" MAX(")); + const ::rtl::OUString sMaxEnd(RTL_CONSTASCII_USTRINGPARAM("),")); + const ::rtl::OUString sQuote = getIdentifierQuoteString(); + ::rtl::OUString sMaxStmt; + aEnd = m_pKeyColumnNames->end(); + ::std::vector< ::rtl::OUString >::iterator aAutoIter = m_aAutoColumns.begin(); + ::std::vector< ::rtl::OUString >::iterator aAutoEnd = m_aAutoColumns.end(); + for (;aAutoIter != aAutoEnd; ++aAutoIter) + { + // we will only fetch values which are keycolumns + if ( m_pKeyColumnNames->find(*aAutoIter) != aEnd ) + { + sMaxStmt += sMax; + sMaxStmt += ::dbtools::quoteName( sQuote,*aAutoIter); + sMaxStmt += sMaxEnd; + } + } + + if(sMaxStmt.getLength()) + { + sMaxStmt = sMaxStmt.replaceAt(sMaxStmt.getLength()-1,1,::rtl::OUString::createFromAscii(" ")); + ::rtl::OUString sStmt = ::rtl::OUString::createFromAscii("SELECT "); + sStmt += sMaxStmt; + sStmt += ::rtl::OUString::createFromAscii("FROM "); + sStmt += m_aSelectComposedTableName; + try + { + // now fetch the autoincrement values + Reference<XStatement> xStatement = m_xConnection->createStatement(); + Reference<XResultSet> xRes = xStatement->executeQuery(sStmt); + Reference<XRow> xRow(xRes,UNO_QUERY); + if(xRow.is() && xRes->next()) + { + aAutoIter = m_aAutoColumns.begin(); + for (sal_Int32 i=1;aAutoIter != aAutoEnd; ++aAutoIter,++i) + { + // we will only fetch values which are keycolumns + SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter); + if ( aFind != aEnd ) + (_rInsertRow->get())[aFind->second.nPosition].fill(i,aFind->second.nType,aFind->second.bNullable,xRow); + } + } + ::comphelper::disposeComponent(xStatement); + } + catch(SQLException&) + { + OSL_ENSURE(0,"Could not fetch with MAX() "); + } + } + } + */ + if ( m_bInserted ) + { + OKeySetMatrix::iterator aKeyIter = m_aKeyMap.end(); + --aKeyIter; + ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_pKeyColumnNames->size()); + copyRowValue(_rInsertRow,aKeyRow,aKeyIter->first + 1); + + m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(aKeyIter->first + 1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(1,NULL)))).first; + // now we set the bookmark for this row + (_rInsertRow->get())[0] = makeAny((sal_Int32)m_aKeyIter->first); + } +} +// ----------------------------------------------------------------------------- +void OptimisticSet::copyRowValue(const ORowSetRow& _rInsertRow,ORowSetRow& _rKeyRow,sal_Int32 i_nBookmark) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::copyRowValue" ); + connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = _rKeyRow->get().begin(); + + // check the if the parameter values have been changed + OSL_ENSURE((m_aParameterValueForCache.get().size()-1) == m_pParameterNames->size(),"OptimisticSet::copyRowValue: Parameter values and names differ!"); + connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaValuesIter = m_aParameterValueForCache.get().begin() +1; + + bool bChanged = false; + SelectColumnsMetaData::const_iterator aParaIter = (*m_pParameterNames).begin(); + SelectColumnsMetaData::const_iterator aParaEnd = (*m_pParameterNames).end(); + for(sal_Int32 i = 1;aParaIter != aParaEnd;++aParaIter,++aParaValuesIter,++i) + { + ORowSetValue aValue(*aParaValuesIter); + aValue.setSigned(m_aSignedFlags[aParaIter->second.nPosition]); + if ( (_rInsertRow->get())[aParaIter->second.nPosition] != aValue ) + { + ORowSetValueVector aCopy(m_aParameterValueForCache); + (aCopy.get())[i] = (_rInsertRow->get())[aParaIter->second.nPosition]; + m_aUpdatedParameter[i_nBookmark] = aCopy; + bChanged = true; + } + } + if ( !bChanged ) + { + m_aUpdatedParameter.erase(i_nBookmark); + } + + // update the key values + SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end(); + for(;aPosIter != aPosEnd;++aPosIter,++aIter) + { + ORowSetValue aValue((_rInsertRow->get())[aPosIter->second.nPosition]); + switch(aPosIter->second.nType) + { + case DataType::DECIMAL: + case DataType::NUMERIC: + { + ::rtl::OUString sValue = aValue.getString(); + sal_Int32 nIndex = sValue.indexOf('.'); + if ( nIndex != -1 ) + { + aValue = sValue.copy(0,nIndex + (aPosIter->second.nScale > 0 ? aPosIter->second.nScale + 1 : 0)); + } + } + break; + default: + break; + } + *aIter = aValue; + aIter->setTypeKind(aPosIter->second.nType); + } +} +// ------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException) +{ + ::rtl::OUString sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?")); + ::rtl::OUString sIsNull(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")); + static const ::rtl::OUString s_sAnd(RTL_CONSTASCII_USTRINGPARAM(" AND ")); + ::rtl::OUString aQuote = getIdentifierQuoteString(); + ::rtl::OUString aColumnName; + ::rtl::OUStringBuffer sKeyCondition,sIndexCondition; + ::std::vector<sal_Int32> aIndexColumnPositions; + TSQLStatements aKeyConditions; + TSQLStatements aIndexConditions; + TSQLStatements aSql; + + // sal_Int32 i = 1; + // here we build the condition part for the update statement + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + for(;aIter != aEnd;++aIter) + { + if ( m_aJoinedKeyColumns.find(aIter->second.nPosition) == m_aJoinedKeyColumns.end() && m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() ) + { + // only delete rows which aren't the key in the join + const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aIter->second.sRealName); + lcl_fillKeyCondition(aIter->second.sTableName,sQuotedColumnName,(_rDeleteRow->get())[aIter->second.nPosition],aKeyConditions); + } + } + Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData(); + TSQLStatements::iterator aSqlIter = aKeyConditions.begin(); + TSQLStatements::iterator aSqlEnd = aKeyConditions.end(); + for(;aSqlIter != aSqlEnd ; ++aSqlIter) + { + ::rtl::OUStringBuffer& rCondition = aSqlIter->second; + if ( rCondition.getLength() ) + { + ::rtl::OUStringBuffer sSql; + sSql.appendAscii("DELETE FROM "); + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + sSql.append( ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ) ); + sSql.appendAscii(" WHERE "); + sSql.append( rCondition ); + executeDelete(_rDeleteRow,sSql.makeStringAndClear(),aSqlIter->first); + } + } +} +// ------------------------------------------------------------------------- +void OptimisticSet::executeDelete(const ORowSetRow& _rDeleteRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::executeDelete" ); + + // now create end execute the prepared statement + Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL)); + Reference< XParameters > xParameter(xPrep,UNO_QUERY); + + SelectColumnsMetaData::const_iterator aIter = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pKeyColumnNames->end(); + sal_Int32 i = 1; + for(;aIter != aEnd;++aIter) + { + if ( aIter->second.sTableName == i_sTableName ) + setParameter(i++,xParameter,(_rDeleteRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale); + } + m_bDeleted = xPrep->executeUpdate() > 0; + + if(m_bDeleted) + { + sal_Int32 nBookmark = ::comphelper::getINT32((_rDeleteRow->get())[0].getAny()); + if(m_aKeyIter == m_aKeyMap.find(nBookmark) && m_aKeyIter != m_aKeyMap.end()) + ++m_aKeyIter; + m_aKeyMap.erase(nBookmark); + m_bDeleted = sal_True; + } +} +// ------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::cancelRowUpdates( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::cancelRowUpdates" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; +} +// ------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::moveToInsertRow( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::moveToInsertRow" ); +} +// ------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::moveToCurrentRow( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::moveToCurrentRow" ); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::next( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::next" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + + if(isAfterLast()) + return sal_False; + if(!m_bRowCountFinal) // not yet all records fetched + { + ++m_aKeyIter; // this is possible because we stand on begin() and this is the "beforefirst" row + if(m_aKeyIter == m_aKeyMap.end() && !fetchRow()) + m_aKeyIter = m_aKeyMap.end(); + } + else if(!isAfterLast()) + ++m_aKeyIter; + + refreshRow(); + return !isAfterLast(); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::isBeforeFirst( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::isBeforeFirst" ); + return m_aKeyIter == m_aKeyMap.begin(); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::isAfterLast( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::isAfterLast" ); + return m_bRowCountFinal && m_aKeyIter == m_aKeyMap.end(); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::isFirst( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::isFirst" ); + OKeySetMatrix::iterator aTemp = m_aKeyMap.begin(); + ++aTemp; + return m_aKeyIter == aTemp && m_aKeyIter != m_aKeyMap.end(); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::isLast( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::isLast" ); + if(!m_bRowCountFinal) + return sal_False; + + OKeySetMatrix::iterator aTemp = m_aKeyMap.end(); + --aTemp; + return m_aKeyIter == aTemp; +} +// ----------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::beforeFirst( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::beforeFirst" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + m_aKeyIter = m_aKeyMap.begin(); + m_xSet = NULL; + ::comphelper::disposeComponent(m_xRow); +} +// ----------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::afterLast( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::afterLast" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + fillAllRows(); + m_aKeyIter = m_aKeyMap.end(); + m_xSet = NULL; + ::comphelper::disposeComponent(m_xRow); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::first( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::first" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + m_aKeyIter = m_aKeyMap.begin(); + ++m_aKeyIter; + if(m_aKeyIter == m_aKeyMap.end() && !fetchRow()) + m_aKeyIter = m_aKeyMap.end(); + + refreshRow(); + return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::last( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::last" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + fillAllRows(); + + m_aKeyIter = m_aKeyMap.end(); + --m_aKeyIter; + refreshRow(); + return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(); +} +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL OptimisticSet::getRow( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getRow" ); + OSL_ENSURE(!isAfterLast(),"getRow is not allowed when afterlast record!"); + OSL_ENSURE(!isBeforeFirst(),"getRow is not allowed when beforefirst record!"); + + return ::std::distance(m_aKeyMap.begin(),m_aKeyIter); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::absolute" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + OSL_ENSURE(row,"absolute(0) isn't allowed!"); + if(row < 0) + { + if(!m_bRowCountFinal) + fillAllRows(); + + for(;row < 0 && m_aKeyIter != m_aKeyMap.begin();++row) + m_aKeyIter--; + } + else + { + if(row >= (sal_Int32)m_aKeyMap.size()) + { + if(!m_bRowCountFinal) + { + sal_Bool bNext = sal_True; + for(sal_Int32 i=m_aKeyMap.size()-1;i < row && bNext;++i) + bNext = fetchRow(); + } + else + m_aKeyIter = m_aKeyMap.end(); + } + else + { + m_aKeyIter = m_aKeyMap.begin(); + for(;row > 0 && m_aKeyIter != m_aKeyMap.end();--row) + ++m_aKeyIter; + } + } + refreshRow(); + + return m_aKeyIter != m_aKeyMap.end() && m_aKeyIter != m_aKeyMap.begin(); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::relative( sal_Int32 rows ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::relative" ); + if(!rows) + { + refreshRow(); + return sal_True; + } + return absolute(getRow()+rows); +} +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::previous( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::previous" ); + m_bInserted = m_bUpdated = m_bDeleted = sal_False; + if(m_aKeyIter != m_aKeyMap.begin()) + { + --m_aKeyIter; + refreshRow(); + } + return m_aKeyIter != m_aKeyMap.begin(); +} +// ----------------------------------------------------------------------------- +void SAL_CALL OptimisticSet::refreshRow() throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::refreshRow" ); + if(isBeforeFirst() || isAfterLast() || !m_xStatement.is()) + return; + + m_xSet.clear(); + ::comphelper::disposeComponent(m_xRow); + // we just reassign the base members + Reference< XParameters > xParameter(m_xStatement,UNO_QUERY); + OSL_ENSURE(xParameter.is(),"No Parameter interface!"); + xParameter->clearParameters(); + + sal_Int32 nPos=1; + connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaIter; + connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aParaEnd; + OUpdatedParameter::iterator aUpdateFind = m_aUpdatedParameter.find(m_aKeyIter->first); + if ( aUpdateFind == m_aUpdatedParameter.end() ) + { + aParaIter = m_aParameterValueForCache.get().begin(); + aParaEnd = m_aParameterValueForCache.get().end(); + } + else + { + aParaIter = aUpdateFind->second.get().begin(); + aParaEnd = aUpdateFind->second.get().end(); + } + + // first put the parameters set by the outer rowset + for(++aParaIter;aParaIter != aParaEnd;++aParaIter,++nPos) + { + ::dbtools::setObjectWithInfo( xParameter, nPos, aParaIter->makeAny(), aParaIter->getTypeKind() ); + } + + // now set the primary key column values + connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter = m_aKeyIter->second.first->get().begin(); + SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end(); + for(;aPosIter != aPosEnd;++aPosIter,++aIter,++nPos) + setParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale); + + m_xSet = m_xStatement->executeQuery(); + OSL_ENSURE(m_xSet.is(),"No resultset form statement!"); + sal_Bool bOK = m_xSet->next(); + if ( !bOK ) + m_aKeyIter = m_aKeyMap.end(); + m_xRow.set(m_xSet,UNO_QUERY); + OSL_ENSURE(m_xRow.is(),"No row form statement!"); +} +// ----------------------------------------------------------------------------- +sal_Bool OptimisticSet::fetchRow() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::fetchRow" ); + // fetch the next row and append on the OptimisticSet + sal_Bool bRet = sal_False; + if ( !m_bRowCountFinal ) + bRet = m_xDriverSet->next(); + if ( bRet ) + { + ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >(m_pKeyColumnNames->size()); + connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = aKeyRow->get().begin(); + // first fetch the values needed for the key column + SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end(); + for(;aPosIter != aPosEnd;++aPosIter,++aIter) + { + const SelectColumnDescription& rColDesc = aPosIter->second; + aIter->fill(rColDesc.nPosition,rColDesc.nType,rColDesc.bNullable,m_xDriverRow); + } + m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(m_aKeyMap.rbegin()->first+1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(0,NULL)))).first; + } + else + m_bRowCountFinal = sal_True; + return bRet; +} +// ------------------------------------------------------------------------- +void OptimisticSet::fillAllRows() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::fillAllRows" ); + if(!m_bRowCountFinal) + { + while(fetchRow()) + ; + } +} +// XRow +sal_Bool SAL_CALL OptimisticSet::wasNull( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::wasNull" ); + return m_xRow->wasNull(); +} +// ------------------------------------------------------------------------- +::rtl::OUString SAL_CALL OptimisticSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getString" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getString(columnIndex); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getBoolean" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getBoolean(columnIndex); +} +// ------------------------------------------------------------------------- +sal_Int8 SAL_CALL OptimisticSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getByte" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getByte(columnIndex); +} +// ------------------------------------------------------------------------- +sal_Int16 SAL_CALL OptimisticSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getShort" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getShort(columnIndex); +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OptimisticSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getInt" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getInt(columnIndex); +} +// ------------------------------------------------------------------------- +sal_Int64 SAL_CALL OptimisticSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getLong" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getLong(columnIndex); +} +// ------------------------------------------------------------------------- +float SAL_CALL OptimisticSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getFloat" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getFloat(columnIndex); +} +// ------------------------------------------------------------------------- +double SAL_CALL OptimisticSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getDouble" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getDouble(columnIndex); +} +// ------------------------------------------------------------------------- +Sequence< sal_Int8 > SAL_CALL OptimisticSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getBytes" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getBytes(columnIndex); +} +// ------------------------------------------------------------------------- +::com::sun::star::util::Date SAL_CALL OptimisticSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getDate" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getDate(columnIndex); +} +// ------------------------------------------------------------------------- +::com::sun::star::util::Time SAL_CALL OptimisticSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getTime" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getTime(columnIndex); +} +// ------------------------------------------------------------------------- +::com::sun::star::util::DateTime SAL_CALL OptimisticSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getTimestamp" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getTimestamp(columnIndex); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::io::XInputStream > SAL_CALL OptimisticSet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getBinaryStream" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getBinaryStream(columnIndex); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::io::XInputStream > SAL_CALL OptimisticSet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getCharacterStream" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getCharacterStream(columnIndex); +} +// ------------------------------------------------------------------------- +Any SAL_CALL OptimisticSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getObject" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getObject(columnIndex,typeMap); +} +// ------------------------------------------------------------------------- +Reference< XRef > SAL_CALL OptimisticSet::getRef( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getRef" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getRef(columnIndex); +} +// ------------------------------------------------------------------------- +Reference< XBlob > SAL_CALL OptimisticSet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getBlob" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getBlob(columnIndex); +} +// ------------------------------------------------------------------------- +Reference< XClob > SAL_CALL OptimisticSet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getClob" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getClob(columnIndex); +} +// ------------------------------------------------------------------------- +Reference< XArray > SAL_CALL OptimisticSet::getArray( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getArray" ); + OSL_ENSURE(m_xRow.is(),"m_xRow is null!"); + return m_xRow->getArray(columnIndex); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::rowUpdated( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::rowUpdated" ); + return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 2; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::rowInserted( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::rowInserted" ); + return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 1; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OptimisticSet::rowDeleted( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::rowDeleted" ); + sal_Bool bDeleted = m_bDeleted; + m_bDeleted = sal_False; + return bDeleted; +} +// ----------------------------------------------------------------------------- +::rtl::OUString OptimisticSet::getComposedTableName(const ::rtl::OUString& /*_sCatalog*/, + const ::rtl::OUString& /*_sSchema*/, + const ::rtl::OUString& /*_sTable*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::getComposedTableName" ); + ::rtl::OUString aComposedName; +/* + Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData(); + + if( xMetaData.is() && xMetaData->supportsTableCorrelationNames() ) + { + aComposedName = ::dbtools::composeTableName( xMetaData, _sCatalog, _sSchema, _sTable, sal_False, ::dbtools::eInDataManipulation ); + // first we have to check if the composed tablename is in the select clause or if an alias is used + Reference<XTablesSupplier> xTabSup(m_xComposer,UNO_QUERY); + Reference<XNameAccess> xSelectTables = xTabSup->getTables(); + OSL_ENSURE(xSelectTables.is(),"No Select tables!"); + if(xSelectTables.is()) + { + if(!xSelectTables->hasByName(aComposedName)) + { // the composed name isn't used in the select clause so we have to find out which name is used instead + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMetaData,m_sUpdateTableName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + aComposedName = ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ); + } + else + aComposedName = ::dbtools::composeTableNameForSelect( m_xConnection, _sCatalog, _sSchema, _sTable ); + } + } + else + aComposedName = ::dbtools::composeTableNameForSelect( m_xConnection, _sCatalog, _sSchema, _sTable ); +*/ + return aComposedName; +} +// ----------------------------------------------------------------------------- +/* +namespace dbaccess +{ + void getColumnPositions(const Reference<XNameAccess>& _rxQueryColumns, + const Sequence< ::rtl::OUString>& _aColumnNames, + const ::rtl::OUString& _rsUpdateTableName, + SelectColumnsMetaData& _rColumnNames) + { + // get the real name of the columns + Sequence< ::rtl::OUString> aSelNames(_rxQueryColumns->getElementNames()); + const ::rtl::OUString* pSelBegin = aSelNames.getConstArray(); + const ::rtl::OUString* pSelEnd = pSelBegin + aSelNames.getLength(); + + const ::rtl::OUString* pColumnIter = _aColumnNames.getConstArray(); + const ::rtl::OUString* pColumnEnd = pColumnIter + _aColumnNames.getLength(); + + ::comphelper::UStringMixLess aTmp(_rColumnNames.key_comp()); + ::comphelper::UStringMixEqual bCase(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive()); + + for(sal_Int32 nPos = 1;pSelBegin != pSelEnd;++pSelBegin,++nPos) + { + Reference<XPropertySet> xColumnProp(_rxQueryColumns->getByName(*pSelBegin),UNO_QUERY); + ::rtl::OUString sRealName,sTableName; + OSL_ENSURE(xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!"); + OSL_ENSURE(xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!"); + xColumnProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName; + xColumnProp->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName; + + for(;pColumnIter != pColumnEnd;++pColumnIter) + { + if(bCase(sRealName,*pColumnIter) && bCase(_rsUpdateTableName,sTableName) && _rColumnNames.find(*pColumnIter) == _rColumnNames.end()) + { + sal_Int32 nType = 0; + xColumnProp->getPropertyValue(PROPERTY_TYPE) >>= nType; + sal_Int32 nScale = 0; + xColumnProp->getPropertyValue(PROPERTY_SCALE) >>= nScale; + ::rtl::OUString sColumnDefault; + if ( xColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE) ) + xColumnProp->getPropertyValue(PROPERTY_DEFAULTVALUE) >>= sColumnDefault; + + sal_Int32 bNullable = sal_False; + xColumnProp->getPropertyValue(PROPERTY_ISNULLABLE) >>= bNullable; + + + _rColumnNames[sRealName] = SelectColumnDescription( nPos, nType,nScale,bNullable != sdbc::ColumnValue::NO_NULLS, sColumnDefault ); + break; + } + } + pColumnIter = _aColumnNames.getConstArray(); + } + } +} +*/ +// ----------------------------------------------------------------------------- +void OptimisticSet::impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData) +{ + ORowSetValue& aValue((_rInsertRow->get())[i_aMetaData.nPosition]); + switch(i_aMetaData.nType) + { + case DataType::DECIMAL: + case DataType::NUMERIC: + { + ::rtl::OUString sValue = aValue.getString(); + sal_Int32 nIndex = sValue.indexOf('.'); + if ( nIndex != -1 ) + { + aValue = sValue.copy(0,nIndex + (i_aMetaData.nScale > 0 ? i_aMetaData.nScale + 1 : 0)); + } + } + break; + default: + break; + } +} +// ----------------------------------------------------------------------------- +void OptimisticSet::findTableColumnsMatching_throw(const Any& i_aTable + ,const Reference<XDatabaseMetaData>& i_xMeta + ,const Reference<XNameAccess>& i_xQueryColumns) +{ + ::rtl::OUString sCatalog,sSchema,sTable; + Reference<XPropertySet> xTableProp(i_aTable,UNO_QUERY); + Any aCatalog = xTableProp->getPropertyValue(PROPERTY_CATALOGNAME); + aCatalog >>= sCatalog; + xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema; + xTableProp->getPropertyValue(PROPERTY_NAME) >>= sTable; + + // first ask the database itself for the best columns which can be used + ::std::vector< ::rtl::OUString> aBestRowColumnNames; + Reference<XResultSet> xBestRes(i_xMeta->getBestRowIdentifier(aCatalog,sSchema,sTable,0,sal_False)); + Reference<XRow> xBestRow(xBestRes,uno::UNO_QUERY); + while ( xBestRes->next() ) + { + aBestRowColumnNames.push_back(xBestRow->getString(2)); + } + + Sequence< ::rtl::OUString> aBestColumnNames; + if ( aBestRowColumnNames.empty() ) + { + Reference<XNameAccess> xKeyColumns = getPrimaryKeyColumns_throw(i_aTable); + if ( xKeyColumns.is() ) + aBestColumnNames = xKeyColumns->getElementNames(); + } + else + aBestColumnNames = Sequence< ::rtl::OUString>(&aBestRowColumnNames[0],aBestRowColumnNames.size()); + + const Reference<XColumnsSupplier> xTblColSup(i_aTable,UNO_QUERY_THROW); + const Reference<XNameAccess> xTblColumns = xTblColSup->getColumns(); + const ::rtl::OUString sComposedUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation ); + ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sComposedUpdateTableName,(*m_pKeyColumnNames),true); + ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sComposedUpdateTableName,(*m_pColumnNames),true); + + // locate parameter in select columns + Reference<XParametersSupplier> xParaSup(m_xComposer,UNO_QUERY); + Reference<XIndexAccess> xQueryParameters = xParaSup->getParameters(); + const sal_Int32 nParaCount = xQueryParameters->getCount(); + Sequence< ::rtl::OUString> aParameterColumns(nParaCount); + for(sal_Int32 i = 0; i< nParaCount;++i) + { + Reference<XPropertySet> xPara(xQueryParameters->getByIndex(i),UNO_QUERY_THROW); + xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i]; + } + ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sComposedUpdateTableName,(*m_pParameterNames),true); + + SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end(); + for(;aPosIter != aPosEnd;++aPosIter) + { + if ( xTblColumns->hasByName(aPosIter->second.sRealName) ) + { + Reference<XPropertySet> xProp(xTblColumns->getByName(aPosIter->second.sRealName),UNO_QUERY); + sal_Bool bAuto = sal_False; + if( (xProp->getPropertyValue(PROPERTY_ISAUTOINCREMENT) >>= bAuto) && bAuto) + m_aAutoColumns.push_back(aPosIter->first); + } + } +} +// ----------------------------------------------------------------------------- +void OptimisticSet::executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName) +{ + // now create end execute the prepared statement + Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL)); + Reference< XParameters > xParameter(xPrep,UNO_QUERY); + + sal_Int32 i = 1; + // first the set values + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + sal_uInt16 j = 0; + for(;aIter != aEnd;++aIter,++j) + { + if ( aIter->second.sTableName == i_sTableName ) + { + sal_Int32 nPos = aIter->second.nPosition; + if((_rInsertRow->get())[nPos].isModified()) + { + impl_convertValue_throw(_rInsertRow,aIter->second); + (_rInsertRow->get())[nPos].setSigned((_rOrginalRow->get())[nPos].isSigned()); + setParameter(i++,xParameter,(_rInsertRow->get())[nPos],aIter->second.nType,aIter->second.nScale); + } + } + } + // and then the values of the where condition + aIter = m_pKeyColumnNames->begin(); + aEnd = m_pKeyColumnNames->end(); + j = 0; + for(;aIter != aEnd;++aIter,++j) + { + if ( aIter->second.sTableName == i_sTableName ) + { + setParameter(i++,xParameter,(_rOrginalRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale); + } + } +/* + // now we have to set the index values + ::std::vector<sal_Int32>::iterator aIdxColIter = aIndexColumnPositions.begin(); + ::std::vector<sal_Int32>::iterator aIdxColEnd = aIndexColumnPositions.end(); + j = 0; + aIter = m_pColumnNames->begin(); + for(;aIdxColIter != aIdxColEnd;++aIdxColIter,++i,++j,++aIter) + { + setParameter(i,xParameter,(_rOrginalRow->get())[*aIdxColIter],(_rOrginalRow->get())[*aIdxColIter].getTypeKind(),aIter->second.nScale); + } +*/ + const sal_Int32 nRowsUpdated = xPrep->executeUpdate(); + m_bUpdated = nRowsUpdated > 0; + if(m_bUpdated) + { + const sal_Int32 nBookmark = ::comphelper::getINT32((_rInsertRow->get())[0].getAny()); + m_aKeyIter = m_aKeyMap.find(nBookmark); + m_aKeyIter->second.second.first = 2; + copyRowValue(_rInsertRow,m_aKeyIter->second.first,nBookmark); + } +} +// ----------------------------------------------------------------------------- +void OptimisticSet::fillJoinedColumns_throw(const ::std::vector< TNodePair >& i_aJoinColumns) +{ + ::std::vector< TNodePair >::const_iterator aIter = i_aJoinColumns.begin(); + for(;aIter != i_aJoinColumns.end();++aIter) + { + ::rtl::OUString sColumnName,sTableName; + m_aSqlIterator.getColumnRange(aIter->first,sColumnName,sTableName); + ::rtl::OUStringBuffer sLeft,sRight; + sLeft.append(sTableName); + sLeft.appendAscii("."); + sLeft.append(sColumnName); + m_aSqlIterator.getColumnRange(aIter->second,sColumnName,sTableName); + sRight.append(sTableName); + sRight.appendAscii("."); + sRight.append(sColumnName); + fillJoinedColumns_throw(sLeft.makeStringAndClear(),sRight.makeStringAndClear()); + } +} +// ----------------------------------------------------------------------------- +void OptimisticSet::fillJoinedColumns_throw(const ::rtl::OUString& i_sLeftColumn,const ::rtl::OUString& i_sRightColumn) +{ + sal_Int32 nLeft = 0,nRight = 0; + SelectColumnsMetaData::const_iterator aLeftIter = m_pKeyColumnNames->find(i_sLeftColumn); + SelectColumnsMetaData::const_iterator aRightIter = m_pKeyColumnNames->find(i_sRightColumn); + + bool bLeftKey = aLeftIter != m_pKeyColumnNames->end(); + if ( bLeftKey ) + { + nLeft = aLeftIter->second.nPosition; + } + else + { + aLeftIter = m_pColumnNames->find(i_sLeftColumn); + if ( aLeftIter != m_pColumnNames->end() ) + nLeft = aLeftIter->second.nPosition; + } + + bool bRightKey = aRightIter != m_pKeyColumnNames->end(); + if ( bRightKey ) + { + nRight = aRightIter->second.nPosition; + } + else + { + aRightIter = m_pColumnNames->find(i_sRightColumn); + if ( aRightIter != m_pColumnNames->end() ) + nRight = aRightIter->second.nPosition; + } + + if (bLeftKey) + m_aJoinedKeyColumns[nLeft] = nRight; + else + m_aJoinedColumns[nLeft] = nRight; + if (bRightKey) + m_aJoinedKeyColumns[nRight] = nLeft; + else + m_aJoinedColumns[nRight] = nLeft; +} +// ----------------------------------------------------------------------------- +bool OptimisticSet::isResultSetChanged() const +{ + bool bOld = m_bResultSetChanged; + m_bResultSetChanged = false; + return bOld; +} +// ----------------------------------------------------------------------------- +void OptimisticSet::reset(const Reference< XResultSet>& _xDriverSet) +{ + OCacheSet::construct(_xDriverSet,::rtl::OUString()); + m_bRowCountFinal = sal_False; + m_aKeyMap.clear(); + m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,::std::pair<sal_Int32,Reference<XRow> >(0,NULL)))); + m_aKeyIter = m_aKeyMap.begin(); +} +// ----------------------------------------------------------------------------- +void OptimisticSet::mergeColumnValues(sal_Int32 i_nColumnIndex,ORowSetValueVector::Vector& io_aInsertRow,ORowSetValueVector::Vector& io_aRow,::std::vector<sal_Int32>& o_aChangedColumns) +{ + o_aChangedColumns.push_back(i_nColumnIndex); + ::std::map<sal_Int32,sal_Int32>::const_iterator aJoinIter = m_aJoinedColumns.find(i_nColumnIndex); + if ( aJoinIter != m_aJoinedColumns.end() ) + { + io_aRow[aJoinIter->second] = io_aRow[i_nColumnIndex]; + io_aInsertRow[aJoinIter->second] = io_aInsertRow[i_nColumnIndex]; + io_aRow[aJoinIter->second].setModified(); + o_aChangedColumns.push_back(aJoinIter->second); + } +} +namespace +{ + struct PositionFunctor : ::std::unary_function<SelectColumnsMetaData::value_type,bool> + { + sal_Int32 m_nPos; + PositionFunctor(sal_Int32 i_nPos) + : m_nPos(i_nPos) + { + } + + inline bool operator()(const SelectColumnsMetaData::value_type& _aType) + { + return m_nPos == _aType.second.nPosition; + } + }; + struct TableNameFunctor : ::std::unary_function<SelectColumnsMetaData::value_type,bool> + { + ::rtl::OUString m_sTableName; + TableNameFunctor(const ::rtl::OUString& i_sTableName) + : m_sTableName(i_sTableName) + { + } + + inline bool operator()(const SelectColumnsMetaData::value_type& _aType) + { + return m_sTableName == _aType.second.sTableName; + } + }; +} +// ----------------------------------------------------------------------------- +bool OptimisticSet::updateColumnValues(const ORowSetValueVector::Vector& io_aCachedRow,ORowSetValueVector::Vector& io_aRow,const ::std::vector<sal_Int32>& i_aChangedColumns) +{ + bool bRet = false; + ::std::vector<sal_Int32>::const_iterator aColIdxIter = i_aChangedColumns.begin(); + for(;aColIdxIter != i_aChangedColumns.end();++aColIdxIter) + { + SelectColumnsMetaData::const_iterator aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),PositionFunctor(*aColIdxIter)); + if ( aFind != m_pKeyColumnNames->end() ) + { + const ::rtl::OUString sTableName = aFind->second.sTableName; + aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),TableNameFunctor(sTableName)); + while( aFind != m_pKeyColumnNames->end() ) + { + io_aRow[aFind->second.nPosition].setSigned(io_aCachedRow[aFind->second.nPosition].isSigned()); + if ( io_aCachedRow[aFind->second.nPosition] != io_aRow[aFind->second.nPosition] ) + break; + ++aFind; + } + if ( aFind == m_pKeyColumnNames->end() ) + { + bRet = true; + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + for ( ;aIter != aEnd;++aIter ) + { + if ( aIter->second.sTableName == sTableName ) + { + io_aRow[aIter->second.nPosition] = io_aCachedRow[aIter->second.nPosition]; + io_aRow[aIter->second.nPosition].setModified(); + } + } + } + } + } + return bRet; +} +// ----------------------------------------------------------------------------- +bool OptimisticSet::columnValuesUpdated(ORowSetValueVector::Vector& o_aCachedRow,const ORowSetValueVector::Vector& i_aRow) +{ + bool bRet = false; + SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end(); + for(;aIter != aEnd;++aIter) + { + SelectColumnsMetaData::const_iterator aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),PositionFunctor(aIter->second.nPosition)); + if ( aFind != m_pKeyColumnNames->end() ) + { + const ::rtl::OUString sTableName = aFind->second.sTableName; + aFind = ::std::find_if(m_pKeyColumnNames->begin(),m_pKeyColumnNames->end(),TableNameFunctor(sTableName)); + while( aFind != m_pKeyColumnNames->end() ) + { + o_aCachedRow[aFind->second.nPosition].setSigned(i_aRow[aFind->second.nPosition].isSigned()); + if ( o_aCachedRow[aFind->second.nPosition] != i_aRow[aFind->second.nPosition] ) + break; + ++aFind; + } + if ( aFind == m_pKeyColumnNames->end() ) + { + bRet = true; + SelectColumnsMetaData::const_iterator aIter2 = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aEnd2 = m_pColumnNames->end(); + for ( ;aIter2 != aEnd2;++aIter2 ) + { + if ( aIter2->second.sTableName == sTableName ) + { + o_aCachedRow[aIter2->second.nPosition] = i_aRow[aIter2->second.nPosition]; + o_aCachedRow[aIter2->second.nPosition].setModified(); + } + } + fillMissingValues(o_aCachedRow); + } + } + } + return bRet; +} +// ----------------------------------------------------------------------------- +void OptimisticSet::fillMissingValues(ORowSetValueVector::Vector& io_aRow) const +{ + TSQLStatements aSql; + TSQLStatements aKeyConditions; + ::std::map< ::rtl::OUString,bool > aResultSetChanged; + ::rtl::OUString aQuote = getIdentifierQuoteString(); + static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND "); + ::rtl::OUString sIsNull(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")); + ::rtl::OUString sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?")); + // here we build the condition part for the update statement + SelectColumnsMetaData::const_iterator aColIter = m_pColumnNames->begin(); + SelectColumnsMetaData::const_iterator aColEnd = m_pColumnNames->end(); + for(;aColIter != aColEnd;++aColIter) + { + const ::rtl::OUString sQuotedColumnName = ::dbtools::quoteName( aQuote,aColIter->second.sRealName); + if ( m_aJoinedKeyColumns.find(aColIter->second.nPosition) != m_aJoinedKeyColumns.end() ) + { + lcl_fillKeyCondition(aColIter->second.sTableName,sQuotedColumnName,io_aRow[aColIter->second.nPosition],aKeyConditions); + } + ::rtl::OUStringBuffer& rPart = aSql[aColIter->second.sTableName]; + if ( rPart.getLength() ) + rPart.appendAscii(", "); + rPart.append(sQuotedColumnName); + } + Reference<XDatabaseMetaData> xMetaData = m_xConnection->getMetaData(); + TSQLStatements::iterator aSqlIter = aSql.begin(); + TSQLStatements::iterator aSqlEnd = aSql.end(); + for(;aSqlIter != aSqlEnd ; ++aSqlIter) + { + if ( aSqlIter->second.getLength() ) + { + ::rtl::OUStringBuffer& rCondition = aKeyConditions[aSqlIter->first]; + if ( rCondition.getLength() ) + { + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMetaData,aSqlIter->first,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + ::rtl::OUString sComposedTableName = ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable ); + ::rtl::OUStringBuffer sQuery; + sQuery.appendAscii("SELECT "); + sQuery.append(aSqlIter->second); + sQuery.appendAscii(" FROM "); + sQuery.append(sComposedTableName); + sQuery.appendAscii(" WHERE "); + sQuery.append(rCondition.makeStringAndClear()); + + try + { + Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(sQuery.makeStringAndClear())); + Reference< XParameters > xParameter(xPrep,UNO_QUERY); + // and then the values of the where condition + SelectColumnsMetaData::iterator aKeyIter = m_pKeyColumnNames->begin(); + SelectColumnsMetaData::iterator aKeyEnd = m_pKeyColumnNames->end(); + sal_Int32 i = 1; + for(;aKeyIter != aKeyEnd;++aKeyIter) + { + if ( aKeyIter->second.sTableName == aSqlIter->first ) + { + setParameter(i++,xParameter,io_aRow[aKeyIter->second.nPosition],aKeyIter->second.nType,aKeyIter->second.nScale); + } + } + Reference<XResultSet> xRes = xPrep->executeQuery(); + Reference<XRow> xRow(xRes,UNO_QUERY); + if ( xRow.is() && xRes->next() ) + { + i = 1; + aColIter = m_pColumnNames->begin(); + for(;aColIter != aColEnd;++aColIter) + { + if ( aColIter->second.sTableName == aSqlIter->first ) + { + io_aRow[aColIter->second.nPosition].fill(i++,aColIter->second.nType,aColIter->second.bNullable,xRow); + io_aRow[aColIter->second.nPosition].setModified(); + } + } + } + } + catch(const SQLException&) + { + } + } + } + } +} +// ----------------------------------------------------------------------------- + diff --git a/dbaccess/source/core/api/OptimisticSet.hxx b/dbaccess/source/core/api/OptimisticSet.hxx new file mode 100644 index 000000000..1f42bebdf --- /dev/null +++ b/dbaccess/source/core/api/OptimisticSet.hxx @@ -0,0 +1,196 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: KeySet.hxx,v $ + * $Revision: 1.30 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DBACCESS_CORE_API_OPTIMISTICSET_HXX +#define DBACCESS_CORE_API_OPTIMISTICSET_HXX + +#include "CacheSet.hxx" +#include "KeySet.hxx" +#include <cppuhelper/implbase1.hxx> +#include <map> +#include <memory> +#include <connectivity/sqlparse.hxx> +#include <connectivity/sqliterator.hxx> + +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp> +#include <comphelper/stl_types.hxx> +#include <comphelper/componentcontext.hxx> + +namespace dbaccess +{ + // is used when the source supports keys + class OptimisticSet : public OCacheSet + { + ::connectivity::OSQLParser m_aSqlParser; + ::connectivity::OSQLParseTreeIterator m_aSqlIterator; + OKeySetMatrix m_aKeyMap; + OKeySetMatrix::iterator m_aKeyIter; + + ::std::vector< ::rtl::OUString > m_aAutoColumns; // contains all columns which are autoincrement ones + ::std::map<sal_Int32,sal_Int32> m_aJoinedColumns; + ::std::map<sal_Int32,sal_Int32> m_aJoinedKeyColumns; + + OUpdatedParameter m_aUpdatedParameter; // contains all parameter which have been updated and are needed for refetching + ORowSetValueVector m_aParameterValueForCache; + ::std::auto_ptr<SelectColumnsMetaData> m_pKeyColumnNames; // contains all key column names + ::std::auto_ptr<SelectColumnsMetaData> m_pColumnNames; // contains all column names + ::std::auto_ptr<SelectColumnsMetaData> m_pParameterNames; // contains all parameter names + connectivity::OSQLTable m_xTable; // reference to our table + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement> m_xStatement; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet> m_xSet; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow> m_xRow; + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryAnalyzer > m_xComposer; + + sal_Bool m_bRowCountFinal; + mutable bool m_bResultSetChanged; + + /** + getComposedTableName return the composed table name for the query + @param _sCatalog the catalogname may be empty + @param _sSchema the schemaname may be empty + @param _sTable the tablename + + @return the composed name + */ + ::rtl::OUString getComposedTableName( const ::rtl::OUString& _sCatalog, + const ::rtl::OUString& _sSchema, + const ::rtl::OUString& _sTable); + + /** copies the values from the insert row into the key row + * + * \param _rInsertRow the row which was inserted + * \param _rKeyRow The current key row of the row set. + + \param i_nBookmark The bookmark is used to update the parameter + */ + void copyRowValue(const ORowSetRow& _rInsertRow,ORowSetRow& _rKeyRow,sal_Int32 i_nBookmark); + + void fillAllRows(); + sal_Bool fetchRow(); + + void impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData); + void findTableColumnsMatching_throw( const ::com::sun::star::uno::Any& i_aTable + ,const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>& i_xMeta + ,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& i_xQueryColumns); + void executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName); + void executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName); + void executeDelete(const ORowSetRow& _rDeleteRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName); + void fillJoinedColumns_throw(const ::std::vector< ::connectivity::TNodePair>& i_aJoinColumns); + void fillJoinedColumns_throw(const ::rtl::OUString& i_sLeftColumn,const ::rtl::OUString& i_sRightColumn); + protected: + virtual ~OptimisticSet(); + public: + OptimisticSet(const ::comphelper::ComponentContext& _rContext, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& i_xConnection, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryAnalyzer >& _xComposer, + const ORowSetValueVector& _aParameterValueForCache); + + // late ctor which can throw exceptions + virtual void construct(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter); + + // ::com::sun::star::sdbc::XRow + virtual sal_Bool SAL_CALL wasNull( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getString( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL getBoolean( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int8 SAL_CALL getByte( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getShort( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getInt( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLong( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual float SAL_CALL getFloat( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getDouble( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getBytes( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Date SAL_CALL getDate( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Time SAL_CALL getTime( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::DateTime SAL_CALL getTimestamp( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getBinaryStream( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getCharacterStream( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef > SAL_CALL getRef( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob > SAL_CALL getBlob( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob > SAL_CALL getClob( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray > SAL_CALL getArray( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + + virtual sal_Bool SAL_CALL rowUpdated( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL rowInserted( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL rowDeleted( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdbc::XResultSet + virtual sal_Bool SAL_CALL next( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isBeforeFirst( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isAfterLast( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isFirst( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isLast( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL beforeFirst( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL afterLast( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL first( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL last( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL absolute( sal_Int32 row ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL relative( sal_Int32 rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL previous( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL refreshRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdbcx::XRowLocate + virtual ::com::sun::star::uno::Any SAL_CALL getBookmark() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ------------------------------------------------------------------------- + virtual sal_Bool SAL_CALL moveToBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ------------------------------------------------------------------------- + virtual sal_Bool SAL_CALL moveRelativeToBookmark( const ::com::sun::star::uno::Any& bookmark, sal_Int32 rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ------------------------------------------------------------------------- + virtual sal_Int32 SAL_CALL compareBookmarks( const ::com::sun::star::uno::Any& first, const ::com::sun::star::uno::Any& second ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ------------------------------------------------------------------------- + virtual sal_Bool SAL_CALL hasOrderedBookmarks( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ------------------------------------------------------------------------- + virtual sal_Int32 SAL_CALL hashBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ------------------------------------------------------------------------- + // ::com::sun::star::sdbcx::XDeleteRows + virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL deleteRows( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rows ,const connectivity::OSQLTable& _xTable) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdbc::XResultSetUpdate + virtual void SAL_CALL updateRow(const ORowSetRow& _rInsertRow,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deleteRow(const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancelRowUpdates( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToInsertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToCurrentRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + + // CacheSet + virtual bool isResultSetChanged() const; + virtual void reset(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet); + virtual void mergeColumnValues(sal_Int32 i_nColumnIndex,ORowSetValueVector::Vector& io_aInsertRow,ORowSetValueVector::Vector& io_aRow,::std::vector<sal_Int32>& o_aChangedColumns); + virtual bool columnValuesUpdated(ORowSetValueVector::Vector& o_aCachedRow,const ORowSetValueVector::Vector& i_aRow); + virtual bool updateColumnValues(const ORowSetValueVector::Vector& io_aCachedRow,ORowSetValueVector::Vector& io_aRow,const ::std::vector<sal_Int32>& i_aChangedColumns); + virtual void fillMissingValues(ORowSetValueVector::Vector& io_aRow) const; + + bool isReadOnly() const { return m_aJoinedKeyColumns.empty(); } + const ::std::map<sal_Int32,sal_Int32>& getJoinedColumns() const { return m_aJoinedColumns; } + const ::std::map<sal_Int32,sal_Int32>& getJoinedKeyColumns() const { return m_aJoinedKeyColumns; } + }; +} +#endif // DBACCESS_CORE_API_OPTIMISTICSET_HXX + diff --git a/dbaccess/source/core/api/RowSet.cxx b/dbaccess/source/core/api/RowSet.cxx index 579b1d490..20483cff0 100644 --- a/dbaccess/source/core/api/RowSet.cxx +++ b/dbaccess/source/core/api/RowSet.cxx @@ -138,8 +138,6 @@ extern "C" void SAL_CALL createRegistryInfo_ORowSet() namespace dbaccess { //.................................................................. - - //-------------------------------------------------------------------------- Reference< XInterface > ORowSet_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory) { @@ -152,6 +150,7 @@ ORowSet::ORowSet( const Reference< ::com::sun::star::lang::XMultiServiceFactory ,m_pParameters( NULL ) ,m_aRowsetListeners(*m_pMutex) ,m_aApproveListeners(*m_pMutex) + ,m_aRowsChangeListener(*m_pMutex) ,m_pTables(NULL) ,m_nFetchDirection(FetchDirection::FORWARD) ,m_nFetchSize(50) @@ -198,6 +197,7 @@ ORowSet::ORowSet( const Reference< ::com::sun::star::lang::XMultiServiceFactory registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, nRT, &m_nPrivileges, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); registerProperty(PROPERTY_ISMODIFIED, PROPERTY_ID_ISMODIFIED, nBT, &m_bModified, ::getBooleanCppuType()); registerProperty(PROPERTY_ISNEW, PROPERTY_ID_ISNEW, nRBT, &m_bNew, ::getBooleanCppuType()); + registerProperty(PROPERTY_SINGLESELECTQUERYCOMPOSER,PROPERTY_ID_SINGLESELECTQUERYCOMPOSER, nRT, &m_xComposer, ::getCppuType(reinterpret_cast< Reference< XSingleSelectQueryComposer >* >(NULL))); // sdbcx.ResultSet Properties registerProperty(PROPERTY_ISBOOKMARKABLE, PROPERTY_ID_ISBOOKMARKABLE, nRT, &m_bIsBookmarable, ::getBooleanCppuType()); @@ -528,6 +528,7 @@ void SAL_CALL ORowSet::disposing() aDisposeEvent.Source = static_cast< XComponent* >(this); m_aRowsetListeners.disposeAndClear( aDisposeEvent ); m_aApproveListeners.disposeAndClear( aDisposeEvent ); + m_aRowsChangeListener.disposeAndClear( aDisposeEvent ); freeResources( true ); @@ -700,12 +701,10 @@ void ORowSet::updateValue(sal_Int32 columnIndex,const ORowSetValue& x) checkUpdateConditions(columnIndex); checkUpdateIterator(); - ::connectivity::ORowSetValue aOldValue(((*m_aCurrentRow)->get())[columnIndex]); - m_pCache->updateValue(columnIndex,x); - // we have to notify all listeners - ((*m_aCurrentRow)->get())[columnIndex] = x; - firePropertyChange(columnIndex-1 ,aOldValue); - fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False); + ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); + ORowSetNotifier aNotify(this,rRow); + m_pCache->updateValue(columnIndex,x,rRow,aNotify.getChangedColumns()); + aNotify.firePropertyChange(); } // ------------------------------------------------------------------------- // XRowUpdate @@ -717,12 +716,10 @@ void SAL_CALL ORowSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, R checkUpdateConditions(columnIndex); checkUpdateIterator(); - ::connectivity::ORowSetValue aOldValue(((*m_aCurrentRow)->get())[columnIndex]); - m_pCache->updateNull(columnIndex); - // we have to notify all listeners - ((*m_aCurrentRow)->get())[columnIndex].setNull(); - firePropertyChange(columnIndex-1 ,aOldValue); - fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False); + ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); + ORowSetNotifier aNotify(this,rRow); + m_pCache->updateNull(columnIndex,rRow,aNotify.getChangedColumns()); + aNotify.firePropertyChange(); } // ------------------------------------------------------------------------- void SAL_CALL ORowSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException) @@ -788,11 +785,8 @@ void SAL_CALL ORowSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun: void SAL_CALL ORowSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) { ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( *m_pMutex ); - checkUpdateConditions(columnIndex); - checkUpdateIterator(); //if(((*m_aCurrentRow)->get())[columnIndex].getTypeKind() == DataType::BLOB) @@ -816,26 +810,20 @@ void SAL_CALL ORowSet::updateBinaryStream( sal_Int32 columnIndex, const Referenc void SAL_CALL ORowSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) { ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( *m_pMutex ); checkUpdateConditions(columnIndex); - checkUpdateIterator(); - m_pCache->updateCharacterStream(columnIndex,x,length); - - ::connectivity::ORowSetValue aOldValue(((*m_aCurrentRow)->get())[columnIndex]); - ((*m_aCurrentRow)->get())[columnIndex] = makeAny(x); - firePropertyChange(columnIndex-1 ,aOldValue); - fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False); + ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); + ORowSetNotifier aNotify(this,rRow); + m_pCache->updateCharacterStream(columnIndex,x,length,rRow,aNotify.getChangedColumns()); + aNotify.firePropertyChange(); } // ------------------------------------------------------------------------- void SAL_CALL ORowSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException) { ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( *m_pMutex ); checkUpdateConditions(columnIndex); - checkUpdateIterator(); Any aNewValue = x; @@ -868,29 +856,23 @@ void SAL_CALL ORowSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw if (!::dbtools::implUpdateObject(this, columnIndex, aNewValue)) { // there is no other updateXXX call which can handle the value in x - ::connectivity::ORowSetValue aOldValue(((*m_aCurrentRow)->get())[columnIndex]); - m_pCache->updateObject(columnIndex,aNewValue); - // we have to notify all listeners - ((*m_aCurrentRow)->get())[columnIndex] = aNewValue; - firePropertyChange(columnIndex-1 ,aOldValue); - fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False); + ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); + ORowSetNotifier aNotify(this,rRow); + m_pCache->updateObject(columnIndex,aNewValue,rRow,aNotify.getChangedColumns()); + aNotify.firePropertyChange(); } } // ------------------------------------------------------------------------- void SAL_CALL ORowSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 scale ) throw(SQLException, RuntimeException) { ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); - ::osl::MutexGuard aGuard( *m_pMutex ); checkUpdateConditions(columnIndex); - checkUpdateIterator(); - ::connectivity::ORowSetValue aOldValue(((*m_aCurrentRow)->get())[columnIndex]); - m_pCache->updateNumericObject(columnIndex,x,scale); - // we have to notify all listeners - ((*m_aCurrentRow)->get())[columnIndex] = x; - firePropertyChange(columnIndex-1 ,aOldValue); - fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False); + ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); + ORowSetNotifier aNotify(this,rRow); + m_pCache->updateNumericObject(columnIndex,x,scale,rRow,aNotify.getChangedColumns()); + aNotify.firePropertyChange(); } // ------------------------------------------------------------------------- @@ -915,10 +897,12 @@ void SAL_CALL ORowSet::insertRow( ) throw(SQLException, RuntimeException) ORowSetRow aOldValues; if ( !m_aCurrentRow.isNull() ) aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() ); - RowChangeEvent aEvt(*this,RowChangeAction::INSERT,1); + Sequence<Any> aChangedBookmarks; + RowsChangeEvent aEvt(*this,RowChangeAction::INSERT,1,aChangedBookmarks); notifyAllListenersRowBeforeChange(aGuard,aEvt); - sal_Bool bInserted = m_pCache->insertRow(); + ::std::vector< Any > aBookmarks; + sal_Bool bInserted = m_pCache->insertRow(aBookmarks); // make sure that our row is set to the new inserted row before clearing the insert flags in the cache m_pCache->resetInsertRow(bInserted); @@ -927,8 +911,17 @@ void SAL_CALL ORowSet::insertRow( ) throw(SQLException, RuntimeException) // - column values setCurrentRow( sal_False, sal_True, aOldValues, aGuard ); // we don't move here + // read-only flag restored + impl_restoreDataColumnsWriteable_throw(); + // - rowChanged notifyAllListenersRowChanged(aGuard,aEvt); + + if ( !aBookmarks.empty() ) + { + RowsChangeEvent aUpEvt(*this,RowChangeAction::UPDATE,aBookmarks.size(),Sequence<Any>(&(*aBookmarks.begin()),aBookmarks.size())); + notifyAllListenersRowChanged(aGuard,aUpEvt); + } // - IsModified if(!m_bModified) @@ -968,20 +961,31 @@ void SAL_CALL ORowSet::updateRow( ) throw(SQLException, RuntimeException) if ( !m_aCurrentRow.isNull() ) aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() ); - RowChangeEvent aEvt(*this,RowChangeAction::UPDATE,1); + Sequence<Any> aChangedBookmarks; + RowsChangeEvent aEvt(*this,RowChangeAction::UPDATE,1,aChangedBookmarks); notifyAllListenersRowBeforeChange(aGuard,aEvt); - m_pCache->updateRow(m_aCurrentRow.operator ->()); + ::std::vector< Any > aBookmarks; + m_pCache->updateRow(m_aCurrentRow.operator ->(),aBookmarks); + if ( !aBookmarks.empty() ) + aEvt.Bookmarks = Sequence<Any>(&(*aBookmarks.begin()),aBookmarks.size()); + aEvt.Rows += aBookmarks.size(); m_aBookmark = m_pCache->getBookmark(); m_aCurrentRow = m_pCache->m_aMatrixIter; - if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() ) + if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && (*m_pCache->m_aMatrixIter).isValid() ) { - m_aOldRow->setRow(new ORowSetValueVector(m_aCurrentRow->getBody())); - - // notification order - // - column values - ORowSetBase::firePropertyChange(aOldValues); + if ( m_pCache->isResultSetChanged() ) + { + impl_rebuild_throw(aGuard); + } + else + { + m_aOldRow->setRow(new ORowSetValueVector(m_aCurrentRow->getBody())); + // notification order + // - column values + ORowSetBase::firePropertyChange(aOldValues); + } // - rowChanged notifyAllListenersRowChanged(aGuard,aEvt); @@ -989,8 +993,11 @@ void SAL_CALL ORowSet::updateRow( ) throw(SQLException, RuntimeException) if(!m_bModified) fireProperty(PROPERTY_ID_ISMODIFIED,sal_False,sal_True); OSL_ENSURE( !m_bModified, "ORowSet::updateRow: just updated, but _still_ modified?" ); + + // - RowCount/IsRowCountFinal + fireRowcount(); } - else // the update went rong + else if ( !m_bAfterLast ) // the update went rong { ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_UPDATE_FAILED ), SQL_INVALID_CURSOR_POSITION, *this ); } @@ -1026,7 +1033,8 @@ void SAL_CALL ORowSet::deleteRow( ) throw(SQLException, RuntimeException) if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && m_pCache->m_aMatrixIter->isValid() ) aOldValues = new ORowSetValueVector( m_pCache->m_aMatrixIter->getBody() ); - RowChangeEvent aEvt(*this,RowChangeAction::DELETE,1); + Sequence<Any> aChangedBookmarks; + RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,1,aChangedBookmarks); notifyAllListenersRowBeforeChange(aGuard,aEvt); m_pCache->deleteRow(); @@ -1125,10 +1133,11 @@ void ORowSet::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard _rGuard.reset(); } // ------------------------------------------------------------------------- -void ORowSet::notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard, const EventObject& aEvt) +void ORowSet::notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard, const RowsChangeEvent& aEvt) { _rGuard.clear(); - m_aRowsetListeners.notifyEach( &XRowSetListener::rowChanged, aEvt ); + m_aRowsetListeners.notifyEach( &XRowSetListener::rowChanged, (EventObject)aEvt ); + m_aRowsChangeListener.notifyEach( &XRowsChangeListener::rowsChanged, aEvt ); _rGuard.reset(); } // ------------------------------------------------------------------------- @@ -1163,8 +1172,8 @@ void ORowSet::fireRowcount() { sal_Int32 nHandle = PROPERTY_ID_ISROWCOUNTFINAL; Any aNew,aOld; - aNew <<= bool2any( bCurrentRowCountFinal ); - aOld <<= bool2any( m_bLastKnownRowCountFinal ); + aNew <<= bCurrentRowCountFinal; + aOld <<= m_bLastKnownRowCountFinal; fire(&nHandle,&aNew,&aOld,1,sal_False); m_bLastKnownRowCountFinal = bCurrentRowCountFinal; } @@ -1206,6 +1215,9 @@ void SAL_CALL ORowSet::moveToInsertRow( ) throw(SQLException, RuntimeException) m_pCache->moveToInsertRow(); m_aCurrentRow = m_pCache->m_aInsertRow; + // set read-only flag to false + impl_setDataColumnsWriteable_throw(); + // notification order // - column values ORowSetBase::firePropertyChange(aOldValues); @@ -1226,6 +1238,33 @@ void SAL_CALL ORowSet::moveToInsertRow( ) throw(SQLException, RuntimeException) } } // ------------------------------------------------------------------------- +void ORowSet::impl_setDataColumnsWriteable_throw() +{ + impl_restoreDataColumnsWriteable_throw(); + TDataColumns::iterator aIter = m_aDataColumns.begin(); + m_aReadOnlyDataColumns.resize(m_aDataColumns.size(),false); + ::std::bit_vector::iterator aReadIter = m_aReadOnlyDataColumns.begin(); + for(;aIter != m_aDataColumns.end();++aIter,++aReadIter) + { + sal_Bool bReadOnly = sal_False; + (*aIter)->getPropertyValue(PROPERTY_ISREADONLY) >>= bReadOnly; + *aReadIter = bReadOnly; + + (*aIter)->setPropertyValue(PROPERTY_ISREADONLY,makeAny(sal_False)); + } +} +// ------------------------------------------------------------------------- +void ORowSet::impl_restoreDataColumnsWriteable_throw() +{ + TDataColumns::iterator aIter = m_aDataColumns.begin(); + ::std::bit_vector::iterator aReadIter = m_aReadOnlyDataColumns.begin(); + for(;aReadIter != m_aReadOnlyDataColumns.end();++aIter,++aReadIter) + { + (*aIter)->setPropertyValue(PROPERTY_ISREADONLY,makeAny((sal_Bool)*aReadIter )); + } + m_aReadOnlyDataColumns.clear(); +} +// ------------------------------------------------------------------------- void SAL_CALL ORowSet::moveToCurrentRow( ) throw(SQLException, RuntimeException) { ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); @@ -1783,7 +1822,7 @@ void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotifi } m_pCache->setMaxRowSize(m_nFetchSize); m_aCurrentRow = m_pCache->createIterator(this); - m_aOldRow = m_pCache->registerOldRow(); + m_aOldRow = m_pCache->registerOldRow(); } // get the locale @@ -1803,6 +1842,7 @@ void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotifi ::rtl::OUString aDescription; sal_Int32 nFormatKey = 0; + const ::std::map<sal_Int32,sal_Int32>& rKeyColumns = m_pCache->getKeyColumns(); if(!m_xColumns.is()) { RTL_LOGFILE_CONTEXT_AUTHOR( aColumnCreateLog, "dbaccess", "frank.schoenheit@sun.com", "ORowSet::execute_NoApprove_NoNewConn::creating columns" ); @@ -1839,6 +1879,7 @@ void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotifi i+1, m_xActiveConnection->getMetaData(), aDescription, + ::rtl::OUString(), m_aCurrentRow); aColumnMap.insert(StringMap::value_type(sName,0)); aColumns->get().push_back(pColumn); @@ -1846,6 +1887,8 @@ void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotifi aNames.push_back(sName); m_aDataColumns.push_back(pColumn); + pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ISREADONLY,makeAny(rKeyColumns.find(i+1) != rKeyColumns.end())); + try { nFormatKey = 0; @@ -1897,6 +1940,7 @@ void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotifi { xColumn = NULL; bReFetchName = sal_True; + sColumnLabel = ::rtl::OUString(); } if(!xColumn.is()) { @@ -1928,14 +1972,23 @@ void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotifi if(xInfo.is() && xInfo->hasPropertyByName(PROPERTY_DESCRIPTION)) aDescription = comphelper::getString(xColumn->getPropertyValue(PROPERTY_DESCRIPTION)); + ::rtl::OUString sParseLabel; + if ( xColumn.is() ) + { + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sParseLabel; + } ORowSetDataColumn* pColumn = new ORowSetDataColumn( getMetaData(), this, this, i, m_xActiveConnection->getMetaData(), aDescription, + sParseLabel, m_aCurrentRow); aColumns->get().push_back(pColumn); + + pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ISREADONLY,makeAny(rKeyColumns.find(i) != rKeyColumns.end())); + if(!sColumnLabel.getLength()) { if(xColumn.is()) @@ -1985,6 +2038,24 @@ void SAL_CALL ORowSet::removeRowSetApproveListener( const Reference< XRowSetAppr m_aApproveListeners.removeInterface(listener); } +// XRowsChangeBroadcaster +void SAL_CALL ORowSet::addRowsChangeListener( const Reference< XRowsChangeListener >& listener ) throw(RuntimeException) +{ + ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); + + ::osl::MutexGuard aGuard( m_aColumnsMutex ); + + m_aRowsChangeListener.addInterface(listener); +} +// ------------------------------------------------------------------------- +void SAL_CALL ORowSet::removeRowsChangeListener( const Reference< XRowsChangeListener >& listener ) throw(RuntimeException) +{ + ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); + + ::osl::MutexGuard aGuard( m_aColumnsMutex ); + + m_aRowsChangeListener.removeInterface(listener); +} // ------------------------------------------------------------------------- // XResultSetAccess @@ -2020,7 +2091,8 @@ Sequence< sal_Int32 > SAL_CALL ORowSet::deleteRows( const Sequence< Any >& rows ::osl::ResettableMutexGuard aGuard( *m_pMutex ); - RowChangeEvent aEvt(*this,RowChangeAction::DELETE,rows.getLength()); + Sequence<Any> aChangedBookmarks; + RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,rows.getLength(),aChangedBookmarks); // notify the rowset listeners notifyAllListenersRowBeforeChange(aGuard,aEvt); @@ -2222,7 +2294,8 @@ sal_Bool ORowSet::impl_initComposer_throw( ::rtl::OUString& _out_rCommandToExecu if ( !m_xComposer.is() ) m_xComposer = new OSingleSelectQueryComposer( impl_getTables_throw(), m_xActiveConnection, m_aContext ); - m_xComposer->setElementaryQuery( m_aActiveCommand ); + m_xComposer->setCommand( m_aCommand,m_nCommandType ); + m_aActiveCommand = m_xComposer->getQuery(); m_xComposer->setFilter( m_bApplyFilter ? m_aFilter : ::rtl::OUString() ); m_xComposer->setHavingClause( m_bApplyFilter ? m_aHavingClause : ::rtl::OUString() ); @@ -2248,6 +2321,7 @@ sal_Bool ORowSet::impl_initComposer_throw( ::rtl::OUString& _out_rCommandToExecu impl_initParametersContainer_nothrow(); _out_rCommandToExecute = m_xComposer->getQueryWithSubstitution(); + return bUseEscapeProcessing; } @@ -2270,41 +2344,52 @@ sal_Bool ORowSet::impl_buildActiveCommand_throw() case CommandType::TABLE: { impl_resetTables_nothrow(); - - Reference< XNameAccess > xTables( impl_getTables_throw() ); - if ( xTables->hasByName(m_aCommand) ) + if ( bDoEscapeProcessing ) { - Reference< XPropertySet > xTable; - try + Reference< XNameAccess > xTables( impl_getTables_throw() ); + if ( xTables->hasByName(m_aCommand) ) { - xTables->getByName( m_aCommand ) >>= xTable; - } - catch(const WrappedTargetException& e) - { - SQLException e2; - if ( e.TargetException >>= e2 ) - throw e2; +/* + Reference< XPropertySet > xTable; + try + { + xTables->getByName( m_aCommand ) >>= xTable; + } + catch(const WrappedTargetException& e) + { + SQLException e2; + if ( e.TargetException >>= e2 ) + throw e2; + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + + Reference<XColumnsSupplier> xSup(xTable,UNO_QUERY); + if ( xSup.is() ) + m_xColumns = xSup->getColumns(); + + sCommand = rtl::OUString::createFromAscii("SELECT * FROM "); + ::rtl::OUString sCatalog, sSchema, sTable; + ::dbtools::qualifiedNameComponents( m_xActiveConnection->getMetaData(), m_aCommand, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation ); + sCommand += ::dbtools::composeTableNameForSelect( m_xActiveConnection, sCatalog, sSchema, sTable ); +*/ } - catch(Exception&) + else { - DBG_UNHANDLED_EXCEPTION(); + String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) ); + sMessage.SearchAndReplaceAscii( "$table$", m_aCommand ); + throwGenericSQLException(sMessage,*this); } - - Reference<XColumnsSupplier> xSup(xTable,UNO_QUERY); - if ( xSup.is() ) - m_xColumns = xSup->getColumns(); - + } + else + { sCommand = rtl::OUString::createFromAscii("SELECT * FROM "); ::rtl::OUString sCatalog, sSchema, sTable; ::dbtools::qualifiedNameComponents( m_xActiveConnection->getMetaData(), m_aCommand, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation ); sCommand += ::dbtools::composeTableNameForSelect( m_xActiveConnection, sCatalog, sSchema, sTable ); } - else - { - String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) ); - sMessage.SearchAndReplaceAscii( "$table$", m_aCommand ); - throwGenericSQLException(sMessage,*this); - } } break; @@ -2335,10 +2420,11 @@ sal_Bool ORowSet::impl_buildActiveCommand_throw() xQuery->getPropertyValue(PROPERTY_UPDATE_TABLENAME) >>= aTable; if(aTable.getLength()) m_aUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), aCatalog, aSchema, aTable, sal_False, ::dbtools::eInDataManipulation ); - +/* Reference<XColumnsSupplier> xSup(xQuery,UNO_QUERY); if(xSup.is()) m_xColumns = xSup->getColumns(); +*/ } } else @@ -2360,7 +2446,7 @@ sal_Bool ORowSet::impl_buildActiveCommand_throw() m_aActiveCommand = sCommand; - if ( !m_aActiveCommand.getLength() ) + if ( !m_aActiveCommand.getLength() && !bDoEscapeProcessing ) ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_SQL_COMMAND ), SQL_FUNCTION_SEQUENCE_ERROR, *this ); return bDoEscapeProcessing; @@ -2612,20 +2698,16 @@ void SAL_CALL ORowSet::clearWarnings( ) throw (SQLException, RuntimeException) { m_aWarnings.clearWarnings(); } - -// ------------------------------------------------------------------------- -void ORowSet::firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rOldValue) -{ - OSL_ENSURE(_nPos < (sal_Int32)m_aDataColumns.size(),"nPos is invalid!"); - m_aDataColumns[_nPos]->fireValueChange(_rOldValue); -} - // ----------------------------------------------------------------------------- void ORowSet::doCancelModification( ) { //OSL_ENSURE( isModification(), "ORowSet::doCancelModification: invalid call (no cache!)!" ); if ( isModification() ) + { + // read-only flag restored + impl_restoreDataColumnsWriteable_throw(); m_pCache->cancelRowModification(); + } m_bModified = sal_False; } @@ -2693,6 +2775,14 @@ void SAL_CALL ORowSet::refreshRow( ) throw(SQLException, RuntimeException) // - IsNew aNotifier.fire( ); } +// ----------------------------------------------------------------------------- +void ORowSet::impl_rebuild_throw(::osl::ResettableMutexGuard& _rGuard) +{ + Reference< XResultSet > xResultSet( m_xStatement->executeQuery() ); + m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) ); + m_pCache->reset(xResultSet); + notifyAllListeners(_rGuard); +} // *********************************************************** // ORowSetClone // *********************************************************** @@ -2742,11 +2832,15 @@ ORowSetClone::ORowSetClone( const ::comphelper::ComponentContext& _rContext, ORo rParent.m_pColumns->getByName(*pIter) >>= xColumn; if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_DESCRIPTION)) aDescription = comphelper::getString(xColumn->getPropertyValue(PROPERTY_DESCRIPTION)); + + ::rtl::OUString sParseLabel; + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sParseLabel; ORowSetColumn* pColumn = new ORowSetColumn( rParent.getMetaData(), this, i, rParent.m_xActiveConnection->getMetaData(), aDescription, + sParseLabel, m_aCurrentRow); aColumns->get().push_back(pColumn); pColumn->setName(*pIter); diff --git a/dbaccess/source/core/api/RowSet.hxx b/dbaccess/source/core/api/RowSet.hxx index da8f67e56..fdd0ecb85 100644 --- a/dbaccess/source/core/api/RowSet.hxx +++ b/dbaccess/source/core/api/RowSet.hxx @@ -32,68 +32,36 @@ #include "RowSetBase.hxx" /** === begin UNO includes === **/ -#ifndef _COM_SUN_STAR_SDBC_XPREPAREDSTATEMENT_HPP_ #include <com/sun/star/sdbc/XPreparedStatement.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_ #include <com/sun/star/sdbc/XConnection.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_ #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XRESULTSETACCESS_HPP_ #include <com/sun/star/sdb/XResultSetAccess.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XROWSETLISTENER_HPP_ #include <com/sun/star/sdbc/XRowSetListener.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XROWUPDATE_HPP_ #include <com/sun/star/sdbc/XRowUpdate.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XRESULTSETUPDATE_HPP_ #include <com/sun/star/sdbc/XResultSetUpdate.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XPARAMETERS_HPP_ #include <com/sun/star/sdbc/XParameters.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XROWSETAPPROVEBROADCASTER_HPP_ #include <com/sun/star/sdb/XRowSetApproveBroadcaster.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_RESULTSETTYPE_HPP_ #include <com/sun/star/sdbc/ResultSetType.hpp> -#endif -#ifndef _COM_SUN_STAR_UTIL_XCANCELLABLE_HPP_ #include <com/sun/star/util/XCancellable.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XDELETEROWS_HPP_ #include <com/sun/star/sdbcx/XDeleteRows.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XCOMPLETEDEXECUTION_HPP_ #include <com/sun/star/sdb/XCompletedExecution.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_ROWSETVETOEXCEPTION_HPP_ #include <com/sun/star/sdb/RowSetVetoException.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYANALYZER_HPP_ #include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_ #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_XPARAMETERSSUPPLIER_HPP_ #include <com/sun/star/sdb/XParametersSupplier.hpp> -#endif +#include <com/sun/star/sdb/XRowsChangeBroadcaster.hpp> /** === end UNO includes === **/ -#include <cppuhelper/compbase11.hxx> +#include <cppuhelper/compbase12.hxx> #include <connectivity/paramwrapper.hxx> #include <connectivity/FValue.hxx> #include <connectivity/warningscontainer.hxx> namespace dbaccess { - typedef ::cppu::WeakAggComponentImplHelper11 < ::com::sun::star::sdb::XResultSetAccess + typedef ::cppu::WeakAggComponentImplHelper12 < ::com::sun::star::sdb::XResultSetAccess , ::com::sun::star::sdb::XRowSetApproveBroadcaster + , ::com::sun::star::sdb::XRowsChangeBroadcaster , ::com::sun::star::sdbcx::XDeleteRows , ::com::sun::star::sdbc::XParameters , ::com::sun::star::lang::XEventListener @@ -132,9 +100,11 @@ namespace dbaccess ORowSetValueVector m_aPrematureParamValues; ORowSetValueVector m_aParameterValueForCache; ::std::bit_vector m_aParametersSet; + ::std::bit_vector m_aReadOnlyDataColumns; ::cppu::OInterfaceContainerHelper m_aRowsetListeners; ::cppu::OInterfaceContainerHelper m_aApproveListeners; + ::cppu::OInterfaceContainerHelper m_aRowsChangeListener; ::dbtools::WarningsContainer m_aWarnings; @@ -242,10 +212,6 @@ namespace dbaccess // free clones and ParseTree. Plus, if _bComplete is <TRUE/>, *all* other associated resources void freeResources( bool _bComplete ); - // fire a change for one column - // _nPos starts at zero - void firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rNewValue); - /// informs the clones (and ourself) that we are going to delete a record with a given bookmark void notifyRowSetAndClonesRowDelete( const ::com::sun::star::uno::Any& _rBookmark ); @@ -260,6 +226,11 @@ namespace dbaccess void updateValue(sal_Int32 columnIndex,const connectivity::ORowSetValue& x); void checkUpdateConditions(sal_Int32 columnIndex); + void impl_rebuild_throw(::osl::ResettableMutexGuard& _rGuard); + // set all data columns to writeable + void impl_setDataColumnsWriteable_throw(); + // restore the old state of the data column read-only state + void impl_restoreDataColumnsWriteable_throw(); protected: virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const ::com::sun::star::uno::Any& rValue) throw (::com::sun::star::uno::Exception); @@ -268,7 +239,7 @@ namespace dbaccess virtual void fireRowcount(); void notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const ::com::sun::star::sdb::RowChangeEvent &rEvt); - void notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard,const ::com::sun::star::lang::EventObject& rEvt); + void notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard,const ::com::sun::star::sdb::RowsChangeEvent& rEvt); virtual sal_Bool notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard); virtual void notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard); virtual void notifyAllListeners(::osl::ResettableMutexGuard& _rGuard); @@ -392,6 +363,10 @@ namespace dbaccess virtual void SAL_CALL addRowSetApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener >& listener ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL removeRowSetApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener >& listener ) throw(::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdb::XRowsChangeBroadcaster + virtual void SAL_CALL addRowsChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowsChangeListener >& listener ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeRowsChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowsChangeListener >& listener ) throw(::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdb::XResultSetAccess virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL createResultSet( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); diff --git a/dbaccess/source/core/api/RowSetBase.cxx b/dbaccess/source/core/api/RowSetBase.cxx index 935598a80..e19dd8371 100644 --- a/dbaccess/source/core/api/RowSetBase.cxx +++ b/dbaccess/source/core/api/RowSetBase.cxx @@ -1294,7 +1294,12 @@ void ORowSetBase::firePropertyChange(const ORowSetRow& _rOldRow) } DBG_TRACE2("DBACCESS ORowSetBase::firePropertyChange() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL)); } - +// ------------------------------------------------------------------------- +void ORowSetBase::firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rOldValue) +{ + OSL_ENSURE(_nPos < (sal_Int32)m_aDataColumns.size(),"nPos is invalid!"); + m_aDataColumns[_nPos]->fireValueChange(_rOldValue); +} // ----------------------------------------------------------------------------- void ORowSetBase::fireRowcount() { @@ -1472,6 +1477,13 @@ sal_Int32 ORowSetBase::impl_getRowCount() const return nRowCount; } // ============================================================================= +struct ORowSetNotifierImpl +{ + ::std::vector<sal_Int32> aChangedColumns; + ::std::vector<Any> aChangedBookmarks; + ORowSetValueVector::Vector aRow; + +}; DBG_NAME(ORowSetNotifier) // ----------------------------------------------------------------------------- ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet ) @@ -1494,7 +1506,21 @@ ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet ) if ( m_pRowSet->isModification( ORowSetBase::GrantNotifierAccess() ) ) m_pRowSet->doCancelModification( ORowSetBase::GrantNotifierAccess() ); } +// ----------------------------------------------------------------------------- +ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet,const ORowSetValueVector::Vector& i_aRow ) + :m_pImpl(new ORowSetNotifierImpl) + ,m_pRowSet( _pRowSet ) + ,m_bWasNew( sal_False ) + ,m_bWasModified( sal_False ) +#ifdef DBG_UTIL + ,m_bNotifyCalled( sal_False ) +#endif +{ + DBG_CTOR(ORowSetNotifier,NULL); + OSL_ENSURE( m_pRowSet, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." ); + m_pImpl->aRow = i_aRow; // yes, create a copy to store the old values +} // ----------------------------------------------------------------------------- ORowSetNotifier::~ORowSetNotifier( ) { @@ -1522,5 +1548,30 @@ void ORowSetNotifier::fire() m_bNotifyCalled = sal_True; #endif } - +// ----------------------------------------------------------------------------- +::std::vector<sal_Int32>& ORowSetNotifier::getChangedColumns() const +{ + OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!"); + return m_pImpl->aChangedColumns; +} +// ----------------------------------------------------------------------------- +::std::vector<Any>& ORowSetNotifier::getChangedBookmarks() const +{ + OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!"); + return m_pImpl->aChangedBookmarks; +} +// ----------------------------------------------------------------------------- +void ORowSetNotifier::firePropertyChange() +{ + OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!"); + if( m_pImpl.get() ) + { + ::std::vector<sal_Int32>::iterator aIter = m_pImpl->aChangedColumns.begin(); + for(;aIter != m_pImpl->aChangedColumns.end();++aIter) + { + m_pRowSet->firePropertyChange((*aIter)-1 ,m_pImpl->aRow[(*aIter)-1], ORowSetBase::GrantNotifierAccess()); + } + m_pRowSet->fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False, ORowSetBase::GrantNotifierAccess()); + } +} } // namespace dbaccess diff --git a/dbaccess/source/core/api/RowSetBase.hxx b/dbaccess/source/core/api/RowSetBase.hxx index c756c0ca2..4140c2175 100644 --- a/dbaccess/source/core/api/RowSetBase.hxx +++ b/dbaccess/source/core/api/RowSetBase.hxx @@ -168,6 +168,9 @@ namespace dbaccess // fire a notification for all that are listening on column::VALUE property void firePropertyChange(const ORowSetRow& _rOldRow); + // fire a change for one column + // _nPos starts at zero + void firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rNewValue); // fire if rowcount changed virtual void fireRowcount(); @@ -385,6 +388,10 @@ namespace dbaccess { fireProperty( _nProperty, _bNew, _bOld ); } + inline void firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rNewValue, const GrantNotifierAccess& ) + { + firePropertyChange(_nPos,_rNewValue); + } using ::comphelper::OPropertyStateContainer::getFastPropertyValue; ::osl::Mutex* getMutex() const { return m_pMutex; } @@ -395,14 +402,17 @@ namespace dbaccess <p>The class can only be used on the stack, within a method of ORowSetBase (or derivees)</p> */ + struct ORowSetNotifierImpl; class ORowSetNotifier { private: + ::std::auto_ptr<ORowSetNotifierImpl> m_pImpl; ORowSetBase* m_pRowSet; // not aquired! This is not necessary because this class here is to be used on the stack within // a method of ORowSetBase (or derivees) sal_Bool m_bWasNew; sal_Bool m_bWasModified; + #ifdef DBG_UTIL sal_Bool m_bNotifyCalled; #endif @@ -414,6 +424,10 @@ namespace dbaccess */ ORowSetNotifier( ORowSetBase* m_pRowSet ); + /** use this one to consturct an vector for change value notification + */ + ORowSetNotifier( ORowSetBase* m_pRowSet,const ORowSetValueVector::Vector& i_aRow ); + // destructs the object. <member>fire</member> has to be called before. ~ORowSetNotifier( ); @@ -428,6 +442,19 @@ namespace dbaccess @see ORowSetBase::notifyCancelInsert */ void fire(); + + /** notifies value change events and notifies IsModified + @param i_aChangedColumns the index of the changed value columns + @param i_aRow the old values + @see ORowSetBase::notifyCancelInsert + */ + void firePropertyChange(); + + /** use this one to store the inde of the changed column values + */ + ::std::vector<sal_Int32>& getChangedColumns() const; + ::std::vector<com::sun::star::uno::Any>& getChangedBookmarks() const; + }; } // end of namespace diff --git a/dbaccess/source/core/api/RowSetCache.cxx b/dbaccess/source/core/api/RowSetCache.cxx index 4f65ff113..295e29ebe 100644 --- a/dbaccess/source/core/api/RowSetCache.cxx +++ b/dbaccess/source/core/api/RowSetCache.cxx @@ -67,18 +67,11 @@ #ifndef DBACCESS_CORE_API_ROWSETBASE_HXX #include "RowSetBase.hxx" #endif -#ifndef _DBHELPER_DBEXCEPTION_HXX_ #include <connectivity/dbexception.hxx> -#endif -#ifndef _CONNECTIVITY_SQLPARSE_HXX #include <connectivity/sqlparse.hxx> -#endif -#ifndef _CONNECTIVITY_SQLNODE_HXX #include <connectivity/sqlnode.hxx> -#endif -#ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_ +#include <connectivity/dbtools.hxx> #include <connectivity/sqliterator.hxx> -#endif #ifndef _COMPHELPER_PROPERTY_HXX_ #include <comphelper/property.hxx> #endif @@ -111,6 +104,8 @@ #ifndef DBACCESS_SHARED_DBASTRINGS_HRC #include "dbastrings.hrc" #endif +#include "WrappedResultSet.hxx" +#include "OptimisticSet.hxx" using namespace dbaccess; using namespace dbtools; @@ -159,10 +154,35 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, { DBG_CTOR(ORowSetCache,NULL); + // first try if the result can be used to do inserts and updates + try + { + Reference< XResultSetUpdate> xUp(_xRs,UNO_QUERY_THROW); + xUp->moveToInsertRow(); + xUp->cancelRowUpdates(); + _xRs->beforeFirst(); + m_nPrivileges = Privilege::SELECT|Privilege::DELETE|Privilege::INSERT|Privilege::UPDATE; + m_pCacheSet = new WrappedResultSet(); + m_xCacheSet = m_pCacheSet; + m_pCacheSet->construct(_xRs,i_sRowSetFilter); + return; + } + catch(const Exception&) + { + } + _xRs->beforeFirst(); + // check if all keys of the updateable table are fetched sal_Bool bAllKeysFound = sal_False; sal_Int32 nTablesCount = 0; + Reference< XPropertySet> xProp(_xRs,UNO_QUERY); + Reference< XPropertySetInfo > xPropInfo = xProp->getPropertySetInfo(); + sal_Bool bNeedKeySet = !(xPropInfo->hasPropertyByName(PROPERTY_ISBOOKMARKABLE) && + any2bool(xProp->getPropertyValue(PROPERTY_ISBOOKMARKABLE)) && Reference< XRowLocate >(_xRs, UNO_QUERY).is() ); + bNeedKeySet = bNeedKeySet || (xPropInfo->hasPropertyByName(PROPERTY_RESULTSETCONCURRENCY) && + ::comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETCONCURRENCY)) == ResultSetConcurrency::READ_ONLY); + Reference< XIndexAccess> xUpdateTableKeys; ::rtl::OUString aUpdateTableName = _rUpdateTableName; Reference< XConnection> xConnection; @@ -183,58 +203,54 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, Reference<XTablesSupplier> xTabSup(_xAnalyzer,UNO_QUERY); OSL_ENSURE(xTabSup.is(),"ORowSet::execute composer isn't a tablesupplier!"); Reference<XNameAccess> xTables = xTabSup->getTables(); - - - if(_rUpdateTableName.getLength() && xTables->hasByName(_rUpdateTableName)) - xTables->getByName(_rUpdateTableName) >>= m_aUpdateTable; - else if(xTables->getElementNames().getLength()) - { - aUpdateTableName = xTables->getElementNames()[0]; - xTables->getByName(aUpdateTableName) >>= m_aUpdateTable; + Sequence< ::rtl::OUString> aTableNames = xTables->getElementNames(); + if ( aTableNames.getLength() > 1 && !_rUpdateTableName.getLength() && bNeedKeySet ) + {// here we have a join or union and nobody told us which table to update, so we update them all + m_nPrivileges = Privilege::SELECT|Privilege::DELETE|Privilege::INSERT|Privilege::UPDATE; + OptimisticSet* pCursor = new OptimisticSet(m_aContext,xConnection,_xAnalyzer,_aParameterValueForCache); + m_pCacheSet = pCursor; + m_xCacheSet = m_pCacheSet; + try + { + m_pCacheSet->construct(_xRs,i_sRowSetFilter); + if ( pCursor->isReadOnly() ) + m_nPrivileges = Privilege::SELECT; + m_aKeyColumns = pCursor->getJoinedKeyColumns(); + return; + } + catch(const Exception&) + { + } } - Reference<XIndexAccess> xIndexAccess(xTables,UNO_QUERY); - if(xIndexAccess.is()) - nTablesCount = xIndexAccess->getCount(); else - nTablesCount = xTables->getElementNames().getLength(); - - if(m_aUpdateTable.is() && nTablesCount < 3) // for we can't handle more than 2 tables in our keyset { - Reference<XKeysSupplier> xKeys(m_aUpdateTable,UNO_QUERY); - if(xKeys.is()) + if(_rUpdateTableName.getLength() && xTables->hasByName(_rUpdateTableName)) + xTables->getByName(_rUpdateTableName) >>= m_aUpdateTable; + else if(xTables->getElementNames().getLength()) { - xUpdateTableKeys = xKeys->getKeys(); - if ( xUpdateTableKeys.is() ) - { - Reference<XColumnsSupplier> xColumnsSupplier; - // search the one and only primary key - const sal_Int32 nCount = xUpdateTableKeys->getCount(); - for(sal_Int32 i = 0 ; i < nCount ; ++i) - { - Reference<XPropertySet> xProp(xUpdateTableKeys->getByIndex(i),UNO_QUERY); - sal_Int32 nKeyType = 0; - xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; - if(KeyType::PRIMARY == nKeyType) - { - xColumnsSupplier.set(xProp,UNO_QUERY); - break; - } - } + aUpdateTableName = xTables->getElementNames()[0]; + xTables->getByName(aUpdateTableName) >>= m_aUpdateTable; + } + Reference<XIndexAccess> xIndexAccess(xTables,UNO_QUERY); + if(xIndexAccess.is()) + nTablesCount = xIndexAccess->getCount(); + else + nTablesCount = xTables->getElementNames().getLength(); - if(xColumnsSupplier.is()) + if(m_aUpdateTable.is() && nTablesCount < 3) // for we can't handle more than 2 tables in our keyset + { + Reference<XPropertySet> xSet(m_aUpdateTable,UNO_QUERY); + const Reference<XNameAccess> xPrimaryKeyColumns = dbtools::getPrimaryKeyColumns_throw(xSet); + if ( xPrimaryKeyColumns.is() ) + { + Reference<XColumnsSupplier> xColSup(_xAnalyzer,UNO_QUERY); + if ( xColSup.is() ) { - - - Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns(); - Reference<XColumnsSupplier> xColSup(_xAnalyzer,UNO_QUERY); - if ( xColSup.is() ) - { - Reference<XNameAccess> xSelColumns = xColSup->getColumns(); - Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData(); - SelectColumnsMetaData aColumnNames(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() ? true : false); - ::dbaccess::getColumnPositions(xSelColumns,xColumns->getElementNames(),aUpdateTableName,aColumnNames); - bAllKeysFound = !aColumnNames.empty() && sal_Int32(aColumnNames.size()) == xColumns->getElementNames().getLength(); - } + Reference<XNameAccess> xSelColumns = xColSup->getColumns(); + Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData(); + SelectColumnsMetaData aColumnNames(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() ? true : false); + ::dbaccess::getColumnPositions(xSelColumns,xPrimaryKeyColumns->getElementNames(),aUpdateTableName,aColumnNames); + bAllKeysFound = !aColumnNames.empty() && sal_Int32(aColumnNames.size()) == xPrimaryKeyColumns->getElementNames().getLength(); } } } @@ -244,12 +260,6 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, { } } - Reference< XPropertySet> xProp(_xRs,UNO_QUERY); - - sal_Bool bNeedKeySet = !(xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISBOOKMARKABLE) && - any2bool(xProp->getPropertyValue(PROPERTY_ISBOOKMARKABLE)) && Reference< XRowLocate >(_xRs, UNO_QUERY).is() ); - bNeedKeySet = bNeedKeySet || (xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_RESULTSETCONCURRENCY) && - ::comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETCONCURRENCY)) == ResultSetConcurrency::READ_ONLY); // first check if resultset is bookmarkable if(!bNeedKeySet) @@ -313,8 +323,7 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, const ::rtl::OUString* pEnd = pIter + aNames.getLength(); for(;pIter != pEnd;++pIter) { - Reference<XPropertySet> xColumn; - ::cppu::extractInterface(xColumn,xColumns->getByName(*pIter)); + Reference<XPropertySet> xColumn(xColumns->getByName(*pIter),UNO_QUERY); OSL_ENSURE(xColumn.is(),"Column in table is null!"); if(xColumn.is()) { @@ -470,6 +479,21 @@ Reference< XResultSetMetaData > ORowSetCache::getMetaData( ) return m_xMetaData; } // ------------------------------------------------------------------------- +Any lcl_getBookmark(ORowSetValue& i_aValue,OCacheSet* i_pCacheSet) +{ + switch ( i_aValue.getTypeKind() ) + { + case DataType::TINYINT: + case DataType::SMALLINT: + case DataType::INTEGER: + return makeAny((sal_Int32)i_aValue); + default: + if ( i_pCacheSet && i_aValue.isNull()) + i_aValue = i_pCacheSet->getBookmark(); + return i_aValue.getAny(); + } +} +// ------------------------------------------------------------------------- // ::com::sun::star::sdbcx::XRowLocate Any ORowSetCache::getBookmark( ) { @@ -482,17 +506,7 @@ Any ORowSetCache::getBookmark( ) return Any(); // this is allowed here because the rowset knowns what it is doing } - switch(((*m_aMatrixIter)->get())[0].getTypeKind()) - { - case DataType::TINYINT: - case DataType::SMALLINT: - case DataType::INTEGER: - return makeAny((sal_Int32)((*m_aMatrixIter)->get())[0]); - default: - if(((*m_aMatrixIter)->get())[0].isNull()) - ((*m_aMatrixIter)->get())[0] = m_pCacheSet->getBookmark(); - return ((*m_aMatrixIter)->get())[0].getAny(); - } + return lcl_getBookmark(((*m_aMatrixIter)->get())[0],m_pCacheSet); } // ------------------------------------------------------------------------- sal_Bool ORowSetCache::moveToBookmark( const Any& bookmark ) @@ -547,84 +561,106 @@ sal_Int32 ORowSetCache::compareBookmarks( const Any& _first, const Any& _second // ------------------------------------------------------------------------- sal_Bool ORowSetCache::hasOrderedBookmarks( ) { - return m_pCacheSet->hasOrderedBookmarks(); } // ------------------------------------------------------------------------- sal_Int32 ORowSetCache::hashBookmark( const Any& bookmark ) { - return m_pCacheSet->hashBookmark(bookmark); } -// ------------------------------------------------------------------------- // XRowUpdate // ----------------------------------------------------------------------------- -void ORowSetCache::updateNull(sal_Int32 columnIndex) +void ORowSetCache::updateNull(sal_Int32 columnIndex,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ) { checkUpdateConditions(columnIndex); - ((*m_aInsertRow)->get())[columnIndex].setBound(sal_True); - ((*m_aInsertRow)->get())[columnIndex].setNull(); - ((*m_aInsertRow)->get())[columnIndex].setModified(); -} -// ----------------------------------------------------------------------------- -void ORowSetCache::updateValue(sal_Int32 columnIndex,const ORowSetValue& x) -{ - checkUpdateConditions(columnIndex); + ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get()); + rInsert[columnIndex].setBound(sal_True); + rInsert[columnIndex].setNull(); + rInsert[columnIndex].setModified(); + io_aRow[columnIndex].setNull(); - ((*m_aInsertRow)->get())[columnIndex].setBound(sal_True); - ((*m_aInsertRow)->get())[columnIndex] = x; - ((*m_aInsertRow)->get())[columnIndex].setModified(); + m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns); + impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns); } -// ------------------------------------------------------------------------- -void ORowSetCache::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) +// ----------------------------------------------------------------------------- +void ORowSetCache::updateValue(sal_Int32 columnIndex,const ORowSetValue& x + ,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ) { checkUpdateConditions(columnIndex); + ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get()); + rInsert[columnIndex].setBound(sal_True); + rInsert[columnIndex] = x; + rInsert[columnIndex].setModified(); + io_aRow[columnIndex] = rInsert[columnIndex]; - Sequence<sal_Int8> aSeq; - if(x.is()) - x->readBytes(aSeq,length); - updateValue(columnIndex,aSeq); + m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns); + impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns); } // ------------------------------------------------------------------------- -void ORowSetCache::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) +void ORowSetCache::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x + , sal_Int32 length,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ) { checkUpdateConditions(columnIndex); - Sequence<sal_Int8> aSeq; if(x.is()) x->readBytes(aSeq,length); - updateValue(columnIndex,aSeq); + ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get()); + rInsert[columnIndex].setBound(sal_True); + rInsert[columnIndex] = aSeq; + rInsert[columnIndex].setModified(); + io_aRow[columnIndex] = makeAny(x); + + m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns); + impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns); } // ------------------------------------------------------------------------- -void ORowSetCache::updateObject( sal_Int32 columnIndex, const Any& x ) +void ORowSetCache::updateObject( sal_Int32 columnIndex, const Any& x + ,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ) { checkUpdateConditions(columnIndex); + ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get()); + rInsert[columnIndex].setBound(sal_True); + rInsert[columnIndex] = x; + rInsert[columnIndex].setModified(); + io_aRow[columnIndex] = rInsert[columnIndex]; - ((*m_aInsertRow)->get())[columnIndex].setBound(sal_True); - ((*m_aInsertRow)->get())[columnIndex] = x; - ((*m_aInsertRow)->get())[columnIndex].setModified(); + m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns); + impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns); } // ------------------------------------------------------------------------- -void ORowSetCache::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) +void ORowSetCache::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ + ,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ) { checkUpdateConditions(columnIndex); + ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get()); + rInsert[columnIndex].setBound(sal_True); + rInsert[columnIndex] = x; + rInsert[columnIndex].setModified(); + io_aRow[columnIndex] = rInsert[columnIndex]; - ((*m_aInsertRow)->get())[columnIndex].setBound(sal_True); - ((*m_aInsertRow)->get())[columnIndex] = x; - ((*m_aInsertRow)->get())[columnIndex].setModified(); + m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns); + impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns); } // ------------------------------------------------------------------------- // XResultSet sal_Bool ORowSetCache::next( ) { - - if(!isAfterLast()) { m_bBeforeFirst = sal_False; @@ -1223,7 +1259,7 @@ sal_Bool ORowSetCache::rowInserted( ) } // ------------------------------------------------------------------------- // XResultSetUpdate -sal_Bool ORowSetCache::insertRow( ) +sal_Bool ORowSetCache::insertRow(::std::vector< Any >& o_aBookmarks) { if ( !m_bNew || !m_aInsertRow->isValid() ) throw SQLException(DBACORE_RESSTRING(RID_STR_NO_MOVETOINSERTROW_CALLED),NULL,SQLSTATE_GENERAL,1000,Any() ); @@ -1237,7 +1273,19 @@ sal_Bool ORowSetCache::insertRow( ) Any aBookmark = ((*m_aInsertRow)->get())[0].makeAny(); m_bAfterLast = m_bBeforeFirst = sal_False; if(aBookmark.hasValue()) + { moveToBookmark(aBookmark); + // update the cached values + ORowSetValueVector::Vector& rCurrentRow = ((*m_aMatrixIter))->get(); + ORowSetMatrix::iterator aIter = m_pMatrix->begin(); + for(;aIter != m_pMatrix->end();++aIter) + { + if ( m_aMatrixIter != aIter && aIter->isValid() && m_pCacheSet->columnValuesUpdated((*aIter)->get(),rCurrentRow) ) + { + o_aBookmarks.push_back(lcl_getBookmark((*aIter)->get()[0],m_pCacheSet)); + } + } + } else { OSL_ENSURE(0,"There must be a bookmark after the row was inserted!"); @@ -1267,7 +1315,7 @@ void ORowSetCache::cancelRowModification() resetInsertRow(sal_False); } // ------------------------------------------------------------------------- -void ORowSetCache::updateRow( ORowSetMatrix::iterator& _rUpdateRow ) +void ORowSetCache::updateRow( ORowSetMatrix::iterator& _rUpdateRow,::std::vector< Any >& o_aBookmarks ) { if(isAfterLast() || isBeforeFirst()) throw SQLException(DBACORE_RESSTRING(RID_STR_NO_UPDATEROW),NULL,SQLSTATE_GENERAL,1000,Any() ); @@ -1278,17 +1326,24 @@ void ORowSetCache::updateRow( ORowSetMatrix::iterator& _rUpdateRow ) // the row was already fetched moveToBookmark(aBookmark); m_pCacheSet->updateRow(*_rUpdateRow,*m_aMatrixIter,m_aUpdateTable); - // *(*m_aMatrixIter) = *(*_rUpdateRow); // refetch the whole row (*m_aMatrixIter) = NULL; - moveToBookmark(aBookmark); + if ( moveToBookmark(aBookmark) ) + { + // update the cached values + ORowSetValueVector::Vector& rCurrentRow = ((*m_aMatrixIter))->get(); + ORowSetMatrix::iterator aIter = m_pMatrix->begin(); + for(;aIter != m_pMatrix->end();++aIter) + { + if ( m_aMatrixIter != aIter && aIter->isValid() && m_pCacheSet->columnValuesUpdated((*aIter)->get(),rCurrentRow) ) + { + o_aBookmarks.push_back(lcl_getBookmark((*aIter)->get()[0],m_pCacheSet)); + } + } + } - // moveToBookmark((*(*m_aInsertRow))[0].makeAny()); -// if(m_pCacheSet->rowUpdated()) -// *m_aMatrixIter = m_aInsertRow; m_bModified = sal_False; - // refreshRow( ); } // ------------------------------------------------------------------------- bool ORowSetCache::deleteRow( ) @@ -1305,8 +1360,6 @@ bool ORowSetCache::deleteRow( ) OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!"); ORowSetMatrix::iterator aPos = calcPosition(); (*aPos) = NULL; - // (*m_pMatrix)[(m_nPosition - m_nStartPos)] = NULL; // set the deleted row to NULL - ORowSetMatrix::iterator aEnd = m_pMatrix->end(); for(++aPos;aPos != aEnd && aPos->isValid();++aPos) @@ -1623,8 +1676,39 @@ sal_Bool ORowSetCache::fill(ORowSetMatrix::iterator& _aIter,const ORowSetMatrix: return _bCheck; } // ----------------------------------------------------------------------------- +bool ORowSetCache::isResultSetChanged() const +{ + return m_pCacheSet->isResultSetChanged(); +} +// ----------------------------------------------------------------------------- +void ORowSetCache::reset(const Reference< XResultSet>& _xDriverSet) +{ + m_xMetaData.set(Reference< XResultSetMetaDataSupplier >(_xDriverSet,UNO_QUERY)->getMetaData()); + m_pCacheSet->reset(_xDriverSet); - - - - + m_bRowCountFinal = sal_False; + m_nRowCount = 0; + reFillMatrix(m_nStartPos+1,m_nEndPos+1); +} +// ----------------------------------------------------------------------------- +void ORowSetCache::impl_updateRowFromCache_throw(ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns) +{ + if ( o_ChangedColumns.size() > 1 ) + { + ORowSetMatrix::iterator aIter = m_pMatrix->begin(); + for(;aIter != m_pMatrix->end();++aIter) + { + if ( aIter->isValid() && m_pCacheSet->updateColumnValues((*aIter)->get(),io_aRow,o_ChangedColumns)) + { + break; + } + } + + if ( aIter == m_pMatrix->end() ) + { + m_pCacheSet->fillMissingValues(io_aRow); + } + } +} +// ----------------------------------------------------------------------------- diff --git a/dbaccess/source/core/api/RowSetCache.hxx b/dbaccess/source/core/api/RowSetCache.hxx index 6392fb466..d7823a90a 100644 --- a/dbaccess/source/core/api/RowSetCache.hxx +++ b/dbaccess/source/core/api/RowSetCache.hxx @@ -119,6 +119,7 @@ namespace dbaccess typedef ::std::vector< TORowSetOldRowHelperRef > TOldRowSetRows; + ::std::map<sal_Int32,sal_Int32> m_aKeyColumns; //the set can be static, bookmarkable or keyset ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XResultSet> m_xSet; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > m_xMetaData; // must be before m_aInsertRow @@ -166,7 +167,15 @@ namespace dbaccess void firePropertyChange(sal_Int32 _nColumnIndex,const ::connectivity::ORowSetValue& _rOldValue); void rotateCacheIterator(ORowSetMatrix::difference_type _nDist); - void updateValue(sal_Int32 columnIndex,const connectivity::ORowSetValue& x); + void updateValue(sal_Int32 columnIndex + ,const connectivity::ORowSetValue& x + ,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ); + + void impl_updateRowFromCache_throw(ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ); // checks and set the flags isAfterLast isLast and position when afterlast is true void checkPositionFlags(); void checkUpdateConditions(sal_Int32 columnIndex); @@ -219,11 +228,14 @@ namespace dbaccess sal_Int32 hashBookmark( const ::com::sun::star::uno::Any& bookmark ); // ::com::sun::star::sdbc::XRowUpdate - void updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ); - void updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ); - void updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ); - void updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ); - void updateNull(sal_Int32 columnIndex); + void updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length,ORowSetValueVector::Vector& io_aRow,::std::vector<sal_Int32>& o_ChangedColumns + ); + void updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x,ORowSetValueVector::Vector& io_aRow ,::std::vector<sal_Int32>& o_ChangedColumns); + void updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale,ORowSetValueVector::Vector& io_aRow ,::std::vector<sal_Int32>& o_ChangedColumns); + void updateNull(sal_Int32 columnIndex + ,ORowSetValueVector::Vector& io_aRow + ,::std::vector<sal_Int32>& o_ChangedColumns + ); // ::com::sun::star::sdbc::XResultSet sal_Bool next( ); @@ -244,14 +256,17 @@ namespace dbaccess sal_Bool rowInserted( ); // ::com::sun::star::sdbc::XResultSetUpdate - sal_Bool insertRow(); + sal_Bool insertRow(::std::vector< ::com::sun::star::uno::Any >& o_aBookmarks); void resetInsertRow(sal_Bool _bClearInsertRow); - void updateRow(); - void updateRow( ORowSetMatrix::iterator& _rUpdateRow ); + void updateRow( ORowSetMatrix::iterator& _rUpdateRow,::std::vector< ::com::sun::star::uno::Any >& o_aBookmarks ); bool deleteRow(); void cancelRowUpdates( ); void moveToInsertRow( ); + + const ::std::map<sal_Int32,sal_Int32>& getKeyColumns() const { return m_aKeyColumns; } + bool isResultSetChanged() const; + void reset(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet); }; } #endif diff --git a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx index 6144fdc79..fc8013413 100644 --- a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx +++ b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx @@ -43,6 +43,8 @@ #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/sdb/BooleanComparisonMode.hpp> #include <com/sun/star/sdb/SQLFilterOperator.hpp> +#include <com/sun/star/sdb/XQueriesSupplier.hpp> +#include <com/sun/star/sdb/CommandType.hpp> #include <com/sun/star/sdbc/ColumnSearch.hpp> #include <com/sun/star/sdbc/DataType.hpp> #include <com/sun/star/sdbc/XResultSetMetaData.hpp> @@ -188,6 +190,53 @@ namespace if ( _bDispose ) _rIterator.dispose(); } + void lcl_addFilterCriteria_throw(sal_Int32 i_nFilterOperator,const ::rtl::OUString& i_sValue,::rtl::OUStringBuffer& o_sRet) + { + switch( i_nFilterOperator ) + { + case SQLFilterOperator::EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::NOT_EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::LESS: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::GREATER: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::LESS_EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::GREATER_EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::LIKE: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::NOT_LIKE: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::SQLNULL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ); + break; + case SQLFilterOperator::NOT_SQLNULL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ); + break; + default: + throw SQLException(); + } + } + } DBG_NAME(OSingleSelectQueryComposer) @@ -207,6 +256,7 @@ OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAcc ,m_aContext( _rContext ) ,m_pTables(NULL) ,m_nBoolCompareMode( BooleanComparisonMode::EQUAL_INTEGER ) + ,m_nCommandType(CommandType::COMMAND) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::OSingleSelectQueryComposer" ); DBG_CTOR(OSingleSelectQueryComposer,NULL); @@ -233,6 +283,9 @@ OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAcc { OSL_VERIFY( aValue >>= m_nBoolCompareMode ); } + Reference< XQueriesSupplier > xQueriesAccess(m_xConnection, UNO_QUERY); + if (xQueriesAccess.is()) + m_xConnectionQueries = xQueriesAccess->getQueries(); } catch(Exception&) { @@ -304,6 +357,7 @@ void SAL_CALL OSingleSelectQueryComposer::setQuery( const ::rtl::OUString& comma ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); ::osl::MutexGuard aGuard( m_aMutex ); + m_nCommandType = CommandType::COMMAND; // first clear the tables and columns clearCurrentCollections(); // now set the new one @@ -317,6 +371,84 @@ void SAL_CALL OSingleSelectQueryComposer::setQuery( const ::rtl::OUString& comma for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) m_aElementaryParts[ eLoopParts ] = ::rtl::OUString(); } +// ------------------------------------------------------------------------- +void SAL_CALL OSingleSelectQueryComposer::setCommand( const ::rtl::OUString& Command,sal_Int32 _nCommandType ) throw(SQLException, RuntimeException) +{ + ::rtl::OUStringBuffer sSQL; + switch(_nCommandType) + { + case CommandType::COMMAND: + setElementaryQuery(Command); + return; + case CommandType::TABLE: + if ( m_xConnectionTables->hasByName(Command) ) + { + sSQL.appendAscii("SELECT * FROM "); + Reference< XPropertySet > xTable; + try + { + m_xConnectionTables->getByName( Command ) >>= xTable; + } + catch(const WrappedTargetException& e) + { + SQLException e2; + if ( e.TargetException >>= e2 ) + throw e2; + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + + sSQL.append(dbtools::composeTableNameForSelect(m_xConnection,xTable)); + } + else + { + String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) ); + sMessage.SearchAndReplaceAscii( "$table$", Command ); + throwGenericSQLException(sMessage,*this); + } + break; + case CommandType::QUERY: + if ( m_xConnectionQueries->hasByName(Command) ) + { + + Reference<XPropertySet> xQuery(m_xConnectionQueries->getByName(Command),UNO_QUERY); + ::rtl::OUString sCommand; + xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand; + sSQL.append(sCommand); + } + else + { + String sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) ); + sMessage.SearchAndReplaceAscii( "$table$", Command ); + throwGenericSQLException(sMessage,*this); + } + + break; + default: + break; + } + ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); + + ::osl::MutexGuard aGuard( m_aMutex ); + m_nCommandType = _nCommandType; + m_sCommand = Command; + // first clear the tables and columns + clearCurrentCollections(); + // now set the new one + ::rtl::OUString sCommand = sSQL.makeStringAndClear(); + setElementaryQuery(sCommand); + m_sOrignal = sCommand; +/* + // reset the additive iterator to the same statement + parseAndCheck_throwError( m_aSqlParser, m_sOrignal, m_aAdditiveIterator, *this ); + + // we have no "elementary" parts anymore (means filter/groupby/having/order clauses) + for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) + m_aElementaryParts[ eLoopParts ] = ::rtl::OUString(); +*/ +} // ----------------------------------------------------------------------------- void OSingleSelectQueryComposer::setQuery_Impl( const ::rtl::OUString& command ) { @@ -348,18 +480,18 @@ Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getSt return getStructuredCondition(F_tmp); } // ----------------------------------------------------------------------------- -void SAL_CALL OSingleSelectQueryComposer::appendHavingClauseByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ) throw (SQLException, RuntimeException) +void SAL_CALL OSingleSelectQueryComposer::appendHavingClauseByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendHavingClauseByColumn" ); ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> F_tmp(&OSingleSelectQueryComposer::implSetHavingClause); - setConditionByColumn(column,andCriteria,F_tmp); + setConditionByColumn(column,andCriteria,F_tmp,filterOperator); } // ----------------------------------------------------------------------------- -void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ) throw(SQLException, RuntimeException) +void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw(SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendFilterByColumn" ); ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> F_tmp(&OSingleSelectQueryComposer::implSetFilter); - setConditionByColumn(column,andCriteria,F_tmp); + setConditionByColumn(column,andCriteria,F_tmp,filterOperator); } // ----------------------------------------------------------------------------- ::rtl::OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column) @@ -657,6 +789,13 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr ::std::vector< ::rtl::OUString> aNames; ::vos::ORef< OSQLColumns> aSelectColumns; sal_Bool bCase = sal_True; + Reference< XNameAccess> xQueryColumns; + if ( m_nCommandType == CommandType::QUERY ) + { + Reference<XColumnsSupplier> xSup(m_xConnectionQueries->getByName(m_sCommand),UNO_QUERY); + if(xSup.is()) + xQueryColumns = xSup->getColumns(); + } do { @@ -738,7 +877,7 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr { // This is a valid case. If we can syntactically parse the query, but not semantically // (e.g. because it is based on a table we do not know), then there will be no SelectColumns - aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ); + aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ,xQueryColumns); break; } @@ -746,13 +885,21 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr const ::comphelper::TStringMixEqualFunctor aCaseCompareFunctor( bCase ); typedef ::std::set< size_t > SizeTSet; SizeTSet aUsedSelectColumns; + ::connectivity::parse::OParseColumn::StringMap aColumnNames; sal_Int32 nCount = xResultSetMeta->getColumnCount(); OSL_ENSURE( (size_t) nCount == aSelectColumns->get().size(), "OSingleSelectQueryComposer::getColumns: inconsistent column counts, this might result in wrong columns!" ); for(sal_Int32 i=1;i<=nCount;++i) { ::rtl::OUString sColumnName = xResultSetMeta->getColumnName(i); - ::rtl::OUString sColumnLabel = xResultSetMeta->getColumnLabel(i); + ::rtl::OUString sColumnLabel; + if ( xQueryColumns.is() && xQueryColumns->hasByName(sColumnName) ) + { + Reference<XPropertySet> xQueryColumn(xQueryColumns->getByName(sColumnName),UNO_QUERY_THROW); + xQueryColumn->getPropertyValue(PROPERTY_LABEL) >>= sColumnLabel; + } + else + sColumnLabel = xResultSetMeta->getColumnLabel(i); sal_Bool bFound = sal_False; OSQLColumns::Vector::const_iterator aFind = ::connectivity::find(aSelectColumns->get().begin(),aSelectColumns->get().end(),sColumnLabel,aCaseCompare); size_t nFoundSelectColumnPos = aFind - aSelectColumns->get().begin(); @@ -788,7 +935,7 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr if ( i > static_cast< sal_Int32>( aSelectColumns->get().size() ) ) { aSelectColumns->get().push_back( - ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ) + ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ,aColumnNames) ); OSL_ENSURE( aSelectColumns->get().size() == (size_t)i, "OSingleSelectQueryComposer::getColumns: inconsistency!" ); } @@ -932,16 +1079,16 @@ sal_Bool OSingleSelectQueryComposer::setANDCriteria( OSQLParseNode * pCondition, aItem.Name = getColumnName(pCondition->getChild(0),_rIterator); aItem.Value <<= aValue; aItem.Handle = 0; // just to know that this is not one the known ones - if (SQL_ISRULE(pCondition,like_predicate)) + if ( SQL_ISRULE(pCondition,like_predicate) ) { - if (pCondition->count() == 5) + if ( SQL_ISTOKEN(pCondition->getChild(1)->getChild(0),NOT) ) aItem.Handle = SQLFilterOperator::NOT_LIKE; else aItem.Handle = SQLFilterOperator::LIKE; } else if (SQL_ISRULE(pCondition,test_for_null)) { - if (SQL_ISTOKEN(pCondition->getChild(2),NOT) ) + if (SQL_ISTOKEN(pCondition->getChild(1)->getChild(2),NOT) ) aItem.Handle = SQLFilterOperator::NOT_SQLNULL; else aItem.Handle = SQLFilterOperator::SQLNULL; @@ -1103,7 +1250,7 @@ sal_Bool OSingleSelectQueryComposer::setComparsionPredicate(OSQLParseNode * pCon aValue = aValue.copy(aColumnName.getLength()); aValue.trim(); - aItem.Name = UniString(getColumnName(pCondition->getChild(0),_rIterator)); + aItem.Name = getColumnName(pCondition->getChild(0),_rIterator); aItem.Value <<= aValue; aItem.Handle = pCondition->getNodeType(); rFilter.push_back(aItem); @@ -1384,49 +1531,7 @@ namespace sRet.append(pAndIter->Name); ::rtl::OUString sValue; pAndIter->Value >>= sValue; - switch( pAndIter->Handle ) - { - case SQLFilterOperator::EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))); - sRet.append(sValue); - break; - case SQLFilterOperator::NOT_EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> "))); - sRet.append(sValue); - break; - case SQLFilterOperator::LESS: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < "))); - sRet.append(sValue); - break; - case SQLFilterOperator::GREATER: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > "))); - sRet.append(sValue); - break; - case SQLFilterOperator::LESS_EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= "))); - sRet.append(sValue); - break; - case SQLFilterOperator::GREATER_EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= "))); - sRet.append(sValue); - break; - case SQLFilterOperator::LIKE: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))); - sRet.append(sValue); - break; - case SQLFilterOperator::NOT_LIKE: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE "))); - sRet.append(sValue); - break; - case SQLFilterOperator::SQLNULL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ); - break; - case SQLFilterOperator::NOT_SQLNULL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ); - break; - default: - throw IllegalArgumentException(); - } + lcl_addFilterCriteria_throw(pAndIter->Handle,sValue,sRet); ++pAndIter; if ( pAndIter != pAndEnd ) sRet.append(STR_AND); @@ -1453,7 +1558,7 @@ void SAL_CALL OSingleSelectQueryComposer::setStructuredHavingClause( const Seque setHavingClause(lcl_getCondition(filter)); } // ----------------------------------------------------------------------------- -void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor) +void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor,sal_Int32 filterOperator) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setConditionByColumn" ); ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); @@ -1518,18 +1623,24 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert aSQL.append( ::dbtools::quoteName( aQuote, aName ) ); } + if ( aValue.hasValue() ) { if( !m_xTypeConverter.is() ) m_aContext.createComponent( "com.sun.star.script.Converter", m_xTypeConverter ); OSL_ENSURE(m_xTypeConverter.is(),"NO typeconverter!"); + if ( nType != DataType::BOOLEAN && DataType::BIT != nType ) + { + ::rtl::OUString sEmpty; + lcl_addFilterCriteria_throw(filterOperator,sEmpty,aSQL); + } + switch(nType) { case DataType::VARCHAR: case DataType::CHAR: case DataType::LONGVARCHAR: - aSQL.append( STR_LIKE ); aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); break; case DataType::CLOB: @@ -1540,7 +1651,6 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert const ::sal_Int64 nLength = xClob->length(); if ( sal_Int64(nLength + aSQL.getLength() + STR_LIKE.getLength() ) < sal_Int64(SAL_MAX_INT32) ) { - aSQL.append( STR_LIKE ); aSQL.appendAscii("'"); aSQL.append( xClob->getSubString(1,(sal_Int32)nLength) ); aSQL.appendAscii("'"); @@ -1548,7 +1658,6 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert } else { - aSQL.append( STR_LIKE ); aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); } } @@ -1562,11 +1671,8 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert { if(nSearchable == ColumnSearch::CHAR) { - aSQL.append( STR_LIKE ); aSQL.appendAscii( "\'" ); } - else - aSQL.append( STR_EQUAL ); aSQL.appendAscii( "0x" ); const sal_Int8* pBegin = aSeq.getConstArray(); const sal_Int8* pEnd = pBegin + aSeq.getLength(); @@ -1592,13 +1698,18 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert } break; default: - aSQL.append( STR_EQUAL ); aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); break; } } else - aSQL.appendAscii( " IS NULL" ) ; + { + sal_Int32 nFilterOp = filterOperator; + if ( filterOperator != SQLFilterOperator::SQLNULL && filterOperator != SQLFilterOperator::NOT_SQLNULL ) + nFilterOp = SQLFilterOperator::SQLNULL; + ::rtl::OUString sEmpty; + lcl_addFilterCriteria_throw(nFilterOp,sEmpty,aSQL); + } // filter anhaengen // select ohne where und order by aufbauen diff --git a/dbaccess/source/core/api/WrappedResultSet.cxx b/dbaccess/source/core/api/WrappedResultSet.cxx new file mode 100644 index 000000000..6e8175b2e --- /dev/null +++ b/dbaccess/source/core/api/WrappedResultSet.cxx @@ -0,0 +1,256 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BookmarkSet.cxx,v $ + * $Revision: 1.21 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" +#include "WrappedResultSet.hxx" +#include "core_resource.hxx" +#include "core_resource.hrc" +#include <com/sun/star/sdbc/XResultSetUpdate.hpp> +#include <connectivity/dbexception.hxx> +#include <rtl/logfile.hxx> + +#include <limits> + +using namespace dbaccess; +using namespace ::connectivity; +using namespace ::dbtools; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbc; +// using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +// using namespace ::cppu; +using namespace ::osl; + +void WrappedResultSet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::construct" ); + OCacheSet::construct(_xDriverSet,i_sRowSetFilter); + m_xUpd.set(_xDriverSet,UNO_QUERY_THROW); + m_xRowLocate.set(_xDriverSet,UNO_QUERY_THROW); + m_xUpdRow.set(_xDriverSet,UNO_QUERY_THROW); +} +// ----------------------------------------------------------------------------- +Any SAL_CALL WrappedResultSet::getBookmark() throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::getBookmark" ); + return makeAny(m_xDriverSet->getRow()); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL WrappedResultSet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::moveToBookmark" ); + sal_Int32 nPos = 1; + bookmark >>= nPos; + return m_xDriverSet->absolute(nPos); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL WrappedResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::moveRelativeToBookmark" ); + sal_Int32 nPos = 1; + bookmark >>= nPos; + return m_xDriverSet->absolute(nPos + rows); +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL WrappedResultSet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::compareBookmarks" ); + return _first != _second; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL WrappedResultSet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::hasOrderedBookmarks" ); + return sal_True; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL WrappedResultSet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::hashBookmark" ); + sal_Int32 nPos = 1; + bookmark >>= nPos; + return nPos; +} +// ------------------------------------------------------------------------- +// ::com::sun::star::sdbcx::XDeleteRows +Sequence< sal_Int32 > SAL_CALL WrappedResultSet::deleteRows( const Sequence< Any >& rows ,const connectivity::OSQLTable& /*_xTable*/) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::deleteRows" ); + Reference< ::com::sun::star::sdbcx::XDeleteRows> xDeleteRow(m_xRowLocate,UNO_QUERY); + if(xDeleteRow.is()) + { + return xDeleteRow->deleteRows(rows); + } + return Sequence< sal_Int32 >(); +} +// ------------------------------------------------------------------------- +void SAL_CALL WrappedResultSet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::insertRow" ); + + m_xUpd->moveToInsertRow(); + sal_Int32 i = 1; + connectivity::ORowVector< ORowSetValue > ::Vector::iterator aEnd = _rInsertRow->get().end(); + for(connectivity::ORowVector< ORowSetValue > ::Vector::iterator aIter = _rInsertRow->get().begin()+1;aIter != aEnd;++aIter,++i) + { + aIter->setSigned(m_aSignedFlags[i-1]); + updateColumn(i,m_xUpdRow,*aIter); + } + m_xUpd->insertRow(); + (*_rInsertRow->get().begin()) = m_xDriverSet->getRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL WrappedResultSet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::updateRow" ); + sal_Int32 i = 1; + connectivity::ORowVector< ORowSetValue > ::Vector::const_iterator aOrgIter = _rOrginalRow->get().begin()+1; + connectivity::ORowVector< ORowSetValue > ::Vector::iterator aEnd = _rInsertRow->get().end(); + for(connectivity::ORowVector< ORowSetValue > ::Vector::iterator aIter = _rInsertRow->get().begin()+1;aIter != aEnd;++aIter,++i,++aOrgIter) + { + aIter->setSigned(aOrgIter->isSigned()); + updateColumn(i,m_xUpdRow,*aIter); + } + m_xUpd->updateRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL WrappedResultSet::deleteRow(const ORowSetRow& /*_rDeleteRow*/ ,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::deleteRow" ); + m_xUpd->deleteRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL WrappedResultSet::cancelRowUpdates( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::cancelRowUpdates" ); + m_xUpd->cancelRowUpdates(); +} +// ------------------------------------------------------------------------- +void SAL_CALL WrappedResultSet::moveToInsertRow( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::moveToInsertRow" ); + m_xUpd->moveToInsertRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL WrappedResultSet::moveToCurrentRow( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::moveToCurrentRow" ); +} +// ------------------------------------------------------------------------- +void WrappedResultSet::fillValueRow(ORowSetRow& _rRow,sal_Int32 _nPosition) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::fillValueRow" ); + OCacheSet::fillValueRow(_rRow,_nPosition); +} +// ------------------------------------------------------------------------- +void WrappedResultSet::updateColumn(sal_Int32 nPos,Reference< XRowUpdate > _xParameter,const ORowSetValue& _rValue) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::updateColumn" ); + if(_rValue.isBound() && _rValue.isModified()) + { + if(_rValue.isNull()) + _xParameter->updateNull(nPos); + else + { + + switch(_rValue.getTypeKind()) + { + case DataType::DECIMAL: + case DataType::NUMERIC: + _xParameter->updateNumericObject(nPos,_rValue.makeAny(),m_xSetMetaData->getScale(nPos)); + break; + case DataType::CHAR: + case DataType::VARCHAR: + //case DataType::DECIMAL: + //case DataType::NUMERIC: + _xParameter->updateString(nPos,_rValue); + break; + case DataType::BIGINT: + if ( _rValue.isSigned() ) + _xParameter->updateLong(nPos,_rValue); + else + _xParameter->updateString(nPos,_rValue); + break; + case DataType::BIT: + case DataType::BOOLEAN: + _xParameter->updateBoolean(nPos,_rValue); + break; + case DataType::TINYINT: + if ( _rValue.isSigned() ) + _xParameter->updateByte(nPos,_rValue); + else + _xParameter->updateShort(nPos,_rValue); + break; + case DataType::SMALLINT: + if ( _rValue.isSigned() ) + _xParameter->updateShort(nPos,_rValue); + else + _xParameter->updateInt(nPos,_rValue); + break; + case DataType::INTEGER: + if ( _rValue.isSigned() ) + _xParameter->updateInt(nPos,_rValue); + else + _xParameter->updateLong(nPos,_rValue); + break; + case DataType::FLOAT: + _xParameter->updateFloat(nPos,_rValue); + break; + case DataType::DOUBLE: + case DataType::REAL: + _xParameter->updateDouble(nPos,_rValue); + break; + case DataType::DATE: + _xParameter->updateDate(nPos,_rValue); + break; + case DataType::TIME: + _xParameter->updateTime(nPos,_rValue); + break; + case DataType::TIMESTAMP: + _xParameter->updateTimestamp(nPos,_rValue); + break; + case DataType::BINARY: + case DataType::VARBINARY: + case DataType::LONGVARBINARY: + _xParameter->updateBytes(nPos,_rValue); + break; + case DataType::BLOB: + case DataType::CLOB: + _xParameter->updateObject(nPos,_rValue.getAny()); + break; + } + } + } +} + diff --git a/dbaccess/source/core/api/WrappedResultSet.hxx b/dbaccess/source/core/api/WrappedResultSet.hxx new file mode 100644 index 000000000..e78e45a14 --- /dev/null +++ b/dbaccess/source/core/api/WrappedResultSet.hxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: BookmarkSet.hxx,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DBACCESS_CORE_API_WRAPPEDRESULTSET_HXX +#define DBACCESS_CORE_API_WRAPPEDRESULTSET_HXX + +#ifndef DBACCESS_CORE_API_CACHESET_HXX +#include "CacheSet.hxx" +#endif +#include <com/sun/star/sdbc/XRowUpdate.hpp> +#include <com/sun/star/sdbc/XResultSetUpdate.hpp> + +namespace dbaccess +{ + // this set is used when we have a bookmarkable set from the driver + class WrappedResultSet : public OCacheSet + { + ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XRowLocate> m_xRowLocate; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetUpdate> m_xUpd; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowUpdate> m_xUpdRow; + + void updateColumn(sal_Int32 nPos,::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowUpdate > _xParameter,const connectivity::ORowSetValue& _rValue); + public: + WrappedResultSet() + {} + ~WrappedResultSet() + { + m_xRowLocate = NULL; + } + + virtual void construct(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter); + virtual void fillValueRow(ORowSetRow& _rRow,sal_Int32 _nPosition); + // ::com::sun::star::sdbcx::XRowLocate + virtual ::com::sun::star::uno::Any SAL_CALL getBookmark() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL moveToBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL moveRelativeToBookmark( const ::com::sun::star::uno::Any& bookmark, sal_Int32 rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL compareBookmarks( const ::com::sun::star::uno::Any& first, const ::com::sun::star::uno::Any& second ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasOrderedBookmarks( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL hashBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdbcx::XDeleteRows + virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL deleteRows( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rows ,const connectivity::OSQLTable& _xTable) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + // ::com::sun::star::sdbc::XResultSetUpdate + virtual void SAL_CALL insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateRow(const ORowSetRow& _rInsertRow,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deleteRow(const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancelRowUpdates( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToInsertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL moveToCurrentRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + }; +} +#endif // DBACCESS_CORE_API_WRAPPEDRESULTSET_HXX + diff --git a/dbaccess/source/core/api/definitioncolumn.cxx b/dbaccess/source/core/api/definitioncolumn.cxx index c3976e077..7f1e7a244 100644 --- a/dbaccess/source/core/api/definitioncolumn.cxx +++ b/dbaccess/source/core/api/definitioncolumn.cxx @@ -189,14 +189,16 @@ rtl::OUString OTableColumn::getImplementationName( ) throw (RuntimeException) DBG_NAME( OQueryColumn ); // ------------------------------------------------------------------------- -OQueryColumn::OQueryColumn( const Reference< XPropertySet >& _rxParserColumn, const Reference< XConnection >& _rxConnection,const ::rtl::OUString& _sNewName ) +OQueryColumn::OQueryColumn( const Reference< XPropertySet >& _rxParserColumn, const Reference< XConnection >& _rxConnection,const ::rtl::OUString i_sLabel ) :OTableColumnDescriptor( false /* do not act as descriptor */ ) + ,m_sLabel(i_sLabel) { const sal_Int32 nPropAttr = PropertyAttribute::READONLY; registerProperty( PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME, nPropAttr, &m_sCatalogName, ::getCppuType( &m_sCatalogName ) ); registerProperty( PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME, nPropAttr, &m_sSchemaName, ::getCppuType( &m_sSchemaName ) ); registerProperty( PROPERTY_TABLENAME, PROPERTY_ID_TABLENAME, nPropAttr, &m_sTableName, ::getCppuType( &m_sTableName ) ); registerProperty( PROPERTY_REALNAME, PROPERTY_ID_REALNAME, nPropAttr, &m_sRealName, ::getCppuType( &m_sRealName ) ); + registerProperty( PROPERTY_LABEL, PROPERTY_ID_LABEL, nPropAttr, &m_sLabel, ::getCppuType( &m_sLabel ) ); DBG_CTOR( OQueryColumn, NULL ); @@ -207,14 +209,8 @@ OQueryColumn::OQueryColumn( const Reference< XPropertySet >& _rxParserColumn, co OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_TYPE ) >>= m_nType ); OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= m_bAutoIncrement ); OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISCURRENCY ) >>= m_bCurrency ); - if ( _sNewName.getLength() ) - { - m_sName = _sNewName; - } - else - { - OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_NAME ) >>= m_sName ); - } + OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_NAME ) >>= m_sName ); + m_bRowVersion = sal_False; Reference< XPropertySetInfo > xPSI( _rxParserColumn->getPropertySetInfo(), UNO_SET_THROW ); diff --git a/dbaccess/source/core/api/makefile.mk b/dbaccess/source/core/api/makefile.mk index afd42c991..7af260080 100644 --- a/dbaccess/source/core/api/makefile.mk +++ b/dbaccess/source/core/api/makefile.mk @@ -71,6 +71,8 @@ SLOFILES= \ $(SLO)$/HelperCollections.obj \ $(SLO)$/datasettings.obj \ $(SLO)$/View.obj \ + $(SLO)$/WrappedResultSet.obj \ + $(SLO)$/OptimisticSet.obj \ $(SLO)$/columnsettings.obj # --- Targets ---------------------------------- diff --git a/dbaccess/source/core/api/query.cxx b/dbaccess/source/core/api/query.cxx index a18f65bd0..41c8c29fe 100644 --- a/dbaccess/source/core/api/query.cxx +++ b/dbaccess/source/core/api/query.cxx @@ -226,7 +226,7 @@ void OQuery::rebuildColumns() Reference< XDatabaseMetaData > xDBMeta( m_xConnection->getMetaData(), UNO_QUERY_THROW ); ::vos::ORef< OSQLColumns > aParseColumns( - ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, xDBMeta ) ); + ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, xDBMeta,xColumnDefinitions ) ); xColumns = OPrivateColumns::createWithIntrinsicNames( aParseColumns, xDBMeta->storesMixedCaseQuotedIdentifiers(), *this, m_aMutex ); if ( !xColumns.is() ) @@ -234,29 +234,25 @@ void OQuery::rebuildColumns() } Sequence< ::rtl::OUString> aNames = xColumns->getElementNames(); - Sequence< ::rtl::OUString> aDefintionNames; - bool bApplyDefinitionNames = false; - //if ( xColumnDefinitions.is() ) - //{ - // aDefintionNames = xColumnDefinitions->getElementNames(); - // bApplyDefinitionNames = aDefintionNames.getLength() == aNames.getLength(); - //} - - ::rtl::OUString sEmpty; const ::rtl::OUString* pIter = aNames.getConstArray(); - const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); for ( sal_Int32 i = 0;pIter != pEnd; ++pIter,++i) { Reference<XPropertySet> xSource(xColumns->getByName( *pIter ),UNO_QUERY); - OQueryColumn* pColumn = new OQueryColumn( xSource, m_xConnection, bApplyDefinitionNames ? aDefintionNames[i] : sEmpty); + ::rtl::OUString sLabel = *pIter; + if ( xColumnDefinitions.is() && xColumnDefinitions->hasByName(*pIter) ) + { + Reference<XPropertySet> xCommandColumn(xColumnDefinitions->getByName( *pIter ),UNO_QUERY); + xCommandColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + } + OQueryColumn* pColumn = new OQueryColumn( xSource, m_xConnection, sLabel); Reference< XChild > xChild( *pColumn, UNO_QUERY_THROW ); xChild->setParent( *this ); - ::rtl::OUString sNewName = bApplyDefinitionNames ? aDefintionNames[i] : *pIter; - implAppendColumn( sNewName, pColumn ); + implAppendColumn( *pIter, pColumn ); Reference< XPropertySet > xDest( *pColumn, UNO_QUERY_THROW ); if ( m_pColumnMediator.is() ) - m_pColumnMediator->notifyElementCreated( sNewName, xDest ); + m_pColumnMediator->notifyElementCreated( *pIter, xDest ); } } catch( const SQLContext& e ) diff --git a/dbaccess/source/core/api/querycomposer.cxx b/dbaccess/source/core/api/querycomposer.cxx index 36b90fe77..fab4af44c 100644 --- a/dbaccess/source/core/api/querycomposer.cxx +++ b/dbaccess/source/core/api/querycomposer.cxx @@ -88,6 +88,7 @@ #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ #include <com/sun/star/container/XChild.hpp> #endif +#include <com/sun/star/sdb/SQLFilterOperator.hpp> #ifndef DBACCESS_CORE_API_QUERYCOMPOSER_HXX #include "querycomposer.hxx" #endif @@ -282,7 +283,23 @@ void SAL_CALL OQueryComposer::appendFilterByColumn( const Reference< XPropertySe m_xComposerHelper->setQuery(getQuery()); m_xComposerHelper->setFilter(::rtl::OUString()); - m_xComposerHelper->appendFilterByColumn(column,sal_True); + sal_Int32 nOp = SQLFilterOperator::EQUAL; + if ( column.is() ) + { + sal_Int32 nType = 0; + column->getPropertyValue(PROPERTY_TYPE) >>= nType; + switch(nType) + { + case DataType::VARCHAR: + case DataType::CHAR: + case DataType::LONGVARCHAR: + nOp = SQLFilterOperator::LIKE; + break; + default: + nOp = SQLFilterOperator::EQUAL; + } + } + m_xComposerHelper->appendFilterByColumn(column,sal_True,nOp); FilterCreator aFilterCreator; aFilterCreator.append(getFilter()); diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx index 10028cdb8..941653923 100644 --- a/dbaccess/source/core/dataaccess/ModelImpl.cxx +++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx @@ -1140,6 +1140,7 @@ const AsciiPropertyValue* ODatabaseModelImpl::getDefaultDataSourceSettings() AsciiPropertyValue( "ImplicitCatalogRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ), AsciiPropertyValue( "ImplicitSchemaRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ), AsciiPropertyValue( "PrimaryKeySupport", ::cppu::UnoType< sal_Bool >::get() ), + AsciiPropertyValue( "ShowColumnDescription", makeAny( (sal_Bool)sal_False ) ), // known SDB level settings AsciiPropertyValue( "NoNameLengthLimit", makeAny( (sal_Bool)sal_False ) ), AsciiPropertyValue( "AppendTableAliasName", makeAny( (sal_Bool)sal_False ) ), diff --git a/dbaccess/source/core/dataaccess/databasecontext.cxx b/dbaccess/source/core/dataaccess/databasecontext.cxx index 39a6ef73b..e584553e6 100644 --- a/dbaccess/source/core/dataaccess/databasecontext.cxx +++ b/dbaccess/source/core/dataaccess/databasecontext.cxx @@ -74,6 +74,7 @@ #include <tools/urlobj.hxx> #include <ucbhelper/content.hxx> #include <unotools/confignode.hxx> +#include <unotools/pathoptions.hxx> #include <unotools/sharedunocomponent.hxx> #include <list> #include <boost/bind.hpp> diff --git a/dbaccess/source/core/dataaccess/documentdefinition.cxx b/dbaccess/source/core/dataaccess/documentdefinition.cxx index c40282a15..98c88aaf2 100644 --- a/dbaccess/source/core/dataaccess/documentdefinition.cxx +++ b/dbaccess/source/core/dataaccess/documentdefinition.cxx @@ -1453,8 +1453,6 @@ sal_Bool ODocumentDefinition::save(sal_Bool _bApprove) aRequest.Name = DBACORE_RESSTRING( RID_STR_REPORT ); aRequest.Name = ::dbtools::createUniqueName(xName,aRequest.Name); } - else if ( xName->hasByName(aRequest.Name) ) - aRequest.Name = ::dbtools::createUniqueName(xName,aRequest.Name); aRequest.Content.set(m_xParentContainer,UNO_QUERY); OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest)); diff --git a/dbaccess/source/core/inc/SingleSelectQueryComposer.hxx b/dbaccess/source/core/inc/SingleSelectQueryComposer.hxx index c6a4e9618..5ba9a6329 100644 --- a/dbaccess/source/core/inc/SingleSelectQueryComposer.hxx +++ b/dbaccess/source/core/inc/SingleSelectQueryComposer.hxx @@ -127,6 +127,7 @@ namespace dbaccess ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection> m_xConnection; ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> m_xMetaData; ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess> m_xConnectionTables; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess> m_xConnectionQueries; ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > m_xNumberFormatsSupplier; ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess> m_xColumns; ::comphelper::ComponentContext m_aContext; @@ -137,8 +138,10 @@ namespace dbaccess ::rtl::OUString m_aPureSelectSQL; // the pure select statement, without filter/order/groupby/having ::rtl::OUString m_sDecimalSep; + ::rtl::OUString m_sCommand; ::com::sun::star::lang::Locale m_aLocale; sal_Int32 m_nBoolCompareMode; // how to compare bool values + sal_Int32 m_nCommandType; // <properties> ::rtl::OUString m_sOrignal; @@ -169,8 +172,8 @@ namespace dbaccess void setConditionByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column , sal_Bool andCriteria - ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor); - + ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor + ,sal_Int32 filterOperator); /** getStructuredCondition returns the structured condition for the where or having clause @param _aGetFunctor @@ -246,18 +249,19 @@ namespace dbaccess virtual void SAL_CALL setElementaryQuery( const ::rtl::OUString& _rElementary ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setFilter( const ::rtl::OUString& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setStructuredFilter( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL appendFilterByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool andCriteria ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL appendFilterByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL appendGroupByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setGroup( const ::rtl::OUString& group ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setHavingClause( const ::rtl::OUString& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setStructuredHavingClause( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL appendHavingClauseByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool andCriteria ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL appendHavingClauseByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL appendOrderByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool ascending ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setOrder( const ::rtl::OUString& order ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); // XSingleSelectQueryAnalyzer virtual ::rtl::OUString SAL_CALL getQuery( ) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setQuery( const ::rtl::OUString& command ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCommand( const ::rtl::OUString& command,sal_Int32 CommandType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getFilter( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > > SAL_CALL getStructuredFilter( ) throw (::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getGroup( ) throw (::com::sun::star::uno::RuntimeException); diff --git a/dbaccess/source/core/inc/definitioncolumn.hxx b/dbaccess/source/core/inc/definitioncolumn.hxx index b9ea45cd3..462e273d0 100644 --- a/dbaccess/source/core/inc/definitioncolumn.hxx +++ b/dbaccess/source/core/inc/definitioncolumn.hxx @@ -154,6 +154,7 @@ namespace dbaccess ::rtl::OUString m_sSchemaName; ::rtl::OUString m_sTableName; ::rtl::OUString m_sRealName; + ::rtl::OUString m_sLabel; // </properties> ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xOriginalTableColumn; @@ -165,7 +166,7 @@ namespace dbaccess OQueryColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxParserColumn, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection, - const ::rtl::OUString& _sNewName + const ::rtl::OUString i_sLabel ); // XTypeProvider diff --git a/dbaccess/source/core/misc/dsntypes.cxx b/dbaccess/source/core/misc/dsntypes.cxx index bfb284829..f473586b4 100644 --- a/dbaccess/source/core/misc/dsntypes.cxx +++ b/dbaccess/source/core/misc/dsntypes.cxx @@ -284,6 +284,12 @@ sal_Bool ODsnTypeCollection::supportsTableCreation(const ::rtl::OUString& _sURL) return aFeatures.getOrDefault("SupportsTableCreation",sal_False); } // ----------------------------------------------------------------------------- +sal_Bool ODsnTypeCollection::supportsColumnDescription(const ::rtl::OUString& _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("SupportsColumnDescription",sal_False); +} +// ----------------------------------------------------------------------------- sal_Bool ODsnTypeCollection::supportsBrowsing(const ::rtl::OUString& _sURL) const { const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); diff --git a/dbaccess/source/inc/dsntypes.hxx b/dbaccess/source/inc/dsntypes.hxx index fdebe6bf3..f08c59c66 100644 --- a/dbaccess/source/inc/dsntypes.hxx +++ b/dbaccess/source/inc/dsntypes.hxx @@ -157,6 +157,9 @@ public: /// check if the given data source allows creation of tables sal_Bool supportsTableCreation(const ::rtl::OUString& _sURL) const; + + /// check if the given data source allows to show column description. + sal_Bool supportsColumnDescription(const ::rtl::OUString& _sURL) const; // check if a Browse button may be shown to insert connection url sal_Bool supportsBrowsing(const ::rtl::OUString& _sURL) const; diff --git a/dbaccess/source/inc/stringconstants.hrc b/dbaccess/source/inc/stringconstants.hrc index 939272dea..5d7b985ea 100644 --- a/dbaccess/source/inc/stringconstants.hrc +++ b/dbaccess/source/inc/stringconstants.hrc @@ -182,6 +182,7 @@ #define PROPERTY_ID_HELP_URL 142 #define PROPERTY_ID_PERSISTENT_PATH 143 #define PROPERTY_ID_CURRENT_QUERY_DESIGN 144 +#define PROPERTY_ID_SINGLESELECTQUERYCOMPOSER 145 //============================================================ //= property names @@ -338,6 +339,7 @@ DECLARE_CONSTASCII_USTRING(PROPERTY_AS_TEMPLATE); DECLARE_CONSTASCII_USTRING(PROPERTY_HAVING_CLAUSE); DECLARE_CONSTASCII_USTRING(PROPERTY_GROUP_BY); DECLARE_CONSTASCII_USTRING(PROPERTY_EDIT_WIDTH); +DECLARE_CONSTASCII_USTRING(PROPERTY_SINGLESELECTQUERYCOMPOSER); //============================================================ //= service names diff --git a/dbaccess/source/inc/stringconstants.inc b/dbaccess/source/inc/stringconstants.inc index 4639167bd..f2a39b06f 100644 --- a/dbaccess/source/inc/stringconstants.inc +++ b/dbaccess/source/inc/stringconstants.inc @@ -182,6 +182,7 @@ IMPLEMENT_CONSTASCII_USTRING(PROPERTY_AS_TEMPLATE, "AsTemplate"); IMPLEMENT_CONSTASCII_USTRING(PROPERTY_HAVING_CLAUSE, "HavingClause"); IMPLEMENT_CONSTASCII_USTRING(PROPERTY_GROUP_BY, "GroupBy"); IMPLEMENT_CONSTASCII_USTRING(PROPERTY_EDIT_WIDTH, "EditWidth"); +IMPLEMENT_CONSTASCII_USTRING(PROPERTY_SINGLESELECTQUERYCOMPOSER,"SingleSelectQueryComposer"); //============================================================ //= service names diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx index 4b1285f26..94bbb23d7 100644 --- a/dbaccess/source/ui/app/AppController.cxx +++ b/dbaccess/source/ui/app/AppController.cxx @@ -83,7 +83,6 @@ #include <svl/urihelper.hxx> #include <svl/filenotation.hxx> - #include <svtools/svtreebx.hxx> #include <svtools/transfer.hxx> #include <svtools/cliplistener.hxx> @@ -125,7 +124,6 @@ #include <svx/svxdlg.hxx> #include <vos/mutex.hxx> - #include "AppView.hxx" #include "browserids.hxx" #include "dbu_reghelper.hxx" diff --git a/dbaccess/source/ui/browser/brwctrlr.cxx b/dbaccess/source/ui/browser/brwctrlr.cxx index 1d08aa456..41bb28651 100644 --- a/dbaccess/source/ui/browser/brwctrlr.cxx +++ b/dbaccess/source/ui/browser/brwctrlr.cxx @@ -64,6 +64,7 @@ #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp> #include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp> #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/sdb/SQLFilterOperator.hpp> #include <com/sun/star/sdbc/XConnection.hpp> #include <com/sun/star/sdbc/XResultSetUpdate.hpp> #include <com/sun/star/sdbc/XRowSetListener.hpp> @@ -731,6 +732,11 @@ sal_Bool SbaXDataBrowserController::reloadForm( const Reference< XLoadable >& _r else _rxLoadable->load(); + m_xParser.clear(); + const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING))) + xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser; + Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY ); if ( xWarnings.is() ) { @@ -1202,31 +1208,31 @@ void SbaXDataBrowserController::propertyChange(const PropertyChangeEvent& evt) t // the filter or the sort criterias have changed ? -> update our parser if (evt.PropertyName.equals(PROPERTY_ACTIVECOMMAND)) { - if (m_xParser.is()) - DO_SAFE( m_xParser->setElementaryQuery(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new query to my parser !" ); + // if (m_xParser.is()) + //DO_SAFE( m_xParser->setElementaryQuery(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new query to my parser !" ); } else if (evt.PropertyName.equals(PROPERTY_FILTER)) { - if ( m_xParser.is() && m_xParser->getFilter() != ::comphelper::getString(evt.NewValue)) - { - DO_SAFE( m_xParser->setFilter(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" ); - } + // if ( m_xParser.is() && m_xParser->getFilter() != ::comphelper::getString(evt.NewValue)) + //{ + // DO_SAFE( m_xParser->setFilter(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" ); + //} InvalidateFeature(ID_BROWSER_REMOVEFILTER); } else if (evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE)) { - if ( m_xParser.is() && m_xParser->getHavingClause() != ::comphelper::getString(evt.NewValue)) - { - DO_SAFE( m_xParser->setHavingClause(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" ); - } + //if ( m_xParser.is() && m_xParser->getHavingClause() != ::comphelper::getString(evt.NewValue)) + //{ + // DO_SAFE( m_xParser->setHavingClause(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" ); + //} InvalidateFeature(ID_BROWSER_REMOVEFILTER); } else if (evt.PropertyName.equals(PROPERTY_ORDER)) { - if ( m_xParser.is() && m_xParser->getOrder() != ::comphelper::getString(evt.NewValue)) - { - DO_SAFE( m_xParser->setOrder(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new order to my parser !" ); - } + //if ( m_xParser.is() && m_xParser->getOrder() != ::comphelper::getString(evt.NewValue)) + //{ + // DO_SAFE( m_xParser->setOrder(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new order to my parser !" ); + //} InvalidateFeature(ID_BROWSER_REMOVEFILTER); } @@ -1362,14 +1368,8 @@ void SbaXDataBrowserController::disposing() { DBG_UNHANDLED_EXCEPTION(); } - try - { - ::comphelper::disposeComponent(m_xParser); - } - catch(const Exception&) - { - DBG_UNHANDLED_EXCEPTION(); - } + m_xParser.clear(); + // don't dispose, just reset - it's owned by the RowSet } //------------------------------------------------------------------------------ void SbaXDataBrowserController::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException ) @@ -1781,7 +1781,7 @@ FeatureState SbaXDataBrowserController::GetState(sal_uInt16 nId) const } //------------------------------------------------------------------------------ -void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrder) +void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrder,const Reference< XSingleSelectQueryComposer >& _xParser) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserOrder" ); Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); @@ -1795,7 +1795,7 @@ void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrd sal_Bool bSuccess = sal_False; try { - xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(m_xParser->getOrder())); + xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_xParser->getOrder())); bSuccess = reloadForm(m_xLoadable); } catch(Exception&) @@ -1805,7 +1805,7 @@ void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrd if (!bSuccess) { xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_rOldOrder)); - DO_SAFE( m_xParser->setOrder(_rOldOrder), "SbaXDataBrowserController::applyParserOrder: could not restore the old order of my parser !" ); + //DO_SAFE( _xParser->setOrder(_rOldOrder), "SbaXDataBrowserController::applyParserOrder: could not restore the old order of my parser !" ); try { @@ -1824,7 +1824,7 @@ void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrd } //------------------------------------------------------------------------------ -void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving) +void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving,const Reference< XSingleSelectQueryComposer >& _xParser) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserFilter" ); Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); @@ -1840,8 +1840,8 @@ void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFi try { FormErrorHelper aError(this); - xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(m_xParser->getFilter())); - xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(m_xParser->getHavingClause())); + xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_xParser->getFilter())); + xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_xParser->getHavingClause())); xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(sal_True))); bSuccess = reloadForm(m_xLoadable); @@ -1871,7 +1871,26 @@ void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFi setCurrentColumnPosition(nPos); } - +//------------------------------------------------------------------------------ +Reference< XSingleSelectQueryComposer > SbaXDataBrowserController::createParser_nothrow() +{ + Reference< XSingleSelectQueryComposer > xRet; + try + { + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY_THROW); + const Reference<XMultiServiceFactory> xFactory(::dbtools::getConnection(getRowSet()),UNO_QUERY_THROW); + xRet.set(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY_THROW); + xRet->setElementaryQuery(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ACTIVECOMMAND))); + xRet->setFilter(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_FILTER))); + xRet->setHavingClause(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE))); + xRet->setOrder(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ORDER))); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xRet; +} //------------------------------------------------------------------------------ void SbaXDataBrowserController::ExecuteFilterSortCrit(sal_Bool bFilter) { @@ -1883,29 +1902,30 @@ void SbaXDataBrowserController::ExecuteFilterSortCrit(sal_Bool bFilter) const ::rtl::OUString sOldVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder(); const ::rtl::OUString sOldHaving = m_xParser->getHavingClause(); + Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow(); try { Reference< ::com::sun::star::sdbcx::XColumnsSupplier> xSup = getColumnsSupplier(); Reference< XConnection> xCon(xFormSet->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY); if(bFilter) { - DlgFilterCrit aDlg( getBrowserView(), getORB(), xCon, m_xParser, xSup->getColumns() ); + DlgFilterCrit aDlg( getBrowserView(), getORB(), xCon, xParser, xSup->getColumns() ); String aFilter; if(!aDlg.Execute()) { - m_xParser->setFilter(sOldVal); - m_xParser->setHavingClause(sOldHaving); + //m_xParser->setFilter(sOldVal); + //m_xParser->setHavingClause(sOldHaving); return; // if so we don't need to actualize the grid } aDlg.BuildWherePart(); } else { - DlgOrderCrit aDlg( getBrowserView(),xCon,m_xParser,xSup->getColumns() ); + DlgOrderCrit aDlg( getBrowserView(),xCon,xParser,xSup->getColumns() ); String aOrder; if(!aDlg.Execute()) { - m_xParser->setOrder(sOldVal); + //m_xParser->setOrder(sOldVal); return; // if so we don't need to actualize the grid } aDlg.BuildOrderPart(); @@ -1922,23 +1942,24 @@ void SbaXDataBrowserController::ExecuteFilterSortCrit(sal_Bool bFilter) return; } - ::rtl::OUString sNewVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder(); + ::rtl::OUString sNewVal = bFilter ? xParser->getFilter() : xParser->getOrder(); sal_Bool bOldFilterApplied(sal_False); if (bFilter) { try { bOldFilterApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); } catch(Exception&) { } ; } - ::rtl::OUString sNewHaving = m_xParser->getHavingClause(); + ::rtl::OUString sNewHaving = xParser->getHavingClause(); if ( sOldVal.equals(sNewVal) && (!bFilter || sOldHaving.equals(sNewHaving)) ) // nothing to be done return; if (bFilter) - applyParserFilter(sOldVal, bOldFilterApplied,sOldHaving); + applyParserFilter(sOldVal, bOldFilterApplied,sOldHaving,xParser); else - applyParserOrder(sOldVal); + applyParserOrder(sOldVal,xParser); + ::comphelper::disposeComponent(xParser); } //------------------------------------------------------------------------------ @@ -2131,17 +2152,18 @@ void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< Property if (!xField.is()) break; - const ::rtl::OUString sOldSort = m_xParser->getOrder(); + Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow(); + const ::rtl::OUString sOldSort = xParser->getOrder(); sal_Bool bParserSuccess = sal_False; HANDLE_SQL_ERRORS( - m_xParser->setOrder(::rtl::OUString()); m_xParser->appendOrderByColumn(xField, bSortUp), + xParser->setOrder(::rtl::OUString()); xParser->appendOrderByColumn(xField, bSortUp), bParserSuccess, UniString(ModuleRes(SBA_BROWSER_SETTING_ORDER)), "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !" ) if (bParserSuccess) - applyParserOrder(sOldSort); + applyParserOrder(sOldSort,xParser); } break; @@ -2171,8 +2193,9 @@ void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< Property xProp->getPropertyValue(sAgg) >>= bHaving; } - const ::rtl::OUString sOldFilter = m_xParser->getFilter(); - const ::rtl::OUString sOldHaving = m_xParser->getHavingClause(); + Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow(); + const ::rtl::OUString sOldFilter = xParser->getFilter(); + const ::rtl::OUString sOldHaving = xParser->getHavingClause(); Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); sal_Bool bApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); @@ -2180,16 +2203,32 @@ void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< Property // -> completely overwrite it, else append one if (!bApplied) { - DO_SAFE( (bHaving ? m_xParser->setHavingClause(::rtl::OUString()) : m_xParser->setFilter(::rtl::OUString())), "SbaXDataBrowserController::Execute : caught an exception while resetting the new filter !" ); + DO_SAFE( (bHaving ? xParser->setHavingClause(::rtl::OUString()) : xParser->setFilter(::rtl::OUString())), "SbaXDataBrowserController::Execute : caught an exception while resetting the new filter !" ); } sal_Bool bParserSuccess = sal_False; + sal_Int32 nOp = SQLFilterOperator::EQUAL; + if ( xField.is() ) + { + sal_Int32 nType = 0; + xField->getPropertyValue(PROPERTY_TYPE) >>= nType; + switch(nType) + { + case DataType::VARCHAR: + case DataType::CHAR: + case DataType::LONGVARCHAR: + nOp = SQLFilterOperator::LIKE; + break; + default: + nOp = SQLFilterOperator::EQUAL; + } + } if ( bHaving ) { HANDLE_SQL_ERRORS( - m_xParser->appendHavingClauseByColumn(xField,sal_True), + xParser->appendHavingClauseByColumn(xField,sal_True,nOp), bParserSuccess, UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)), "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !" @@ -2198,7 +2237,7 @@ void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< Property else { HANDLE_SQL_ERRORS( - m_xParser->appendFilterByColumn(xField,sal_True), + xParser->appendFilterByColumn(xField,sal_True,nOp), bParserSuccess, UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)), "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !" @@ -2206,7 +2245,7 @@ void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< Property } if (bParserSuccess) - applyParserFilter(sOldFilter, bApplied,sOldHaving); + applyParserFilter(sOldFilter, bApplied,sOldHaving,xParser); InvalidateFeature(ID_BROWSER_REMOVEFILTER); InvalidateFeature(ID_BROWSER_FILTERED); @@ -2667,11 +2706,14 @@ void SbaXDataBrowserController::initializeParser() const if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING))) { // (only if the statement isn't native) // (it is allowed to use the PROPERTY_ISPASSTHROUGH : _after_ loading a form it is valid) + xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser; +/* const Reference<XMultiServiceFactory> xFactory(::dbtools::getConnection(getRowSet()),UNO_QUERY); if ( xFactory.is() ) m_xParser.set(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY); +*/ } - +/* // initialize the parser with the current sql-statement of the form if ( m_xParser.is() ) { @@ -2680,6 +2722,7 @@ void SbaXDataBrowserController::initializeParser() const m_xParser->setHavingClause(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE))); m_xParser->setOrder(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ORDER))); } +*/ } catch(Exception&) { @@ -2714,6 +2757,7 @@ void SbaXDataBrowserController::unloaded(const EventObject& /*aEvent*/) throw( R // change as a reaction on that event. as we have no chance to be notified of this change (which is // the one we're interested in) we give them time to do what they want to before invalidating our // bound-field-dependent slots .... + /* try { ::comphelper::disposeComponent(m_xParser); @@ -2722,6 +2766,7 @@ void SbaXDataBrowserController::unloaded(const EventObject& /*aEvent*/) throw( R { OSL_ENSURE(0,"Exception thrown by dispose"); } + */ } //------------------------------------------------------------------------------ diff --git a/dbaccess/source/ui/browser/dbexchange.cxx b/dbaccess/source/ui/browser/dbexchange.cxx index 8ecdabc65..48a466907 100644 --- a/dbaccess/source/ui/browser/dbexchange.cxx +++ b/dbaccess/source/ui/browser/dbexchange.cxx @@ -28,36 +28,16 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" -#ifndef DBAUI_DBEXCHANGE_HXX #include "dbexchange.hxx" -#endif -#ifndef _SOT_FORMATS_HXX #include <sot/formats.hxx> -#endif -#ifndef _SOT_STORAGE_HXX #include <sot/storage.hxx> -#endif -#ifndef _OSL_DIAGNOSE_H_ #include <osl/diagnose.h> -#endif -#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_ #include <com/sun/star/sdb/CommandType.hpp> -#endif -#ifndef DBAUI_TOKENWRITER_HXX +#include <com/sun/star/sdb/XResultSetAccess.hpp> #include "TokenWriter.hxx" -#endif -#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC #include "dbustrings.hrc" -#endif -//#ifndef _COMPHELPER_EXTRACT_HXX_ -//#include <comphelper/extract.hxx> -//#endif -#ifndef _COMPHELPER_UNO3_HXX_ #include <comphelper/uno3.hxx> -#endif -#ifndef _SVX_DATACCESSDESCRIPTOR_HXX_ #include <svx/dataaccessdescriptor.hxx> -#endif #include "UITools.hxx" @@ -75,23 +55,17 @@ namespace dbaui namespace { - template<class T > void lcl_addListener(const Reference<T>& _xComponent,ODataClipboard* _pListener) + template<class T > void lcl_setListener(const Reference<T>& _xComponent, const Reference< XEventListener >& i_rListener, const bool i_bAdd ) { - if ( _xComponent.is() ) - { - Reference< XComponent> xCom(_xComponent,UNO_QUERY); - if ( xCom.is() ) - xCom->addEventListener(Reference< XEventListener>((::cppu::OWeakObject*)_pListener,UNO_QUERY)); - } - } - template<class T > void lcl_removeListener(const Reference<T>& _xComponent,ODataClipboard* _pListener) - { - if ( _xComponent.is() ) - { - Reference< XComponent> xCom(_xComponent,UNO_QUERY); - if ( xCom.is() ) - xCom->removeEventListener(Reference< XEventListener>((::cppu::OWeakObject*)_pListener,UNO_QUERY)); - } + if ( !_xComponent.is() ) + return; + + Reference< XComponent> xCom( _xComponent, UNO_QUERY ); + OSL_ENSURE( xCom.is(), "lcl_setListener: no component!" ); + if ( !xCom.is() ) + return; + + i_bAdd ? xCom->addEventListener( i_rListener ) : xCom->removeEventListener( i_rListener ); } } @@ -108,13 +82,11 @@ namespace dbaui ,m_pRtf(NULL) { osl_incrementInterlockedCount( &m_refCount ); - lcl_addListener(_rxConnection,this); + lcl_setListener( _rxConnection, this, true ); - m_pHtml = new OHTMLImportExport(getDescriptor(), _rxORB, _rxFormatter); - m_aEventListeners.push_back(m_pHtml); + m_pHtml.set( new OHTMLImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); + m_pRtf.set( new ORTFImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); - m_pRtf = new ORTFImportExport(getDescriptor(), _rxORB, _rxFormatter); - m_aEventListeners.push_back(m_pRtf); osl_decrementInterlockedCount( &m_refCount ); } @@ -129,48 +101,51 @@ namespace dbaui ,m_pHtml(NULL) ,m_pRtf(NULL) { - m_pHtml = new OHTMLImportExport(getDescriptor(),_rxORB, _rxFormatter); - m_aEventListeners.push_back(m_pHtml); - - m_pRtf = new ORTFImportExport(getDescriptor(),_rxORB, _rxFormatter); - m_aEventListeners.push_back(m_pRtf); + m_pHtml.set( new OHTMLImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); + m_pRtf.set( new ORTFImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); } // ----------------------------------------------------------------------------- - ODataClipboard::ODataClipboard( const Reference< XPropertySet >& _rxLivingForm, - const Sequence< Any >& _rSelectedRows, - const Reference< XResultSet>& _rxResultSet, - const Reference< XMultiServiceFactory >& _rxORB) - :ODataAccessObjectTransferable( _rxLivingForm ) + ODataClipboard::ODataClipboard( const Reference< XPropertySet >& i_rAliveForm, + const Sequence< Any >& i_rSelectedRows, + const sal_Bool i_bBookmarkSelection, + const Reference< XMultiServiceFactory >& i_rORB ) + :ODataAccessObjectTransferable( i_rAliveForm ) ,m_pHtml(NULL) ,m_pRtf(NULL) { + OSL_PRECOND( i_rORB.is(), "ODataClipboard::ODataClipboard: having no factory is not good ..." ); + osl_incrementInterlockedCount( &m_refCount ); Reference<XConnection> xConnection; - getDescriptor()[daConnection] >>= xConnection; - lcl_addListener(xConnection,this); - lcl_addListener(_rxResultSet,this); + getDescriptor()[ daConnection ] >>= xConnection; + lcl_setListener( xConnection, this, true ); - getDescriptor()[daSelection] <<= _rSelectedRows; - getDescriptor()[daBookmarkSelection]<<= sal_False; // by definition, it's the indicies - getDescriptor()[daCursor] <<= _rxResultSet; - addCompatibleSelectionDescription( _rSelectedRows ); + // do not pass the form itself as source result set, since the client might operate on the form, which + // might lead to undesired effects. Instead, use a clone. + Reference< XResultSet > xResultSetClone; + Reference< XResultSetAccess > xResultSetAccess( i_rAliveForm, UNO_QUERY ); + if ( xResultSetAccess.is() ) + xResultSetClone = xResultSetAccess->createResultSet(); + OSL_ENSURE( xResultSetClone.is(), "ODataClipboard::ODataClipboard: could not clone the form's result set" ); + lcl_setListener( xResultSetClone, this, true ); - if ( xConnection.is() && _rxORB.is() ) + getDescriptor()[daCursor] <<= xResultSetClone; + getDescriptor()[daSelection] <<= i_rSelectedRows; + getDescriptor()[daBookmarkSelection]<<= i_bBookmarkSelection; + addCompatibleSelectionDescription( i_rSelectedRows ); + + if ( xConnection.is() && i_rORB.is() ) { - Reference< XNumberFormatter > xFormatter( getNumberFormatter( xConnection, _rxORB ) ); + Reference< XNumberFormatter > xFormatter( getNumberFormatter( xConnection, i_rORB ) ); if ( xFormatter.is() ) { - m_pHtml = new OHTMLImportExport( getDescriptor(),_rxORB, xFormatter ); - m_aEventListeners.push_back( m_pHtml ); - - m_pRtf = new ORTFImportExport( getDescriptor(),_rxORB, xFormatter ); - m_aEventListeners.push_back( m_pRtf ); + m_pHtml.set( new OHTMLImportExport( getDescriptor(), i_rORB, xFormatter ) ); + m_pRtf.set( new ORTFImportExport( getDescriptor(), i_rORB, xFormatter ) ); } } - osl_decrementInterlockedCount( &m_refCount ); } @@ -192,13 +167,11 @@ namespace dbaui // ----------------------------------------------------------------------------- void ODataClipboard::AddSupportedFormats() { - // RTF? - if (m_pRtf) - AddFormat(SOT_FORMAT_RTF); + if ( m_pRtf.is() ) + AddFormat( SOT_FORMAT_RTF ); - // HTML? - if (m_pHtml) - AddFormat(SOT_FORMATSTR_ID_HTML); + if ( m_pHtml.is() ) + AddFormat( SOT_FORMATSTR_ID_HTML ); ODataAccessObjectTransferable::AddSupportedFormats(); } @@ -210,13 +183,14 @@ namespace dbaui switch (nFormat) { case SOT_FORMAT_RTF: - if ( m_pRtf ) + if ( m_pRtf.is() ) m_pRtf->initialize(getDescriptor()); - return m_pRtf && SetObject(m_pRtf, SOT_FORMAT_RTF, rFlavor); + return m_pRtf.is() && SetObject( m_pRtf.get(), SOT_FORMAT_RTF, rFlavor ); + case SOT_FORMATSTR_ID_HTML: - if ( m_pHtml ) + if ( m_pHtml.is() ) m_pHtml->initialize(getDescriptor()); - return m_pHtml && SetObject(m_pHtml, SOT_FORMATSTR_ID_HTML, rFlavor); + return m_pHtml.is() && SetObject( m_pHtml.get(), SOT_FORMATSTR_ID_HTML, rFlavor ); } return ODataAccessObjectTransferable::GetData( rFlavor ); @@ -225,59 +199,65 @@ namespace dbaui // ----------------------------------------------------------------------------- void ODataClipboard::ObjectReleased() { - if ( m_pHtml ) + if ( m_pHtml.is() ) { m_pHtml->dispose(); - m_pHtml = NULL; - } // if ( m_pHtml ) - if ( m_pRtf ) + m_pHtml.clear(); + } + + if ( m_pRtf.is() ) { m_pRtf->dispose(); - m_pRtf = NULL; + m_pRtf.clear(); + } + + if ( getDescriptor().has( daConnection ) ) + { + Reference<XConnection> xConnection( getDescriptor()[daConnection], UNO_QUERY ); + lcl_setListener( xConnection, this, false ); + } + + if ( getDescriptor().has( daCursor ) ) + { + Reference< XResultSet > xResultSet( getDescriptor()[ daCursor ], UNO_QUERY ); + lcl_setListener( xResultSet, this, false ); } - m_aEventListeners.clear(); - Reference<XConnection> xConnection; - Reference<XResultSet> xProp; - if ( getDescriptor().has(daConnection) && (getDescriptor()[daConnection] >>= xConnection) ) - lcl_removeListener(xConnection,this); - if ( getDescriptor().has(daCursor) && (getDescriptor()[daCursor] >>= xProp) ) - lcl_removeListener(xProp,this); ODataAccessObjectTransferable::ObjectReleased( ); } + // ----------------------------------------------------------------------------- - void SAL_CALL ODataClipboard::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException) + void SAL_CALL ODataClipboard::disposing( const ::com::sun::star::lang::EventObject& i_rSource ) throw (::com::sun::star::uno::RuntimeException) { - Reference<XConnection> xConnection; - Reference<XResultSet> xProp; - if ( getDescriptor().has(daConnection) && (getDescriptor()[daConnection] >>= xConnection) ) - { - lcl_removeListener(xConnection,this); - getDescriptor().erase(daConnection); - } // if ( getDescriptor().has(daConnection) && (getDescriptor()[daConnection] >>= xConnection) ) - if ( getDescriptor().has(daCursor) && (getDescriptor()[daCursor] >>= xProp) ) - { - lcl_removeListener(xProp,this); - getDescriptor().erase(daCursor); - } // if ( getDescriptor().has(daCursor) && (getDescriptor()[daCursor] >>= xProp) ) + ODataAccessDescriptor& rDescriptor( getDescriptor() ); - if ( getDescriptor().has(daColumnObject) ) - getDescriptor().erase(daColumnObject); - - if ( getDescriptor().has(daComponent) ) - getDescriptor().erase(daComponent); + if ( rDescriptor.has( daConnection ) ) + { + Reference< XConnection > xConnection( rDescriptor[daConnection], UNO_QUERY ); + if ( xConnection == i_rSource.Source ) + { + rDescriptor.erase( daConnection ); + } + } + if ( rDescriptor.has( daCursor ) ) + { + Reference< XResultSet > xResultSet( rDescriptor[ daCursor ], UNO_QUERY ); + if ( xResultSet == i_rSource.Source ) + { + rDescriptor.erase( daCursor ); + // Selection and BookmarkSelection are meaningless without a result set + if ( rDescriptor.has( daSelection ) ) + rDescriptor.erase( daSelection ); + if ( rDescriptor.has( daBookmarkSelection ) ) + rDescriptor.erase( daBookmarkSelection ); + } + } + // no matter whether it was the source connection or the source result set which died, + // we cannot provide the data anymore. ClearFormats(); - //getDescriptor().clear(); - AddSupportedFormats(); - - /*m_pHtml = NULL; - m_pRtf = NULL; - m_aEventListeners.clear();*/ } - // ----------------------------------------------------------------------------- - IMPLEMENT_FORWARD_XINTERFACE2( ODataClipboard, ODataAccessObjectTransferable, TDataClipboard_BASE ) } diff --git a/dbaccess/source/ui/browser/sbagrid.cxx b/dbaccess/source/ui/browser/sbagrid.cxx index 44ce546ad..d8bb49710 100644 --- a/dbaccess/source/ui/browser/sbagrid.cxx +++ b/dbaccess/source/ui/browser/sbagrid.cxx @@ -1440,39 +1440,30 @@ void SbaGridControl::DoRowDrag( sal_Int16 nRowPos ) // ----------------------------------------------------------------------- void SbaGridControl::implTransferSelectedRows( sal_Int16 nRowPos, bool _bTrueIfClipboardFalseIfDrag ) { - Reference< XPropertySet > xDataSource(getDataSource(), UNO_QUERY); - DBG_ASSERT(xDataSource.is(), "SbaGridControl::implTransferSelectedRows : invalid data source !"); + Reference< XPropertySet > xForm( getDataSource(), UNO_QUERY ); + DBG_ASSERT( xForm.is(), "SbaGridControl::implTransferSelectedRows: invalid form!" ); // build the sequence of numbers of selected rows Sequence< Any > aSelectedRows; + sal_Bool bSelectionBookmarks = sal_True; // collect the affected rows if ((GetSelectRowCount() == 0) && (nRowPos >= 0)) { - aSelectedRows.realloc(1); + aSelectedRows.realloc( 1 ); aSelectedRows[0] <<= (sal_Int32)(nRowPos + 1); + bSelectionBookmarks = sal_False; } else if ( !IsAllSelected() && GetSelectRowCount() ) { - aSelectedRows.realloc(GetSelectRowCount()); - Any* pSelectedRows = aSelectedRows.getArray(); - - for (long nIdx = FirstSelectedRow(); - nIdx >= 0; - nIdx = NextSelectedRow(), ++pSelectedRows) - { - (*pSelectedRows) <<= (sal_Int32)(nIdx + 1); - } + aSelectedRows = getSelectionBookmarks(); + bSelectionBookmarks = sal_True; } Reference< XResultSet> xRowSetClone; try { - Reference< XResultSetAccess > xResultSetAccess(xDataSource,UNO_QUERY); - if ( xResultSetAccess.is() ) - xRowSetClone = xResultSetAccess->createResultSet(); - - ODataClipboard* pTransfer = new ODataClipboard(xDataSource, aSelectedRows,xRowSetClone, getServiceManager()); + ODataClipboard* pTransfer = new ODataClipboard( xForm, aSelectedRows, bSelectionBookmarks, getServiceManager() ); Reference< XTransferable > xEnsureDelete = pTransfer; if ( _bTrueIfClipboardFalseIfDrag ) diff --git a/dbaccess/source/ui/browser/unodatbr.cxx b/dbaccess/source/ui/browser/unodatbr.cxx index 70f7aa774..bdd31895a 100644 --- a/dbaccess/source/ui/browser/unodatbr.cxx +++ b/dbaccess/source/ui/browser/unodatbr.cxx @@ -647,7 +647,12 @@ sal_Bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun:: } aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) ); - aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) ); + ::rtl::OUString sLabel; + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + if ( sLabel.getLength() ) + aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) ); + else + aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) ); Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW ); Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW ); @@ -678,8 +683,12 @@ sal_Bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun:: Any aDescription; if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) ) aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT ); - if ( !aDescription.hasValue() ) - aDescription <<= ::rtl::OUString(); + ::rtl::OUString sTemp; + aDescription >>= sTemp; + if ( !sTemp.getLength() ) + xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp; + + aDescription <<= sTemp; aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) ); // ... horizontal justify @@ -1096,7 +1105,11 @@ SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::rtl::OUString& _rDataS { // expand if required so if (_bExpandAncestors) + { + m_sToBeLoaded = _rCommand; m_pTreeView->getListBox().Expand(pCommandType); + m_sToBeLoaded = ::rtl::OUString(); + } // look for the object ::rtl::OUString sCommand = _rCommand; @@ -2041,7 +2054,7 @@ void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAcce const ::rtl::OUString* pEnd = pIter + aNames.getLength(); for (; pIter != pEnd; ++pIter) { - if(!m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent)) + if( (!m_sToBeLoaded.getLength() || m_sToBeLoaded == *pIter) && !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent)) { Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY); DBTreeListUserData* pEntryData = new DBTreeListUserData; diff --git a/dbaccess/source/ui/control/sqledit.cxx b/dbaccess/source/ui/control/sqledit.cxx index 97bd2a03c..b812f585f 100644 --- a/dbaccess/source/ui/control/sqledit.cxx +++ b/dbaccess/source/ui/control/sqledit.cxx @@ -84,8 +84,9 @@ OSqlEdit::~OSqlEdit() void OSqlEdit::KeyInput( const KeyEvent& rKEvt ) { DBG_CHKTHIS(OSqlEdit,NULL); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_CUT); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_COPY); + OJoinController& rController = m_pView->getContainerWindow()->getDesignView()->getController(); + rController.InvalidateFeature(SID_CUT); + rController.InvalidateFeature(SID_COPY); // Ist dies ein Cut, Copy, Paste Event? KeyFuncType aKeyFunc = rKEvt.GetKeyCode().GetFunction(); @@ -124,14 +125,15 @@ IMPL_LINK(OSqlEdit, OnUndoActionTimer, void*, EMPTYARG) String aText =GetText(); if(aText != m_strOrigText) { - SfxUndoManager* pUndoMgr = m_pView->getContainerWindow()->getDesignView()->getController().getUndoMgr(); + OJoinController& rController = m_pView->getContainerWindow()->getDesignView()->getController(); + SfxUndoManager* pUndoMgr = rController.getUndoMgr(); OSqlEditUndoAct* pUndoAct = new OSqlEditUndoAct( this ); pUndoAct->SetOriginalText( m_strOrigText ); pUndoMgr->AddUndoAction( pUndoAct ); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_UNDO); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_REDO); + rController.InvalidateFeature(SID_UNDO); + rController.InvalidateFeature(SID_REDO); m_strOrigText =aText; } @@ -141,8 +143,9 @@ IMPL_LINK(OSqlEdit, OnUndoActionTimer, void*, EMPTYARG) //------------------------------------------------------------------------------ IMPL_LINK(OSqlEdit, OnInvalidateTimer, void*, EMPTYARG) { - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_CUT); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_COPY); + OJoinController& rController = m_pView->getContainerWindow()->getDesignView()->getController(); + rController.InvalidateFeature(SID_CUT); + rController.InvalidateFeature(SID_COPY); if(!m_bStopTimer) m_timerInvalidate.Start(); return 0L; @@ -154,12 +157,13 @@ IMPL_LINK(OSqlEdit, ModifyHdl, void*, /*EMPTYTAG*/) m_timerUndoActionCreation.Stop(); m_timerUndoActionCreation.Start(); - if (!m_pView->getContainerWindow()->getDesignView()->getController().isModified()) - m_pView->getContainerWindow()->getDesignView()->getController().setModified( sal_True ); + OJoinController& rController = m_pView->getContainerWindow()->getDesignView()->getController(); + if (!rController.isModified()) + rController.setModified( sal_True ); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_SBA_QRY_EXECUTE); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_CUT); - m_pView->getContainerWindow()->getDesignView()->getController().InvalidateFeature(SID_COPY); + rController.InvalidateFeature(SID_SBA_QRY_EXECUTE); + rController.InvalidateFeature(SID_CUT); + rController.InvalidateFeature(SID_COPY); m_lnkTextModifyHdl.Call(NULL); return 0; diff --git a/dbaccess/source/ui/dlg/DbAdminImpl.cxx b/dbaccess/source/ui/dlg/DbAdminImpl.cxx index 27f0191cf..04640808b 100644 --- a/dbaccess/source/ui/dlg/DbAdminImpl.cxx +++ b/dbaccess/source/ui/dlg/DbAdminImpl.cxx @@ -31,6 +31,11 @@ #include "DbAdminImpl.hxx" #include "dsmeta.hxx" +#include <svl/poolitem.hxx> +#include <svl/itempool.hxx> +#include <svl/stritem.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> #include "DriverSettings.hxx" #include "IItemSetHelper.hxx" #include "UITools.hxx" diff --git a/dbaccess/source/ui/dlg/adminpages.cxx b/dbaccess/source/ui/dlg/adminpages.cxx index 21689d2d7..de8488116 100644 --- a/dbaccess/source/ui/dlg/adminpages.cxx +++ b/dbaccess/source/ui/dlg/adminpages.cxx @@ -32,6 +32,9 @@ #include "dbadmin.hrc" #include "dbadmin.hxx" #include "dbu_dlg.hrc" +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> #include "dbustrings.hrc" #include "dsitems.hxx" #include "dsselect.hxx" diff --git a/dbaccess/source/ui/dlg/dbadmin.cxx b/dbaccess/source/ui/dlg/dbadmin.cxx index fd3bd38f4..481ee3981 100644 --- a/dbaccess/source/ui/dlg/dbadmin.cxx +++ b/dbaccess/source/ui/dlg/dbadmin.cxx @@ -35,6 +35,9 @@ #include "dbadmin.hrc" #include "dbadmin.hxx" #include "dbu_dlg.hrc" +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> #include "dbustrings.hrc" #include "dsitems.hxx" #include "dsnItem.hxx" diff --git a/dbaccess/source/ui/dlg/dlgsave.cxx b/dbaccess/source/ui/dlg/dlgsave.cxx index 1bbc4a91a..f8ae40b61 100644 --- a/dbaccess/source/ui/dlg/dlgsave.cxx +++ b/dbaccess/source/ui/dlg/dlgsave.cxx @@ -322,6 +322,7 @@ OSaveAsDlg::OSaveAsDlg( Window * pParent, } else m_pImpl->m_aTitle.SetText(m_pImpl->m_aName); + m_pImpl->m_aTitle.SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) ); m_pImpl->m_aPB_OK.SetPosPixel(Point(m_pImpl->m_aPB_OK.GetPosPixel().X(),aPos.Y())); m_pImpl->m_aPB_CANCEL.SetPosPixel(Point(m_pImpl->m_aPB_CANCEL.GetPosPixel().X(),aPos.Y())); diff --git a/dbaccess/source/ui/dlg/indexdialog.cxx b/dbaccess/source/ui/dlg/indexdialog.cxx index 2dbb5cb10..1938fdab9 100644 --- a/dbaccess/source/ui/dlg/indexdialog.cxx +++ b/dbaccess/source/ui/dlg/indexdialog.cxx @@ -217,7 +217,7 @@ DBG_NAME(DbaIndexDialog) ,m_aDescription (this, ModuleRes(FT_DESCRIPTION)) ,m_aUnique (this, ModuleRes(CB_UNIQUE)) ,m_aFieldsLabel (this, ModuleRes(FT_FIELDS)) - ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex)) + ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex,::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ))) ,m_aClose (this, ModuleRes(PB_CLOSE)) ,m_aHelp (this, ModuleRes(HB_HELP)) ,m_pIndexes(NULL) diff --git a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx index f802e2d69..e26a99a3f 100644 --- a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx +++ b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx @@ -119,12 +119,13 @@ namespace dbaui //================================================================== DBG_NAME(IndexFieldsControl) //------------------------------------------------------------------ - IndexFieldsControl::IndexFieldsControl( Window* _pParent, const ResId& _rId ,sal_Int32 _nMaxColumnsInIndex) + IndexFieldsControl::IndexFieldsControl( Window* _pParent, const ResId& _rId ,sal_Int32 _nMaxColumnsInIndex,sal_Bool _bAddIndexAppendix) :EditBrowseBox(_pParent, _rId, EBBF_SMART_TAB_TRAVEL | EBBF_ACTIVATE_ON_BUTTONDOWN, BROWSER_STANDARD_FLAGS) ,m_aSeekRow(m_aFields.end()) ,m_pSortingCell(NULL) ,m_pFieldNameCell(NULL) ,m_nMaxColumnsInIndex(_nMaxColumnsInIndex) + ,m_bAddIndexAppendix(_bAddIndexAppendix) { DBG_CTOR(IndexFieldsControl,NULL); @@ -205,7 +206,7 @@ DBG_NAME(IndexFieldsControl) RowInserted(GetRowCount(), m_aFields.size(), sal_False); // insert an additional row for a new field for that index // if(!m_nMaxColumnsInIndex || GetRowCount() < m_nMaxColumnsInIndex ) - RowInserted(GetRowCount(), 1, sal_False); + RowInserted(GetRowCount(), 1, sal_False); SetUpdateMode(sal_True); GoToRowColumnId(0, COLUMN_ID_FIELDNAME); @@ -247,51 +248,52 @@ DBG_NAME(IndexFieldsControl) { RemoveColumns(); - m_sAscendingText = String(ModuleRes(STR_ORDER_ASCENDING)); - m_sDescendingText = String(ModuleRes(STR_ORDER_DESCENDING)); - - // the "sort order" column - String sColumnName = String(ModuleRes(STR_TAB_INDEX_SORTORDER)); - // the width of the order column is the maximum widths of the texts used - // (the title of the column) - sal_Int32 nSortOrderColumnWidth = GetTextWidth(sColumnName); - // ("ascending" + scrollbar width) - sal_Int32 nOther = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); - nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther; - // ("descending" + scrollbar width) - nOther = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); - nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther; - // (plus some additional space) - nSortOrderColumnWidth += GetTextWidth('0') * 2; - InsertDataColumn(COLUMN_ID_ORDER, sColumnName, nSortOrderColumnWidth, HIB_STDSTYLE, 1); - // for the width: both columns together should be somewhat smaller than the whole window (without the scrollbar) sal_Int32 nFieldNameWidth = GetSizePixel().Width(); - nFieldNameWidth -= nSortOrderColumnWidth; + if ( m_bAddIndexAppendix ) + { + m_sAscendingText = String(ModuleRes(STR_ORDER_ASCENDING)); + m_sDescendingText = String(ModuleRes(STR_ORDER_DESCENDING)); + + // the "sort order" column + String sColumnName = String(ModuleRes(STR_TAB_INDEX_SORTORDER)); + // the width of the order column is the maximum widths of the texts used + // (the title of the column) + sal_Int32 nSortOrderColumnWidth = GetTextWidth(sColumnName); + // ("ascending" + scrollbar width) + sal_Int32 nOther = GetTextWidth(m_sAscendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); + nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther; + // ("descending" + scrollbar width) + nOther = GetTextWidth(m_sDescendingText) + GetSettings().GetStyleSettings().GetScrollBarSize(); + nSortOrderColumnWidth = nSortOrderColumnWidth > nOther ? nSortOrderColumnWidth : nOther; + // (plus some additional space) + nSortOrderColumnWidth += GetTextWidth('0') * 2; + InsertDataColumn(COLUMN_ID_ORDER, sColumnName, nSortOrderColumnWidth, HIB_STDSTYLE, 1); + + m_pSortingCell = new ListBoxControl(&GetDataWindow()); + m_pSortingCell->InsertEntry(m_sAscendingText); + m_pSortingCell->InsertEntry(m_sDescendingText); + m_pSortingCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER ); + + nFieldNameWidth -= nSortOrderColumnWidth; + } StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings(); nFieldNameWidth -= aSystemStyle.GetScrollBarSize(); nFieldNameWidth -= 8; - // the "field name" column - sColumnName = String(ModuleRes(STR_TAB_INDEX_FIELD)); + String sColumnName = String(ModuleRes(STR_TAB_INDEX_FIELD)); InsertDataColumn(COLUMN_ID_FIELDNAME, sColumnName, nFieldNameWidth, HIB_STDSTYLE, 0); // create the cell controllers // for the field name cell m_pFieldNameCell = new ListBoxControl(&GetDataWindow()); m_pFieldNameCell->InsertEntry(String()); + m_pFieldNameCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD ); const ::rtl::OUString* pFields = _rAvailableFields.getConstArray(); const ::rtl::OUString* pFieldsEnd = pFields + _rAvailableFields.getLength(); for (;pFields < pFieldsEnd; ++pFields) m_pFieldNameCell->InsertEntry(*pFields); - // for the sort cell - m_pSortingCell = new ListBoxControl(&GetDataWindow()); - m_pSortingCell->InsertEntry(m_sAscendingText); - m_pSortingCell->InsertEntry(m_sDescendingText); - - m_pFieldNameCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_FIELD ); - m_pSortingCell->SetHelpId( HID_DLGINDEX_INDEXDETAILS_SORTORDER ); } //------------------------------------------------------------------ diff --git a/dbaccess/source/ui/inc/FieldDescControl.hxx b/dbaccess/source/ui/inc/FieldDescControl.hxx index 00e809e91..af7204fc8 100644 --- a/dbaccess/source/ui/inc/FieldDescControl.hxx +++ b/dbaccess/source/ui/inc/FieldDescControl.hxx @@ -47,22 +47,23 @@ // die Spalten einer Feld-Beschreibung einer Tabelle #define FIELD_NAME 1 #define FIELD_TYPE 2 -#define FIELD_DESCR 3 +#define HELP_TEXT 3 +#define COLUMN_DESCRIPTION 4 -#define FIELD_FIRST_VIRTUAL_COLUMN 4 +#define FIELD_FIRST_VIRTUAL_COLUMN 5 -#define FIELD_PROPERTY_REQUIRED 4 -#define FIELD_PROPERTY_NUMTYPE 5 -#define FIELD_PROPERTY_AUTOINC 6 -#define FIELD_PROPERTY_DEFAULT 7 -#define FIELD_PROPERTY_TEXTLEN 8 -#define FIELD_PROPERTY_LENGTH 9 -#define FIELD_PROPERTY_SCALE 10 -#define FIELD_PROPERTY_BOOL_DEFAULT 11 -#define FIELD_PROPERTY_FORMAT 12 -#define FIELD_PRPOERTY_COLUMNNAME 13 -#define FIELD_PRPOERTY_TYPE 14 -#define FIELD_PRPOERTY_AUTOINCREMENT 15 +#define FIELD_PROPERTY_REQUIRED 5 +#define FIELD_PROPERTY_NUMTYPE 6 +#define FIELD_PROPERTY_AUTOINC 7 +#define FIELD_PROPERTY_DEFAULT 8 +#define FIELD_PROPERTY_TEXTLEN 9 +#define FIELD_PROPERTY_LENGTH 10 +#define FIELD_PROPERTY_SCALE 11 +#define FIELD_PROPERTY_BOOL_DEFAULT 12 +#define FIELD_PROPERTY_FORMAT 13 +#define FIELD_PRPOERTY_COLUMNNAME 14 +#define FIELD_PRPOERTY_TYPE 15 +#define FIELD_PRPOERTY_AUTOINCREMENT 16 class FixedText; class PushButton; diff --git a/dbaccess/source/ui/inc/FieldDescriptions.hxx b/dbaccess/source/ui/inc/FieldDescriptions.hxx index e20f7c6fc..13ff8e7e9 100644 --- a/dbaccess/source/ui/inc/FieldDescriptions.hxx +++ b/dbaccess/source/ui/inc/FieldDescriptions.hxx @@ -64,6 +64,7 @@ namespace dbaui ::rtl::OUString m_sName; ::rtl::OUString m_sTypeName; ::rtl::OUString m_sDescription; + ::rtl::OUString m_sHelpText; ::rtl::OUString m_sAutoIncrementValue; sal_Int32 m_nType; // only used when m_pType is null @@ -85,7 +86,8 @@ namespace dbaui ~OFieldDescription(); void SetName(const ::rtl::OUString& _rName); - void SetDescription(const ::rtl::OUString& _rDescription); + void SetDescription(const ::rtl::OUString& _rDescription); + void SetHelpText(const ::rtl::OUString& _sHelptext); void SetDefaultValue(const ::com::sun::star::uno::Any& _rDefaultValue); void SetControlDefault(const ::com::sun::star::uno::Any& _rControlDefault); void SetAutoIncrementValue(const ::rtl::OUString& _sAutoIncValue); @@ -110,6 +112,7 @@ namespace dbaui ::rtl::OUString GetName() const; ::rtl::OUString GetDescription() const; + ::rtl::OUString GetHelpText() const; ::com::sun::star::uno::Any GetControlDefault() const; ::rtl::OUString GetAutoIncrementValue() const; sal_Int32 GetType() const; diff --git a/dbaccess/source/ui/inc/RTableConnectionData.hxx b/dbaccess/source/ui/inc/RTableConnectionData.hxx index e129cff77..34282557a 100644 --- a/dbaccess/source/ui/inc/RTableConnectionData.hxx +++ b/dbaccess/source/ui/inc/RTableConnectionData.hxx @@ -61,9 +61,9 @@ namespace dbaui sal_Int32 m_nDeleteRules; sal_Int32 m_nCardinality; - BOOL checkPrimaryKey(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xKeys,EConnectionSide _eEConnectionSide) const; - BOOL IsSourcePrimKey() const { return checkPrimaryKey(getReferencingTable()->getKeys(),JTCS_FROM); } - BOOL IsDestPrimKey() const { return checkPrimaryKey(getReferencedTable()->getKeys(),JTCS_TO); } + BOOL checkPrimaryKey(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& i_xTable,EConnectionSide _eEConnectionSide) const; + BOOL IsSourcePrimKey() const { return checkPrimaryKey(getReferencingTable()->getTable(),JTCS_FROM); } + BOOL IsDestPrimKey() const { return checkPrimaryKey(getReferencedTable()->getTable(),JTCS_TO); } protected: virtual OConnectionLineDataRef CreateLineDataObj(); diff --git a/dbaccess/source/ui/inc/TableCopyHelper.hxx b/dbaccess/source/ui/inc/TableCopyHelper.hxx index 0556180cc..abcbdd7e8 100644 --- a/dbaccess/source/ui/inc/TableCopyHelper.hxx +++ b/dbaccess/source/ui/inc/TableCopyHelper.hxx @@ -191,30 +191,17 @@ namespace dbaui ); /** insert a table into the data source. The source can eihter be a table or a query - @param _nCommandType - The command type. - @param _xSrcConnection - The connection of the source. - @param _aSelection - The selection of the rows to copy. - @param _bBookmarkSelection - If <TRUE/> the selection is bookmark selection. - @param _sCommand - The name of the query or table. - @param _sSrcDataSourceName - The name of the source data source. - @param _sDestDataSourceName - The name of the dest data source. */ void insertTable( - sal_Int32 _nCommandType, - const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xSrcConnection, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _aSelection, - sal_Bool _bBookmarkSelection, - const ::rtl::OUString& _sCommand, - const ::rtl::OUString& _sSrcDataSourceName, - const ::rtl::OUString& _sDestDataSourceName, - const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xDestConnection + const ::rtl::OUString& i_rSourceDataSource, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& i_rSourceConnection, + const ::rtl::OUString& i_rCommand, + const sal_Int32 i_nCommandType, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& i_rSourceRows, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& i_rSelection, + const sal_Bool i_bBookmarkSelection, + const ::rtl::OUString& i_rDestDataSource, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& i_rDestConnection ); }; diff --git a/dbaccess/source/ui/inc/TokenWriter.hxx b/dbaccess/source/ui/inc/TokenWriter.hxx index 3a0d07bea..5715cfd6d 100644 --- a/dbaccess/source/ui/inc/TokenWriter.hxx +++ b/dbaccess/source/ui/inc/TokenWriter.hxx @@ -27,51 +27,25 @@ #ifndef DBAUI_TOKENWRITER_HXX #define DBAUI_TOKENWRITER_HXX -#ifndef DBAUI_DATABASEEXPORT_HXX #include "DExport.hxx" -#endif -#ifndef _DBAUI_MODULE_DBU_HXX_ #include "moduledbu.hxx" -#endif -#ifndef _STREAM_HXX //autogen -#include <tools/stream.hxx> -#endif -#ifndef _COM_SUN_STAR_AWT_FONTDESCRIPTOR_HPP_ +#include "commontypes.hxx" + #include <com/sun/star/awt/FontDescriptor.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_ #include <com/sun/star/sdbc/XResultSet.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XRESULTSETUPDATE_HPP_ #include <com/sun/star/sdbc/XResultSetUpdate.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ #include <com/sun/star/sdbc/XRow.hpp> -#endif -#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ #include <com/sun/star/lang/XMultiServiceFactory.hpp> -#endif -#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HPP_ #include <com/sun/star/lang/XEventListener.hpp> -#endif -#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_ #include <com/sun/star/frame/XModel.hpp> -#endif -#ifndef _CPPUHELPER_IMPLBASE1_HXX_ -#include <cppuhelper/implbase1.hxx> -#endif -#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ #include <com/sun/star/beans/PropertyValue.hpp> -#endif -#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_ #include <com/sun/star/sdb/CommandType.hpp> -#endif -#ifndef _SVX_DATACCESSDESCRIPTOR_HXX_ +#include <com/sun/star/sdbcx/XRowLocate.hpp> + +#include <cppuhelper/implbase1.hxx> +#include <tools/stream.hxx> #include <svx/dataaccessdescriptor.hxx> -#endif -#ifndef _DBAUI_COMMON_TYPES_HXX_ -#include "commontypes.hxx" -#endif + #include <memory> namespace com { namespace sun { namespace star { @@ -95,13 +69,15 @@ namespace dbaui protected: ::com::sun::star::lang::Locale m_aLocale; ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> m_aSelection; + sal_Bool m_bBookmarkSelection; SvStream* m_pStream; ::com::sun::star::awt::FontDescriptor m_aFont; ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xObject; // table/query - SharedConnection m_xConnection; // - ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > m_xResultSet; // - ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > m_xRow; // - ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > m_xResultSetMetaData; // + SharedConnection m_xConnection; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > m_xResultSet; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > m_xRow; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XRowLocate > m_xRowLocate; + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > m_xResultSetMetaData; ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > m_xRowSetColumns; ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > m_xFormatter; // a number formatter working with the connection's NumberFormatsSupplier ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xFactory; diff --git a/dbaccess/source/ui/inc/brwctrlr.hxx b/dbaccess/source/ui/inc/brwctrlr.hxx index 80380a223..1a1193592 100644 --- a/dbaccess/source/ui/inc/brwctrlr.hxx +++ b/dbaccess/source/ui/inc/brwctrlr.hxx @@ -338,14 +338,15 @@ namespace dbaui void ExecuteSearch(); void initializeParser() const; // changes the mutable member m_xParser - void applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving = ::rtl::OUString()); - void applyParserOrder(const ::rtl::OUString& _rOldOrder); + void applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving,const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer >& _xParser); + void applyParserOrder(const ::rtl::OUString& _rOldOrder,const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer >& _xParser); sal_Int16 getCurrentColumnPosition(); void setCurrentColumnPosition( sal_Int16 _nPos ); void addColumnListeners(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel); void impl_checkForCannotSelectUnfiltered( const ::dbtools::SQLExceptionInfo& _rError ); + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer > createParser_nothrow(); // time to check the CUT/COPY/PASTE-slot-states DECL_LINK( OnInvalidateClipboard, AutoTimer* ); diff --git a/dbaccess/source/ui/inc/dbexchange.hxx b/dbaccess/source/ui/inc/dbexchange.hxx index 437c3b1e1..bc4834b0f 100644 --- a/dbaccess/source/ui/inc/dbexchange.hxx +++ b/dbaccess/source/ui/inc/dbexchange.hxx @@ -53,20 +53,19 @@ #endif #include <vector> +#include <rtl/ref.hxx> + namespace dbaui { class ORTFImportExport; class OHTMLImportExport; - typedef ::cppu::ImplHelper1< ::com::sun::star::lang::XEventListener > TDataClipboard_BASE; - class ODataClipboard : public ::svx::ODataAccessObjectTransferable - , public TDataClipboard_BASE + class ODataClipboard : public ::svx::ODataAccessObjectTransferable { - ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener> > m_aEventListeners; - OHTMLImportExport* m_pHtml; - ORTFImportExport* m_pRtf; + ::rtl::Reference< OHTMLImportExport > m_pHtml; + ::rtl::Reference< ORTFImportExport > m_pRtf; public: ODataClipboard( @@ -87,15 +86,15 @@ namespace dbaui ); ODataClipboard( - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxLivingForm, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rSelectedRows, - const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet>& _rxResultSet, - const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& i_rAliveForm, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& i_rSelectedRows, + const sal_Bool i_bBookmarkSelection, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_rORB ); - DECLARE_XINTERFACE( ) - + // XEventListener virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + protected: virtual void AddSupportedFormats(); virtual sal_Bool GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); diff --git a/dbaccess/source/ui/inc/dbu_tbl.hrc b/dbaccess/source/ui/inc/dbu_tbl.hrc index d1681225d..310baa5eb 100644 --- a/dbaccess/source/ui/inc/dbu_tbl.hrc +++ b/dbaccess/source/ui/inc/dbu_tbl.hrc @@ -41,7 +41,7 @@ #define STR_TAB_FIELD_NAME RID_STR_TBL_START + 7 #define STR_TAB_FIELD_DATATYPE RID_STR_TBL_START + 8 #define STR_TAB_FIELD_LENGTH RID_STR_TBL_START + 9 -#define STR_TAB_FIELD_DESCR RID_STR_TBL_START + 10 +#define STR_TAB_HELP_TEXT RID_STR_TBL_START + 10 #define STR_TAB_FIELD_NULLABLE RID_STR_TBL_START + 11 #define STR_FIELD_AUTOINCREMENT RID_STR_TBL_START + 12 #define STR_TAB_PROPERTIES RID_STR_TBL_START + 13 @@ -86,6 +86,7 @@ #define STR_CHANGE_COLUMN_ATTRIBUTE RID_STR_TBL_START + 52 #define STR_TABLEDESIGN_SAVE_ERROR RID_STR_TBL_START + 53 #define STR_TABLEDESIGN_COULD_NOT_DROP_COL RID_STR_TBL_START + 54 +#define STR_COLUMN_DESCRIPTION RID_STR_TBL_START + 55 // please adjust checking before insert new strings diff --git a/dbaccess/source/ui/inc/indexfieldscontrol.hxx b/dbaccess/source/ui/inc/indexfieldscontrol.hxx index 82e944e17..93fddf107 100644 --- a/dbaccess/source/ui/inc/indexfieldscontrol.hxx +++ b/dbaccess/source/ui/inc/indexfieldscontrol.hxx @@ -67,9 +67,10 @@ namespace dbaui String m_sDescendingText; sal_Int32 m_nMaxColumnsInIndex; + sal_Bool m_bAddIndexAppendix; public: - IndexFieldsControl( Window* _pParent, const ResId& _rId ,sal_Int32 _nMaxColumnsInIndex); + IndexFieldsControl( Window* _pParent, const ResId& _rId ,sal_Int32 _nMaxColumnsInIndex,sal_Bool _bAddIndexAppendix); ~IndexFieldsControl(); void Init(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rAvailableFields); diff --git a/dbaccess/source/ui/inc/unodatbr.hxx b/dbaccess/source/ui/inc/unodatbr.hxx index fa50bd40a..0fb37b65d 100644 --- a/dbaccess/source/ui/inc/unodatbr.hxx +++ b/dbaccess/source/ui/inc/unodatbr.hxx @@ -157,6 +157,7 @@ namespace dbaui OTableCopyHelper m_aTableCopyHelper; ::rtl::OUString m_sQueryCommand; // the command of the query currently loaded (if any) + ::rtl::OUString m_sToBeLoaded; // contains the element name which should be loaded if any DBTreeView* m_pTreeView; Splitter* m_pSplitter; diff --git a/dbaccess/source/ui/misc/TableCopyHelper.cxx b/dbaccess/source/ui/misc/TableCopyHelper.cxx index ff8c97d75..6508aaf91 100644 --- a/dbaccess/source/ui/misc/TableCopyHelper.cxx +++ b/dbaccess/source/ui/misc/TableCopyHelper.cxx @@ -160,21 +160,15 @@ using namespace ::com::sun::star::ucb; OTableCopyHelper::OTableCopyHelper(OGenericUnoController* _pControler) :m_pController(_pControler) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::OTableCopyHelper" ); } // ----------------------------------------------------------------------------- -void OTableCopyHelper::insertTable(sal_Int32 _nCommandType - ,const Reference<XConnection>& _xSrcConnection - ,const Sequence< Any >& _aSelection - ,sal_Bool _bBookmarkSelection - ,const ::rtl::OUString& _sCommand - ,const ::rtl::OUString& _sSrcDataSourceName - ,const ::rtl::OUString& _sDestDataSourceName - ,const Reference<XConnection>& _xDestConnection) +void OTableCopyHelper::insertTable( const ::rtl::OUString& i_rSourceDataSource, const Reference<XConnection>& i_rSourceConnection, + const ::rtl::OUString& i_rCommand, const sal_Int32 i_nCommandType, + const Reference< XResultSet >& i_rSourceRows, const Sequence< Any >& i_rSelection, const sal_Bool i_bBookmarkSelection, + const ::rtl::OUString& i_rDestDataSource, const Reference<XConnection>& i_rDestConnection) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::insertTable" ); - if ( CommandType::QUERY != _nCommandType && CommandType::TABLE != _nCommandType ) + if ( CommandType::QUERY != i_nCommandType && CommandType::TABLE != i_nCommandType ) { DBG_ERROR( "OTableCopyHelper::insertTable: invalid call (no supported format found)!" ); return; @@ -182,11 +176,11 @@ void OTableCopyHelper::insertTable(sal_Int32 _nCommandType try { - Reference<XConnection> xSrcConnection( _xSrcConnection ); - if ( _sSrcDataSourceName == _sDestDataSourceName ) - xSrcConnection = _xDestConnection; + Reference<XConnection> xSrcConnection( i_rSourceConnection ); + if ( i_rSourceDataSource == i_rDestDataSource ) + xSrcConnection = i_rDestConnection; - if ( !xSrcConnection.is() || !_xDestConnection.is() ) + if ( !xSrcConnection.is() || !i_rDestConnection.is() ) { OSL_ENSURE( false, "OTableCopyHelper::insertTable: no connection/s!" ); return; @@ -197,14 +191,15 @@ void OTableCopyHelper::insertTable(sal_Int32 _nCommandType Reference< XDataAccessDescriptorFactory > xFactory( DataAccessDescriptorFactory::get( aContext.getUNOContext() ) ); Reference< XPropertySet > xSource( xFactory->createDataAccessDescriptor(), UNO_SET_THROW ); - xSource->setPropertyValue( PROPERTY_COMMAND_TYPE, makeAny( _nCommandType ) ); - xSource->setPropertyValue( PROPERTY_COMMAND, makeAny( _sCommand ) ); + xSource->setPropertyValue( PROPERTY_COMMAND_TYPE, makeAny( i_nCommandType ) ); + xSource->setPropertyValue( PROPERTY_COMMAND, makeAny( i_rCommand ) ); xSource->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( xSrcConnection ) ); - xSource->setPropertyValue( PROPERTY_SELECTION, makeAny( _aSelection ) ); - xSource->setPropertyValue( PROPERTY_BOOKMARK_SELECTION, makeAny( _bBookmarkSelection ) ); + xSource->setPropertyValue( PROPERTY_RESULT_SET, makeAny( i_rSourceRows ) ); + xSource->setPropertyValue( PROPERTY_SELECTION, makeAny( i_rSelection ) ); + xSource->setPropertyValue( PROPERTY_BOOKMARK_SELECTION, makeAny( i_bBookmarkSelection ) ); Reference< XPropertySet > xDest( xFactory->createDataAccessDescriptor(), UNO_SET_THROW ); - xDest->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _xDestConnection ) ); + xDest->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( i_rDestConnection ) ); Reference< XCopyTableWizard > xWizard( CopyTableWizard::create( aContext.getUNOContext(), xSource, xDest ), UNO_SET_THROW ); @@ -227,72 +222,62 @@ void OTableCopyHelper::insertTable(sal_Int32 _nCommandType } // ----------------------------------------------------------------------------- -void OTableCopyHelper::pasteTable( const ::svx::ODataAccessDescriptor& _rPasteData, const ::rtl::OUString& _sDestDataSourceName, - const SharedConnection& _xDestConnection ) +void OTableCopyHelper::pasteTable( const ::svx::ODataAccessDescriptor& _rPasteData, const ::rtl::OUString& i_rDestDataSourceName, + const SharedConnection& i_rDestConnection ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::pasteTable" ); - Reference<XConnection> xSrcConnection; - ::rtl::OUString sCommand, - sSrcDataSourceName = _rPasteData.getDataSource(); + ::rtl::OUString sSrcDataSourceName = _rPasteData.getDataSource(); + + ::rtl::OUString sCommand; + _rPasteData[ daCommand ] >>= sCommand; - _rPasteData[daCommand] >>= sCommand; + Reference<XConnection> xSrcConnection; if ( _rPasteData.has(daConnection) ) - _rPasteData[daConnection] >>= xSrcConnection; -#if OSL_DEBUG_LEVEL > 0 + { + OSL_VERIFY( _rPasteData[daConnection] >>= xSrcConnection ); + } + + Reference< XResultSet > xResultSet; if ( _rPasteData.has(daCursor) ) { - Reference< XResultSet > xSrcRs; - _rPasteData[daCursor] >>= xSrcRs; - OSL_ENSURE( !xSrcRs.is(), "OTableCopyHelper::pasteTable: source result set not supported anymore!" ); - // There was a time where we supported passing a result set as shortcut to the source - // object. That is, we do not need to create an own result set we already have one. - // Since we UNOized the Copy Table Wizard (#i81658#), we removed this support, since it - // contradicted the semantics of DataAccessDescriptor.ResultSet. - // - // This shouldn't be a problem, since there seems to be no client which actually - // passed a result set here. - // However, if there still is, we probably need to introduce an (undocumented?) property - // at the DataAccessDescriptor, which takes this "source result set". + OSL_VERIFY( _rPasteData[ daCursor ] >>= xResultSet ); } - if ( _rPasteData.has( daSelection ) || _rPasteData.has( daBookmarkSelection ) ) + Sequence< Any > aSelection; + if ( _rPasteData.has( daSelection ) ) { - OSL_ENSURE( false, "OTableCopyHelper::pasteTable: bookmark/selection not supported anymore!" ); - // similar notes here: Selection and BookmarkSelection are not supported in the UNOized - // copy table wizard anymore (it doesn't make sense without support for a source result set), - // and there seem to be no clients which actually use it. So, instead of implementing an - // unused case, we dropped this here. + OSL_VERIFY( _rPasteData[ daSelection ] >>= aSelection ); + OSL_ENSURE( _rPasteData.has( daBookmarkSelection ), "OTableCopyHelper::pasteTable: you should specify BookmarkSelection, too, to be on the safe side!" ); } -#endif - // paste into the tables + + sal_Bool bBookmarkSelection( sal_True ); + if ( _rPasteData.has( daBookmarkSelection ) ) + { + OSL_VERIFY( _rPasteData[ daBookmarkSelection ] >>= bBookmarkSelection ); + } + OSL_ENSURE( bBookmarkSelection, "OTableCopyHelper::pasteTable: working with selection-indicies (instead of bookmarks) is error-prone, and thus deprecated!" ); + sal_Int32 nCommandType = CommandType::COMMAND; if ( _rPasteData.has(daCommandType) ) _rPasteData[daCommandType] >>= nCommandType; - insertTable( nCommandType - ,xSrcConnection - ,Sequence< Any >() - ,sal_False - ,sCommand - ,sSrcDataSourceName - ,_sDestDataSourceName - ,_xDestConnection); + insertTable( sSrcDataSourceName, xSrcConnection, sCommand, nCommandType, + xResultSet, aSelection, bBookmarkSelection, + i_rDestDataSourceName, i_rDestConnection ); } // ----------------------------------------------------------------------------- void OTableCopyHelper::pasteTable( SotFormatStringId _nFormatId ,const TransferableDataHelper& _rTransData - ,const ::rtl::OUString& _sDestDataSourceName + ,const ::rtl::OUString& i_rDestDataSource ,const SharedConnection& _xConnection) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::pasteTable" ); if ( _nFormatId == SOT_FORMATSTR_ID_DBACCESS_TABLE || _nFormatId == SOT_FORMATSTR_ID_DBACCESS_QUERY ) { if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(_rTransData.GetDataFlavorExVector()) ) { ::svx::ODataAccessDescriptor aPasteData = ODataAccessObjectTransferable::extractObjectDescriptor(_rTransData); - pasteTable( aPasteData,_sDestDataSourceName,_xConnection); + pasteTable( aPasteData,i_rDestDataSource,_xConnection); } } else if ( _rTransData.HasFormat(_nFormatId) ) @@ -326,22 +311,20 @@ void OTableCopyHelper::pasteTable( SotFormatStringId _nFormatId // ----------------------------------------------------------------------------- void OTableCopyHelper::pasteTable( const TransferableDataHelper& _rTransData - ,const ::rtl::OUString& _sDestDataSourceName + ,const ::rtl::OUString& i_rDestDataSource ,const SharedConnection& _xConnection) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::pasteTable" ); if ( _rTransData.HasFormat(SOT_FORMATSTR_ID_DBACCESS_TABLE) || _rTransData.HasFormat(SOT_FORMATSTR_ID_DBACCESS_QUERY) ) - pasteTable( SOT_FORMATSTR_ID_DBACCESS_TABLE,_rTransData,_sDestDataSourceName,_xConnection); + pasteTable( SOT_FORMATSTR_ID_DBACCESS_TABLE,_rTransData,i_rDestDataSource,_xConnection); else if ( _rTransData.HasFormat(SOT_FORMATSTR_ID_HTML) ) - pasteTable( SOT_FORMATSTR_ID_HTML,_rTransData,_sDestDataSourceName,_xConnection); + pasteTable( SOT_FORMATSTR_ID_HTML,_rTransData,i_rDestDataSource,_xConnection); else if ( _rTransData.HasFormat(SOT_FORMAT_RTF) ) - pasteTable( SOT_FORMAT_RTF,_rTransData,_sDestDataSourceName,_xConnection); + pasteTable( SOT_FORMAT_RTF,_rTransData,i_rDestDataSource,_xConnection); } // ----------------------------------------------------------------------------- sal_Bool OTableCopyHelper::copyTagTable(OTableCopyHelper::DropDescriptor& _rDesc, sal_Bool _bCheck,const SharedConnection& _xConnection) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::copyTagTable" ); Reference<XEventListener> xEvt; ODatabaseImportExport* pImport = NULL; if ( _rDesc.bHtml ) @@ -364,7 +347,6 @@ sal_Bool OTableCopyHelper::copyTagTable(OTableCopyHelper::DropDescriptor& _rDesc // ----------------------------------------------------------------------------- sal_Bool OTableCopyHelper::isTableFormat(const TransferableDataHelper& _rClipboard) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::isTableFormat" ); sal_Bool bTableFormat = _rClipboard.HasFormat(SOT_FORMATSTR_ID_DBACCESS_TABLE) || _rClipboard.HasFormat(SOT_FORMATSTR_ID_DBACCESS_QUERY) || _rClipboard.HasFormat(SOT_FORMAT_RTF) @@ -377,7 +359,6 @@ sal_Bool OTableCopyHelper::copyTagTable(const TransferableDataHelper& _aDroppedD ,DropDescriptor& _rAsyncDrop ,const SharedConnection& _xConnection) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::copyTagTable" ); sal_Bool bRet = sal_False; sal_Bool bHtml = _aDroppedData.HasFormat(SOT_FORMATSTR_ID_HTML); if ( bHtml || _aDroppedData.HasFormat(SOT_FORMAT_RTF) ) @@ -410,10 +391,9 @@ sal_Bool OTableCopyHelper::copyTagTable(const TransferableDataHelper& _aDroppedD } // ----------------------------------------------------------------------------- void OTableCopyHelper::asyncCopyTagTable( DropDescriptor& _rDesc - ,const ::rtl::OUString& _sDestDataSourceName + ,const ::rtl::OUString& i_rDestDataSource ,const SharedConnection& _xConnection) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "OTableCopyHelper::asyncCopyTagTable" ); if ( _rDesc.aHtmlRtfStorage.Is() ) { copyTagTable(_rDesc,sal_False,_xConnection); @@ -424,7 +404,7 @@ void OTableCopyHelper::asyncCopyTagTable( DropDescriptor& _rDesc ::utl::UCBContentHelper::Kill(aURL.GetMainURL(INetURLObject::NO_DECODE)); } else if ( !_rDesc.bError ) - pasteTable(_rDesc.aDroppedData,_sDestDataSourceName,_xConnection); + pasteTable(_rDesc.aDroppedData,i_rDestDataSource,_xConnection); else m_pController->showError(SQLException(String(ModuleRes(STR_NO_TABLE_FORMAT_INSIDE)),*m_pController,::rtl::OUString::createFromAscii("S1000") ,0,Any())); } diff --git a/dbaccess/source/ui/misc/TokenWriter.cxx b/dbaccess/source/ui/misc/TokenWriter.cxx index 73288f1a2..b97321980 100644 --- a/dbaccess/source/ui/misc/TokenWriter.cxx +++ b/dbaccess/source/ui/misc/TokenWriter.cxx @@ -100,7 +100,8 @@ ODatabaseImportExport::ODatabaseImportExport(const ::svx::ODataAccessDescriptor& const Reference< XMultiServiceFactory >& _rM, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxNumberF, const String& rExchange) - :m_xFormatter(_rxNumberF) + :m_bBookmarkSelection( NULL ) + ,m_xFormatter(_rxNumberF) ,m_xFactory(_rM) ,m_nCommandType(CommandType::TABLE) ,m_bNeedToReInitialize(sal_False) @@ -130,7 +131,8 @@ ODatabaseImportExport::ODatabaseImportExport(const ::svx::ODataAccessDescriptor& // import data ODatabaseImportExport::ODatabaseImportExport( const ::dbtools::SharedConnection& _rxConnection, const Reference< XNumberFormatter >& _rxNumberF, const Reference< XMultiServiceFactory >& _rM ) - :m_xConnection(_rxConnection) + :m_bBookmarkSelection( NULL ) + ,m_xConnection(_rxConnection) ,m_xFormatter(_rxNumberF) ,m_xFactory(_rM) ,m_nCommandType(::com::sun::star::sdb::CommandType::TABLE) @@ -184,6 +186,7 @@ void ODatabaseImportExport::dispose() m_xResultSetMetaData.clear(); m_xResultSet.clear(); m_xRow.clear(); + m_xRowLocate.clear(); m_xFormatter.clear(); } // ----------------------------------------------------------------------------- @@ -228,20 +231,37 @@ void ODatabaseImportExport::impl_initFromDescriptor( const ODataAccessDescriptor if (xComponent.is() && xEvt.is()) xComponent->addEventListener(xEvt); } - if(_aDataDescriptor.has(daSelection)) - _aDataDescriptor[daSelection] >>= m_aSelection; - sal_Bool bBookmarkSelection = sal_True; // the default if not present + if ( _aDataDescriptor.has( daSelection ) ) + _aDataDescriptor[ daSelection ] >>= m_aSelection; + if ( _aDataDescriptor.has( daBookmarkSelection ) ) + _aDataDescriptor[ daBookmarkSelection ] >>= m_bBookmarkSelection; + + if ( _aDataDescriptor.has( daCursor ) ) { - _aDataDescriptor[ daBookmarkSelection ] >>= bBookmarkSelection; - DBG_ASSERT( !bBookmarkSelection, "ODatabaseImportExport::ODatabaseImportExport: bookmarked selection not yet supported!" ); + _aDataDescriptor[ daCursor ] >>= m_xResultSet; + m_xRowLocate.set( m_xResultSet, UNO_QUERY ); } + if ( m_aSelection.getLength() != 0 ) + { + if ( !m_xResultSet.is() ) + { + OSL_ENSURE( false, "ODatabaseImportExport::impl_initFromDescriptor: selection without result set is nonsense!" ); + m_aSelection.realloc( 0 ); + } + } - if(_aDataDescriptor.has(daCursor)) - _aDataDescriptor[daCursor] >>= m_xResultSet; - } // if ( !_bPlusDefaultInit ) + if ( m_aSelection.getLength() != 0 ) + { + if ( m_bBookmarkSelection && !m_xRowLocate.is() ) + { + OSL_ENSURE( false, "ODatabaseImportExport::impl_initFromDescriptor: no XRowLocate -> no bookmars!" ); + m_aSelection.realloc( 0 ); + } + } + } else initialize(); @@ -311,19 +331,14 @@ void ODatabaseImportExport::initialize() // the result set may be already set with the datadescriptor if ( !m_xResultSet.is() ) { - m_xResultSet.set(m_xFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.sdb.RowSet")),UNO_QUERY); - Reference<XPropertySet > xProp(m_xResultSet,UNO_QUERY); - if(xProp.is()) - { - xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( m_xConnection.getTyped() ) ); - xProp->setPropertyValue(PROPERTY_COMMAND_TYPE,makeAny(m_nCommandType)); - xProp->setPropertyValue(PROPERTY_COMMAND,makeAny(m_sName)); - Reference<XRowSet> xRowSet(xProp,UNO_QUERY); - xRowSet->execute(); - } - else - OSL_ENSURE(sal_False, "ODatabaseImportExport::initialize: could not instantiate a rowset!"); - } // if ( !m_xResultSet.is() ) + m_xResultSet.set( m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.sdb.RowSet" ) ), UNO_QUERY ); + Reference< XPropertySet > xProp( m_xResultSet, UNO_QUERY_THROW ); + xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( m_xConnection.getTyped() ) ); + xProp->setPropertyValue( PROPERTY_COMMAND_TYPE, makeAny( m_nCommandType ) ); + xProp->setPropertyValue( PROPERTY_COMMAND, makeAny( m_sName ) ); + Reference< XRowSet > xRowSet( xProp, UNO_QUERY ); + xRowSet->execute(); + } impl_initializeRowMember_throw(); } catch(Exception& ) @@ -372,7 +387,8 @@ void ODatabaseImportExport::impl_initializeRowMember_throw() RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseImportExport::impl_initializeRowMember_throw" ); if ( !m_xRow.is() && m_xResultSet.is() ) { - m_xRow.set(m_xResultSet,UNO_QUERY); + m_xRow.set( m_xResultSet, UNO_QUERY ); + m_xRowLocate.set( m_xResultSet, UNO_QUERY ); m_xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(m_xRow,UNO_QUERY)->getMetaData(); Reference<XColumnsSupplier> xSup(m_xResultSet,UNO_QUERY_THROW); m_xRowSetColumns.set(xSup->getColumns(),UNO_QUERY_THROW); @@ -567,22 +583,29 @@ BOOL ORTFImportExport::Write() Reference< XRowSet > xRowSet(m_xRow,UNO_QUERY); sal_Int32 k=1; sal_Int32 kk=0; - if(m_aSelection.getLength()) + if ( m_aSelection.getLength() ) { const Any* pSelIter = m_aSelection.getConstArray(); const Any* pEnd = pSelIter + m_aSelection.getLength(); + sal_Bool bContinue = sal_True; - for(;pSelIter != pEnd && bContinue;++pSelIter) + for( ; pSelIter != pEnd && bContinue; ++pSelIter ) { - sal_Int32 nPos = -1; - *pSelIter >>= nPos; - OSL_ENSURE(nPos != -1,"Invalid posiotion!"); - bContinue = (m_xResultSet->absolute(nPos)); - if ( bContinue ) - appendRow(pHorzChar,nCount,k,kk); + if ( m_bBookmarkSelection ) + { + bContinue = m_xRowLocate->moveToBookmark( *pSelIter ); + } + else + { + sal_Int32 nPos = -1; + OSL_VERIFY( *pSelIter >>= nPos ); + bContinue = ( m_xResultSet->absolute( nPos ) ); + } + if ( bContinue ) + appendRow( pHorzChar, nCount, k, kk ); } - } // if(m_aSelection.getLength()) + } else { m_xResultSet->beforeFirst(); // set back before the first row diff --git a/dbaccess/source/ui/misc/UITools.cxx b/dbaccess/source/ui/misc/UITools.cxx index 8a6e16e28..d1db9ec78 100644 --- a/dbaccess/source/ui/misc/UITools.cxx +++ b/dbaccess/source/ui/misc/UITools.cxx @@ -889,6 +889,7 @@ void setColumnProperties(const Reference<XPropertySet>& _rxColumn,const OFieldDe _rxColumn->setPropertyValue(PROPERTY_SCALE,makeAny(_pFieldDesc->GetScale())); _rxColumn->setPropertyValue(PROPERTY_ISNULLABLE, makeAny(_pFieldDesc->GetIsNullable())); _rxColumn->setPropertyValue(PROPERTY_ISAUTOINCREMENT,::cppu::bool2any(_pFieldDesc->IsAutoIncrement())); + _rxColumn->setPropertyValue(PROPERTY_DESCRIPTION,makeAny(_pFieldDesc->GetDescription())); if ( _rxColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISCURRENCY) && _pFieldDesc->IsCurrency() ) _rxColumn->setPropertyValue(PROPERTY_ISCURRENCY,::cppu::bool2any(_pFieldDesc->IsCurrency())); // set autoincrement value when available diff --git a/dbaccess/source/ui/misc/WCopyTable.cxx b/dbaccess/source/ui/misc/WCopyTable.cxx index fd20d5f0f..d59b5010f 100644 --- a/dbaccess/source/ui/misc/WCopyTable.cxx +++ b/dbaccess/source/ui/misc/WCopyTable.cxx @@ -230,22 +230,10 @@ Sequence< ::rtl::OUString > ObjectCopySource::getColumnNames() const //------------------------------------------------------------------------ Sequence< ::rtl::OUString > ObjectCopySource::getPrimaryKeyColumnNames() const { - Reference<XKeysSupplier> xSup(m_xObject,UNO_QUERY); - Reference< XIndexAccess> xKeys; - if(xSup.is() ) - xKeys = xSup->getKeys(); - - ::std::vector< Reference< XNameAccess > > aPrimaryKeyColumns( ::dbaui::getKeyColumns( xKeys, KeyType::PRIMARY ) ); - OSL_ENSURE( ( aPrimaryKeyColumns.size() == 1 ) || aPrimaryKeyColumns.empty(), - "ObjectCopySource::getPrimaryKeyColumnNames: more than one primary key?!" ); - - Reference< XNameAccess > xKeyCols; - if ( !aPrimaryKeyColumns.empty() ) - xKeyCols = aPrimaryKeyColumns[0]; - + const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(m_xObject); Sequence< ::rtl::OUString > aKeyColNames; - if ( xKeyCols.is() ) - aKeyColNames = xKeyCols->getElementNames(); + if ( xPrimaryKeyColumns.is() ) + aKeyColNames = xPrimaryKeyColumns->getElementNames(); return aKeyColNames; } @@ -368,7 +356,7 @@ void NamedTableCopySource::impl_ensureColumnInfo_throw() OFieldDescription aDesc; aDesc.SetName( xStatementMeta->getColumnName( i ) ); - aDesc.SetDescription( xStatementMeta->getColumnLabel( i ) ); + aDesc.SetHelpText( xStatementMeta->getColumnLabel( i ) ); aDesc.SetTypeValue( xStatementMeta->getColumnType( i ) ); aDesc.SetTypeName( xStatementMeta->getColumnTypeName( i ) ); aDesc.SetPrecision( xStatementMeta->getPrecision( i ) ); diff --git a/dbaccess/source/ui/querydesign/QueryDesignView.cxx b/dbaccess/source/ui/querydesign/QueryDesignView.cxx index fcc65664a..42ec8d4a4 100644 --- a/dbaccess/source/ui/querydesign/QueryDesignView.cxx +++ b/dbaccess/source/ui/querydesign/QueryDesignView.cxx @@ -607,14 +607,16 @@ namespace //------------------------------------------------------------------------------ SqlParseError InsertJoinConnection( const OQueryDesignView* _pView, const ::connectivity::OSQLParseNode *pNode, - const EJoinType& _eJoinType) + const EJoinType& _eJoinType, + const ::connectivity::OSQLParseNode *pLeftTable, + const ::connectivity::OSQLParseNode *pRightTable) { SqlParseError eErrorCode = eOk; if (pNode->count() == 3 && // Ausdruck is geklammert SQL_ISPUNCTUATION(pNode->getChild(0),"(") && SQL_ISPUNCTUATION(pNode->getChild(2),")")) { - eErrorCode = InsertJoinConnection(_pView,pNode->getChild(1), _eJoinType); + eErrorCode = InsertJoinConnection(_pView,pNode->getChild(1), _eJoinType,pLeftTable,pRightTable); } else if (SQL_ISRULEOR2(pNode,search_condition,boolean_term) && // AND/OR-Verknuepfung: pNode->count() == 3) @@ -622,8 +624,8 @@ namespace // nur AND Verknüpfung zulassen if (!SQL_ISTOKEN(pNode->getChild(1),AND)) eErrorCode = eIllegalJoinCondition; - else if ( eOk == (eErrorCode = InsertJoinConnection(_pView,pNode->getChild(0), _eJoinType)) ) - eErrorCode = InsertJoinConnection(_pView,pNode->getChild(2), _eJoinType); + else if ( eOk == (eErrorCode = InsertJoinConnection(_pView,pNode->getChild(0), _eJoinType,pLeftTable,pRightTable)) ) + eErrorCode = InsertJoinConnection(_pView,pNode->getChild(2), _eJoinType,pLeftTable,pRightTable); } else if (SQL_ISRULE(pNode,comparison_predicate)) { @@ -644,7 +646,17 @@ namespace eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(2),aDragRight))) return eErrorCode; - insertConnection(_pView,_eJoinType,aDragLeft,aDragRight); + if ( pLeftTable ) + { + OQueryTableWindow* pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pLeftTable->getByRule(OSQLParseNode::table_ref) )); + // OQueryTableWindow* pRightWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pRightTable->getByRule(OSQLParseNode::table_ref) )); + if ( pLeftWindow == aDragLeft->GetTabWindow() ) + insertConnection(_pView,_eJoinType,aDragLeft,aDragRight); + else + insertConnection(_pView,_eJoinType,aDragRight,aDragLeft); + } + else + insertConnection(_pView,_eJoinType,aDragLeft,aDragRight); } else eErrorCode = eIllegalJoin; @@ -654,7 +666,7 @@ namespace sal_Bool GetInnerJoinCriteria( const OQueryDesignView* _pView, const ::connectivity::OSQLParseNode *pCondition) { - return InsertJoinConnection(_pView,pCondition, INNER_JOIN) != eOk; + return InsertJoinConnection(_pView,pCondition, INNER_JOIN,NULL,NULL) != eOk; } //------------------------------------------------------------------------------ ::rtl::OUString GenerateSelectList( const OQueryDesignView* _pView, @@ -1096,53 +1108,76 @@ namespace { ::std::vector<OTableConnection*>::const_iterator aIter = pConnList->begin(); ::std::vector<OTableConnection*>::const_iterator aEnd = pConnList->end(); + ::std::map<OTableWindow*,sal_Int32> aConnectionCount; for(;aIter != aEnd;++aIter) + { static_cast<OQueryTableConnection*>(*aIter)->SetVisited(sal_False); + if ( aConnectionCount.find((*aIter)->GetSourceWin()) == aConnectionCount.end() ) + aConnectionCount.insert(::std::map<OTableWindow*,sal_Int32>::value_type((*aIter)->GetSourceWin(),0)); + else + aConnectionCount[(*aIter)->GetSourceWin()]++; + if ( aConnectionCount.find((*aIter)->GetDestWin()) == aConnectionCount.end() ) + aConnectionCount.insert(::std::map<OTableWindow*,sal_Int32>::value_type((*aIter)->GetDestWin(),0)); + else + aConnectionCount[(*aIter)->GetDestWin()]++; + } + ::std::multimap<sal_Int32 , OTableWindow*> aMulti; + ::std::map<OTableWindow*,sal_Int32>::iterator aCountIter = aConnectionCount.begin(); + ::std::map<OTableWindow*,sal_Int32>::iterator aCountEnd = aConnectionCount.end(); + for(;aCountIter != aCountEnd;++aCountIter) + { + aMulti.insert(::std::multimap<sal_Int32 , OTableWindow*>::value_type(aCountIter->second,aCountIter->first)); + } - aIter = pConnList->begin(); const sal_Bool bUseEscape = ::dbtools::getBooleanDataSourceSetting( _xConnection, PROPERTY_OUTERJOINESCAPE ); - for(;aIter != aEnd;++aIter) + ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aRIter = aMulti.rbegin(); + ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aREnd = aMulti.rend(); + for(;aRIter != aREnd;++aRIter) { - OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter); - if(!pEntryConn->IsVisited()) + ::std::vector<OTableConnection*>::const_iterator aConIter = aRIter->second->getTableView()->getTableConnections(aRIter->second); + for(;aConIter != aEnd;++aConIter) { - ::rtl::OUString aJoin; - GetNextJoin(_xConnection,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin); - - if(aJoin.getLength()) + OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aConIter); + if(!pEntryConn->IsVisited() && pEntryConn->GetSourceWin() == aRIter->second ) { - // insert tables into table list to avoid double entries - OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()); - OQueryTableWindow* pEntryTabTo = static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()); - - ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom)); - if(aTableNames.find(sTabName) == aTableNames.end()) - aTableNames[sTabName] = sal_True; - sTabName = BuildTable(_xConnection,pEntryTabTo); - if(aTableNames.find(sTabName) == aTableNames.end()) - aTableNames[sTabName] = sal_True; - - ::rtl::OUString aStr; - switch(static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get())->GetJoinType()) + ::rtl::OUString aJoin; + GetNextJoin(_xConnection,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin); + + if(aJoin.getLength()) { - case LEFT_JOIN: - case RIGHT_JOIN: - case FULL_JOIN: - { - // create outer join - if ( bUseEscape ) - aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("{ OJ ")); + // insert tables into table list to avoid double entries + OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()); + OQueryTableWindow* pEntryTabTo = static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()); + + ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom)); + if(aTableNames.find(sTabName) == aTableNames.end()) + aTableNames[sTabName] = sal_True; + sTabName = BuildTable(_xConnection,pEntryTabTo); + if(aTableNames.find(sTabName) == aTableNames.end()) + aTableNames[sTabName] = sal_True; + + ::rtl::OUString aStr; + switch(static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get())->GetJoinType()) + { + case LEFT_JOIN: + case RIGHT_JOIN: + case FULL_JOIN: + { + // create outer join + if ( bUseEscape ) + aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("{ OJ ")); + aStr += aJoin; + if ( bUseEscape ) + aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" }")); + } + break; + default: aStr += aJoin; - if ( bUseEscape ) - aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" }")); - } - break; - default: - aStr += aJoin; - break; + break; + } + aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")); + aTableListStr += aStr; } - aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")); - aTableListStr += aStr; } } } @@ -1940,7 +1975,7 @@ namespace } if ( SQL_ISRULE(pNode->getChild(4),join_condition) ) { - if ( InsertJoinConnection(_pView,pNode->getChild(4)->getChild(1), eJoinType) != eOk ) + if ( InsertJoinConnection(_pView,pNode->getChild(4)->getChild(1), eJoinType,pNode->getChild(0),pRightTableRef) != eOk ) return sal_False; } } @@ -3128,6 +3163,7 @@ OSQLParseNode* OQueryDesignView::getPredicateTreeFromEntry(OTableFieldDescRef pE parse::OParseColumn* pColumn = new parse::OParseColumn( pEntry->GetField(), ::rtl::OUString(), ::rtl::OUString(), + ::rtl::OUString(), ColumnValue::NULLABLE_UNKNOWN, 0, 0, diff --git a/dbaccess/source/ui/querydesign/TableWindow.cxx b/dbaccess/source/ui/querydesign/TableWindow.cxx index 650b2164c..01890fd6f 100644 --- a/dbaccess/source/ui/querydesign/TableWindow.cxx +++ b/dbaccess/source/ui/querydesign/TableWindow.cxx @@ -59,8 +59,6 @@ #endif #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> -#include <com/sun/star/sdbcx/XKeysSupplier.hpp> -#include <com/sun/star/sdbcx/KeyType.hpp> #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/accessibility/AccessibleEventId.hpp> @@ -73,6 +71,7 @@ #include "UITools.hxx" #include "TableWindowAccess.hxx" #include "browserids.hxx" +#include <connectivity/dbtools.hxx> using namespace dbaui; @@ -221,30 +220,7 @@ BOOL OTableWindow::FillListBox() Reference<XNameAccess> xPKeyColumns; try { - // first we need the keys from the table - Reference< XIndexAccess> xKeyIndex = m_pData->getKeys(); - // search the one and only primary key - if ( xKeyIndex.is() ) - { - Reference<XColumnsSupplier> xColumnsSupplier; - for(sal_Int32 i=0;i< xKeyIndex->getCount();++i) - { - Reference<XPropertySet> xProp; - xKeyIndex->getByIndex(i) >>= xProp; - if ( xProp.is() ) - { - sal_Int32 nKeyType = 0; - xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; - if(KeyType::PRIMARY == nKeyType) - { - xColumnsSupplier.set(xProp,UNO_QUERY); - break; - } - } - } - if ( xColumnsSupplier.is() ) - xPKeyColumns = xColumnsSupplier->getColumns(); - } + xPKeyColumns = dbtools::getPrimaryKeyColumns_throw(m_pData->getTable()); } catch(Exception&) { diff --git a/dbaccess/source/ui/querydesign/querycontroller.cxx b/dbaccess/source/ui/querydesign/querycontroller.cxx index e3dd6541f..06a2eb5cb 100644 --- a/dbaccess/source/ui/querydesign/querycontroller.cxx +++ b/dbaccess/source/ui/querydesign/querycontroller.cxx @@ -1748,7 +1748,7 @@ void OQueryController::impl_reset( const bool i_bForceCurrentControllerSettings m_pSqlIterator->traverseAll(); if ( m_pSqlIterator->hasErrors() ) { - if ( !i_bForceCurrentControllerSettings && !editingView() ) + if ( !i_bForceCurrentControllerSettings && m_bGraphicalDesign && !editingView() ) { impl_showAutoSQLViewError( makeAny( m_pSqlIterator->getErrors() ) ); } diff --git a/dbaccess/source/ui/relationdesign/RTableConnectionData.cxx b/dbaccess/source/ui/relationdesign/RTableConnectionData.cxx index f574890a0..145568f25 100644 --- a/dbaccess/source/ui/relationdesign/RTableConnectionData.cxx +++ b/dbaccess/source/ui/relationdesign/RTableConnectionData.cxx @@ -42,6 +42,7 @@ #include "UITools.hxx" #include "moduledbu.hxx" #include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> using namespace dbaui; using namespace ::com::sun::star::sdbc; @@ -173,35 +174,29 @@ void ORelationTableConnectionData::SetCardinality() } // ----------------------------------------------------------------------------- -BOOL ORelationTableConnectionData::checkPrimaryKey(const Reference< XIndexAccess>& _xKeys,EConnectionSide _eEConnectionSide) const +BOOL ORelationTableConnectionData::checkPrimaryKey(const Reference< XPropertySet>& i_xTable,EConnectionSide _eEConnectionSide) const { // check if Table has the primary key column dependig on _eEConnectionSide USHORT nPrimKeysCount = 0, nValidLinesCount = 0; - ::std::vector<Reference<XNameAccess> > vKeyColumns = ::dbaui::getKeyColumns(_xKeys,KeyType::PRIMARY); - if ( vKeyColumns.size() == 1 ) + const Reference< XNameAccess> xKeyColumns = dbtools::getPrimaryKeyColumns_throw(i_xTable); + if ( xKeyColumns.is() ) { -// OSL_ENSURE(vKeyColumns.size()==1,"There can be only one primary key in a table!"); - Sequence< ::rtl::OUString> aKeyColumns; - Reference<XNameAccess> xKeyColumns = *vKeyColumns.begin(); - if ( xKeyColumns.is() ) - { - aKeyColumns = xKeyColumns->getElementNames(); - const ::rtl::OUString* pKeyIter = aKeyColumns.getConstArray(); - const ::rtl::OUString* pKeyEnd = pKeyIter + aKeyColumns.getLength(); + Sequence< ::rtl::OUString> aKeyColumns = xKeyColumns->getElementNames(); + const ::rtl::OUString* pKeyIter = aKeyColumns.getConstArray(); + const ::rtl::OUString* pKeyEnd = pKeyIter + aKeyColumns.getLength(); - for(;pKeyIter != pKeyEnd;++pKeyIter) + for(;pKeyIter != pKeyEnd;++pKeyIter) + { + OConnectionLineDataVec::const_iterator aIter = m_vConnLineData.begin(); + OConnectionLineDataVec::const_iterator aEnd = m_vConnLineData.end(); + for(;aIter != aEnd;++aIter) { - OConnectionLineDataVec::const_iterator aIter = m_vConnLineData.begin(); - OConnectionLineDataVec::const_iterator aEnd = m_vConnLineData.end(); - for(;aIter != aEnd;++aIter) + ++nValidLinesCount; + if ( (*aIter)->GetFieldName(_eEConnectionSide) == *pKeyIter ) { - ++nValidLinesCount; - if ( (*aIter)->GetFieldName(_eEConnectionSide) == *pKeyIter ) - { - ++nPrimKeysCount; - break; - } + ++nPrimKeysCount; + break; } } } diff --git a/dbaccess/source/ui/relationdesign/RelationTableView.cxx b/dbaccess/source/ui/relationdesign/RelationTableView.cxx index cddea3e7e..8e7e3feb6 100644 --- a/dbaccess/source/ui/relationdesign/RelationTableView.cxx +++ b/dbaccess/source/ui/relationdesign/RelationTableView.cxx @@ -225,9 +225,8 @@ void ORelationTableView::AddConnection(const OJoinExchangeData& jxdSource, const ::rtl::OUString sDestFieldName = jxdDest.pListBox->GetEntryText(jxdDest.pEntry); // die Anzahl der PKey-Felder in der Quelle - - ::std::vector< Reference< XNameAccess> > aPkeys = ::dbaui::getKeyColumns(pSourceWin->GetData()->getKeys(),KeyType::PRIMARY); - bool bAskUser = aPkeys.size() == 1 && Reference< XIndexAccess>(aPkeys[0],UNO_QUERY)->getCount() > 1; + const Reference< XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(pSourceWin->GetData()->getTable()); + bool bAskUser = xPrimaryKeyColumns.is() && Reference< XIndexAccess>(xPrimaryKeyColumns,UNO_QUERY)->getCount() > 1; pTabConnData->SetConnLine( 0, sSourceFieldName, sDestFieldName ); diff --git a/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx b/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx index 1b004d80f..77d7ccf43 100644 --- a/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx +++ b/dbaccess/source/ui/tabledesign/FieldDescriptions.cxx @@ -154,6 +154,12 @@ OFieldDescription::OFieldDescription(const Reference< XPropertySet >& xAffectedC SetName(::comphelper::getString(xAffectedCol->getPropertyValue(PROPERTY_NAME))); if(xPropSetInfo->hasPropertyByName(PROPERTY_DESCRIPTION)) SetDescription(::comphelper::getString(xAffectedCol->getPropertyValue(PROPERTY_DESCRIPTION))); + if(xPropSetInfo->hasPropertyByName(PROPERTY_HELPTEXT)) + { + ::rtl::OUString sHelpText; + xAffectedCol->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText; + SetHelpText(sHelpText); + } if(xPropSetInfo->hasPropertyByName(PROPERTY_DEFAULTVALUE)) SetDefaultValue( xAffectedCol->getPropertyValue(PROPERTY_DEFAULTVALUE) ); @@ -285,6 +291,21 @@ void OFieldDescription::SetName(const ::rtl::OUString& _rName) } } // ----------------------------------------------------------------------------- +void OFieldDescription::SetHelpText(const ::rtl::OUString& _sHelpText) +{ + try + { + if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_HELPTEXT) ) + m_xDest->setPropertyValue(PROPERTY_HELPTEXT,makeAny(_sHelpText)); + else + m_sHelpText = _sHelpText; + } + catch(const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} +// ----------------------------------------------------------------------------- void OFieldDescription::SetDescription(const ::rtl::OUString& _rDescription) { try @@ -501,6 +522,14 @@ void OFieldDescription::SetCurrency(sal_Bool _bIsCurrency) return m_sDescription; } // ----------------------------------------------------------------------------- +::rtl::OUString OFieldDescription::GetHelpText() const +{ + if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_HELPTEXT) ) + return ::comphelper::getString(m_xDest->getPropertyValue(PROPERTY_HELPTEXT)); + else + return m_sHelpText; +} +// ----------------------------------------------------------------------------- ::com::sun::star::uno::Any OFieldDescription::GetControlDefault() const { if ( m_xDest.is() && m_xDestInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT) ) @@ -654,8 +683,8 @@ void OFieldDescription::copyColumnSettingsTo(const Reference< XPropertySet >& _r _rxColumn->setPropertyValue(PROPERTY_FORMATKEY,makeAny(GetFormatKey())); if ( GetHorJustify() != SVX_HOR_JUSTIFY_STANDARD && xInfo->hasPropertyByName(PROPERTY_ALIGN) ) _rxColumn->setPropertyValue(PROPERTY_ALIGN,makeAny(dbaui::mapTextAllign(GetHorJustify()))); - if ( GetDescription().getLength() && xInfo->hasPropertyByName(PROPERTY_HELPTEXT) ) - _rxColumn->setPropertyValue(PROPERTY_HELPTEXT,makeAny(GetDescription())); + if ( GetHelpText().getLength() && xInfo->hasPropertyByName(PROPERTY_HELPTEXT) ) + _rxColumn->setPropertyValue(PROPERTY_HELPTEXT,makeAny(GetHelpText())); if ( GetControlDefault().hasValue() && xInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT) ) _rxColumn->setPropertyValue(PROPERTY_CONTROLDEFAULT,GetControlDefault()); diff --git a/dbaccess/source/ui/tabledesign/TEditControl.cxx b/dbaccess/source/ui/tabledesign/TEditControl.cxx index ec45164d5..9169bf643 100644 --- a/dbaccess/source/ui/tabledesign/TEditControl.cxx +++ b/dbaccess/source/ui/tabledesign/TEditControl.cxx @@ -105,6 +105,7 @@ #ifndef DBAUI_TABLEFIELDCONTROL_HXX #include "TableFieldControl.hxx" #endif +#include "dsntypes.hxx" using namespace ::dbaui; using namespace ::comphelper; @@ -199,13 +200,21 @@ void OTableEditorCtrl::Init() ////////////////////////////////////////////////////////////////////// // Spalten einfuegen String aColumnName( ModuleRes(STR_TAB_FIELD_COLUMN_NAME) ); - InsertDataColumn( 1, aColumnName, FIELDNAME_WIDTH ); + InsertDataColumn( FIELD_NAME, aColumnName, FIELDNAME_WIDTH ); aColumnName = String( ModuleRes(STR_TAB_FIELD_COLUMN_DATATYPE) ); - InsertDataColumn( 2, aColumnName, FIELDTYPE_WIDTH ); + InsertDataColumn( FIELD_TYPE, aColumnName, FIELDTYPE_WIDTH ); - aColumnName = String( ModuleRes(STR_TAB_FIELD_DESCR) ); - InsertDataColumn( 3, aColumnName, FIELDDESCR_WIDTH ); + ::dbaccess::ODsnTypeCollection aDsnTypes(GetView()->getController().getORB()); + sal_Bool bShowColumnDescription = aDsnTypes.supportsColumnDescription(::comphelper::getString(GetView()->getController().getDataSource()->getPropertyValue(PROPERTY_URL))); + aColumnName = String( ModuleRes(STR_TAB_HELP_TEXT) ); + InsertDataColumn( HELP_TEXT, aColumnName, bShowColumnDescription ? FIELDTYPE_WIDTH : FIELDDESCR_WIDTH ); + + if ( bShowColumnDescription ) + { + aColumnName = String( ModuleRes(STR_COLUMN_DESCRIPTION) ); + InsertDataColumn( COLUMN_DESCRIPTION, aColumnName, FIELDTYPE_WIDTH ); + } InitCellController(); @@ -229,6 +238,7 @@ OTableEditorCtrl::OTableEditorCtrl(Window* pWindow) :OTableRowView(pWindow) ,pNameCell(NULL) ,pTypeCell(NULL) + ,pHelpTextCell(NULL) ,pDescrCell(NULL) ,pDescrWin(NULL) ,nIndexEvent(0) @@ -342,12 +352,16 @@ void OTableEditorCtrl::InitCellController() pDescrCell = new Edit( &GetDataWindow(), WB_LEFT ); pDescrCell->SetMaxTextLen( MAX_DESCR_LEN ); + pHelpTextCell = new Edit( &GetDataWindow(), WB_LEFT ); + pHelpTextCell->SetMaxTextLen( MAX_DESCR_LEN ); + pNameCell->SetHelpId(HID_TABDESIGN_NAMECELL); pTypeCell->SetHelpId(HID_TABDESIGN_TYPECELL); pDescrCell->SetHelpId(HID_TABDESIGN_COMMENTCELL); + pHelpTextCell->SetHelpId(HID_TABDESIGN_HELPTEXT); Size aHeight; - const Control* pControls[] = { pTypeCell,pDescrCell,pNameCell}; + const Control* pControls[] = { pTypeCell,pDescrCell,pNameCell,pHelpTextCell}; for(sal_Size i= 0; i < sizeof(pControls)/sizeof(pControls[0]);++i) { const Size aTemp( pControls[i]->GetOptimalSize(WINDOWSIZE_PREFERRED) ); @@ -365,6 +379,7 @@ void OTableEditorCtrl::ClearModified() DBG_CHKTHIS(OTableEditorCtrl,NULL); pNameCell->ClearModifyFlag(); pDescrCell->ClearModifyFlag(); + pHelpTextCell->ClearModifyFlag(); pTypeCell->SaveValue(); } @@ -396,6 +411,7 @@ OTableEditorCtrl::~OTableEditorCtrl() delete pNameCell; delete pTypeCell; delete pDescrCell; + delete pHelpTextCell; } //------------------------------------------------------------------------------ @@ -471,10 +487,16 @@ CellController* OTableEditorCtrl::GetController(long nRow, sal_uInt16 nColumnId) if (pActFieldDescr && (pActFieldDescr->GetName().getLength() != 0)) return new ListBoxCellController( pTypeCell ); else return NULL; - case FIELD_DESCR: + case HELP_TEXT: + if (pActFieldDescr && (pActFieldDescr->GetName().getLength() != 0)) + return new EditCellController( pHelpTextCell ); + else + return NULL; + case COLUMN_DESCRIPTION: if (pActFieldDescr && (pActFieldDescr->GetName().getLength() != 0)) return new EditCellController( pDescrCell ); - else return NULL; + else + return NULL; default: return NULL; } @@ -516,7 +538,13 @@ void OTableEditorCtrl::InitController(CellControllerRef&, long nRow, sal_uInt16 } break; - case FIELD_DESCR: + case HELP_TEXT: + if( pActFieldDescr ) + aInitString = pActFieldDescr->GetHelpText(); + pHelpTextCell->SetText( aInitString ); + pHelpTextCell->SaveValue(); + break; + case COLUMN_DESCRIPTION: if( pActFieldDescr ) aInitString = pActFieldDescr->GetDescription(); pDescrCell->SetText( aInitString ); @@ -576,7 +604,8 @@ void OTableEditorCtrl::DisplayData(long nRow, sal_Bool bGrabFocus) CellControllerRef aTemp; InitController(aTemp, nRow, FIELD_NAME); InitController(aTemp, nRow, FIELD_TYPE); - InitController(aTemp, nRow, FIELD_DESCR); + InitController(aTemp, nRow, COLUMN_DESCRIPTION); + InitController(aTemp, nRow, HELP_TEXT); GoToRow(nRow); // das Description-Window aktualisieren @@ -601,7 +630,8 @@ void OTableEditorCtrl::CursorMoved() CellControllerRef aTemp; InitController(aTemp,m_nDataPos,FIELD_NAME); InitController(aTemp,m_nDataPos,FIELD_TYPE); - InitController(aTemp,m_nDataPos,FIELD_DESCR); + InitController(aTemp,m_nDataPos,COLUMN_DESCRIPTION); + InitController(aTemp,m_nDataPos,HELP_TEXT); } OTableRowView::CursorMoved(); @@ -675,7 +705,20 @@ sal_Bool OTableEditorCtrl::SaveData(long nRow, sal_uInt16 nColId) ////////////////////////////////////////////////////////////// // Speichern Inhalt DescrCell - case FIELD_DESCR: + case HELP_TEXT: + { + ////////////////////////////////////////////////////////////// + // Wenn aktuelle Feldbeschreibung NULL, Default setzen + if( !pActFieldDescr ) + { + pHelpTextCell->SetText(String()); + pHelpTextCell->ClearModifyFlag(); + } + else + pActFieldDescr->SetHelpText( pHelpTextCell->GetText() ); + break; + } + case COLUMN_DESCRIPTION: { ////////////////////////////////////////////////////////////// // Wenn aktuelle Feldbeschreibung NULL, Default setzen @@ -811,7 +854,8 @@ void OTableEditorCtrl::CellModified( long nRow, sal_uInt16 nColId ) { case FIELD_NAME: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_NAME ) ); break; case FIELD_TYPE: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_TYPE ) ); break; - case FIELD_DESCR: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_DESCRIPTION ) ); break; + case HELP_TEXT: + case COLUMN_DESCRIPTION: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_DESCRIPTION ) ); break; default: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_ATTRIBUTE ) ); break; } @@ -1176,7 +1220,7 @@ void OTableEditorCtrl::SetCellData( long nRow, sal_uInt16 nColId, const ::com::s OSL_ENSURE(sal_False, "OTableEditorCtrl::SetCellData: invalid column!"); break; - case FIELD_DESCR: + case COLUMN_DESCRIPTION: pFieldDescr->SetDescription( sValue = ::comphelper::getString(_rNewData) ); break; @@ -1265,9 +1309,12 @@ Any OTableEditorCtrl::GetCellData( long nRow, sal_uInt16 nColId ) sValue = pFieldDescr->getTypeInfo()->aUIName; break; - case FIELD_DESCR: + case COLUMN_DESCRIPTION: sValue = pFieldDescr->GetDescription(); break; + case HELP_TEXT: + sValue = pFieldDescr->GetHelpText(); + break; case FIELD_PROPERTY_DEFAULT: return pFieldDescr->GetControlDefault(); @@ -1347,16 +1394,24 @@ sal_Bool OTableEditorCtrl::IsCutAllowed( long nRow ) if(bIsCutAllowed) { - if(m_eChildFocus == DESCRIPTION) - bIsCutAllowed = pDescrCell->GetSelected().Len() != 0; - else if(m_eChildFocus == NAME) - bIsCutAllowed = pNameCell->GetSelected().Len() != 0; - else if(m_eChildFocus == ROW) - // only rows are selected for cutting so we look if all rows are valid - // wwe don't waant to copy empty rows here - bIsCutAllowed = IsCopyAllowed(nRow); - else - bIsCutAllowed = sal_False; + switch(m_eChildFocus) + { + case DESCRIPTION: + bIsCutAllowed = pDescrCell->GetSelected().Len() != 0; + break; + case HELPTEXT: + bIsCutAllowed = pHelpTextCell->GetSelected().Len() != 0; + break; + case NAME: + bIsCutAllowed = pNameCell->GetSelected().Len() != 0; + break; + case ROW: + bIsCutAllowed = IsCopyAllowed(nRow); + break; + default: + bIsCutAllowed = sal_False; + break; + } } // Reference<XPropertySet> xTable = GetView()->getController().getTable(); @@ -1372,8 +1427,10 @@ sal_Bool OTableEditorCtrl::IsCopyAllowed( long /*nRow*/ ) { DBG_CHKTHIS(OTableEditorCtrl,NULL); sal_Bool bIsCopyAllowed = sal_False; - if(m_eChildFocus == DESCRIPTION) + if(m_eChildFocus == DESCRIPTION ) bIsCopyAllowed = pDescrCell->GetSelected().Len() != 0; + else if(HELPTEXT == m_eChildFocus ) + bIsCopyAllowed = pHelpTextCell->GetSelected().Len() != 0; else if(m_eChildFocus == NAME) bIsCopyAllowed = pNameCell->GetSelected().Len() != 0; else if(m_eChildFocus == ROW) @@ -1435,9 +1492,18 @@ void OTableEditorCtrl::cut() { if(GetView()->getController().isAlterAllowed()) { - SaveData(-1,FIELD_DESCR); + SaveData(-1,COLUMN_DESCRIPTION); pDescrCell->Cut(); - CellModified(-1,FIELD_DESCR); + CellModified(-1,COLUMN_DESCRIPTION); + } + } + else if(HELPTEXT == m_eChildFocus ) + { + if(GetView()->getController().isAlterAllowed()) + { + SaveData(-1,HELP_TEXT); + pHelpTextCell->Cut(); + CellModified(-1,HELP_TEXT); } } else if(m_eChildFocus == ROW) @@ -1455,7 +1521,9 @@ void OTableEditorCtrl::copy() OTableRowView::copy(); else if(m_eChildFocus == NAME) pNameCell->Copy(); - else if(m_eChildFocus == DESCRIPTION) + else if(HELPTEXT == m_eChildFocus ) + pHelpTextCell->Copy(); + else if(m_eChildFocus == DESCRIPTION ) pDescrCell->Copy(); } @@ -1477,6 +1545,14 @@ void OTableEditorCtrl::paste() CellModified(); } } + else if(HELPTEXT == m_eChildFocus ) + { + if(GetView()->getController().isAlterAllowed()) + { + pHelpTextCell->Paste(); + CellModified(); + } + } else if(m_eChildFocus == DESCRIPTION) { if(GetView()->getController().isAlterAllowed()) @@ -1493,16 +1569,6 @@ sal_Bool OTableEditorCtrl::IsDeleteAllowed( long /*nRow*/ ) DBG_CHKTHIS(OTableEditorCtrl,NULL); return GetSelectRowCount() != 0 && GetView()->getController().isDropAllowed(); -// Reference<XPropertySet> xTable = GetView()->getController().getTable(); -// if( !GetSelectRowCount() || (xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == ::rtl::OUString::createFromAscii("VIEW"))) -// return sal_False; -// -// // Wenn nur Felder hinzugefuegt werden duerfen, Delete nur auf neuen Feldern -// Reference<XConnection> xCon = GetView()->getController().getConnection(); -// Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : NULL; -// -// return !(xTable.is() && xTable->getPropertySetInfo()->getPropertyByName(PROPERTY_NAME).Attributes & PropertyAttribute::READONLY) || -// ( xMetaData.is() && xMetaData->supportsAlterTableWithAddColumn() && xMetaData->supportsAlterTableWithDropColumn()); } //------------------------------------------------------------------------------ @@ -1933,7 +1999,9 @@ long OTableEditorCtrl::PreNotify( NotifyEvent& rNEvt ) { if (rNEvt.GetType() == EVENT_GETFOCUS) { - if( pDescrCell && pDescrCell->HasChildPathFocus() ) + if( pHelpTextCell && pHelpTextCell->HasChildPathFocus() ) + m_eChildFocus = HELPTEXT; + else if( pDescrCell && pDescrCell->HasChildPathFocus() ) m_eChildFocus = DESCRIPTION; else if(pNameCell && pNameCell->HasChildPathFocus() ) m_eChildFocus = NAME; diff --git a/dbaccess/source/ui/tabledesign/TEditControl.hxx b/dbaccess/source/ui/tabledesign/TEditControl.hxx index 8b916d558..7d0fc5821 100644 --- a/dbaccess/source/ui/tabledesign/TEditControl.hxx +++ b/dbaccess/source/ui/tabledesign/TEditControl.hxx @@ -56,6 +56,7 @@ namespace dbaui { enum ChildFocusState { + HELPTEXT, DESCRIPTION, NAME, ROW, @@ -67,6 +68,7 @@ namespace dbaui OSQLNameEdit* pNameCell; ::svt::ListBoxControl* pTypeCell; + Edit* pHelpTextCell; Edit* pDescrCell; OTableFieldDescWin* pDescrWin; // properties of one column diff --git a/dbaccess/source/ui/tabledesign/TableController.cxx b/dbaccess/source/ui/tabledesign/TableController.cxx index 9b45c0eea..05b72dc89 100644 --- a/dbaccess/source/ui/tabledesign/TableController.cxx +++ b/dbaccess/source/ui/tabledesign/TableController.cxx @@ -868,7 +868,7 @@ void OTableController::loadData() sal_Int32 nAlign = 0; sal_Bool bIsAutoIncrement = false, bIsCurrency = false; - ::rtl::OUString sName,sDescription,sTypeName; + ::rtl::OUString sName,sDescription,sTypeName,sHelpText; Any aControlDefault; // get the properties from the column @@ -880,10 +880,11 @@ void OTableController::loadData() xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType; xColumn->getPropertyValue(PROPERTY_SCALE) >>= nScale; xColumn->getPropertyValue(PROPERTY_PRECISION) >>= nPrecision; - + xColumn->getPropertyValue(PROPERTY_DESCRIPTION) >>= sDescription; if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_HELPTEXT)) - xColumn->getPropertyValue(PROPERTY_HELPTEXT) >>= sDescription; + xColumn->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText; + if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_CONTROLDEFAULT)) aControlDefault = xColumn->getPropertyValue(PROPERTY_CONTROLDEFAULT); if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_FORMATKEY)) @@ -909,6 +910,7 @@ void OTableController::loadData() pActFieldDescr->SetFormatKey(nFormatKey); // pActFieldDescr->SetPrimaryKey(pPrimary->GetValue()); pActFieldDescr->SetDescription(sDescription); + pActFieldDescr->SetHelpText(sHelpText); pActFieldDescr->SetAutoIncrement(bIsAutoIncrement); pActFieldDescr->SetHorJustify(dbaui::mapTextJustify(nAlign)); pActFieldDescr->SetCurrency(bIsCurrency); @@ -966,39 +968,7 @@ void OTableController::loadData() // ----------------------------------------------------------------------------- Reference<XNameAccess> OTableController::getKeyColumns() const { - // use keys and indexes for excat postioning - // first the keys - Reference<XKeysSupplier> xKeySup(m_xTable,UNO_QUERY); - Reference<XIndexAccess> xKeys; - if(xKeySup.is()) - xKeys = xKeySup->getKeys(); - - Reference<XColumnsSupplier> xKeyColsSup; - Reference<XNameAccess> xKeyColumns; - if(xKeys.is()) - { - Reference<XPropertySet> xProp; - sal_Int32 nCount = xKeys->getCount(); - for(sal_Int32 i=0;i< nCount;++i) - { - xKeys->getByIndex(i) >>= xProp; - OSL_ENSURE(xProp.is(),"Key is invalid: NULL!"); - if ( xProp.is() ) - { - sal_Int32 nKeyType = 0; - xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; - if(KeyType::PRIMARY == nKeyType) - { - xKeyColsSup.set(xProp,UNO_QUERY); - OSL_ENSURE(xKeyColsSup.is(),"Columnsupplier is null!"); - xKeyColumns = xKeyColsSup->getColumns(); - break; - } - } - } - } - - return xKeyColumns; + return getPrimaryKeyColumns_throw(m_xTable); } // ----------------------------------------------------------------------------- sal_Bool OTableController::checkColumns(sal_Bool _bNew) throw(::com::sun::star::sdbc::SQLException) @@ -1117,13 +1087,14 @@ void OTableController::alterColumns() sal_Int32 nType=0,nPrecision=0,nScale=0,nNullable=0; sal_Bool bAutoIncrement = false; - ::rtl::OUString sTypeName; + ::rtl::OUString sTypeName,sDescription; xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType; xColumn->getPropertyValue(PROPERTY_PRECISION) >>= nPrecision; xColumn->getPropertyValue(PROPERTY_SCALE) >>= nScale; xColumn->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullable; xColumn->getPropertyValue(PROPERTY_ISAUTOINCREMENT) >>= bAutoIncrement; + xColumn->getPropertyValue(PROPERTY_DESCRIPTION) >>= sDescription; try { xColumn->getPropertyValue(PROPERTY_TYPENAME) >>= sTypeName; } catch( const Exception& ) @@ -1141,7 +1112,8 @@ void OTableController::alterColumns() sTypeName != pField->GetTypeName() || (nPrecision != pField->GetPrecision() && nPrecision ) || nScale != pField->GetScale() || - nNullable != pField->GetIsNullable() || + nNullable != pField->GetIsNullable() || + sDescription != pField->GetDescription() || bAutoIncrement != pField->IsAutoIncrement())&& xColumnFactory.is()) { @@ -1261,7 +1233,8 @@ void OTableController::alterColumns() xColumns->getByName(pField->GetName()) >>= xColumn; Reference<XPropertySetInfo> xInfo = xColumn->getPropertySetInfo(); if ( xInfo->hasPropertyByName(PROPERTY_HELPTEXT) ) - xColumn->setPropertyValue(PROPERTY_HELPTEXT,makeAny(pField->GetDescription())); + xColumn->setPropertyValue(PROPERTY_HELPTEXT,makeAny(pField->GetHelpText())); + if(xInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT)) xColumn->setPropertyValue(PROPERTY_CONTROLDEFAULT,pField->GetControlDefault()); if(xInfo->hasPropertyByName(PROPERTY_FORMATKEY)) diff --git a/dbaccess/source/ui/tabledesign/TableRow.cxx b/dbaccess/source/ui/tabledesign/TableRow.cxx index dc7d79268..17456ba8c 100644 --- a/dbaccess/source/ui/tabledesign/TableRow.cxx +++ b/dbaccess/source/ui/tabledesign/TableRow.cxx @@ -137,6 +137,7 @@ namespace dbaui _rStr << (sal_Int32)1; _rStr.WriteByteString(pFieldDesc->GetName()); _rStr.WriteByteString(pFieldDesc->GetDescription()); + _rStr.WriteByteString(pFieldDesc->GetHelpText()); double nValue = 0.0; Any aValue = pFieldDesc->GetControlDefault(); if ( aValue >>= nValue ) @@ -181,6 +182,8 @@ namespace dbaui _rStr.ReadByteString(sValue); pFieldDesc->SetDescription(sValue); + _rStr.ReadByteString(sValue); + pFieldDesc->SetHelpText(sValue); _rStr >> nValue; Any aControlDefault; diff --git a/dbaccess/source/ui/tabledesign/table.src b/dbaccess/source/ui/tabledesign/table.src index b882fc6d9..974dd5602 100644 --- a/dbaccess/source/ui/tabledesign/table.src +++ b/dbaccess/source/ui/tabledesign/table.src @@ -103,10 +103,14 @@ String STR_TAB_FIELD_LENGTH { Text [ en-US ] = "Field length" ; }; -String STR_TAB_FIELD_DESCR +String STR_TAB_HELP_TEXT { Text [ en-US ] = "Description" ; }; +String STR_COLUMN_DESCRIPTION +{ + Text [ en-US ] = "Column Description" ; +}; String STR_TAB_FIELD_NULLABLE { Text [ en-US ] = "Input required" ; diff --git a/dbaccess/source/ui/uno/copytablewizard.cxx b/dbaccess/source/ui/uno/copytablewizard.cxx index abec37723..032e5b117 100644 --- a/dbaccess/source/ui/uno/copytablewizard.cxx +++ b/dbaccess/source/ui/uno/copytablewizard.cxx @@ -258,6 +258,17 @@ namespace dbaui sal_Int32& _out_rCommandType ) const; + /** extracts the result set to copy records from, and the selection-related aspects, if any. + + Effectively, this method extracts m_xSourceResultSet, m_aSourceSelection, and m_bSourceSelectionBookmarks. + + If an inconsistent/insufficent sub set of those properties is present in the descriptor, and exception + is thrown. + */ + void impl_extractSourceResultSet_throw( + const Reference< XPropertySet >& i_rDescriptor + ); + /** checks whether the given copy source descriptor contains settings which are not supported (yet) @@ -299,7 +310,7 @@ namespace dbaui /** creates the INSERT INTO statement @param _xTable The destination table. */ - ::rtl::OUString impl_getSelectStatement_nothrow(const Reference< XPropertySet >& _xTable); + ::rtl::OUString impl_getServerSideCopyStatement_throw( const Reference< XPropertySet >& _xTable ); /** creates the statement which, when executed, will produce the source data to copy @@ -342,8 +353,9 @@ private: sal_Int32 m_nCommandType; ::std::auto_ptr< ICopyTableSourceObject > m_pSourceObject; + Reference< XResultSet > m_xSourceResultSet; Sequence< Any > m_aSourceSelection; - bool m_bSourceSelectionBookmarks; + sal_Bool m_bSourceSelectionBookmarks; // destination SharedConnection m_xDestConnection; @@ -390,13 +402,13 @@ CopyTableWizard::CopyTableWizard( const Reference< XMultiServiceFactory >& _rxOR ,m_xSourceConnection() ,m_nCommandType( CommandType::COMMAND ) ,m_pSourceObject() + ,m_xSourceResultSet() ,m_aSourceSelection() - ,m_bSourceSelectionBookmarks( true ) + ,m_bSourceSelectionBookmarks( sal_True ) ,m_xDestConnection() ,m_aCopyTableListeners( m_aMutex ) ,m_nOverrideExecutionResult( -1 ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::CopyTableWizard" ); } //------------------------------------------------------------------------- @@ -412,7 +424,7 @@ CopyTableWizard::~CopyTableWizard() // TODO: shouldn't we have explicit disposal support? If a listener is registered // at our instance, and perhaps holds this our instance by a hard ref, then we'll never - // destroyed. + // be destroyed. // However, adding XComponent support to the GenericUNODialog probably requires // some thinking - would it break existing clients which do not call a dispose, then? } @@ -459,7 +471,6 @@ Reference< XPropertySetInfo > SAL_CALL CopyTableWizard::getPropertySetInfo() thr //-------------------------------------------------------------------- ::sal_Int16 SAL_CALL CopyTableWizard::getOperation() throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getOperation" ); CopyTableAccessGuard aGuard( *this ); return m_nOperation; } @@ -467,7 +478,6 @@ Reference< XPropertySetInfo > SAL_CALL CopyTableWizard::getPropertySetInfo() thr //-------------------------------------------------------------------- void SAL_CALL CopyTableWizard::setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setOperation" ); CopyTableAccessGuard aGuard( *this ); if ( ( _operation != CopyTableOperation::CopyDefinitionAndData ) @@ -492,7 +502,6 @@ void SAL_CALL CopyTableWizard::setOperation( ::sal_Int16 _operation ) throw (Ill //-------------------------------------------------------------------- ::rtl::OUString SAL_CALL CopyTableWizard::getDestinationTableName() throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getDestinationTableName" ); CopyTableAccessGuard aGuard( *this ); return m_sDestinationTable; } @@ -500,7 +509,6 @@ void SAL_CALL CopyTableWizard::setOperation( ::sal_Int16 _operation ) throw (Ill //-------------------------------------------------------------------- void SAL_CALL CopyTableWizard::setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setDestinationTableName" ); CopyTableAccessGuard aGuard( *this ); m_sDestinationTable = _destinationTableName; } @@ -508,7 +516,6 @@ void SAL_CALL CopyTableWizard::setDestinationTableName( const ::rtl::OUString& _ //-------------------------------------------------------------------- Optional< ::rtl::OUString > SAL_CALL CopyTableWizard::getCreatePrimaryKey() throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getCreatePrimaryKey" ); CopyTableAccessGuard aGuard( *this ); return m_aPrimaryKeyName; } @@ -516,7 +523,6 @@ Optional< ::rtl::OUString > SAL_CALL CopyTableWizard::getCreatePrimaryKey() thro //-------------------------------------------------------------------- void SAL_CALL CopyTableWizard::setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setCreatePrimaryKey" ); CopyTableAccessGuard aGuard( *this ); if ( _newPrimaryKey.IsPresent && !OCopyTableWizard::supportsPrimaryKey( m_xDestConnection ) ) @@ -543,7 +549,6 @@ void SAL_CALL CopyTableWizard::setUseHeaderLineAsColumnNames( sal_Bool _bUseHead //-------------------------------------------------------------------- void SAL_CALL CopyTableWizard::addCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::addCopyTableListener" ); CopyTableAccessGuard aGuard( *this ); if ( _rxListener.is() ) m_aCopyTableListeners.addInterface( _rxListener ); @@ -552,7 +557,6 @@ void SAL_CALL CopyTableWizard::addCopyTableListener( const Reference< XCopyTable //-------------------------------------------------------------------- void SAL_CALL CopyTableWizard::removeCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::removeCopyTableListener" ); CopyTableAccessGuard aGuard( *this ); if ( _rxListener.is() ) m_aCopyTableListeners.removeInterface( _rxListener ); @@ -561,7 +565,6 @@ void SAL_CALL CopyTableWizard::removeCopyTableListener( const Reference< XCopyTa //-------------------------------------------------------------------- void SAL_CALL CopyTableWizard::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setTitle" ); CopyTableAccessGuard aGuard( *this ); CopyTableWizard_DialogBase::setTitle( _rTitle ); } @@ -569,7 +572,6 @@ void SAL_CALL CopyTableWizard::setTitle( const ::rtl::OUString& _rTitle ) throw //-------------------------------------------------------------------- ::sal_Int16 SAL_CALL CopyTableWizard::execute( ) throw (RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::execute" ); CopyTableAccessGuard aGuard( *this ); m_nOverrideExecutionResult = -1; @@ -583,7 +585,6 @@ void SAL_CALL CopyTableWizard::setTitle( const ::rtl::OUString& _rTitle ) throw //------------------------------------------------------------------------- OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_getDialog_throw" ); OCopyTableWizard* pWizard = dynamic_cast< OCopyTableWizard* >( m_pDialog ); if ( !pWizard ) throw DisposedException( ::rtl::OUString(), *this ); @@ -593,7 +594,6 @@ OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() //------------------------------------------------------------------------- const OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_getDialog_throw" ); const OCopyTableWizard* pWizard = dynamic_cast< const OCopyTableWizard* >( m_pDialog ); if ( !pWizard ) throw DisposedException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) ); @@ -603,7 +603,6 @@ const OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() const //------------------------------------------------------------------------- void CopyTableWizard::impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_attributesToDialog_nothrow" ); // primary key column _rDialog.setCreatePrimaryKey( m_aPrimaryKeyName.IsPresent, m_aPrimaryKeyName.Value ); _rDialog.setUseHeaderLine(m_bUseHeaderLineAsColumnNames); @@ -614,7 +613,6 @@ void CopyTableWizard::impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialo //------------------------------------------------------------------------- void CopyTableWizard::impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_dialogToAttributes_nothrow" ); m_aPrimaryKeyName.IsPresent = _rDialog.shouldCreatePrimaryKey(); if ( m_aPrimaryKeyName.IsPresent ) m_aPrimaryKeyName.Value = _rDialog.getPrimaryKeyName(); @@ -689,7 +687,6 @@ Reference< XPropertySet > CopyTableWizard::impl_ensureDataAccessDescriptor_throw const Sequence< Any >& _rAllArgs, const sal_Int16 _nArgPos, SharedConnection& _out_rxConnection, InteractionHandler& _out_rxDocInteractionHandler ) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_ensureDataAccessDescriptor_throw" ); Reference< XPropertySet > xDescriptor; _rAllArgs[ _nArgPos ] >>= xDescriptor; @@ -742,32 +739,19 @@ namespace //------------------------------------------------------------------------- void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< XPropertySet >& _rxSourceDescriptor ) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_checkForUnsupportedSettings_throw" ); OSL_PRECOND( _rxSourceDescriptor.is(), "CopyTableWizard::impl_checkForUnsupportedSettings_throw: illegal argument!" ); Reference< XPropertySetInfo > xPSI( _rxSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW ); ::rtl::OUString sUnsupportedSetting; - // in theory, we could allow to use a mere result set as copy source. However, since this is currently - // not implemented at all, we report this in the initialization phase already - if ( xPSI->hasPropertyByName( PROPERTY_RESULT_SET ) ) - { - Reference< XResultSet > xSource( _rxSourceDescriptor->getPropertyValue( PROPERTY_RESULT_SET ), UNO_QUERY ); - if ( xSource.is() ) - sUnsupportedSetting = PROPERTY_RESULT_SET; - } - - if ( sUnsupportedSetting.getLength() == 0 ) + const ::rtl::OUString aSettings[] = { + PROPERTY_FILTER, PROPERTY_ORDER, PROPERTY_HAVING_CLAUSE, PROPERTY_GROUP_BY + }; + for ( size_t i=0; i < sizeof( aSettings ) / sizeof( aSettings[0] ); ++i ) { - const ::rtl::OUString aSettings[] = { - PROPERTY_FILTER, PROPERTY_ORDER, PROPERTY_HAVING_CLAUSE, PROPERTY_GROUP_BY - }; - for ( size_t i=0; i < sizeof( aSettings ) / sizeof( aSettings[0] ); ++i ) + if ( lcl_hasNonEmptyStringValue_throw( _rxSourceDescriptor, xPSI, aSettings[i] ) ) { - if ( lcl_hasNonEmptyStringValue_throw( _rxSourceDescriptor, xPSI, aSettings[i] ) ) - { - sUnsupportedSetting = aSettings[i]; - break; - } + sUnsupportedSetting = aSettings[i]; + break; } } @@ -787,17 +771,15 @@ void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< X //------------------------------------------------------------------------- ::std::auto_ptr< ICopyTableSourceObject > CopyTableWizard::impl_extractSourceObject_throw( const Reference< XPropertySet >& _rxDescriptor, sal_Int32& _out_rCommandType ) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_extractSourceObject_throw" ); OSL_PRECOND( _rxDescriptor.is() && m_xSourceConnection.is(), "CopyTableWizard::impl_extractSourceObject_throw: illegal arguments!" ); - impl_checkForUnsupportedSettings_throw( _rxDescriptor ); - Reference< XPropertySetInfo > xPSI( _rxDescriptor->getPropertySetInfo(), UNO_SET_THROW ); if ( !xPSI->hasPropertyByName( PROPERTY_COMMAND ) || !xPSI->hasPropertyByName( PROPERTY_COMMAND_TYPE ) ) throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expecting a table or query specification." ) ), + // TODO: resource *const_cast< CopyTableWizard* >( this ), 1 ); @@ -857,10 +839,48 @@ void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< X } //------------------------------------------------------------------------- +void CopyTableWizard::impl_extractSourceResultSet_throw( const Reference< XPropertySet >& i_rDescriptor ) +{ + Reference< XPropertySetInfo > xPSI( i_rDescriptor->getPropertySetInfo(), UNO_SET_THROW ); + + // extract relevant settings + if ( xPSI->hasPropertyByName( PROPERTY_RESULT_SET ) ) + m_xSourceResultSet.set( i_rDescriptor->getPropertyValue( PROPERTY_RESULT_SET ), UNO_QUERY ); + + if ( xPSI->hasPropertyByName( PROPERTY_SELECTION ) ) + OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_SELECTION ) >>= m_aSourceSelection ); + + if ( xPSI->hasPropertyByName( PROPERTY_BOOKMARK_SELECTION ) ) + OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_BOOKMARK_SELECTION ) >>= m_bSourceSelectionBookmarks ); + + // sanity checks + const bool bHasResultSet = m_xSourceResultSet.is(); + const bool bHasSelection = ( m_aSourceSelection.getLength() != 0 ); + if ( bHasSelection && !bHasResultSet ) + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A result set is needed when specifying a selection to copy." ) ), + // TODO: resource + *this, + 1 + ); + + if ( bHasSelection && m_bSourceSelectionBookmarks ) + { + Reference< XRowLocate > xRowLocate( m_xSourceResultSet, UNO_QUERY ); + if ( !xRowLocate.is() ) + { + ::dbtools::throwGenericSQLException( + String( ModuleRes( STR_CTW_COPY_SOURCE_NEEDS_BOOKMARKS ) ), + *this + ); + } + } +} + +//------------------------------------------------------------------------- SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< XPropertySet >& _rxDataSourceDescriptor, InteractionHandler& _out_rxDocInteractionHandler ) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_extractConnection_throw" ); SharedConnection xConnection; OSL_PRECOND( _rxDataSourceDescriptor.is(), "CopyTableWizard::impl_extractConnection_throw: no descriptor!" ); @@ -954,7 +974,6 @@ SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< //------------------------------------------------------------------------- ::utl::SharedUNOComponent< XPreparedStatement > CopyTableWizard::impl_createSourceStatement_throw() const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_createSourceStatement_throw" ); OSL_PRECOND( m_xSourceConnection.is(), "CopyTableWizard::impl_createSourceStatement_throw: illegal call!" ); if ( !m_xSourceConnection.is() ) throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) ); @@ -1059,7 +1078,6 @@ namespace //------------------------------------------------------------------------- bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _rEvent ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_processCopyError_nothrow" ); Reference< XCopyTableListener > xListener; try { @@ -1138,7 +1156,6 @@ bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _r void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSourceResultSet, const Reference< XPropertySet >& _rxDestTable ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_copyRows_throw" ); OSL_PRECOND( m_xDestConnection.is(), "CopyTableWizard::impl_copyRows_throw: illegal call!" ); if ( !m_xDestConnection.is() ) throw RuntimeException( ::rtl::OUString(), *this ); @@ -1150,16 +1167,7 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou bool bAutoIncrement = rWizard.shouldCreatePrimaryKey(); Reference< XRow > xRow ( _rxSourceResultSet, UNO_QUERY_THROW ); - Reference< XRowLocate > xRowLocate ( _rxSourceResultSet, UNO_QUERY ); - - bool bSelectedRecordsOnly = m_aSourceSelection.getLength() > 0; - if ( bSelectedRecordsOnly && m_bSourceSelectionBookmarks && !xRowLocate.is() ) - { - ::dbtools::throwGenericSQLException( - String( ModuleRes( STR_CTW_COPY_SOURCE_NEEDS_BOOKMARKS ) ), - *this - ); - } + Reference< XRowLocate > xRowLocate ( _rxSourceResultSet, UNO_QUERY_THROW ); Reference< XResultSetMetaDataSupplier > xSuppResMeta( _rxSourceResultSet, UNO_QUERY_THROW ); Reference< XResultSetMetaData> xMeta( xSuppResMeta->getMetaData() ); @@ -1177,9 +1185,11 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou Reference< XPreparedStatement > xStatement( ODatabaseExport::createPreparedStatment( xDestMetaData, _rxDestTable, aColumnMapping ), UNO_SET_THROW ); Reference< XParameters > xStatementParams( xStatement, UNO_QUERY_THROW ); + const bool bSelectedRecordsOnly = m_aSourceSelection.getLength() != 0; + const Any* pSelectedRow = m_aSourceSelection.getConstArray(); + const Any* pSelEnd = pSelectedRow + m_aSourceSelection.getLength(); + sal_Int32 nRowCount = 0; - const Any* pSelectedRow = m_aSourceSelection.getConstArray(); - const Any* pSelEnd = pSelectedRow + m_aSourceSelection.getLength(); bool bContinue = false; CopyTableRowEvent aCopyEvent; @@ -1195,7 +1205,7 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou { if ( m_bSourceSelectionBookmarks ) { - xRowLocate->moveToBookmark( *pSelectedRow ); + bContinue = xRowLocate->moveToBookmark( *pSelectedRow ); } else { @@ -1355,7 +1365,6 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou //------------------------------------------------------------------------- void CopyTableWizard::impl_doCopy_nothrow() { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_doCopy_nothrow" ); Any aError; try @@ -1396,26 +1405,41 @@ void CopyTableWizard::impl_doCopy_nothrow() } } - bool bServerCopy = CommandType::TABLE == m_nCommandType && m_xSourceConnection.getTyped() == m_xDestConnection.getTyped() && !m_aSourceSelection.getLength(); - try + ::utl::SharedUNOComponent< XPreparedStatement > xSourceStatement; + ::utl::SharedUNOComponent< XResultSet > xSourceResultSet; + + if ( m_xSourceResultSet.is() ) { - if ( bServerCopy ) - { - m_xDestConnection->createStatement()->executeUpdate( impl_getSelectStatement_nothrow(xTable) ); - } + xSourceResultSet.reset( m_xSourceResultSet, ::utl::SharedUNOComponent< XResultSet >::NoTakeOwnership ); } - catch( const Exception& e ) + else { - (void)e; - bServerCopy = false; + const bool bIsSameConnection = ( m_xSourceConnection.getTyped() == m_xDestConnection.getTyped() ); + const bool bIsTable = ( CommandType::TABLE == m_nCommandType ); + bool bDone = false; + if ( bIsSameConnection && bIsTable ) + { + // try whether the server supports copying via SQL + try + { + m_xDestConnection->createStatement()->executeUpdate( impl_getServerSideCopyStatement_throw(xTable) ); + bDone = true; + } + catch( const Exception& ) + { + // this is allowed. + } + } + + if ( !bDone ) + { + xSourceStatement.set( impl_createSourceStatement_throw(), UNO_SET_THROW ); + xSourceResultSet.set( xSourceStatement->executeQuery(), UNO_SET_THROW ); + } } - if ( !bServerCopy ) - { - ::utl::SharedUNOComponent< XPreparedStatement > xStatement( impl_createSourceStatement_throw(), UNO_SET_THROW ); - Reference< XResultSet > xSourceResultSet( xStatement->executeQuery() ); + if ( xSourceResultSet.is() ) impl_copyRows_throw( xSourceResultSet, xTable ); - } } break; @@ -1455,7 +1479,7 @@ void CopyTableWizard::impl_doCopy_nothrow() } } // ----------------------------------------------------------------------------- -::rtl::OUString CopyTableWizard::impl_getSelectStatement_nothrow(const Reference< XPropertySet >& _xTable) +::rtl::OUString CopyTableWizard::impl_getServerSideCopyStatement_throw(const Reference< XPropertySet >& _xTable) { const Reference<XColumnsSupplier> xDestColsSup(_xTable,UNO_QUERY_THROW); const Sequence< ::rtl::OUString> aDestColumnNames = xDestColsSup->getColumns()->getElementNames(); @@ -1493,7 +1517,6 @@ void CopyTableWizard::impl_doCopy_nothrow() //------------------------------------------------------------------------- void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::initialize" ); ::osl::MutexGuard aGuard( m_aMutex ); if ( isInitialized() ) throw AlreadyInitializedException( ::rtl::OUString(), *this ); @@ -1522,7 +1545,9 @@ void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) InteractionHandler xSourceDocHandler; Reference< XPropertySet > xSourceDescriptor( impl_ensureDataAccessDescriptor_throw( _rArguments, 0, m_xSourceConnection, xSourceDocHandler ) ); + impl_checkForUnsupportedSettings_throw( xSourceDescriptor ); m_pSourceObject = impl_extractSourceObject_throw( xSourceDescriptor, m_nCommandType ); + impl_extractSourceResultSet_throw( xSourceDescriptor ); InteractionHandler xDestDocHandler; impl_ensureDataAccessDescriptor_throw( _rArguments, 1, m_xDestConnection, xDestDocHandler ); @@ -1546,14 +1571,12 @@ void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) //------------------------------------------------------------------------- ::cppu::IPropertyArrayHelper& CopyTableWizard::getInfoHelper() { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getInfoHelper" ); return *getArrayHelper(); } //------------------------------------------------------------------------------ ::cppu::IPropertyArrayHelper* CopyTableWizard::createArrayHelper( ) const { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::createArrayHelper" ); Sequence< Property > aProps; describeProperties( aProps ); return new ::cppu::OPropertyArrayHelper( aProps ); @@ -1562,7 +1585,6 @@ void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) //------------------------------------------------------------------------------ Dialog* CopyTableWizard::createDialog( Window* _pParent ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::createDialog" ); OSL_PRECOND( isInitialized(), "CopyTableWizard::createDialog: not initialized!" ); // this should have been prevented in ::execute already @@ -1585,7 +1607,6 @@ Dialog* CopyTableWizard::createDialog( Window* _pParent ) //------------------------------------------------------------------------------ void CopyTableWizard::executedDialog( sal_Int16 _nExecutionResult ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::executedDialog" ); CopyTableWizard_DialogBase::executedDialog( _nExecutionResult ); if ( _nExecutionResult == RET_OK ) diff --git a/dbaccess/util/hidother.src b/dbaccess/util/hidother.src index c4085dae1..e0f0d2a26 100644 --- a/dbaccess/util/hidother.src +++ b/dbaccess/util/hidother.src @@ -146,6 +146,8 @@ hidspecial HID_CTL_TABLEEDIT { HelpId = HID_CTL_TABLEEDIT; }; hidspecial HID_TABDESIGN_NAMECELL { HelpId = HID_TABDESIGN_NAMECELL; }; hidspecial HID_TABDESIGN_TYPECELL { HelpId = HID_TABDESIGN_TYPECELL; }; hidspecial HID_TABDESIGN_COMMENTCELL { HelpId = HID_TABDESIGN_COMMENTCELL; }; +hidspecial HID_TABDESIGN_HELPTEXT { HelpId = HID_TABDESIGN_HELPTEXT; }; + hidspecial SID_TABLEDESIGN_INSERTROWS { HelpId = SID_TABLEDESIGN_INSERTROWS; }; hidspecial SID_TABLEDESIGN_TABED_PRIMARYKEY { HelpId = SID_TABLEDESIGN_TABED_PRIMARYKEY; }; hidspecial HID_TLB_TABLEDESIGN { HelpId = HID_TLB_TABLEDESIGN; }; diff --git a/reportdesign/source/core/api/Section.cxx b/reportdesign/source/core/api/Section.cxx index cf501a729..f3937d3e2 100644 --- a/reportdesign/source/core/api/Section.cxx +++ b/reportdesign/source/core/api/Section.cxx @@ -456,7 +456,7 @@ uno::Reference< report::XReportDefinition > SAL_CALL OSection::getReportDefiniti uno::Reference< report::XGroup > xGroup = m_xGroup; if ( !xRet.is() && xGroup.is() ) { - uno::Reference< report::XGroups> xGroups(xGroup->getParent(),uno::UNO_QUERY); + uno::Reference< report::XGroups> xGroups(xGroup->getGroups()); if ( xGroups.is() ) xRet = xGroups->getReportDefinition(); } diff --git a/reportdesign/source/filter/xml/xmlGroup.cxx b/reportdesign/source/filter/xml/xmlGroup.cxx index 19f198fd5..18ae61973 100644 --- a/reportdesign/source/filter/xml/xmlGroup.cxx +++ b/reportdesign/source/filter/xml/xmlGroup.cxx @@ -142,9 +142,9 @@ OXMLGroup::OXMLGroup( ORptFilter& _rImport sInterval = sInterval.getToken(0,')',nIndex); m_xGroup->setGroupInterval(sInterval.toInt32()); } - else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:YEAR"))) + else if ( sFormula == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:YEAR"))) nGroupOn = report::GroupOn::YEAR; - else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:MONTH"))) + else if ( sFormula == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:MONTH"))) { nGroupOn = report::GroupOn::MONTH; } diff --git a/reportdesign/source/ui/dlg/AddField.cxx b/reportdesign/source/ui/dlg/AddField.cxx index 2660b2cb8..46618c3c0 100644 --- a/reportdesign/source/ui/dlg/AddField.cxx +++ b/reportdesign/source/ui/dlg/AddField.cxx @@ -47,6 +47,8 @@ #include "CondFormat.hrc" #include "ModuleHelper.hxx" #include "uistrings.hrc" +#include "ColumnInfo.hxx" + #include <comphelper/property.hxx> #include <svtools/imgdef.hxx> @@ -66,6 +68,7 @@ using namespace beans; using namespace lang; using namespace container; using namespace ::svx; + class OAddFieldWindowListBox : public SvTreeListBox { OAddFieldWindow* m_pTabWin; @@ -226,6 +229,15 @@ OAddFieldWindow::OAddFieldWindow(Window* pParent //----------------------------------------------------------------------- OAddFieldWindow::~OAddFieldWindow() { + if ( m_pListBox.get() ) + { + SvLBoxTreeList* pModel = m_pListBox->GetModel(); + ULONG nCount = pModel->GetEntryCount(); + for(ULONG i = 0; i< nCount;++i) + { + delete static_cast<ColumnInfo*>(pModel->GetEntry(i)->GetUserData()); + } + } if (m_pChangeListener.is()) m_pChangeListener->dispose(); if ( m_pContainerListener.is() ) @@ -281,7 +293,24 @@ namespace const ::rtl::OUString* pEntries = _rEntries.getConstArray(); sal_Int32 nEntries = _rEntries.getLength(); for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries ) - _rListBox.InsertEntry( *pEntries ); + _rListBox.InsertEntry( *pEntries,NULL,FALSE,LIST_APPEND,new ColumnInfo(*pEntries) ); + } + void lcl_addToList( OAddFieldWindowListBox& _rListBox, const uno::Reference< container::XNameAccess>& i_xColumns ) + { + uno::Sequence< ::rtl::OUString > aEntries = i_xColumns->getElementNames(); + const ::rtl::OUString* pEntries = aEntries.getConstArray(); + sal_Int32 nEntries = aEntries.getLength(); + for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries ) + { + uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(*pEntries),UNO_QUERY_THROW); + ::rtl::OUString sLabel; + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + if ( sLabel.getLength() ) + _rListBox.InsertEntry( sLabel,NULL,FALSE,LIST_APPEND,new ColumnInfo(*pEntries,sLabel) ); + else + _rListBox.InsertEntry( *pEntries,NULL,FALSE,LIST_APPEND,new ColumnInfo(*pEntries,sLabel) ); + } } } @@ -328,7 +357,7 @@ void OAddFieldWindow::Update() m_xColumns = dbtools::getFieldsByCommandDescriptor( xCon, GetCommandType(), GetCommand(), m_xHoldAlive ); if ( m_xColumns.is() ) { - lcl_addToList( *m_pListBox, m_xColumns->getElementNames() ); + lcl_addToList( *m_pListBox, m_xColumns ); uno::Reference< container::XContainer> xContainer(m_xColumns,uno::UNO_QUERY); if ( xContainer.is() ) m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer); @@ -426,10 +455,11 @@ void OAddFieldWindow::fillDescriptor(SvLBoxEntry* _pSelected,::svx::ODataAccessD _rDescriptor[ ::svx::daEscapeProcessing ] <<= GetEscapeProcessing(); _rDescriptor[ ::svx::daConnection ] <<= getConnection(); - ::rtl::OUString sColumnName = m_pListBox->GetEntryText( _pSelected ); - _rDescriptor[ ::svx::daColumnName ] <<= sColumnName; - if ( m_xColumns->hasByName( sColumnName ) ) - _rDescriptor[ ::svx::daColumnObject ] <<= m_xColumns->getByName(sColumnName); + ColumnInfo* pInfo = static_cast<ColumnInfo*>(_pSelected->GetUserData()); + // ::rtl::OUString sColumnName = m_pListBox->GetEntryText( _pSelected ); + _rDescriptor[ ::svx::daColumnName ] <<= pInfo->sColumnName; + if ( m_xColumns->hasByName( pInfo->sColumnName ) ) + _rDescriptor[ ::svx::daColumnObject ] <<= m_xColumns->getByName(pInfo->sColumnName); } } // ----------------------------------------------------------------------------- @@ -438,8 +468,17 @@ void OAddFieldWindow::_elementInserted( const container::ContainerEvent& _rEvent if ( m_pListBox.get() ) { ::rtl::OUString sName; - if ( _rEvent.Accessor >>= sName ) - m_pListBox->InsertEntry(sName); + if ( (_rEvent.Accessor >>= sName) && m_xColumns->hasByName(sName) ) + { + uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(sName),UNO_QUERY_THROW); + ::rtl::OUString sLabel; + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + if ( sLabel.getLength() ) + m_pListBox->InsertEntry( sLabel,NULL,FALSE,LIST_APPEND,new ColumnInfo(sName,sLabel) ); + else + m_pListBox->InsertEntry( sName,NULL,FALSE,LIST_APPEND,new ColumnInfo(sName,sLabel) ); + } } } // ----------------------------------------------------------------------------- @@ -449,7 +488,7 @@ void OAddFieldWindow::_elementRemoved( const container::ContainerEvent& /*_rEven { m_pListBox->Clear(); if ( m_xColumns.is() ) - lcl_addToList( *m_pListBox, m_xColumns->getElementNames() ); + lcl_addToList( *m_pListBox, m_xColumns ); } } // ----------------------------------------------------------------------------- diff --git a/reportdesign/source/ui/dlg/GroupsSorting.cxx b/reportdesign/source/ui/dlg/GroupsSorting.cxx index 1efecf26b..542ff4bfd 100644 --- a/reportdesign/source/ui/dlg/GroupsSorting.cxx +++ b/reportdesign/source/ui/dlg/GroupsSorting.cxx @@ -49,6 +49,7 @@ #include "UndoActions.hxx" #include "uistrings.hrc" #include "ReportController.hxx" +#include "ColumnInfo.hxx" #include <cppuhelper/implbase1.hxx> #include <comphelper/property.hxx> @@ -70,6 +71,25 @@ using namespace ::com::sun::star; using namespace svt; using namespace ::comphelper; + void lcl_addToList_throw( ComboBoxControl& _rListBox, ::std::vector<ColumnInfo>& o_aColumnList,const uno::Reference< container::XNameAccess>& i_xColumns ) + { + uno::Sequence< ::rtl::OUString > aEntries = i_xColumns->getElementNames(); + const ::rtl::OUString* pEntries = aEntries.getConstArray(); + sal_Int32 nEntries = aEntries.getLength(); + for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries ) + { + uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(*pEntries),uno::UNO_QUERY_THROW); + ::rtl::OUString sLabel; + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + o_aColumnList.push_back( ColumnInfo(*pEntries,sLabel) ); + if ( sLabel.getLength() ) + _rListBox.InsertEntry( sLabel ); + else + _rListBox.InsertEntry( *pEntries ); + } + } + typedef ::svt::EditBrowseBox OFieldExpressionControl_Base; typedef ::cppu::WeakImplHelper1< container::XContainerListener > TContainerListenerBase; class OFieldExpressionControl : public TContainerListenerBase @@ -77,6 +97,7 @@ class OFieldExpressionControl : public TContainerListenerBase { ::osl::Mutex m_aMutex; ::std::vector<sal_Int32> m_aGroupPositions; + ::std::vector<ColumnInfo> m_aColumnInfo; ::svt::ComboBoxControl* m_pComboCell; sal_Int32 m_nDataPos; sal_Int32 m_nCurrentPos; @@ -332,13 +353,7 @@ void OFieldExpressionControl::fillColumns(const uno::Reference< container::XName { m_pComboCell->Clear(); if ( _xColumns.is() ) - { - uno::Sequence< ::rtl::OUString> aColumnNames = _xColumns->getElementNames(); - const ::rtl::OUString* pIter = aColumnNames.getConstArray(); - const ::rtl::OUString* pEnd = pIter + aColumnNames.getLength(); - for(;pIter != pEnd;++pIter) - m_pComboCell->InsertEntry(*pIter); - } // if ( _xColumns.is() ) + lcl_addToList_throw(*m_pComboCell,m_aColumnInfo,_xColumns); } //------------------------------------------------------------------------------ void OFieldExpressionControl::lateInit() @@ -477,7 +492,7 @@ BOOL OFieldExpressionControl::SaveModified(bool _bAppendRow) sExpression = m_pComboCell->GetText(); else { - sExpression = m_pComboCell->GetEntry(nPos); + sExpression = m_aColumnInfo[nPos].sColumnName; } xGroup->setExpression( sExpression ); @@ -516,7 +531,18 @@ String OFieldExpressionControl::GetCellText( long nRow, USHORT /*nColId*/ ) cons try { uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]); - sText = xGroup->getExpression(); + ::rtl::OUString sExpression = xGroup->getExpression(); + + for(::std::vector<ColumnInfo>::const_iterator aIter = m_aColumnInfo.begin(); aIter != m_aColumnInfo.end();++aIter) + { + if ( aIter->sColumnName == sExpression ) + { + if ( aIter->sLabel.getLength() ) + sExpression = aIter->sLabel; + break; + } + } + sText = sExpression; } catch(uno::Exception&) { @@ -1308,10 +1334,7 @@ void OGroupsSortingDialog::_propertyChanged(const beans::PropertyChangeEvent& _r // ----------------------------------------------------------------------------- void OGroupsSortingDialog::fillColumns() { - m_xColumns.clear(); - uno::Reference< report::XReportDefinition> xReport = m_pController->getReportDefinition(); - if ( xReport->getCommand().getLength() ) - m_xColumns = dbtools::getFieldsByCommandDescriptor(m_pController->getConnection(),xReport->getCommandType(),xReport->getCommand(),m_xHoldAlive); + m_xColumns = m_pController->getColumns(); m_pFieldExpression->fillColumns(m_xColumns); } // ----------------------------------------------------------------------------- diff --git a/reportdesign/source/ui/inc/ColumnInfo.hxx b/reportdesign/source/ui/inc/ColumnInfo.hxx new file mode 100644 index 000000000..5943fdba8 --- /dev/null +++ b/reportdesign/source/ui/inc/ColumnInfo.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AddField.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef RPTUI_COLUMNINFO_HXX +#define RPTUI_COLUMNINFO_HXX + +#include <rtl/ustring.hxx> + +namespace rptui +{ + struct ColumnInfo + { + ::rtl::OUString sColumnName; + ::rtl::OUString sLabel; + bool bColumn; + ColumnInfo(const ::rtl::OUString& i_sColumnName,const ::rtl::OUString& i_sLabel) + : sColumnName(i_sColumnName) + , sLabel(i_sLabel) + , bColumn(true) + { + } + ColumnInfo(const ::rtl::OUString& i_sColumnName) + : sColumnName(i_sColumnName) + , bColumn(false) + { + } + }; +// ============================================================================= +} // namespace rptui +// ============================================================================= +#endif // RPTUI_COLUMNINFO_HXX diff --git a/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx b/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx index b66d41821..5fbfcc6ab 100644 --- a/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx +++ b/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx @@ -33,7 +33,6 @@ #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/awt/XVclWindowPeer.hpp> #include <com/sun/star/report/XReportComponent.hpp> -#include <com/sun/star/report/XFormattedField.hpp> /** === end UNO includes === **/ //#include <boost/noncopyable.hpp> diff --git a/reportdesign/source/ui/inc/GroupsSorting.hxx b/reportdesign/source/ui/inc/GroupsSorting.hxx index 831fb43f7..fcf150feb 100644 --- a/reportdesign/source/ui/inc/GroupsSorting.hxx +++ b/reportdesign/source/ui/inc/GroupsSorting.hxx @@ -102,7 +102,6 @@ class OGroupsSortingDialog : public FloatingWindow ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener; ::com::sun::star::uno::Reference< ::com::sun::star::report::XGroups> m_xGroups; ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xColumns; - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xHoldAlive; sal_Bool m_bReadOnly; private: DECL_LINK( OnControlFocusLost, Control* ); diff --git a/reportdesign/source/ui/inc/ReportController.hxx b/reportdesign/source/ui/inc/ReportController.hxx index 3a2e80065..8552e4ee2 100644 --- a/reportdesign/source/ui/inc/ReportController.hxx +++ b/reportdesign/source/ui/inc/ReportController.hxx @@ -114,6 +114,8 @@ namespace rptui ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet > m_xRowSet; ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > m_xRowSetMediator; ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > m_xFormatter; // a number formatter working with the report's NumberFormatsSupplier + mutable ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xHoldAlive; + mutable ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xColumns; ::com::sun::star::awt::Size m_aVisualAreaSize; ::boost::shared_ptr<rptui::OReportModel> @@ -472,6 +474,9 @@ namespace rptui ::boost::shared_ptr<OSectionWindow> getSectionWindow(const ::com::sun::star::uno::Reference< ::com::sun::star::report::XSection>& _xSection) const; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > getColumns() const; + ::rtl::OUString getColumnLabel_throw(const ::rtl::OUString& i_sColumnName) const; + private: virtual void onLoadedMenu( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager >& _xLayoutManager ); virtual void impl_initialize( ); diff --git a/reportdesign/source/ui/inc/ReportControllerObserver.hxx b/reportdesign/source/ui/inc/ReportControllerObserver.hxx index d65a7088b..8531feab9 100644 --- a/reportdesign/source/ui/inc/ReportControllerObserver.hxx +++ b/reportdesign/source/ui/inc/ReportControllerObserver.hxx @@ -65,11 +65,6 @@ namespace rptui // do not allow copy OXReportControllerObserver(const OXReportControllerObserver&); OXReportControllerObserver& operator=(const OXReportControllerObserver&); - -// protected: - - void switchListening(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxObject, sal_Bool _bStartListening); - virtual ~OXReportControllerObserver(); // UNO Object must have private destructor! public: OXReportControllerObserver(const OReportController& _rController); diff --git a/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx b/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx index eee76979a..6bfe1a913 100644 --- a/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx +++ b/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx @@ -88,39 +88,41 @@ namespace rptui void FormattedFieldBeautifier::setPlaceholderText( const uno::Reference< uno::XInterface >& _rxComponent ) { ::rtl::OUString sDataField; - uno::Reference< report::XReportComponent > xComponent; + uno::Reference< report::XReportComponent > xComponent( _rxComponent, uno::UNO_QUERY ); try { - // is it a formatted field? - uno::Reference< report::XFormattedField > xFormattedField( _rxComponent, uno::UNO_QUERY ); - if ( xFormattedField.is() ) + uno::Reference< report::XReportControlModel > xControlModel( xComponent, uno::UNO_QUERY ); + if ( xControlModel.is() ) { - sDataField = xFormattedField->getDataField(); - xComponent.set( xFormattedField.get() ); - } - else - { - // perhaps an image control? - uno::Reference< report::XImageControl > xImageControl( _rxComponent, uno::UNO_QUERY ); - if ( xImageControl.is() ) + sDataField = xControlModel->getDataField(); + + if ( sDataField.getLength() ) { - sDataField = xImageControl->getDataField(); - xComponent.set( xImageControl.get() ); + ReportFormula aFormula( sDataField ); + bool bSet = true; + if ( aFormula.getType() == ReportFormula::Field ) + { + const ::rtl::OUString sColumnName = aFormula.getFieldName(); + ::rtl::OUString sLabel = m_rReportController.getColumnLabel_throw(sColumnName); + if ( sLabel.getLength() ) + { + ::rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( "=" ); + aBuffer.append( sLabel ); + sDataField = aBuffer.makeStringAndClear(); + bSet = false; + } + } + if ( bSet ) + sDataField = aFormula.getEqualUndecoratedContent(); } } - if ( !xComponent.is() ) - return; - - if ( sDataField.getLength() ) - { - ReportFormula aFormula( sDataField ); - sDataField = aFormula.getEqualUndecoratedContent(); - } - setPlaceholderText( getVclWindowPeer( xComponent ), sDataField ); + if ( xComponent.is() ) + setPlaceholderText( getVclWindowPeer( xComponent ), sDataField ); } - catch (uno::Exception e) + catch (uno::Exception) { DBG_UNHANDLED_EXCEPTION(); } diff --git a/reportdesign/source/ui/report/ReportController.cxx b/reportdesign/source/ui/report/ReportController.cxx index 375abfd36..020990af9 100644 --- a/reportdesign/source/ui/report/ReportController.cxx +++ b/reportdesign/source/ui/report/ReportController.cxx @@ -350,6 +350,8 @@ void OReportController::disposing() try { + m_xHoldAlive.clear(); + m_xColumns.clear(); ::comphelper::disposeComponent( m_xRowSet ); ::comphelper::disposeComponent( m_xRowSetMediator ); ::comphelper::disposeComponent( m_xFormatter ); @@ -2302,6 +2304,8 @@ void SAL_CALL OReportController::propertyChange( const beans::PropertyChangeEven || evt.PropertyName.equals( PROPERTY_FILTER ) ) { + m_xColumns.clear(); + m_xHoldAlive.clear(); InvalidateFeature(SID_FM_ADD_FIELD); if ( !getDesignView()->isAddFieldVisible() && isUiVisible() ) getDesignView()->toggleAddField(); @@ -3556,6 +3560,10 @@ void OReportController::addPairControls(const Sequence< PropertyValue >& aArgs) aPos.Y += xShapeProp->getHeight(); aPos.X += nShapeWidth; } + ::rtl::OUString sLabel; + if ( xField->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xField->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + if (pSectionViews[0] != pSectionViews[1] && nOBJID == OBJ_DLG_FORMATTEDFIELD) // we want this nice feature only at FORMATTEDFIELD { @@ -3563,6 +3571,8 @@ void OReportController::addPairControls(const Sequence< PropertyValue >& aArgs) // pSectionViews[1].position.x = pSectionViews[0].position.x uno::Reference< report::XReportComponent> xShapePropLabel(pObjs[0]->getUnoShape(),uno::UNO_QUERY_THROW); uno::Reference< report::XReportComponent> xShapePropTextField(pObjs[1]->getUnoShape(),uno::UNO_QUERY_THROW); + if ( sLabel.getLength() ) + xShapePropTextField->setName(sLabel); awt::Point aPosLabel = xShapePropLabel->getPosition(); awt::Point aPosTextField = xShapePropTextField->getPosition(); aPosTextField.X = aPosLabel.X; @@ -3581,9 +3591,9 @@ void OReportController::addPairControls(const Sequence< PropertyValue >& aArgs) xShapePropLabel->setPosition(aPosLabel); } OUnoObject* pObj = dynamic_cast<OUnoObject*>(pControl[0]); - uno::Reference< report::XReportComponent> xShapeProp(pObj->getUnoShape(),uno::UNO_QUERY_THROW); + uno::Reference< report::XFixedText> xShapeProp(pObj->getUnoShape(),uno::UNO_QUERY_THROW); xShapeProp->setName(xShapeProp->getName() + sDefaultName ); - + for(i = 0; i < sizeof(pControl)/sizeof(pControl[0]);++i) // insert controls { correctOverlapping(pControl[i],pSectionWindow[1-i]->getReportSection()); @@ -4367,3 +4377,26 @@ embed::VisualRepresentation SAL_CALL OReportController::getPreferredVisualRepres { return embed::EmbedMapUnits::ONE_100TH_MM; } +// ----------------------------------------------------------------------------- +uno::Reference< container::XNameAccess > OReportController::getColumns() const +{ + if ( !m_xColumns.is() && m_xReportDefinition.is() && m_xReportDefinition->getCommand().getLength() ) + { + m_xColumns = dbtools::getFieldsByCommandDescriptor(getConnection(),m_xReportDefinition->getCommandType(),m_xReportDefinition->getCommand(),m_xHoldAlive); + } + return m_xColumns; +} +// ----------------------------------------------------------------------------- +::rtl::OUString OReportController::getColumnLabel_throw(const ::rtl::OUString& i_sColumnName) const +{ + ::rtl::OUString sLabel; + uno::Reference< container::XNameAccess > xColumns = getColumns(); + if ( xColumns.is() && xColumns->hasByName(i_sColumnName) ) + { + uno::Reference< beans::XPropertySet> xColumn(xColumns->getByName(i_sColumnName),uno::UNO_QUERY_THROW); + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + } + return sLabel; +} +// ----------------------------------------------------------------------------- diff --git a/reportdesign/source/ui/report/ReportControllerObserver.cxx b/reportdesign/source/ui/report/ReportControllerObserver.cxx index e6ccabac5..ef38d86f2 100644 --- a/reportdesign/source/ui/report/ReportControllerObserver.cxx +++ b/reportdesign/source/ui/report/ReportControllerObserver.cxx @@ -180,30 +180,6 @@ public: return 0L; } - // ----------------------------------------------------------------------------- - void OXReportControllerObserver::switchListening(const uno::Reference< uno::XInterface >& _rxObject, sal_Bool _bStartListening) - { - try - { - uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY ); - if ( xProps.is() ) - { - if ( _bStartListening ) - { - xProps->addPropertyChangeListener( ::rtl::OUString(), this ); - } - else - { - xProps->removePropertyChangeListener( ::rtl::OUString(), this ); - } - } - } - catch( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - } - // XEventListener void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e) throw( uno::RuntimeException ) { diff --git a/reportdesign/source/ui/report/SectionWindow.cxx b/reportdesign/source/ui/report/SectionWindow.cxx index f0589b50e..ec1c9718c 100644 --- a/reportdesign/source/ui/report/SectionWindow.cxx +++ b/reportdesign/source/ui/report/SectionWindow.cxx @@ -29,7 +29,6 @@ #include "ReportWindow.hxx" #include "ReportRuler.hxx" #include "rptui_slotid.hrc" -#include <svtools/colorcfg.hxx> #include "ReportController.hxx" #include "SectionView.hxx" #include "RptDef.hxx" @@ -38,13 +37,16 @@ #include "uistrings.hrc" #include "helpids.hrc" #include "RptResId.hrc" +#include "StartMarker.hxx" +#include "EndMarker.hxx" +#include "ViewsWindow.hxx" + +#include <svtools/colorcfg.hxx> #include <boost/bind.hpp> #include <functional> #include <algorithm> #include <vcl/svapp.hxx> -#include "StartMarker.hxx" -#include "EndMarker.hxx" -#include "ViewsWindow.hxx" +#include <connectivity/dbtools.hxx> namespace rptui { @@ -192,8 +194,15 @@ bool OSectionWindow::setGroupSectionTitle(const uno::Reference< report::XGroup>& const bool bRet = _pIsSectionOn(&aGroupHelper) && _pGetSection(&aGroupHelper) == m_aReportSection.getSection() ; if ( bRet ) { + ::rtl::OUString sExpression = _xGroup->getExpression(); + ::rtl::OUString sLabel = getViewsWindow()->getView()->getReportView()->getController().getColumnLabel_throw(sExpression); + if ( sLabel.getLength() ) + { + sExpression = sLabel; + } + String sTitle = String(ModuleRes(_nResId)); - sTitle.SearchAndReplace('#',_xGroup->getExpression()); + sTitle.SearchAndReplace('#',sExpression); m_aStartMarker.setTitle(sTitle); m_aStartMarker.Invalidate(INVALIDATE_CHILDREN); } // if ( _pIsSectionOn(&aGroupHelper) ) |