diff options
-rw-r--r-- | dbaccess/source/core/api/KeySet.cxx | 70 | ||||
-rw-r--r-- | dbaccess/source/core/api/KeySet.hxx | 7 | ||||
-rw-r--r-- | dbaccess/source/core/api/OptimisticSet.cxx | 2 | ||||
-rw-r--r-- | dbaccess/source/core/api/RowSetCache.cxx | 103 |
4 files changed, 79 insertions, 103 deletions
diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx index 6a7cd4087..1f20fd129 100644 --- a/dbaccess/source/core/api/KeySet.cxx +++ b/dbaccess/source/core/api/KeySet.cxx @@ -197,9 +197,10 @@ void OKeySet::initColumns() m_pParameterNames.reset( new SelectColumnsMetaData(bCase) ); m_pForeignColumnNames.reset( new SelectColumnsMetaData(bCase) ); } -void OKeySet::findTableColumnsMatching_throw(const Any& i_aTable - ,const Reference<XDatabaseMetaData>& i_xMeta - ,const Reference<XNameAccess>& i_xQueryColumns) +void OKeySet::findTableColumnsMatching_throw( const Any& i_aTable, + const ::rtl::OUString& i_rUpdateTableName, + const Reference<XDatabaseMetaData>& i_xMeta, + const Reference<XNameAccess>& i_xQueryColumns) { // first ask the database itself for the best columns which can be used Sequence< ::rtl::OUString> aBestColumnNames; @@ -220,37 +221,48 @@ void OKeySet::findTableColumnsMatching_throw(const Any& i_aTable xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i]; } - if ( m_sUpdateTableName.getLength() ) + ::rtl::OUString sUpdateTableName( i_rUpdateTableName ); + if ( sUpdateTableName.getLength() == 0 ) { - ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,m_sUpdateTableName,(*m_pKeyColumnNames),true); - ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),m_sUpdateTableName,(*m_pColumnNames),true); - ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,m_sUpdateTableName,(*m_pParameterNames),true); + OSL_ENSURE( false, "OKeySet::findTableColumnsMatching_throw: This is a fallback only - it won't work when the table has an alias name." ); + // If i_aTable originates from a query composer, and is a table which appears with an alias in the SELECT statement, + // then the below code will not produce correct results. + // For instance, imagine a "SELECT alias.col FROM table AS alias". Now i_aTable would be the table named + // "table", so our sUpdateTableName would be "table" as well - not the information about the "alias" is + // already lost here. + // now getColumnPositions would travers the columns, and check which of them belong to the table denoted + // by sUpdateTableName. Since the latter is "table", but the columns only know that they belong to a table + // named "alias", there will be no matching - so getColumnPositions wouldn't find anything. + + ::rtl::OUString sCatalog, sSchema, sTable; + Reference<XPropertySet> xTableProp( i_aTable, UNO_QUERY_THROW ); + xTableProp->getPropertyValue( PROPERTY_CATALOGNAME )>>= sCatalog; + xTableProp->getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema; + xTableProp->getPropertyValue( PROPERTY_NAME ) >>= sTable; + sUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation ); } - else + + ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sUpdateTableName,(*m_pKeyColumnNames),true); + ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sUpdateTableName,(*m_pColumnNames),true); + ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sUpdateTableName,(*m_pParameterNames),true); + + if ( m_pKeyColumnNames->empty() ) { - ::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; - 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); - ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sComposedUpdateTableName,(*m_pParameterNames),true); + ::dbtools::throwGenericSQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not find any key column." ) ), *this ); } - SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin(); - SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end(); - for(;aPosIter != aPosEnd;++aPosIter) + for ( SelectColumnsMetaData::const_iterator keyColumn = m_pKeyColumnNames->begin(); + keyColumn != m_pKeyColumnNames->end(); + ++keyColumn + ) { - 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); - } + if ( !xTblColumns->hasByName( keyColumn->second.sRealName ) ) + continue; + + Reference<XPropertySet> xProp( xTblColumns->getByName( keyColumn->second.sRealName ), UNO_QUERY ); + sal_Bool bAuto = sal_False; + if ( ( xProp->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= bAuto ) && bAuto ) + m_aAutoColumns.push_back( keyColumn->first ); } } ::rtl::OUStringBuffer OKeySet::createKeyFilter() @@ -286,7 +298,7 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY); const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns(); - findTableColumnsMatching_throw(makeAny(m_xTable),xMeta,xQueryColumns); + findTableColumnsMatching_throw(makeAny(m_xTable),m_sUpdateTableName,xMeta,xQueryColumns); // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first // without extra varaible to be set diff --git a/dbaccess/source/core/api/KeySet.hxx b/dbaccess/source/core/api/KeySet.hxx index 5403a56d6..631c22340 100644 --- a/dbaccess/source/core/api/KeySet.hxx +++ b/dbaccess/source/core/api/KeySet.hxx @@ -142,9 +142,10 @@ namespace dbaccess void impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData); void initColumns(); - 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 findTableColumnsMatching_throw( const ::com::sun::star::uno::Any& i_aTable, + const ::rtl::OUString& i_rUpdateTableName, + 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); ::rtl::OUStringBuffer createKeyFilter(); void tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch); void executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,const ::std::vector<sal_Int32>& _aIndexColumnPositions = ::std::vector<sal_Int32>()); diff --git a/dbaccess/source/core/api/OptimisticSet.cxx b/dbaccess/source/core/api/OptimisticSet.cxx index b68910d0f..832513330 100644 --- a/dbaccess/source/core/api/OptimisticSet.cxx +++ b/dbaccess/source/core/api/OptimisticSet.cxx @@ -133,7 +133,7 @@ void OptimisticSet::construct(const Reference< XResultSet>& _xDriverSet,const :: const ::rtl::OUString* pTableNameEnd = pTableNameIter + aTableNames.getLength(); for( ; pTableNameIter != pTableNameEnd ; ++pTableNameIter) { - findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),xMeta,xQueryColumns); + findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),*pTableNameIter,xMeta,xQueryColumns); } // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first diff --git a/dbaccess/source/core/api/RowSetCache.cxx b/dbaccess/source/core/api/RowSetCache.cxx index d42c8d20f..73c671258 100644 --- a/dbaccess/source/core/api/RowSetCache.cxx +++ b/dbaccess/source/core/api/RowSetCache.cxx @@ -28,84 +28,44 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" -#ifndef _COMPHELPER_SEQSTREAM_HXX -#include <comphelper/seqstream.hxx> -#endif -#ifndef _COMPHELPER_UNO3_HXX_ -#include <comphelper/uno3.hxx> -#endif -#ifndef _COMPHELPER_EXTRACT_HXX_ -#include <comphelper/extract.hxx> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_ -#include <com/sun/star/sdbcx/XKeysSupplier.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_ -#include <com/sun/star/sdbcx/XTablesSupplier.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_ -#include <com/sun/star/sdbcx/KeyType.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_RESULTSETCONCURRENCY_HPP_ -#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_ -#include <com/sun/star/sdbc/ColumnValue.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ -#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_ -#include <com/sun/star/sdbcx/Privilege.hpp> -#endif -#ifndef _DBACORE_DATACOLUMN_HXX_ -#include "CRowSetDataColumn.hxx" -#endif -#ifndef DBACCESS_CORE_API_CROWSETCOLUMN_HXX + +#include "BookmarkSet.hxx" #include "CRowSetColumn.hxx" -#endif -#ifndef DBACCESS_CORE_API_ROWSETBASE_HXX +#include "CRowSetDataColumn.hxx" +#include "KeySet.hxx" +#include "OptimisticSet.hxx" #include "RowSetBase.hxx" -#endif +#include "RowSetCache.hxx" +#include "StaticSet.hxx" +#include "WrappedResultSet.hxx" +#include "core_resource.hrc" +#include "core_resource.hxx" +#include "dbastrings.hrc" + +/** === begin UNO includes === **/ +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbcx/CompareBookmark.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XKeysSupplier.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +/** === end UNO includes === **/ + +#include <comphelper/extract.hxx> +#include <comphelper/property.hxx> +#include <comphelper/seqstream.hxx> +#include <comphelper/uno3.hxx> #include <connectivity/dbexception.hxx> -#include <connectivity/sqlparse.hxx> -#include <connectivity/sqlnode.hxx> #include <connectivity/dbtools.hxx> #include <connectivity/sqliterator.hxx> -#ifndef _COMPHELPER_PROPERTY_HXX_ -#include <comphelper/property.hxx> -#endif -#ifndef _COM_SUN_STAR_SDBCX_COMPAREBOOKMARK_HPP_ -#include <com/sun/star/sdbcx/CompareBookmark.hpp> -#endif -#ifndef _TOOLS_DEBUG_HXX +#include <connectivity/sqlnode.hxx> +#include <connectivity/sqlparse.hxx> #include <tools/debug.hxx> -#endif +#include <tools/diagnose_ex.h> #include <algorithm> -#ifndef DBACCESS_CORE_API_ROWSETCACHE_HXX -#include "RowSetCache.hxx" -#endif -#ifndef _DBA_CORE_RESOURCE_HXX_ -#include "core_resource.hxx" -#endif -#ifndef _DBA_CORE_RESOURCE_HRC_ -#include "core_resource.hrc" -#endif -#ifndef DBACCESS_CORE_API_BOOKMARKSET_HXX -#include "BookmarkSet.hxx" -#endif -#ifndef DBACCESS_CORE_API_STATICSET_HXX -#include "StaticSet.hxx" -#endif -#ifndef DBACCESS_CORE_API_KEYSET_HXX -#include "KeySet.hxx" -#endif -#ifndef DBACCESS_SHARED_DBASTRINGS_HRC -#include "dbastrings.hrc" -#endif -#include "WrappedResultSet.hxx" -#include "OptimisticSet.hxx" using namespace dbaccess; using namespace dbtools; @@ -228,7 +188,10 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, } catch(const Exception&) { + DBG_UNHANDLED_EXCEPTION(); } + m_pCacheSet = NULL; + m_xCacheSet.clear(); } else { |