summaryrefslogtreecommitdiff
path: root/dbaccess/source/core/api
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/core/api')
-rw-r--r--dbaccess/source/core/api/BookmarkSet.cxx278
-rw-r--r--dbaccess/source/core/api/BookmarkSet.hxx75
-rw-r--r--dbaccess/source/core/api/CIndexColumn.hxx59
-rw-r--r--dbaccess/source/core/api/CIndexes.cxx123
-rw-r--r--dbaccess/source/core/api/CIndexes.hxx58
-rw-r--r--dbaccess/source/core/api/CRowSetColumn.cxx111
-rw-r--r--dbaccess/source/core/api/CRowSetColumn.hxx66
-rw-r--r--dbaccess/source/core/api/CRowSetDataColumn.cxx292
-rw-r--r--dbaccess/source/core/api/CRowSetDataColumn.hxx113
-rw-r--r--dbaccess/source/core/api/CacheSet.cxx753
-rw-r--r--dbaccess/source/core/api/CacheSet.hxx179
-rw-r--r--dbaccess/source/core/api/FilteredContainer.cxx498
-rw-r--r--dbaccess/source/core/api/HelperCollections.cxx122
-rw-r--r--dbaccess/source/core/api/HelperCollections.hxx128
-rw-r--r--dbaccess/source/core/api/KeySet.cxx1704
-rw-r--r--dbaccess/source/core/api/KeySet.hxx233
-rw-r--r--dbaccess/source/core/api/OptimisticSet.cxx767
-rw-r--r--dbaccess/source/core/api/OptimisticSet.hxx109
-rw-r--r--dbaccess/source/core/api/PrivateRow.cxx142
-rw-r--r--dbaccess/source/core/api/PrivateRow.hxx69
-rw-r--r--dbaccess/source/core/api/RowSet.cxx3057
-rw-r--r--dbaccess/source/core/api/RowSet.hxx544
-rw-r--r--dbaccess/source/core/api/RowSetBase.cxx1577
-rw-r--r--dbaccess/source/core/api/RowSetBase.hxx463
-rw-r--r--dbaccess/source/core/api/RowSetCache.cxx1685
-rw-r--r--dbaccess/source/core/api/RowSetCache.hxx273
-rw-r--r--dbaccess/source/core/api/RowSetCacheIterator.cxx152
-rw-r--r--dbaccess/source/core/api/RowSetCacheIterator.hxx92
-rw-r--r--dbaccess/source/core/api/RowSetRow.hxx108
-rw-r--r--dbaccess/source/core/api/SingleSelectQueryComposer.cxx1875
-rw-r--r--dbaccess/source/core/api/StaticSet.cxx392
-rw-r--r--dbaccess/source/core/api/StaticSet.hxx93
-rw-r--r--dbaccess/source/core/api/TableDeco.cxx758
-rw-r--r--dbaccess/source/core/api/View.cxx161
-rw-r--r--dbaccess/source/core/api/WrappedResultSet.cxx255
-rw-r--r--dbaccess/source/core/api/WrappedResultSet.hxx79
-rw-r--r--dbaccess/source/core/api/callablestatement.cxx344
-rw-r--r--dbaccess/source/core/api/column.cxx481
-rw-r--r--dbaccess/source/core/api/columnsettings.cxx182
-rw-r--r--dbaccess/source/core/api/datacolumn.cxx485
-rw-r--r--dbaccess/source/core/api/datacolumn.hxx129
-rw-r--r--dbaccess/source/core/api/datasettings.cxx254
-rw-r--r--dbaccess/source/core/api/definitioncolumn.cxx673
-rw-r--r--dbaccess/source/core/api/makefile.mk82
-rw-r--r--dbaccess/source/core/api/preparedstatement.cxx473
-rw-r--r--dbaccess/source/core/api/query.cxx445
-rw-r--r--dbaccess/source/core/api/query.hxx186
-rw-r--r--dbaccess/source/core/api/querycomposer.cxx406
-rw-r--r--dbaccess/source/core/api/querycontainer.cxx475
-rw-r--r--dbaccess/source/core/api/querydescriptor.cxx323
-rw-r--r--dbaccess/source/core/api/querydescriptor.hxx183
-rw-r--r--dbaccess/source/core/api/resultcolumn.cxx357
-rw-r--r--dbaccess/source/core/api/resultcolumn.hxx101
-rw-r--r--dbaccess/source/core/api/resultset.cxx1208
-rw-r--r--dbaccess/source/core/api/resultset.hxx278
-rw-r--r--dbaccess/source/core/api/statement.cxx696
-rw-r--r--dbaccess/source/core/api/table.cxx417
-rw-r--r--dbaccess/source/core/api/tablecontainer.cxx516
-rw-r--r--dbaccess/source/core/api/viewcontainer.cxx274
59 files changed, 26411 insertions, 0 deletions
diff --git a/dbaccess/source/core/api/BookmarkSet.cxx b/dbaccess/source/core/api/BookmarkSet.cxx
new file mode 100644
index 000000000000..b5b9ec0ec787
--- /dev/null
+++ b/dbaccess/source/core/api/BookmarkSet.cxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef DBACCESS_CORE_API_BOOKMARKSET_HXX
+#include "BookmarkSet.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HXX_
+#include "core_resource.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HRC_
+#include "core_resource.hrc"
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETUPDATE_HPP_
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#endif
+#ifndef _DBHELPER_DBEXCEPTION_HXX_
+#include <connectivity/dbexception.hxx>
+#endif
+#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 OBookmarkSet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::construct" );
+ OCacheSet::construct(_xDriverSet,i_sRowSetFilter);
+ m_xRowLocate.set(_xDriverSet,UNO_QUERY);
+}
+// -----------------------------------------------------------------------------
+Any SAL_CALL OBookmarkSet::getBookmark() throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::getBookmark" );
+ return m_xRowLocate->getBookmark();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OBookmarkSet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::moveToBookmark" );
+ return m_xRowLocate->moveToBookmark(bookmark);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OBookmarkSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::moveRelativeToBookmark" );
+ return m_xRowLocate->moveRelativeToBookmark(bookmark,rows);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OBookmarkSet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::compareBookmarks" );
+ return m_xRowLocate->compareBookmarks(_first,_second);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OBookmarkSet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::hasOrderedBookmarks" );
+ return m_xRowLocate->hasOrderedBookmarks();
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OBookmarkSet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::hashBookmark" );
+ return m_xRowLocate->hashBookmark(bookmark);
+}
+// -------------------------------------------------------------------------
+// ::com::sun::star::sdbcx::XDeleteRows
+Sequence< sal_Int32 > SAL_CALL OBookmarkSet::deleteRows( const Sequence< Any >& rows ,const connectivity::OSQLTable& /*_xTable*/) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::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 OBookmarkSet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::insertRow" );
+ Reference<XRowUpdate> xUpdRow(m_xRowLocate,UNO_QUERY);
+ if(!xUpdRow.is())
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_XROWUPDATE ), SQL_GENERAL_ERROR, *this );
+
+ Reference<XResultSetUpdate> xUpd(m_xRowLocate,UNO_QUERY);
+ if(xUpd.is())
+ {
+ 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,xUpdRow,*aIter);
+ }
+ xUpd->insertRow();
+ (*_rInsertRow->get().begin()) = m_xRowLocate->getBookmark();
+ }
+ else
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_XRESULTSETUPDATE ), SQL_GENERAL_ERROR, *this );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OBookmarkSet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::updateRow" );
+ // OCacheSet::updateRow( _rInsertRow,_rOrginalRow,_xTable);
+ Reference<XRowUpdate> xUpdRow(m_xRowLocate,UNO_QUERY);
+ if(!xUpdRow.is())
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_XROWUPDATE ), SQL_GENERAL_ERROR, *this );
+
+ 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,xUpdRow,*aIter);
+ }
+
+
+ Reference<XResultSetUpdate> xUpd(m_xRowLocate,UNO_QUERY);
+ if(xUpd.is())
+ xUpd->updateRow();
+ else
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_XRESULTSETUPDATE ), SQL_GENERAL_ERROR, *this );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OBookmarkSet::deleteRow(const ORowSetRow& /*_rDeleteRow*/ ,const connectivity::OSQLTable& /*_xTable*/ ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::deleteRow" );
+ Reference<XResultSetUpdate> xUpd(m_xRowLocate,UNO_QUERY);
+
+ xUpd->deleteRow();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OBookmarkSet::cancelRowUpdates( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::cancelRowUpdates" );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OBookmarkSet::moveToInsertRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::moveToInsertRow" );
+ Reference<XResultSetUpdate> xUpd(m_xRowLocate,UNO_QUERY);
+ if(xUpd.is())
+ xUpd->moveToInsertRow();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OBookmarkSet::moveToCurrentRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::moveToCurrentRow" );
+}
+// -------------------------------------------------------------------------
+void OBookmarkSet::fillValueRow(ORowSetRow& _rRow,sal_Int32 _nPosition)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::fillValueRow" );
+ OCacheSet::fillValueRow(_rRow,_nPosition);
+}
+// -------------------------------------------------------------------------
+void OBookmarkSet::updateColumn(sal_Int32 nPos,Reference< XRowUpdate > _xParameter,const ORowSetValue& _rValue)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OBookmarkSet::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/BookmarkSet.hxx b/dbaccess/source/core/api/BookmarkSet.hxx
new file mode 100644
index 000000000000..36d3c90c7969
--- /dev/null
+++ b/dbaccess/source/core/api/BookmarkSet.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_BOOKMARKSET_HXX
+#define DBACCESS_CORE_API_BOOKMARKSET_HXX
+
+#ifndef DBACCESS_CORE_API_CACHESET_HXX
+#include "CacheSet.hxx"
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROWUPDATE_HPP_
+#include <com/sun/star/sdbc/XRowUpdate.hpp>
+#endif
+
+namespace dbaccess
+{
+ // this set is used when we have a bookmarkable set from the driver
+ class OBookmarkSet : public OCacheSet
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XRowLocate> m_xRowLocate;
+
+ void updateColumn(sal_Int32 nPos,::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowUpdate > _xParameter,const connectivity::ORowSetValue& _rValue);
+ public:
+ OBookmarkSet()
+ {}
+ ~OBookmarkSet()
+ {
+ 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_BOOKMARKSET_HXX
+
diff --git a/dbaccess/source/core/api/CIndexColumn.hxx b/dbaccess/source/core/api/CIndexColumn.hxx
new file mode 100644
index 000000000000..948d472ef88c
--- /dev/null
+++ b/dbaccess/source/core/api/CIndexColumn.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_INDEXCOLUMN_HXX_
+#define DBACCESS_INDEXCOLUMN_HXX_
+
+#ifndef _CONNECTIVITY_ADABAS_COLUMN_HXX_
+#include "adabas/BColumn.hxx"
+#endif
+
+namespace connectivity
+{
+ namespace adabas
+ {
+ class OIndexColumn : public OAdabasColumn
+ {
+ protected:
+ sal_Bool m_IsAscending;
+ public:
+ OIndexColumn();
+ OIndexColumn( sal_Bool _IsAscending,
+ const ::rtl::OUString& _Name,
+ const ::rtl::OUString& _TypeName,
+ const ::rtl::OUString& _DefaultValue,
+ sal_Int32 _IsNullable,
+ sal_Int32 _Precision,
+ sal_Int32 _Scale,
+ sal_Int32 _Type,
+ sal_Bool _IsAutoIncrement);
+
+ virtual void construct();
+ };
+ }
+}
+#endif // DBACCESS_INDEXCOLUMN_HXX_
diff --git a/dbaccess/source/core/api/CIndexes.cxx b/dbaccess/source/core/api/CIndexes.cxx
new file mode 100644
index 000000000000..3fdd9cc4de1a
--- /dev/null
+++ b/dbaccess/source/core/api/CIndexes.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef DBACCESS_INDEXES_HXX_
+#include "CIndexes.hxx"
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_INDEXTYPE_HPP_
+#include <com/sun/star/sdbc/IndexType.hpp>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _COMPHELPER_EXTRACT_HXX_
+#include <comphelper/extract.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+
+using namespace connectivity;
+using namespace connectivity::sdbcx;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace dbaccess;
+using namespace cppu;
+
+
+ObjectType OIndexes::createObject(const ::rtl::OUString& _rName)
+{
+ ObjectType xRet;
+ if ( m_xIndexes.is() && m_xIndexes->hasByName(_rName) )
+ xRet.set(m_xIndexes->getByName(_rName),UNO_QUERY);
+ else
+ xRet = OIndexesHelper::createObject(_rName);
+
+ return xRet;
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OIndexes::createDescriptor()
+{
+ Reference<XDataDescriptorFactory> xData( m_xIndexes,UNO_QUERY);
+ if(xData.is())
+ return xData->createDataDescriptor();
+ else
+ return OIndexesHelper::createDescriptor();
+}
+// -------------------------------------------------------------------------
+// XAppend
+ObjectType OIndexes::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ Reference<XAppend> xData( m_xIndexes,UNO_QUERY);
+ if ( !xData.is() )
+ return OIndexesHelper::appendObject( _rForName, descriptor );
+
+ xData->appendByDescriptor(descriptor);
+ return createObject( _rForName );
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OIndexes::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
+{
+ if ( m_xIndexes.is() )
+ {
+ Reference<XDrop> xData( m_xIndexes,UNO_QUERY);
+ if ( xData.is() )
+ xData->dropByName(_sElementName);
+ }
+ else
+ OIndexesHelper::dropObject(_nPos,_sElementName);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OIndexes::disposing(void)
+{
+ if ( m_xIndexes.is() )
+ clear_NoDispose();
+ else
+ OIndexesHelper::disposing();
+}
+// -----------------------------------------------------------------------------
+
+
+
+
diff --git a/dbaccess/source/core/api/CIndexes.hxx b/dbaccess/source/core/api/CIndexes.hxx
new file mode 100644
index 000000000000..c461204754be
--- /dev/null
+++ b/dbaccess/source/core/api/CIndexes.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_INDEXES_HXX_
+#define DBACCESS_INDEXES_HXX_
+
+#ifndef CONNECTIVITY_INDEXESHELPER_HXX
+#include "connectivity/TIndexes.hxx"
+#endif
+
+namespace dbaccess
+{
+ class OIndexes : public connectivity::OIndexesHelper
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xIndexes;
+ protected:
+ virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createDescriptor();
+ virtual connectivity::sdbcx::ObjectType appendObject( const ::rtl::OUString& _rForName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor );
+ virtual void dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName);
+ public:
+ OIndexes(connectivity::OTableHelper* _pTable,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxIndexes
+ ) : connectivity::OIndexesHelper(_pTable,_rMutex,_rVector)
+ ,m_xIndexes(_rxIndexes)
+ {}
+
+ virtual void SAL_CALL disposing(void);
+ };
+}
+
+#endif // DBACCESS_INDEXES_HXX_
diff --git a/dbaccess/source/core/api/CRowSetColumn.cxx b/dbaccess/source/core/api/CRowSetColumn.cxx
new file mode 100644
index 000000000000..12a7d16e8716
--- /dev/null
+++ b/dbaccess/source/core/api/CRowSetColumn.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "dbastrings.hrc"
+#include "apitools.hxx"
+#include "CRowSetColumn.hxx"
+
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <comphelper/types.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::beans;
+
+//..............................................................................
+namespace dbaccess
+{
+//..............................................................................
+
+//------------------------------------------------------------------------------
+ORowSetColumn::ORowSetColumn( const Reference < XResultSetMetaData >& _xMetaData, const Reference < XRow >& _xRow, sal_Int32 _nPos,
+ 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 )
+{
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* ORowSetColumn::createArrayHelper( ) const
+{
+ const sal_Int32 nDerivedProperties = 21;
+ Sequence< Property> aDerivedProperties( nDerivedProperties );
+ Property* pDesc = aDerivedProperties.getArray();
+ sal_Int32 nPos = 0;
+
+ DECL_PROP1( CATALOGNAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( DISPLAYSIZE, sal_Int32, READONLY );
+ DECL_PROP1_BOOL( ISAUTOINCREMENT, READONLY );
+ DECL_PROP1_BOOL( ISCASESENSITIVE, READONLY );
+ DECL_PROP1_BOOL( ISCURRENCY, READONLY );
+ DECL_PROP1_BOOL( ISDEFINITELYWRITABLE, READONLY );
+ DECL_PROP1( ISNULLABLE, sal_Int32, READONLY );
+ DECL_PROP1_BOOL( ISREADONLY, BOUND );
+ DECL_PROP1_BOOL( ISROWVERSION, READONLY );
+ DECL_PROP1_BOOL( ISSEARCHABLE, READONLY );
+ DECL_PROP1_BOOL( ISSIGNED, READONLY );
+ DECL_PROP1_BOOL( ISWRITABLE, READONLY );
+ DECL_PROP1( LABEL, ::rtl::OUString, READONLY );
+ DECL_PROP1( PRECISION, sal_Int32, READONLY );
+ DECL_PROP1( SCALE, sal_Int32, READONLY );
+ DECL_PROP1( SCHEMANAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( SERVICENAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( TABLENAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( TYPE, sal_Int32, READONLY );
+ DECL_PROP1( TYPENAME, ::rtl::OUString, READONLY );
+ DECL_PROP2( VALUE, Any, READONLY, BOUND );
+ OSL_ENSURE( nPos == nDerivedProperties, "ORowSetColumn::createArrayHelper: inconsistency!" );
+
+ Sequence< Property > aRegisteredProperties;
+ describeProperties( aRegisteredProperties );
+
+ return new ::cppu::OPropertyArrayHelper( ::comphelper::concatSequences( aDerivedProperties, aRegisteredProperties ), sal_False );
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& ORowSetColumn::getInfoHelper()
+{
+ return *static_cast< ::comphelper::OPropertyArrayUsageHelper< ORowSetColumn >* >(this)->getArrayHelper();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ORowSetColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue )throw (Exception)
+{
+ OSL_ENSURE( nHandle != PROPERTY_ID_VALUE, "ORowSetColumn::setFastPropertyValue_NoBroadcast: hmm? This property is marked as READONLY!" );
+ if ( nHandle != PROPERTY_ID_VALUE )
+ ORowSetDataColumn::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+}
+
+//..............................................................................
+} // namespace dbaccess
+//..............................................................................
diff --git a/dbaccess/source/core/api/CRowSetColumn.hxx b/dbaccess/source/core/api/CRowSetColumn.hxx
new file mode 100644
index 000000000000..043837f44589
--- /dev/null
+++ b/dbaccess/source/core/api/CRowSetColumn.hxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_CROWSETCOLUMN_HXX
+#define DBACCESS_CORE_API_CROWSETCOLUMN_HXX
+
+#ifndef DBACCESS_CORE_API_ROWSETROW_HXX
+#include "RowSetRow.hxx"
+#endif
+#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
+#include <connectivity/CommonTools.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
+#include <comphelper/proparrhlp.hxx>
+#endif
+#ifndef DBACCESS_CORE_API_CROWSETDATACOLUMN_HXX
+#include "CRowSetDataColumn.hxx"
+#endif
+
+namespace dbaccess
+{
+ class ORowSetColumn;
+ class ORowSetColumn :public ORowSetDataColumn
+ ,public ::comphelper::OPropertyArrayUsageHelper< ORowSetColumn >
+
+ {
+ public:
+ ORowSetColumn( const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData >& _xMetaData,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRow >& _xRow,
+ 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;
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,const ::com::sun::star::uno::Any& rValue )throw (::com::sun::star::uno::Exception );
+ };
+
+}
+
+#endif // DBACCESS_CORE_API_CROWSETCOLUMN_HXX
diff --git a/dbaccess/source/core/api/CRowSetDataColumn.cxx b/dbaccess/source/core/api/CRowSetDataColumn.cxx
new file mode 100644
index 000000000000..9bdcda88c93d
--- /dev/null
+++ b/dbaccess/source/core/api/CRowSetDataColumn.cxx
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _DBACORE_DATACOLUMN_HXX_
+#include "CRowSetDataColumn.hxx"
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+using namespace dbaccess;
+using namespace comphelper;
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+// using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace cppu;
+using namespace osl;
+
+DBG_NAME(ORowSetDataColumn)
+// -------------------------------------------------------------------------
+ORowSetDataColumn::ORowSetDataColumn( const Reference < XResultSetMetaData >& _xMetaData,
+ const Reference < XRow >& _xRow,
+ const Reference < XRowUpdate >& _xRowUpdate,
+ 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);
+ OColumnSettings::registerProperties( *this );
+ registerProperty( PROPERTY_DESCRIPTION, PROPERTY_ID_DESCRIPTION, PropertyAttribute::READONLY, &m_aDescription, ::getCppuType( &m_aDescription ) );
+}
+// -------------------------------------------------------------------------
+ORowSetDataColumn::~ORowSetDataColumn()
+{
+ DBG_DTOR(ORowSetDataColumn,NULL);
+}
+// -------------------------------------------------------------------------
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* ORowSetDataColumn::createArrayHelper( ) const
+{
+ const sal_Int32 nDerivedProperties = 21;
+ Sequence< Property> aDerivedProperties( nDerivedProperties );
+ Property* pDesc = aDerivedProperties.getArray();
+ sal_Int32 nPos = 0;
+
+ DECL_PROP1( CATALOGNAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( DISPLAYSIZE, sal_Int32, READONLY );
+ DECL_PROP1_BOOL( ISAUTOINCREMENT, READONLY );
+ DECL_PROP1_BOOL( ISCASESENSITIVE, READONLY );
+ DECL_PROP1_BOOL( ISCURRENCY, READONLY );
+ DECL_PROP1_BOOL( ISDEFINITELYWRITABLE, READONLY );
+ DECL_PROP1( ISNULLABLE, sal_Int32, READONLY );
+ DECL_PROP1_BOOL( ISREADONLY, BOUND );
+ DECL_PROP1_BOOL( ISROWVERSION, READONLY );
+ DECL_PROP1_BOOL( ISSEARCHABLE, READONLY );
+ DECL_PROP1_BOOL( ISSIGNED, READONLY );
+ DECL_PROP1_BOOL( ISWRITABLE, READONLY );
+ DECL_PROP1( LABEL, ::rtl::OUString, READONLY );
+ DECL_PROP1( PRECISION, sal_Int32, READONLY );
+ DECL_PROP1( SCALE, sal_Int32, READONLY );
+ DECL_PROP1( SCHEMANAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( SERVICENAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( TABLENAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( TYPE, sal_Int32, READONLY );
+ DECL_PROP1( TYPENAME, ::rtl::OUString, READONLY );
+ DECL_PROP1( VALUE, Any, BOUND );
+ OSL_ENSURE( nPos == nDerivedProperties, "ORowSetDataColumn::createArrayHelper: inconsistency!" );
+
+ Sequence< Property > aRegisteredProperties;
+ describeProperties( aRegisteredProperties );
+
+ return new ::cppu::OPropertyArrayHelper( ::comphelper::concatSequences( aDerivedProperties, aRegisteredProperties ), sal_False );
+}
+
+// cppu::OPropertySetHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& ORowSetDataColumn::getInfoHelper()
+{
+ return *static_cast< ::comphelper::OPropertyArrayUsageHelper< ORowSetDataColumn >* >(this)->getArrayHelper();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetDataColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ if ( PROPERTY_ID_VALUE == nHandle )
+ {
+ if ( !m_aColumnValue.isNull() && m_aColumnValue->isValid() )
+ {
+ ::osl::Mutex* pMutex = m_aColumnValue.getMutex();
+ ::osl::MutexGuard aGuard( *pMutex );
+#if OSL_DEBUG_LEVEL > 0
+ ORowSetRow aRow = *m_aColumnValue;
+#endif
+ OSL_ENSURE((sal_Int32)aRow->get().size() > m_nPos,"Pos is greater than size of vector");
+ rValue = ((*m_aColumnValue)->get())[m_nPos].makeAny();
+ }
+ }
+ else if ( PROPERTY_ID_LABEL == nHandle && m_sLabel.getLength() )
+ rValue <<= m_sLabel;
+ else
+ ODataColumn::getFastPropertyValue( rValue, nHandle );
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetDataColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue )throw (Exception)
+{
+ switch( nHandle )
+ {
+ 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;
+ }
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetDataColumn::convertFastPropertyValue( Any & rConvertedValue,
+ Any & rOldValue,
+ sal_Int32 nHandle,
+ const Any& rValue ) throw (IllegalArgumentException)
+{
+ sal_Bool bModified = sal_False;
+ switch( nHandle )
+ {
+ 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;
+ }
+
+ return bModified;
+}
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > ORowSetDataColumn::getImplementationId() throw (RuntimeException)
+{
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+// -------------------------------------------------------------------------
+void ORowSetDataColumn::fireValueChange(const ORowSetValue& _rOldValue)
+{
+ if ( !m_aColumnValue.isNull() && m_aColumnValue->isValid() && (!(((*m_aColumnValue)->get())[m_nPos] == _rOldValue)) )
+ {
+ sal_Int32 nHandle = PROPERTY_ID_VALUE;
+ m_aOldValue = _rOldValue.makeAny();
+ Any aNew = ((*m_aColumnValue)->get())[m_nPos].makeAny();
+
+ fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
+ }
+ else if ( !m_aColumnValue.isNull() && !_rOldValue.isNull() )
+ {
+ sal_Int32 nHandle = PROPERTY_ID_VALUE;
+ m_aOldValue = _rOldValue.makeAny();
+ Any aNew;
+
+ fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
+ }
+}
+// -----------------------------------------------------------------------------
+DBG_NAME(ORowSetDataColumns )
+ORowSetDataColumns::ORowSetDataColumns(
+ sal_Bool _bCase,
+ const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector
+ ) : connectivity::sdbcx::OCollection(_rParent,_bCase,_rMutex,_rVector)
+ ,m_aColumns(_rColumns)
+{
+ DBG_CTOR(ORowSetDataColumns ,NULL);
+}
+// -----------------------------------------------------------------------------
+ORowSetDataColumns::~ORowSetDataColumns()
+{
+ DBG_DTOR(ORowSetDataColumns ,NULL);
+}
+// -----------------------------------------------------------------------------
+sdbcx::ObjectType ORowSetDataColumns::createObject(const ::rtl::OUString& _rName)
+{
+ connectivity::sdbcx::ObjectType xNamed;
+
+ ::comphelper::UStringMixEqual aCase(isCaseSensitive());
+ ::connectivity::OSQLColumns::Vector::const_iterator first = ::connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),_rName,aCase);
+ if(first != m_aColumns->get().end())
+ xNamed.set(*first,UNO_QUERY);
+
+ return xNamed;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ORowSetDataColumns::disposing(void)
+{
+ // clear_NoDispose();
+ ORowSetDataColumns_BASE::disposing();
+ m_aColumns = NULL;
+ // m_aColumns.clear();
+}
+// -----------------------------------------------------------------------------
+void ORowSetDataColumns::assign(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,const ::std::vector< ::rtl::OUString> &_rVector)
+{
+ m_aColumns = _rColumns;
+ reFill(_rVector);
+}
+// -----------------------------------------------------------------------------
+void ORowSetDataColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
+{
+}
+// -----------------------------------------------------------------------------
+
+
diff --git a/dbaccess/source/core/api/CRowSetDataColumn.hxx b/dbaccess/source/core/api/CRowSetDataColumn.hxx
new file mode 100644
index 000000000000..e5009d4d6f7c
--- /dev/null
+++ b/dbaccess/source/core/api/CRowSetDataColumn.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_CROWSETDATACOLUMN_HXX
+#define DBACCESS_CORE_API_CROWSETDATACOLUMN_HXX
+
+#include "datacolumn.hxx"
+#include "RowSetRow.hxx"
+#include "RowSetCacheIterator.hxx"
+#include "columnsettings.hxx"
+
+#include <connectivity/CommonTools.hxx>
+#include <comphelper/proparrhlp.hxx>
+
+namespace dbaccess
+{
+ class ORowSetDataColumn;
+ typedef ::comphelper::OPropertyArrayUsageHelper<ORowSetDataColumn> ORowSetDataColumn_PROP;
+
+ class ORowSetDataColumn : public ODataColumn,
+ public OColumnSettings,
+ public ORowSetDataColumn_PROP
+ {
+ protected:
+ ORowSetCacheIterator m_aColumnValue;
+ ::com::sun::star::uno::Any m_aOldValue;
+
+ ::rtl::OUString m_sLabel;
+ ::rtl::OUString m_aDescription; // description
+ ORowSetBase* m_pRowSet;
+
+ virtual ~ORowSetDataColumn();
+ public:
+ ORowSetDataColumn(const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData >& _xMetaData,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRow >& _xRow,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRowUpdate >& _xRowUpdate,
+ 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);
+
+
+ // com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any & rConvertedValue,
+ ::com::sun::star::uno::Any & rOldValue,
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+ 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;
+ };
+ // -------------------------------------------------------------------------
+// typedef connectivity::ORefVector< ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> >
+// ORowSetDataColumns_COLLECTION;
+
+ typedef connectivity::sdbcx::OCollection ORowSetDataColumns_BASE;
+ class ORowSetDataColumns : public ORowSetDataColumns_BASE
+ {
+ ::vos::ORef< ::connectivity::OSQLColumns> m_aColumns;
+ protected:
+ virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
+ virtual void impl_refresh() throw(::com::sun::star::uno::RuntimeException);
+ public:
+ ORowSetDataColumns(
+ sal_Bool _bCase,
+ const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector
+ );
+ virtual ~ORowSetDataColumns();
+ // only the name is identical to ::cppu::OComponentHelper
+ virtual void SAL_CALL disposing(void);
+ void assign(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,const ::std::vector< ::rtl::OUString> &_rVector);
+ };
+}
+
+#endif
+
diff --git a/dbaccess/source/core/api/CacheSet.cxx b/dbaccess/source/core/api/CacheSet.cxx
new file mode 100644
index 000000000000..dd64e835adb4
--- /dev/null
+++ b/dbaccess/source/core/api/CacheSet.cxx
@@ -0,0 +1,753 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef DBACCESS_CORE_API_CACHESET_HXX
+#include "CacheSet.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HXX_
+#include "core_resource.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HRC_
+#include "core_resource.hrc"
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_COMPAREBOOKMARK_HPP_
+#include <com/sun/star/sdbcx/CompareBookmark.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XPREPAREDSTATEMENT_HPP_
+#include <com/sun/star/sdbc/XPreparedStatement.hpp>
+#endif
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#ifndef _COM_SUN_STAR_SDBC_XPARAMETERS_HPP_
+#include <com/sun/star/sdbc/XParameters.hpp>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XINDEXESSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
+#endif
+
+#include <limits>
+
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#endif
+#ifndef _COMPHELPER_EXTRACT_HXX_
+#include <comphelper/extract.hxx>
+#endif
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace comphelper;
+
+using namespace dbaccess;
+using namespace dbtools;
+using namespace connectivity;
+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::io;
+// using namespace ::cppu;
+using namespace ::osl;
+
+DBG_NAME(OCacheSet)
+// -------------------------------------------------------------------------
+OCacheSet::OCacheSet()
+ :m_bInserted(sal_False)
+ ,m_bUpdated(sal_False)
+ ,m_bDeleted(sal_False)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::OCacheSet" );
+ DBG_CTOR(OCacheSet,NULL);
+
+}
+// -------------------------------------------------------------------------
+::rtl::OUString OCacheSet::getIdentifierQuoteString() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getIdentifierQuoteString" );
+ ::rtl::OUString sQuote;
+ Reference<XDatabaseMetaData> xMeta;
+ if ( m_xConnection.is() && (xMeta = m_xConnection->getMetaData()).is() )
+ sQuote = xMeta->getIdentifierQuoteString();
+ return sQuote;
+}
+// -------------------------------------------------------------------------
+void OCacheSet::construct( const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& /*i_sRowSetFilter*/)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::construct" );
+ OSL_ENSURE(_xDriverSet.is(),"Invalid resultSet");
+ if(_xDriverSet.is())
+ {
+ m_xDriverSet = _xDriverSet;
+ m_xDriverRow.set(_xDriverSet,UNO_QUERY);
+ m_xSetMetaData = Reference<XResultSetMetaDataSupplier>(_xDriverSet,UNO_QUERY)->getMetaData();
+ if ( m_xSetMetaData.is() )
+ {
+ const sal_Int32 nCount = m_xSetMetaData->getColumnCount();
+ m_aNullable.realloc(nCount);
+ m_aSignedFlags.realloc(nCount);
+ m_aColumnTypes.realloc(nCount);
+ sal_Bool* pNullableIter = m_aNullable.getArray();
+ sal_Bool* pSignedIter = m_aSignedFlags.getArray();
+ sal_Int32* pColumnIter = m_aColumnTypes.getArray();
+ for (sal_Int32 i=1; i <= nCount; ++i,++pSignedIter,++pColumnIter,++pNullableIter)
+ {
+ *pNullableIter = m_xSetMetaData->isNullable(i) != ColumnValue::NO_NULLS;
+ *pSignedIter = m_xSetMetaData->isSigned(i);
+ *pColumnIter = m_xSetMetaData->getColumnType(i);
+ }
+ }
+ Reference< XStatement> xStmt(m_xDriverSet->getStatement(),UNO_QUERY);
+ if(xStmt.is())
+ m_xConnection = xStmt->getConnection();
+ else
+ {
+ Reference< XPreparedStatement> xPrepStmt(m_xDriverSet->getStatement(),UNO_QUERY);
+ if ( xPrepStmt.is() )
+ m_xConnection = xPrepStmt->getConnection();
+ }
+ }
+}
+// -------------------------------------------------------------------------
+OCacheSet::~OCacheSet()
+{
+ try
+ {
+ m_xDriverSet = NULL;
+ m_xDriverRow = NULL;
+ m_xSetMetaData = NULL;
+ m_xConnection = NULL;
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(0,"Exception occured");
+ }
+ catch(...)
+ {
+ OSL_ENSURE(0,"Unknown Exception occured");
+ }
+
+ DBG_DTOR(OCacheSet,NULL);
+}
+// -----------------------------------------------------------------------------
+void OCacheSet::fillTableName(const Reference<XPropertySet>& _xTable) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::fillTableName" );
+ OSL_ENSURE(_xTable.is(),"OCacheSet::fillTableName: PropertySet is empty!");
+ if(!m_aComposedTableName.getLength() && _xTable.is() )
+ {
+ Reference<XDatabaseMetaData> xMeta(m_xConnection->getMetaData());
+ m_aComposedTableName = composeTableName(xMeta
+ ,comphelper::getString(_xTable->getPropertyValue(PROPERTY_CATALOGNAME))
+ ,comphelper::getString(_xTable->getPropertyValue(PROPERTY_SCHEMANAME))
+ ,comphelper::getString(_xTable->getPropertyValue(PROPERTY_NAME))
+ ,sal_True
+ ,::dbtools::eInDataManipulation);
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OCacheSet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::insertRow" );
+ ::rtl::OUStringBuffer aSql(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("INSERT INTO ")));
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" ( "));
+ // set values and column names
+ ::rtl::OUStringBuffer aValues = ::rtl::OUString::createFromAscii(" VALUES ( ");
+ static ::rtl::OUString aPara(RTL_CONSTASCII_USTRINGPARAM("?,"));
+ ::rtl::OUString aQuote = getIdentifierQuoteString();
+ static ::rtl::OUString aComma(RTL_CONSTASCII_USTRINGPARAM(","));
+ sal_Int32 i = 1;
+ ORowVector< ORowSetValue >::Vector::const_iterator aIter = _rInsertRow->get().begin()+1;
+ connectivity::ORowVector< ORowSetValue > ::Vector::iterator aEnd = _rInsertRow->get().end();
+ for(; aIter != aEnd;++aIter)
+ {
+ aSql.append(::dbtools::quoteName( aQuote,m_xSetMetaData->getColumnName(i++)));
+ aSql.append(aComma);
+ aValues.append(aPara);
+ }
+
+ aSql.setCharAt(aSql.getLength()-1,')');
+ aValues.setCharAt(aValues.getLength()-1,')');
+
+ aSql.append(aValues.makeStringAndClear());
+ // now create end execute the prepared statement
+ {
+ Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
+ Reference< XParameters > xParameter(xPrep,UNO_QUERY);
+ i = 1;
+ for(aIter = _rInsertRow->get().begin()+1; aIter != aEnd;++aIter,++i)
+ {
+ if(aIter->isNull())
+ xParameter->setNull(i,aIter->getTypeKind());
+ else
+ setParameter(i,xParameter,*aIter,m_xSetMetaData->getColumnType(i),m_xSetMetaData->getScale(i));
+ }
+
+ m_bInserted = xPrep->executeUpdate() > 0;
+ }
+
+// ::rtl::OUString aCountSql = ::rtl::OUString::createFromAscii("SELECT COUNT(*) FROM ");
+// aCountSql += m_aComposedTableName;
+// try
+// {
+// Reference< XStatement > xStmt(m_xConnection->createStatement());
+// Reference<XResultSet> xRes(xStmt->executeQuery(aCountSql));
+// if(xRes.is() && xRes->next())
+// {
+// Reference<XRow> xRow(xRes,UNO_QUERY);
+// }
+// }
+// catch(SQLException&)
+// {
+// }
+
+ // TODO set the bookmark in the insert row
+}
+// -------------------------------------------------------------------------
+void OCacheSet::fillParameters( const ORowSetRow& _rRow
+ ,const connectivity::OSQLTable& _xTable
+ ,::rtl::OUStringBuffer& _sCondition
+ ,::rtl::OUStringBuffer& _sParameter
+ ,::std::list< sal_Int32>& _rOrgValues)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::fillParameters" );
+ // use keys and indexes for excat postioning
+ // first the keys
+ 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;
+ if(xIndexSup.is())
+ xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
+
+ // Reference<XColumnsSupplier>
+ Reference<XPropertySet> xIndexColsSup;
+ Reference<XNameAccess> xIndexColumns;
+ ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
+ if(xIndexes.is())
+ {
+ for(sal_Int32 j=0;j<xIndexes->getCount();++j)
+ {
+ xIndexColsSup.set(xIndexes->getByIndex(j),UNO_QUERY);
+ if( xIndexColsSup.is()
+ && comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE))
+ && !comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX))
+ )
+ aAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns());
+ }
+ }
+
+ ::rtl::OUString aColumnName;
+
+ static ::rtl::OUString aPara = ::rtl::OUString::createFromAscii("?,");
+ static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
+
+ ::rtl::OUString aQuote = getIdentifierQuoteString();
+
+ sal_Int32 nCheckCount = 1; // index for the orginal values
+ sal_Int32 i = 1;
+
+ ::rtl::OUString sIsNull(RTL_CONSTASCII_USTRINGPARAM(" IS NULL"));
+ ::rtl::OUString sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
+ ORowVector< ORowSetValue >::Vector::const_iterator aIter = _rRow->get().begin()+1;
+ ORowVector< ORowSetValue >::Vector::const_iterator aEnd = _rRow->get().end()+1;
+ for(; aIter != aEnd;++aIter,++nCheckCount,++i)
+ {
+ aColumnName = m_xSetMetaData->getColumnName(i);
+ if(xPrimaryKeyColumns.is() && xPrimaryKeyColumns->hasByName(aColumnName))
+ {
+ _sCondition.append(::dbtools::quoteName( aQuote,aColumnName));
+ if(aIter->isNull())
+ _sCondition.append(sIsNull);
+ else
+ _sCondition.append(sParam);
+ _sCondition.append(aAnd);
+ _rOrgValues.push_back(nCheckCount);
+
+ } // 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)
+ {
+ if((*aIndexIter)->hasByName(aColumnName))
+ {
+ _sCondition.append(::dbtools::quoteName( aQuote,aColumnName));
+ if(aIter->isNull())
+ _sCondition.append(sIsNull);
+ else
+ _sCondition.append(sParam);
+ _sCondition.append(aAnd);
+ _rOrgValues.push_back(nCheckCount);
+ break;
+ }
+ }
+ if(aIter->isModified())
+ {
+ _sParameter.append(::dbtools::quoteName( aQuote,aColumnName));
+ _sParameter.append(aPara);
+ }
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OCacheSet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::updateRow" );
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("UPDATE ");
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" SET "));
+ // list all cloumns that should be set
+
+ ::rtl::OUStringBuffer aCondition;
+ ::std::list< sal_Int32> aOrgValues;
+ fillParameters(_rInsertRow,_xTable,aCondition,aSql,aOrgValues);
+ aSql.setCharAt(aSql.getLength()-1,' ');
+ if ( aCondition.getLength() )
+ {
+ aCondition.setLength(aCondition.getLength()-5);
+
+ aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
+ aSql.append(aCondition.makeStringAndClear());
+ }
+ else
+ ::dbtools::throwSQLException(
+ DBACORE_RESSTRING( RID_STR_NO_UPDATE_MISSING_CONDITION ), SQL_GENERAL_ERROR, *this );
+
+ // now create end execute the prepared statement
+ Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
+ Reference< XParameters > xParameter(xPrep,UNO_QUERY);
+ sal_Int32 i = 1;
+ connectivity::ORowVector< ORowSetValue > ::Vector::iterator aEnd = _rInsertRow->get().end();
+ for(ORowVector< ORowSetValue >::Vector::const_iterator aIter = _rInsertRow->get().begin()+1; aIter != aEnd;++aIter)
+ {
+ if(aIter->isModified())
+ {
+ setParameter(i,xParameter,*aIter,m_xSetMetaData->getColumnType(i),m_xSetMetaData->getScale(i));
+ ++i;
+ }
+ } // for(ORowVector< ORowSetValue >::Vector::const_iterator aIter = _rInsertRow->get().begin()+1; aIter != aEnd;++aIter)
+ ::std::list< sal_Int32>::const_iterator aOrgValueEnd = aOrgValues.end();
+ for(::std::list< sal_Int32>::const_iterator aOrgValue = aOrgValues.begin(); aOrgValue != aOrgValueEnd;++aOrgValue,++i)
+ {
+ setParameter(i,xParameter,(_rOrginalRow->get())[*aOrgValue],m_xSetMetaData->getColumnType(i),m_xSetMetaData->getScale(i));
+ }
+
+ m_bUpdated = xPrep->executeUpdate() > 0;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OCacheSet::deleteRow(const ORowSetRow& _rDeleteRow ,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::deleteRow" );
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("DELETE FROM ");
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
+
+ // list all cloumns that should be set
+ ::rtl::OUString aQuote = getIdentifierQuoteString();
+ static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
+
+ // use keys and indexes for excat postioning
+ // first the keys
+ const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet);
+ // second the indexes
+ Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
+ Reference<XIndexAccess> xIndexes;
+ if(xIndexSup.is())
+ xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
+
+ // Reference<XColumnsSupplier>
+ Reference<XPropertySet> xIndexColsSup;
+ Reference<XNameAccess> xIndexColumns;
+ ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
+ if(xIndexes.is())
+ {
+ for(sal_Int32 j=0;j<xIndexes->getCount();++j)
+ {
+ xIndexColsSup.set(xIndexes->getByIndex(j),UNO_QUERY);
+ if( xIndexColsSup.is()
+ && comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISUNIQUE))
+ && !comphelper::getBOOL(xIndexColsSup->getPropertyValue(PROPERTY_ISPRIMARYKEYINDEX))
+ )
+ aAllIndexColumns.push_back(Reference<XColumnsSupplier>(xIndexColsSup,UNO_QUERY)->getColumns());
+ }
+ }
+
+ ::rtl::OUStringBuffer aColumnName;
+ ::std::list< sal_Int32> aOrgValues;
+ fillParameters(_rDeleteRow,_xTable,aSql,aColumnName,aOrgValues);
+
+ aSql.setLength(aSql.getLength()-5);
+
+ // now create end execute the prepared statement
+ Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
+ Reference< XParameters > xParameter(xPrep,UNO_QUERY);
+ sal_Int32 i = 1;
+ ::std::list< sal_Int32>::const_iterator aOrgValueEnd = aOrgValues.end();
+ for(::std::list< sal_Int32>::const_iterator j = aOrgValues.begin(); j != aOrgValueEnd;++j,++i)
+ {
+ setParameter(i,xParameter,(_rDeleteRow->get())[*j],m_xSetMetaData->getColumnType(i),m_xSetMetaData->getScale(i));
+ }
+
+ m_bDeleted = xPrep->executeUpdate() > 0;
+}
+// -------------------------------------------------------------------------
+void OCacheSet::setParameter(sal_Int32 nPos
+ ,const Reference< XParameters >& _xParameter
+ ,const ORowSetValue& _rValue
+ ,sal_Int32 _nType
+ ,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();
+ ::dbtools::setObjectWithInfo(_xParameter,nPos,_rValue,nType,_nScale);
+}
+// -------------------------------------------------------------------------
+void OCacheSet::fillValueRow(ORowSetRow& _rRow,sal_Int32 _nPosition)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::fillValueRow" );
+ Any aBookmark = getBookmark();
+ if(!aBookmark.hasValue())
+ aBookmark = makeAny(_nPosition);
+
+ connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = _rRow->get().begin();
+ connectivity::ORowVector< ORowSetValue >::Vector::iterator aEnd = _rRow->get().end();
+ (*aIter) = aBookmark;
+ ++aIter;
+ for(sal_Int32 i=1;aIter != aEnd;++aIter,++i)
+ {
+ aIter->setSigned(m_aSignedFlags[i-1]);
+ aIter->fill(i,m_aColumnTypes[i-1],m_aNullable[i-1],this);
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::wasNull( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::wasNull" );
+ return m_xDriverRow->wasNull();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OCacheSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getString" );
+ return m_xDriverRow->getString(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getBoolean" );
+ return m_xDriverRow->getBoolean(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int8 SAL_CALL OCacheSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getByte" );
+ return m_xDriverRow->getByte(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int16 SAL_CALL OCacheSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getShort" );
+ return m_xDriverRow->getShort(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OCacheSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getInt" );
+ return m_xDriverRow->getInt(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int64 SAL_CALL OCacheSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getLong" );
+ return m_xDriverRow->getLong(columnIndex);
+}
+// -------------------------------------------------------------------------
+float SAL_CALL OCacheSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getFloat" );
+ return m_xDriverRow->getFloat(columnIndex);
+}
+// -------------------------------------------------------------------------
+double SAL_CALL OCacheSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getDouble" );
+ return m_xDriverRow->getDouble(columnIndex);
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL OCacheSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getBytes" );
+ return m_xDriverRow->getBytes(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Date SAL_CALL OCacheSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getDate" );
+ return m_xDriverRow->getDate(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Time SAL_CALL OCacheSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getTime" );
+ return m_xDriverRow->getTime(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::DateTime SAL_CALL OCacheSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getTimestamp" );
+ return m_xDriverRow->getTimestamp(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL OCacheSet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getBinaryStream" );
+ return m_xDriverRow->getBinaryStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL OCacheSet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getCharacterStream" );
+ return m_xDriverRow->getCharacterStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL OCacheSet::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", "OCacheSet::getObject" );
+ return m_xDriverRow->getObject(columnIndex,typeMap);
+}
+// -------------------------------------------------------------------------
+Reference< XRef > SAL_CALL OCacheSet::getRef( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getRef" );
+ return m_xDriverRow->getRef(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL OCacheSet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getBlob" );
+ return m_xDriverRow->getBlob(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XClob > SAL_CALL OCacheSet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getClob" );
+ return m_xDriverRow->getClob(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XArray > SAL_CALL OCacheSet::getArray( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getArray" );
+ return m_xDriverRow->getArray(columnIndex);
+}
+// -------------------------------------------------------------------------
+// XResultSet
+sal_Bool SAL_CALL OCacheSet::next( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::next" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return m_xDriverSet->next();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::isBeforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::isBeforeFirst" );
+ return m_xDriverSet->isBeforeFirst();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::isAfterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::isAfterLast" );
+ return m_xDriverSet->isAfterLast();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::isFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::isFirst" );
+ return m_xDriverSet->isFirst();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::isLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::isLast" );
+ return m_xDriverSet->isLast();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OCacheSet::beforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::beforeFirst" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ m_xDriverSet->beforeFirst();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OCacheSet::afterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::afterLast" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ m_xDriverSet->afterLast();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::first( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::first" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return m_xDriverSet->first();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::last( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::last" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return m_xDriverSet->last();
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OCacheSet::getRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getRow" );
+ return m_xDriverSet->getRow();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::absolute" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return m_xDriverSet->absolute(row);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::relative" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return m_xDriverSet->relative(rows);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::previous( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::previous" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return m_xDriverSet->previous();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OCacheSet::refreshRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::refreshRow" );
+ m_xDriverSet->refreshRow();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::rowUpdated( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::rowUpdated" );
+ return m_xDriverSet->rowUpdated();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::rowInserted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::rowInserted" );
+ return m_xDriverSet->rowInserted();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OCacheSet::rowDeleted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::rowDeleted" );
+ return m_xDriverSet->rowDeleted();
+}
+// -------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL OCacheSet::getStatement( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCacheSet::getStatement" );
+ 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
new file mode 100644
index 000000000000..ef3503fa5e4e
--- /dev/null
+++ b/dbaccess/source/core/api/CacheSet.hxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_CACHESET_HXX
+#define DBACCESS_CORE_API_CACHESET_HXX
+
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
+#include <com/sun/star/sdbc/XConnection.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XDELETEROWS_HPP_
+#include <com/sun/star/sdbcx/XDeleteRows.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_COMPAREBOOKMARK_HPP_
+#include <com/sun/star/sdbcx/CompareBookmark.hpp>
+#endif
+#ifndef DBACCESS_CORE_API_ROWSETROW_HXX
+#include "RowSetRow.hxx"
+#endif
+#ifndef _CPPUHELPER_IMPLBASE1_HXX_
+#include <cppuhelper/implbase1.hxx>
+#endif
+
+#include <list>
+namespace rtl
+{
+ class OUStringBuffer;
+}
+namespace com{ namespace sun { namespace star{namespace sdbc{ class XParameters; } } } }
+
+namespace dbaccess
+{
+ class OCacheSet : public ::cppu::WeakImplHelper1< ::com::sun::star::sdbc::XRow>
+ {
+ protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet> m_xDriverSet;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow> m_xDriverRow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData> m_xSetMetaData;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection> m_xConnection;
+
+ ::com::sun::star::uno::Sequence<sal_Bool> m_aNullable;
+ ::com::sun::star::uno::Sequence<sal_Bool> m_aSignedFlags;
+ ::com::sun::star::uno::Sequence<sal_Int32> m_aColumnTypes;
+ ORowSetRow m_aInsertRow;
+ ::rtl::OUString m_aComposedTableName;
+ sal_Bool m_bInserted;
+ sal_Bool m_bUpdated;
+ sal_Bool m_bDeleted;
+
+ OCacheSet();
+ virtual ~OCacheSet();
+
+ void setParameter(sal_Int32 nPos
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XParameters >& _xParameter
+ ,const connectivity::ORowSetValue& _rValue
+ ,sal_Int32 _nType
+ ,sal_Int32 _nScale
+ ) const;
+ void fillParameters( const ORowSetRow& _rRow
+ ,const connectivity::OSQLTable& _xTable
+ ,::rtl::OUStringBuffer& _sCondition
+ ,::rtl::OUStringBuffer& _sParameter
+ ,::std::list< sal_Int32>& _rOrgValues);
+ void fillTableName(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xTable) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ ::rtl::OUString getIdentifierQuoteString() const;
+ public:
+
+ // late constructor
+ 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::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);
+ // ::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);
+ 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);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getStatement( ) 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) = 0;
+ virtual sal_Bool SAL_CALL moveToBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0;
+ 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) = 0;
+ 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) = 0;
+ virtual sal_Bool SAL_CALL hasOrderedBookmarks( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0;
+ virtual sal_Int32 SAL_CALL hashBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0;
+ // ::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) = 0;
+ // ::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) = 0;
+ virtual void SAL_CALL deleteRow( const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0;
+ 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/FilteredContainer.cxx b/dbaccess/source/core/api/FilteredContainer.cxx
new file mode 100644
index 000000000000..aa20bf080e4d
--- /dev/null
+++ b/dbaccess/source/core/api/FilteredContainer.cxx
@@ -0,0 +1,498 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "dbastrings.hrc"
+#include "FilteredContainer.hxx"
+#include "RefreshListener.hxx"
+#include "sdbcoretools.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <connectivity/dbtools.hxx>
+#include <tools/wldcrd.hxx>
+#include <tools/diagnose_ex.h>
+#include <rtl/logfile.hxx>
+#include <boost/optional.hpp>
+
+namespace dbaccess
+{
+ using namespace dbtools;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ 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::util;
+ using namespace ::com::sun::star::container;
+ using namespace ::osl;
+ using namespace ::comphelper;
+ using namespace ::cppu;
+ using namespace ::connectivity::sdbcx;
+
+//------------------------------------------------------------------------------
+/** creates a vector of WildCards and reduce the _rTableFilter of the length of WildsCards
+*/
+sal_Int32 createWildCardVector(Sequence< ::rtl::OUString >& _rTableFilter, ::std::vector< WildCard >& _rOut)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OFilteredContainer::createWildCardVector" );
+ // for wildcard search : remove all table filters which are a wildcard expression and build a WilCard
+ // for them
+ ::rtl::OUString* pTableFilters = _rTableFilter.getArray();
+ ::rtl::OUString* pEnd = pTableFilters + _rTableFilter.getLength();
+ sal_Int32 nShiftPos = 0;
+ for (sal_Int32 i=0; pEnd != pTableFilters; ++pTableFilters,++i)
+ {
+ if (pTableFilters->indexOf('%') != -1)
+ {
+ _rOut.push_back(WildCard(pTableFilters->replace('%', '*')));
+ }
+ else
+ {
+ if (nShiftPos != i)
+ {
+ _rTableFilter.getArray()[nShiftPos] = _rTableFilter.getArray()[i];
+ }
+ ++nShiftPos;
+ }
+ }
+ // now aTableFilter contains nShiftPos non-wc-strings and aWCSearch all wc-strings
+ _rTableFilter.realloc(nShiftPos);
+ return nShiftPos;
+}
+
+ // -------------------------------------------------------------------------
+ bool lcl_isElementAllowed( const ::rtl::OUString& _rName,
+ const Sequence< ::rtl::OUString >& _rTableFilter,
+ const ::std::vector< WildCard >& _rWCSearch )
+ {
+ sal_Int32 nTableFilterLen = _rTableFilter.getLength();
+
+ const ::rtl::OUString* tableFilter = _rTableFilter.getConstArray();
+ const ::rtl::OUString* tableFilterEnd = _rTableFilter.getConstArray() + nTableFilterLen;
+ bool bFilterMatch = ::std::find( tableFilter, tableFilterEnd, _rName ) != tableFilterEnd;
+ // the table is allowed to "pass" if we had no filters at all or any of the non-wildcard filters matches
+ if (!bFilterMatch && !_rWCSearch.empty())
+ { // or if one of the wildcrad expression matches
+ for ( ::std::vector< WildCard >::const_iterator aLoop = _rWCSearch.begin();
+ aLoop != _rWCSearch.end() && !bFilterMatch;
+ ++aLoop
+ )
+ bFilterMatch = aLoop->Matches( _rName );
+ }
+
+ return bFilterMatch;
+ }
+
+ //--------------------------------------------------------------------------
+ typedef ::boost::optional< ::rtl::OUString > OptionalString;
+ struct TableInfo
+ {
+ OptionalString sComposedName;
+ OptionalString sType;
+ OptionalString sCatalog;
+ OptionalString sSchema;
+ OptionalString sName;
+
+ TableInfo( const ::rtl::OUString& _composedName )
+ :sComposedName( _composedName )
+ {
+ }
+
+ TableInfo( const ::rtl::OUString& _catalog, const ::rtl::OUString& _schema, const ::rtl::OUString& _name,
+ const ::rtl::OUString& _type )
+ :sComposedName()
+ ,sType( _type )
+ ,sCatalog( _catalog )
+ ,sSchema( _schema )
+ ,sName( _name )
+ {
+ }
+ };
+ typedef ::std::vector< TableInfo > TableInfos;
+
+ //--------------------------------------------------------------------------
+ void lcl_ensureComposedName( TableInfo& _io_tableInfo, const Reference< XDatabaseMetaData >& _metaData )
+ {
+ if ( !_metaData.is() )
+ throw RuntimeException();
+
+ if ( !_io_tableInfo.sComposedName )
+ {
+ OSL_ENSURE( !!_io_tableInfo.sCatalog && !!_io_tableInfo.sSchema && !!_io_tableInfo.sName, "lcl_ensureComposedName: How should I composed the name from nothing!?" );
+
+ _io_tableInfo.sComposedName = OptionalString(
+ composeTableName( _metaData, *_io_tableInfo.sCatalog, *_io_tableInfo.sSchema, *_io_tableInfo.sName,
+ sal_False, ::dbtools::eInDataManipulation )
+ );
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ void lcl_ensureType( TableInfo& _io_tableInfo, const Reference< XDatabaseMetaData >& _metaData, const Reference< XNameAccess >& _masterContainer )
+ {
+ if ( !!_io_tableInfo.sType )
+ return;
+
+ lcl_ensureComposedName( _io_tableInfo, _metaData );
+
+ if ( !_masterContainer.is() )
+ throw RuntimeException();
+
+ ::rtl::OUString sTypeName;
+ try
+ {
+ Reference< XPropertySet > xTable( _masterContainer->getByName( *_io_tableInfo.sComposedName ), UNO_QUERY_THROW );
+ OSL_VERIFY( xTable->getPropertyValue( PROPERTY_TYPE ) >>= sTypeName );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ _io_tableInfo.sType = OptionalString( sTypeName );
+ }
+
+ //--------------------------------------------------------------------------
+ connectivity::TStringVector lcl_filter( const TableInfos& _unfilteredTables,
+ const Sequence< ::rtl::OUString >& _tableFilter, const Sequence< ::rtl::OUString >& _tableTypeFilter,
+ const Reference< XDatabaseMetaData >& _metaData, const Reference< XNameAccess >& _masterContainer )
+ {
+ TableInfos aFilteredTables;
+
+ // first, filter for the table names
+ sal_Int32 nTableFilterCount = _tableFilter.getLength();
+ sal_Bool dontFilterTableNames = ( ( nTableFilterCount == 1 ) && _tableFilter[0].equalsAsciiL( "%", 1 ) );
+ if( dontFilterTableNames )
+ {
+ aFilteredTables = _unfilteredTables;
+ }
+ else
+ {
+ // for wildcard search : remove all table filters which are a wildcard expression and build a WilCard
+ // for them
+ ::std::vector< WildCard > aWildCardTableFilter;
+ Sequence< ::rtl::OUString > aNonWildCardTableFilter = _tableFilter;
+ nTableFilterCount = createWildCardVector( aNonWildCardTableFilter, aWildCardTableFilter );
+
+ TableInfos aUnfilteredTables( _unfilteredTables );
+ aUnfilteredTables.reserve( nTableFilterCount + ( aWildCardTableFilter.size() * 10 ) );
+
+ for ( TableInfos::iterator table = aUnfilteredTables.begin();
+ table != aUnfilteredTables.end();
+ ++table
+ )
+ {
+ lcl_ensureComposedName( *table, _metaData );
+
+ if ( lcl_isElementAllowed( *table->sComposedName, aNonWildCardTableFilter, aWildCardTableFilter ) )
+ aFilteredTables.push_back( *table );
+ }
+ }
+
+ // second, filter for the table types
+ sal_Int32 nTableTypeFilterCount = _tableTypeFilter.getLength();
+ sal_Bool dontFilterTableTypes = ( ( nTableTypeFilterCount == 1 ) && _tableTypeFilter[0].equalsAsciiL( "%", 1 ) );
+ dontFilterTableTypes = dontFilterTableTypes || ( nTableTypeFilterCount == 0 );
+ // (for TableTypeFilter, unlike TableFilter, "empty" means "do not filter at all")
+ if ( !dontFilterTableTypes )
+ {
+ TableInfos aUnfilteredTables;
+ aUnfilteredTables.swap( aFilteredTables );
+
+ const ::rtl::OUString* pTableTypeFilterBegin = _tableTypeFilter.getConstArray();
+ const ::rtl::OUString* pTableTypeFilterEnd = pTableTypeFilterBegin + _tableTypeFilter.getLength();
+
+ for ( TableInfos::iterator table = aUnfilteredTables.begin();
+ table != aUnfilteredTables.end();
+ ++table
+ )
+ {
+ // ensure that we know the table type
+ lcl_ensureType( *table, _metaData, _masterContainer );
+
+ if ( ::std::find( pTableTypeFilterBegin, pTableTypeFilterEnd, *table->sType ) != pTableTypeFilterEnd )
+ aFilteredTables.push_back( *table );
+ }
+ }
+
+ connectivity::TStringVector aReturn;
+ for ( TableInfos::iterator table = aFilteredTables.begin();
+ table != aFilteredTables.end();
+ ++table
+ )
+ {
+ lcl_ensureComposedName( *table, _metaData );
+ aReturn.push_back( *table->sComposedName );
+ }
+ return aReturn;
+ }
+
+ //==========================================================================
+ //= OViewContainer
+ //==========================================================================
+ OFilteredContainer::OFilteredContainer(::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const Reference< XConnection >& _xCon,
+ sal_Bool _bCase,
+ IRefreshListener* _pRefreshListener,
+ ::dbtools::IWarningsContainer* _pWarningsContainer
+ ,oslInterlockedCount& _nInAppend)
+ :OCollection(_rParent,_bCase,_rMutex,::std::vector< ::rtl::OUString>())
+ ,m_bConstructed(sal_False)
+ ,m_pWarningsContainer(_pWarningsContainer)
+ ,m_pRefreshListener(_pRefreshListener)
+ ,m_nInAppend(_nInAppend)
+ ,m_xConnection(_xCon)
+ {
+ }
+ // -------------------------------------------------------------------------
+ void OFilteredContainer::construct(const Reference< XNameAccess >& _rxMasterContainer,
+ const Sequence< ::rtl::OUString >& _rTableFilter,
+ const Sequence< ::rtl::OUString >& _rTableTypeFilter)
+ {
+ try
+ {
+ Reference<XConnection> xCon = m_xConnection;
+ if ( xCon.is() )
+ m_xMetaData = xCon->getMetaData();
+ }
+ catch(SQLException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ m_xMasterContainer = _rxMasterContainer;
+
+ if ( m_xMasterContainer.is() )
+ {
+ addMasterContainerListener();
+
+ TableInfos aUnfilteredTables;
+
+ Sequence< ::rtl::OUString > aNames = m_xMasterContainer->getElementNames();
+ const ::rtl::OUString* name = aNames.getConstArray();
+ const ::rtl::OUString* nameEnd = name + aNames.getLength();
+ for ( ; name != nameEnd; ++name )
+ aUnfilteredTables.push_back( TableInfo( *name ) );
+
+ reFill( lcl_filter( aUnfilteredTables,
+ _rTableFilter, _rTableTypeFilter, m_xMetaData, m_xMasterContainer ) );
+
+ m_bConstructed = sal_True;
+ }
+ else
+ {
+ construct( _rTableFilter, _rTableTypeFilter );
+ }
+ }
+ //------------------------------------------------------------------------------
+ void OFilteredContainer::construct(const Sequence< ::rtl::OUString >& _rTableFilter, const Sequence< ::rtl::OUString >& _rTableTypeFilter)
+ {
+ // build sorted versions of the filter sequences, so the visibility decision is faster
+ Sequence< ::rtl::OUString > aTableFilter(_rTableFilter);
+ sal_Int32 nTableFilterLen = aTableFilter.getLength();
+
+ // for wildcard search : remove all table filters which are a wildcard expression and build a WilCard
+ // for them
+ ::std::vector< WildCard > aWCSearch;
+ nTableFilterLen = createWildCardVector(aTableFilter,aWCSearch);
+
+ try
+ {
+ Reference< XConnection > xCon( m_xConnection, UNO_SET_THROW );
+ m_xMetaData.set( xCon->getMetaData(), UNO_SET_THROW );
+
+ // create a table table filter suitable for the XDatabaseMetaData::getTables call,
+ // taking into account both the externally-provided table type filter, and any
+ // table type restriction which is inherent to the container
+ Sequence< ::rtl::OUString > aTableTypeFilter;
+ ::rtl::OUString sInherentTableTypeRestriction( getTableTypeRestriction() );
+ if ( sInherentTableTypeRestriction.getLength() )
+ {
+ if ( _rTableTypeFilter.getLength() != 0 )
+ {
+ const ::rtl::OUString* tableType = _rTableTypeFilter.getConstArray();
+ const ::rtl::OUString* tableTypeEnd = tableType + _rTableTypeFilter.getLength();
+ for ( ; tableType != tableTypeEnd; ++tableType )
+ {
+ if ( *tableType == sInherentTableTypeRestriction )
+ break;
+ }
+ if ( tableType == tableTypeEnd )
+ { // the only table type which can be part of this container is not allowed
+ // by the externally provided table type filter.
+ m_bConstructed = sal_True;
+ return;
+ }
+ }
+ aTableTypeFilter.realloc( 1 );
+ aTableTypeFilter[0] = sInherentTableTypeRestriction;
+ }
+ else
+ {
+ // no container-inherent restriction for the table types
+ if ( _rTableTypeFilter.getLength() == 0 )
+ { // no externally-provided table type filter => use the default filter
+ getAllTableTypeFilter( aTableTypeFilter );
+ }
+ else
+ {
+ aTableTypeFilter = _rTableTypeFilter;
+ }
+ }
+
+ static const ::rtl::OUString sAll = ::rtl::OUString::createFromAscii("%");
+ Reference< XResultSet > xTables = m_xMetaData->getTables( Any(), sAll, sAll, aTableTypeFilter );
+ Reference< XRow > xCurrentRow( xTables, UNO_QUERY_THROW );
+
+ TableInfos aUnfilteredTables;
+
+ ::rtl::OUString sCatalog, sSchema, sName, sType;
+ while ( xTables->next() )
+ {
+ sCatalog = xCurrentRow->getString(1);
+ sSchema = xCurrentRow->getString(2);
+ sName = xCurrentRow->getString(3);
+ sType = xCurrentRow->getString(4);
+
+ aUnfilteredTables.push_back( TableInfo( sCatalog, sSchema, sName, sType ) );
+ }
+
+ reFill( lcl_filter( aUnfilteredTables,
+ _rTableFilter, aTableTypeFilter, m_xMetaData, NULL ) );
+
+ disposeComponent( xTables );
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ disposing();
+ return;
+ }
+
+ m_bConstructed = sal_True;
+ }
+
+ //------------------------------------------------------------------------------
+ void OFilteredContainer::disposing()
+ {
+ OCollection::disposing();
+
+ if ( m_xMasterContainer.is() )
+ removeMasterContainerListener();
+
+ m_xMasterContainer = NULL;
+ m_xMetaData = NULL;
+ m_pWarningsContainer = NULL;
+ m_pRefreshListener = NULL;
+ m_bConstructed = sal_False;
+ }
+
+ // -------------------------------------------------------------------------
+ void OFilteredContainer::impl_refresh() throw(RuntimeException)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OFilteredContainer::impl_refresh" );
+ if ( m_pRefreshListener )
+ {
+ m_bConstructed = sal_False;
+ Reference<XRefreshable> xRefresh(m_xMasterContainer,UNO_QUERY);
+ if ( xRefresh.is() )
+ xRefresh->refresh();
+ m_pRefreshListener->refresh(this);
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ ::rtl::OUString OFilteredContainer::getNameForObject(const ObjectType& _xObject)
+ {
+ OSL_ENSURE( _xObject.is(), "OFilteredContainer::getNameForObject: Object is NULL!" );
+ return ::dbtools::composeTableName( m_xMetaData, _xObject, ::dbtools::eInDataManipulation, false, false, false );
+ }
+
+ // -----------------------------------------------------------------------------
+ // multiple to obtain all tables from XDatabaseMetaData::getTables, via passing a particular
+ // table type filter:
+ // adhere to the standard, which requests to pass a NULL table type filter, if
+ // you want to retrieve all tables
+ #define FILTER_MODE_STANDARD 0
+ // only pass %, which is not allowed by the standard, but understood by some drivers
+ #define FILTER_MODE_WILDCARD 1
+ // only pass TABLE and VIEW
+ #define FILTER_MODE_FIXED 2
+ // do the thing which showed to be the safest way, understood by nearly all
+ // drivers, even the ones which do not understand the standard
+ #define FILTER_MODE_MIX_ALL 3
+
+ void OFilteredContainer::getAllTableTypeFilter( Sequence< ::rtl::OUString >& /* [out] */ _rFilter ) const
+ {
+ sal_Int32 nFilterMode = FILTER_MODE_MIX_ALL;
+ // for compatibility reasons, this is the default: we used this way before we
+ // introduced the TableTypeFilterMode setting
+
+ // obtain the data source we belong to, and the TableTypeFilterMode setting
+ Any aFilterModeSetting;
+ if ( getDataSourceSetting( getDataSource( (Reference< XInterface >)m_rParent ), "TableTypeFilterMode", aFilterModeSetting ) )
+ {
+ OSL_VERIFY( aFilterModeSetting >>= nFilterMode );
+ }
+
+ const ::rtl::OUString sAll( RTL_CONSTASCII_USTRINGPARAM( "%" ) );
+ const ::rtl::OUString sView( RTL_CONSTASCII_USTRINGPARAM( "VIEW" ) );
+ const ::rtl::OUString sTable( RTL_CONSTASCII_USTRINGPARAM( "TABLE" ) );
+
+ switch ( nFilterMode )
+ {
+ default:
+ OSL_ENSURE( sal_False, "OTableContainer::getAllTableTypeFilter: unknown TableTypeFilterMode!" );
+ case FILTER_MODE_MIX_ALL:
+ _rFilter.realloc( 3 );
+ _rFilter[0] = sView;
+ _rFilter[1] = sTable;
+ _rFilter[2] = sAll;
+ break;
+ case FILTER_MODE_FIXED:
+ _rFilter.realloc( 2 );
+ _rFilter[0] = sView;
+ _rFilter[1] = sTable;
+ break;
+ case FILTER_MODE_WILDCARD:
+ _rFilter.realloc( 1 );
+ _rFilter[0] = sAll;
+ break;
+ case FILTER_MODE_STANDARD:
+ _rFilter.realloc( 0 );
+ break;
+ }
+ }
+
+// ..............................................................................
+} // namespace
+// ..............................................................................
+
+
diff --git a/dbaccess/source/core/api/HelperCollections.cxx b/dbaccess/source/core/api/HelperCollections.cxx
new file mode 100644
index 000000000000..2e536b5c2e26
--- /dev/null
+++ b/dbaccess/source/core/api/HelperCollections.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef DBA_HELPERCOLLECTIONS_HXX
+#include "HelperCollections.hxx"
+#endif
+
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+
+namespace dbaccess
+{
+ using namespace dbtools;
+ using namespace comphelper;
+ using namespace connectivity;
+ 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::script;
+ using namespace ::cppu;
+ using namespace ::osl;
+ // -----------------------------------------------------------------------------
+ OPrivateColumns::OPrivateColumns(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
+ sal_Bool _bCase,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector,
+ sal_Bool _bUseAsIndex
+ ) : sdbcx::OCollection(_rParent,_bCase,_rMutex,_rVector,_bUseAsIndex)
+ ,m_aColumns(_rColumns)
+ {
+ }
+
+ // -------------------------------------------------------------------------
+ OPrivateColumns* OPrivateColumns::createWithIntrinsicNames( const ::vos::ORef< ::connectivity::OSQLColumns >& _rColumns,
+ sal_Bool _bCase, ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex )
+ {
+ ::std::vector< ::rtl::OUString > aNames; aNames.reserve( _rColumns->get().size() );
+
+ ::rtl::OUString sColumName;
+ for ( ::connectivity::OSQLColumns::Vector::const_iterator column = _rColumns->get().begin();
+ column != _rColumns->get().end();
+ ++column
+ )
+ {
+ Reference< XPropertySet > xColumn( *column, UNO_QUERY_THROW );
+ xColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumName;
+ aNames.push_back( sColumName );
+ }
+ return new OPrivateColumns( _rColumns, _bCase, _rParent, _rMutex, aNames, sal_False );
+ }
+
+ // -------------------------------------------------------------------------
+ void SAL_CALL OPrivateColumns::disposing(void)
+ {
+ m_aColumns = NULL;
+ clear_NoDispose();
+ // we're not owner of the objects we're holding, instead the object we got in our ctor is
+ // So we're not allowed to dispose our elements.
+ OPrivateColumns_Base::disposing();
+ }
+ // -------------------------------------------------------------------------
+ connectivity::sdbcx::ObjectType OPrivateColumns::createObject(const ::rtl::OUString& _rName)
+ {
+ if ( m_aColumns.isValid() )
+ {
+ ::connectivity::OSQLColumns::Vector::const_iterator aIter = find(m_aColumns->get().begin(),m_aColumns->get().end(),_rName,isCaseSensitive());
+ if(aIter == m_aColumns->get().end())
+ aIter = findRealName(m_aColumns->get().begin(),m_aColumns->get().end(),_rName,isCaseSensitive());
+
+ if(aIter != m_aColumns->get().end())
+ return connectivity::sdbcx::ObjectType(*aIter,UNO_QUERY);
+
+ OSL_ENSURE(0,"Column not found in collection!");
+ }
+ return NULL;
+ }
+ // -------------------------------------------------------------------------
+ connectivity::sdbcx::ObjectType OPrivateTables::createObject(const ::rtl::OUString& _rName)
+ {
+ if ( !m_aTables.empty() )
+ {
+ OSQLTables::iterator aIter = m_aTables.find(_rName);
+ OSL_ENSURE(aIter != m_aTables.end(),"Table not found!");
+ OSL_ENSURE(aIter->second.is(),"Table is null!");
+ return connectivity::sdbcx::ObjectType(m_aTables.find(_rName)->second,UNO_QUERY);
+ }
+ return NULL;
+ }
+ // -----------------------------------------------------------------------------
+}
diff --git a/dbaccess/source/core/api/HelperCollections.hxx b/dbaccess/source/core/api/HelperCollections.hxx
new file mode 100644
index 000000000000..1169a20b0750
--- /dev/null
+++ b/dbaccess/source/core/api/HelperCollections.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 DBA_HELPERCOLLECTIONS_HXX
+#define DBA_HELPERCOLLECTIONS_HXX
+
+#ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_
+#include "connectivity/sdbcx/VCollection.hxx"
+#endif
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _DBHELPER_DBCONVERSION_HXX_
+#include <connectivity/dbconversion.hxx>
+#endif
+#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
+#include <connectivity/PColumn.hxx>
+#endif
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+
+namespace dbaccess
+{
+ using namespace dbtools;
+ using namespace comphelper;
+ using namespace connectivity;
+ 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::script;
+ using namespace ::cppu;
+ using namespace ::osl;
+ // -----------------------------------------------------------------------------
+ typedef connectivity::sdbcx::OCollection OPrivateColumns_Base;
+ class OPrivateColumns : public OPrivateColumns_Base
+ {
+ ::vos::ORef< ::connectivity::OSQLColumns> m_aColumns;
+ protected:
+ virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
+ virtual void impl_refresh() throw(RuntimeException) {}
+ virtual Reference< XPropertySet > createDescriptor()
+ {
+ return NULL;
+ }
+ public:
+ OPrivateColumns(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
+ sal_Bool _bCase,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector,
+ sal_Bool _bUseAsIndex = sal_False
+ );
+
+ /** creates a columns instance as above, but taking the names from the columns itself
+ */
+ static OPrivateColumns* createWithIntrinsicNames(
+ const ::vos::ORef< ::connectivity::OSQLColumns >& _rColumns,
+ sal_Bool _bCase,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex
+ );
+
+ virtual void SAL_CALL disposing(void);
+ };
+ typedef connectivity::sdbcx::OCollection OPrivateTables_BASE;
+
+ //==========================================================================
+ //= OPrivateTables
+ //==========================================================================
+ class OPrivateTables : public OPrivateTables_BASE
+ {
+ OSQLTables m_aTables;
+ protected:
+ virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
+ virtual void impl_refresh() throw(RuntimeException) {}
+ virtual Reference< XPropertySet > createDescriptor()
+ {
+ return NULL;
+ }
+ public:
+ OPrivateTables( const OSQLTables& _rTables,
+ sal_Bool _bCase,
+ ::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector
+ ) : sdbcx::OCollection(_rParent,_bCase,_rMutex,_rVector)
+ ,m_aTables(_rTables)
+ {
+ }
+ virtual void SAL_CALL disposing(void)
+ {
+ clear_NoDispose();
+ // we're not owner of the objects we're holding, instead the object we got in our ctor is
+ // So we're not allowed to dispose our elements.
+ m_aTables.clear();
+ OPrivateTables_BASE::disposing();
+ }
+ };
+}
+#endif // DBA_HELPERCOLLECTIONS_HXX
diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx
new file mode 100644
index 000000000000..a2a324f11469
--- /dev/null
+++ b/dbaccess/source/core/api/KeySet.cxx
@@ -0,0 +1,1704 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle andor its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef DBACCESS_CORE_API_KEYSET_HXX
+#include "KeySet.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HXX_
+#include "core_resource.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HRC_
+#include "core_resource.hrc"
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#endif
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#ifndef _COM_SUN_STAR_SDBC_XPREPAREDSTATEMENT_HPP_
+#include <com/sun/star/sdbc/XPreparedStatement.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCxParameterS_HPP_
+#include <com/sun/star/sdbc/XParameters.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XGENERATEDRESULTSET_HPP_
+#include <com/sun/star/sdbc/XGeneratedResultSet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_
+#include <com/sun/star/sdbc/XColumnLocate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
+#include <com/sun/star/container/XIndexAccess.hpp>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XINDEXESSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XIndexesSupplier.hpp>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#endif
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _DBHELPER_DBEXCEPTION_HXX_
+#include <connectivity/dbexception.hxx>
+#endif
+#include <list>
+#include <algorithm>
+#include <string.h>
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#endif
+#ifndef DBACCESS_CORE_API_QUERYCOMPOSER_HXX
+#include "querycomposer.hxx"
+#endif
+#ifndef DBACCESS_SOURCE_CORE_INC_COMPOSERTOOLS_HXX
+#include "composertools.hxx"
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#include <string.h>
+#include <rtl/logfile.hxx>
+#include "PrivateRow.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;
+
+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());
+ }
+ }
+ }
+}
+DBG_NAME(OKeySet)
+// -------------------------------------------------------------------------
+OKeySet::OKeySet(const connectivity::OSQLTable& _xTable,
+ const Reference< XIndexAccess>& _xTableKeys,
+ const ::rtl::OUString& _rUpdateTableName, // this can be the alias or the full qualified name
+ const Reference< XSingleSelectQueryAnalyzer >& _xComposer,
+ const ORowSetValueVector& _aParameterValueForCache)
+ :m_aParameterValueForCache(_aParameterValueForCache)
+ ,m_pKeyColumnNames(NULL)
+ ,m_pColumnNames(NULL)
+ ,m_pParameterNames(NULL)
+ ,m_pForeignColumnNames(NULL)
+ ,m_xTable(_xTable)
+ ,m_xTableKeys(_xTableKeys)
+ ,m_xComposer(_xComposer)
+ ,m_sUpdateTableName(_rUpdateTableName)
+ ,m_bRowCountFinal(sal_False)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::OKeySet" );
+ DBG_CTOR(OKeySet,NULL);
+
+}
+// -----------------------------------------------------------------------------
+OKeySet::~OKeySet()
+{
+ try
+ {
+ ::comphelper::disposeComponent(m_xStatement);
+ }
+ catch(Exception&)
+ {
+ m_xStatement = NULL;
+ }
+ catch(...)
+ {
+ OSL_ENSURE(0,"Unknown Exception occured");
+ }
+ m_xComposer = NULL;
+
+ DBG_DTOR(OKeySet,NULL);
+}
+void OKeySet::initColumns()
+{
+ 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) );
+ m_pForeignColumnNames.reset( new SelectColumnsMetaData(bCase) );
+}
+void OKeySet::findTableColumnsMatching_throw( const Any& i_aTable,
+ const ::rtl::OUString& i_rUpdateTableName,
+ const Reference<XDatabaseMetaData>& i_xMeta,
+ const Reference<XNameAccess>& i_xQueryColumns,
+ ::std::auto_ptr<SelectColumnsMetaData>& o_pKeyColumnNames)
+{
+ // first ask the database itself for the best columns which can be used
+ Sequence< ::rtl::OUString> aBestColumnNames;
+ Reference<XNameAccess> xKeyColumns = getPrimaryKeyColumns_throw(i_aTable);
+ if ( xKeyColumns.is() )
+ aBestColumnNames = xKeyColumns->getElementNames();
+
+ const Reference<XColumnsSupplier> xTblColSup(i_aTable,UNO_QUERY_THROW);
+ const Reference<XNameAccess> xTblColumns = xTblColSup->getColumns();
+ // 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];
+ }
+
+ ::rtl::OUString sUpdateTableName( i_rUpdateTableName );
+ if ( sUpdateTableName.getLength() == 0 )
+ {
+ 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 );
+ }
+
+ ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sUpdateTableName,(*o_pKeyColumnNames),true);
+ ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sUpdateTableName,(*m_pColumnNames),true);
+ ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sUpdateTableName,(*m_pParameterNames),true);
+
+ if ( o_pKeyColumnNames->empty() )
+ {
+ ::dbtools::throwGenericSQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not find any key column." ) ), *this );
+ }
+
+ for ( SelectColumnsMetaData::const_iterator keyColumn = o_pKeyColumnNames->begin();
+ keyColumn != o_pKeyColumnNames->end();
+ ++keyColumn
+ )
+ {
+ 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()
+{
+ 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
+ Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
+ SelectColumnsMetaData::iterator aPosEnd = m_pKeyColumnNames->end();
+ for(SelectColumnsMetaData::iterator aPosIter = m_pKeyColumnNames->begin();aPosIter != aPosEnd;)
+ {
+ aFilter.append(::dbtools::quoteTableName( xMeta,aPosIter->second.sTableName,::dbtools::eInDataManipulation));
+ aFilter.append(s_sDot);
+ aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName));
+ aFilter.append(s_sParam);
+ ++aPosIter;
+ if(aPosIter != aPosEnd)
+ aFilter.append(aAnd);
+ }
+ return aFilter;
+}
+// -----------------------------------------------------------------------------
+void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::OUString& i_sRowSetFilter)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::construct" );
+ OCacheSet::construct(_xDriverSet,i_sRowSetFilter);
+ initColumns();
+
+ Reference<XNameAccess> xKeyColumns = getKeyColumns();
+ Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
+ Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY);
+ const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns();
+ findTableColumnsMatching_throw(makeAny(m_xTable),m_sUpdateTableName,xMeta,xQueryColumns,m_pKeyColumnNames);
+
+ // 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
+ m_aKeyMap.insert(OKeySetMatrix::value_type(0,OKeySetValue(NULL,::std::pair<sal_Int32,Reference<XRow> >(0,NULL))));
+ m_aKeyIter = m_aKeyMap.begin();
+
+ ::rtl::OUStringBuffer aFilter = createKeyFilter();
+
+ Reference< XSingleSelectQueryComposer> xSourceComposer(m_xComposer,UNO_QUERY);
+ Reference< XMultiServiceFactory > xFactory(m_xConnection, UNO_QUERY_THROW);
+ Reference<XSingleSelectQueryComposer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
+ xAnalyzer->setElementaryQuery(xSourceComposer->getElementaryQuery());
+ Reference<XTablesSupplier> xTabSup(xAnalyzer,uno::UNO_QUERY);
+ Reference<XNameAccess> xSelectTables(xTabSup->getTables(),uno::UNO_QUERY);
+ const Sequence< ::rtl::OUString> aSeq = xSelectTables->getElementNames();
+ if ( aSeq.getLength() > 1 ) // special handling for join
+ {
+ static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
+ const ::rtl::OUString aQuote = getIdentifierQuoteString();
+ static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM("."));
+ static ::rtl::OUString s_sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( *pIter != m_sUpdateTableName )
+ {
+ connectivity::OSQLTable xSelColSup(xSelectTables->getByName(*pIter),uno::UNO_QUERY);
+ Reference<XPropertySet> xProp(xSelColSup,uno::UNO_QUERY);
+ ::rtl::OUString sSelectTableName = ::dbtools::composeTableName( xMeta, xProp, ::dbtools::eInDataManipulation, false, false, false );
+
+ ::dbaccess::getColumnPositions(xQueryColumns,xSelColSup->getColumns()->getElementNames(),sSelectTableName,(*m_pForeignColumnNames));
+
+ SelectColumnsMetaData::iterator aPosEnd = (*m_pForeignColumnNames).end();
+ for(SelectColumnsMetaData::iterator aPosIter = (*m_pForeignColumnNames).begin();aPosIter != aPosEnd;++aPosIter)
+ {
+ // look for columns not in the source columns to use them as filter as well
+ // if ( !xSourceColumns->hasByName(aPosIter->first) )
+ {
+ if ( aFilter.getLength() )
+ aFilter.append(aAnd);
+ aFilter.append(::dbtools::quoteName( aQuote,sSelectTableName));
+ aFilter.append(s_sDot);
+ aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName));
+ aFilter.append(s_sParam);
+ }
+ }
+ break;
+ }
+ }
+ } // if ( aSeq.getLength() > 1 ) // special handling for join
+ executeStatement(aFilter,i_sRowSetFilter,xAnalyzer);
+}
+void OKeySet::executeStatement(::rtl::OUStringBuffer& io_aFilter,const ::rtl::OUString& i_sRowSetFilter,Reference<XSingleSelectQueryComposer>& io_xAnalyzer)
+{
+ bool bFilterSet = i_sRowSetFilter.getLength() != 0;
+ if ( bFilterSet )
+ {
+ FilterCreator aFilterCreator;
+ aFilterCreator.append( i_sRowSetFilter );
+ aFilterCreator.append( io_aFilter.makeStringAndClear() );
+ io_aFilter = aFilterCreator.getComposedAndClear();
+ }
+ io_xAnalyzer->setFilter(io_aFilter.makeStringAndClear());
+ if ( bFilterSet )
+ {
+ Sequence< Sequence< PropertyValue > > aFilter2 = io_xAnalyzer->getStructuredFilter();
+ const Sequence< PropertyValue >* pOr = aFilter2.getConstArray();
+ const Sequence< PropertyValue >* pOrEnd = pOr + aFilter2.getLength();
+ for(;pOr != pOrEnd;++pOr)
+ {
+ const PropertyValue* pAnd = pOr->getConstArray();
+ const PropertyValue* pAndEnd = pAnd + pOr->getLength();
+ for(;pAnd != pAndEnd;++pAnd)
+ {
+ ::rtl::OUString sValue;
+ if ( !(pAnd->Value >>= sValue) || !(sValue.equalsAscii("?") || sValue.matchAsciiL(":",1,0)) )
+ { // we have a criteria which has to be taken into account for updates
+ m_aFilterColumns.push_back(pAnd->Name);
+ }
+ }
+ }
+ }
+ m_xStatement = m_xConnection->prepareStatement(io_xAnalyzer->getQueryWithSubstitution());
+ ::comphelper::disposeComponent(io_xAnalyzer);
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL OKeySet::getBookmark() throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::compareBookmarks" );
+ sal_Int32 nFirst = 0, nSecond = 0;
+ _first >>= nFirst;
+ _second >>= nSecond;
+
+ return (nFirst != nSecond) ? CompareBookmark::NOT_EQUAL : CompareBookmark::EQUAL;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hasOrderedBookmarks" );
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OKeySet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::hashBookmark" );
+ return ::comphelper::getINT32(bookmark);
+}
+// -------------------------------------------------------------------------
+// ::com::sun::star::sdbcx::XDeleteRows
+Sequence< sal_Int32 > SAL_CALL OKeySet::deleteRows( const Sequence< Any >& rows ,const connectivity::OSQLTable& _xTable) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRows" );
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("DELETE FROM ");
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
+
+ // list all cloumns that should be set
+ const ::rtl::OUString aQuote = getIdentifierQuoteString();
+ static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
+ static ::rtl::OUString aOr = ::rtl::OUString::createFromAscii(" OR ");
+ static ::rtl::OUString aEqual = ::rtl::OUString::createFromAscii(" = ?");
+
+
+ // use keys and indexes for excat postioning
+ // first the keys
+ Reference<XNameAccess> xKeyColumns = getKeyColumns();
+
+ ::rtl::OUStringBuffer aCondition = ::rtl::OUString::createFromAscii("( ");
+
+ SelectColumnsMetaData::const_iterator aIter = (*m_pKeyColumnNames).begin();
+ SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
+ for(;aIter != aPosEnd;++aIter)
+ {
+ aCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ aCondition.append(aEqual);
+ aCondition.append(aAnd);
+ }
+ aCondition.setLength(aCondition.getLength()-5);
+ const ::rtl::OUString sCon( aCondition.makeStringAndClear() );
+
+ const Any* pBegin = rows.getConstArray();
+ const Any* pEnd = pBegin + rows.getLength();
+
+ Sequence< Any > aKeys;
+ for(;pBegin != pEnd;++pBegin)
+ {
+ aSql.append(sCon);
+ aSql.append(aOr);
+ }
+ aSql.setLength(aSql.getLength()-3);
+
+ // now create end execute the prepared statement
+
+ Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
+ Reference< XParameters > xParameter(xPrep,UNO_QUERY);
+
+ pBegin = rows.getConstArray();
+ sal_Int32 i=1;
+ for(;pBegin != pEnd;++pBegin)
+ {
+ m_aKeyIter = m_aKeyMap.find(::comphelper::getINT32(*pBegin));
+ if(m_aKeyIter != m_aKeyMap.end())
+ {
+ connectivity::ORowVector< ORowSetValue >::Vector::iterator aKeyIter = m_aKeyIter->second.first->get().begin();
+ connectivity::ORowVector< ORowSetValue >::Vector::iterator aKeyEnd = m_aKeyIter->second.first->get().end();
+ SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
+ for(sal_uInt16 j = 0;aKeyIter != aKeyEnd;++aKeyIter,++j,++aPosIter)
+ {
+ setParameter(i++,xParameter,*aKeyIter,aPosIter->second.nType,aPosIter->second.nScale);
+ }
+ }
+ }
+
+ sal_Bool bOk = xPrep->executeUpdate() > 0;
+ Sequence< sal_Int32 > aRet(rows.getLength());
+ memset(aRet.getArray(),bOk,sizeof(sal_Int32)*aRet.getLength());
+ if(bOk)
+ {
+ pBegin = rows.getConstArray();
+ pEnd = pBegin + rows.getLength();
+
+ for(;pBegin != pEnd;++pBegin)
+ {
+ sal_Int32 nPos = 0;
+ *pBegin >>= nPos;
+ if(m_aKeyIter == m_aKeyMap.find(nPos) && m_aKeyIter != m_aKeyMap.end())
+ ++m_aKeyIter;
+ m_aKeyMap.erase(nPos);
+ m_bDeleted = sal_True;
+ }
+ }
+ return aRet;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OKeySet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::updateRow" );
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("UPDATE ");
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" SET "));
+ // list all cloumns that should be set
+ static ::rtl::OUString aPara = ::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(" = ?"));
+
+ // use keys and indexes for excat postioning
+ // first the keys
+ Reference<XNameAccess> xKeyColumns = getKeyColumns();
+
+ // second the indexes
+ Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
+ Reference<XIndexAccess> xIndexes;
+ if ( xIndexSup.is() )
+ xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
+
+
+ ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
+ lcl_fillIndexColumns(xIndexes,aAllIndexColumns);
+
+ ::rtl::OUString aColumnName;
+ ::rtl::OUStringBuffer sKeyCondition,sIndexCondition;
+ ::std::vector<sal_Int32> aIndexColumnPositions;
+
+ const sal_Int32 nOldLength = aSql.getLength();
+ 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,++i)
+ {
+ //if(xKeyColumns.is() && xKeyColumns->hasByName(aIter->first))
+ if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
+ {
+ sKeyCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ if((_rOrginalRow->get())[aIter->second.nPosition].isNull())
+ sKeyCondition.append(sIsNull);
+ else
+ sKeyCondition.append(sParam);
+ sKeyCondition.append(aAnd);
+ }
+ else
+ {
+ ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end();
+ for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
+ aIndexIter != aIndexEnd;++aIndexIter)
+ {
+ if((*aIndexIter)->hasByName(aIter->first))
+ {
+ sIndexCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ if((_rOrginalRow->get())[aIter->second.nPosition].isNull())
+ sIndexCondition.append(sIsNull);
+ else
+ {
+ sIndexCondition.append(sParam);
+ aIndexColumnPositions.push_back(aIter->second.nPosition);
+ }
+ sIndexCondition.append(aAnd);
+ break;
+ }
+ }
+ }
+ if((_rInsertRow->get())[aIter->second.nPosition].isModified())
+ {
+ aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ aSql.append(aPara);
+ }
+ }
+
+ if( aSql.getLength() != nOldLength )
+ {
+ aSql.setLength(aSql.getLength()-1);
+ }
+ else
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
+
+ if(sKeyCondition.getLength() || sIndexCondition.getLength())
+ {
+ aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
+ if(sKeyCondition.getLength() && sIndexCondition.getLength())
+ {
+ aSql.append(sKeyCondition.makeStringAndClear());
+ aSql.append(sIndexCondition.makeStringAndClear());
+ }
+ else if(sKeyCondition.getLength())
+ {
+ aSql.append(sKeyCondition.makeStringAndClear());
+ }
+ else if(sIndexCondition.getLength())
+ {
+ aSql.append(sIndexCondition.makeStringAndClear());
+ }
+ aSql.setLength(aSql.getLength()-5); // remove the last AND
+ }
+ else
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_CONDITION_FOR_PK ), SQL_GENERAL_ERROR, m_xConnection );
+
+ // now create end execute the prepared statement
+
+ ::rtl::OUString sEmpty;
+ executeUpdate(_rInsertRow ,_rOrginalRow,aSql.makeStringAndClear(),sEmpty,aIndexColumnPositions);
+}
+// -----------------------------------------------------------------------------
+void OKeySet::executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,const ::std::vector<sal_Int32>& _aIndexColumnPositions)
+{
+ // now create end execute the prepared statement
+ Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(i_sSQL));
+ Reference< XParameters > xParameter(xPrep,UNO_QUERY);
+
+ bool bRefetch = true;
+ Reference<XRow> xRow;
+ 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 ( !i_sTableName.getLength() || aIter->second.sTableName == i_sTableName )
+ {
+ sal_Int32 nPos = aIter->second.nPosition;
+ if((_rInsertRow->get())[nPos].isModified())
+ {
+ if ( bRefetch )
+ {
+ bRefetch = ::std::find(m_aFilterColumns.begin(),m_aFilterColumns.end(),aIter->second.sRealName) == m_aFilterColumns.end();
+ }
+ 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 ( !i_sTableName.getLength() || aIter->second.sTableName == i_sTableName )
+ {
+ setParameter(i++,xParameter,(_rOrginalRow->get())[aIter->second.nPosition],aIter->second.nType,aIter->second.nScale);
+ }
+ }
+ if ( !_aIndexColumnPositions.empty() )
+ {
+ // now we have to set the index values
+ ::std::vector<sal_Int32>::const_iterator aIdxColIter = _aIndexColumnPositions.begin();
+ ::std::vector<sal_Int32>::const_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;
+ m_aKeyIter->second.second.second = xRow;
+ copyRowValue(_rInsertRow,m_aKeyIter->second.first,nBookmark);
+ tryRefetch(_rInsertRow,bRefetch);
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OKeySet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::insertRow" );
+ ::rtl::OUStringBuffer aSql(::rtl::OUString::createFromAscii("INSERT INTO "));
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" ( "));
+ // set values and column names
+ ::rtl::OUStringBuffer aValues(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" VALUES ( ")));
+ static ::rtl::OUString aPara(RTL_CONSTASCII_USTRINGPARAM("?,"));
+ ::rtl::OUString aQuote = getIdentifierQuoteString();
+ static ::rtl::OUString aComma(RTL_CONSTASCII_USTRINGPARAM(","));
+
+ SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
+ SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
+ sal_Int32 j = 1;
+ bool bRefetch = true;
+ sal_Bool bModified = sal_False;
+ for(;aIter != aEnd;++aIter,++j)
+ {
+ if((_rInsertRow->get())[aIter->second.nPosition].isModified())
+ {
+ if ( bRefetch )
+ {
+ bRefetch = ::std::find(m_aFilterColumns.begin(),m_aFilterColumns.end(),aIter->second.sRealName) == m_aFilterColumns.end();
+ }
+ aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ aSql.append(aComma);
+ aValues.append(aPara);
+ bModified = sal_True;
+ }
+ }
+ if ( !bModified )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_VALUE_CHANGED ), SQL_GENERAL_ERROR, m_xConnection );
+
+ aSql.setCharAt(aSql.getLength()-1,')');
+ aValues.setCharAt(aValues.getLength()-1,')');
+ aSql.append(aValues.makeStringAndClear());
+ // now create,fill and execute the prepared statement
+ ::rtl::OUString sEmpty;
+ executeInsert(_rInsertRow,aSql.makeStringAndClear(),sEmpty,bRefetch);
+}
+// -------------------------------------------------------------------------
+void OKeySet::executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,bool bRefetch )
+{
+ // 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 ( !i_sTableName.getLength() || 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 ( !i_sTableName.getLength() && !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
+ SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
+ if ( aFind != aEnd )
+ {
+ sMaxStmt += sMax;
+ sMaxStmt += ::dbtools::quoteName( sQuote,aFind->second.sRealName
+);
+ 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 ");
+ ::rtl::OUString sCatalog,sSchema,sTable;
+ ::dbtools::qualifiedNameComponents(m_xConnection->getMetaData(),m_sUpdateTableName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
+ sStmt += ::dbtools::composeTableNameForSelect( m_xConnection, sCatalog, sSchema, sTable );
+ 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);
+ tryRefetch(_rInsertRow,bRefetch);
+ }
+}
+void OKeySet::tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch)
+{
+ if ( bRefetch )
+ {
+ // we just areassign the base members
+ try
+ {
+ 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();
+ }
+
+ for(++aParaIter;aParaIter != aParaEnd;++aParaIter,++nPos)
+ {
+ ::dbtools::setObjectWithInfo( xParameter, nPos, aParaIter->makeAny(), aParaIter->getTypeKind() );
+ }
+ connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter2 = m_aKeyIter->second.first->get().begin();
+ SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
+ SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
+ for(;aPosIter != aPosEnd;++aPosIter,++aIter2,++nPos)
+ setParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
+ aPosIter = (*m_pForeignColumnNames).begin();
+ aPosEnd = (*m_pForeignColumnNames).end();
+ for(;aPosIter != aPosEnd;++aPosIter,++aIter2,++nPos)
+ setParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
+
+ m_xSet = m_xStatement->executeQuery();
+ OSL_ENSURE(m_xSet.is(),"No resultset form statement!");
+ bRefetch = m_xSet->next();
+ }
+ catch(Exception)
+ {
+ bRefetch = false;
+ }
+ }
+ if ( !bRefetch )
+ {
+ m_aKeyIter->second.second.second = new OPrivateRow(_rInsertRow->get());
+ }
+}
+// -----------------------------------------------------------------------------
+void OKeySet::copyRowValue(const ORowSetRow& _rInsertRow,ORowSetRow& _rKeyRow,sal_Int32 i_nBookmark)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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(),"OKeySet::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)
+ {
+ *aIter = (_rInsertRow->get())[aPosIter->second.nPosition];
+ impl_convertValue_throw(_rKeyRow,aPosIter->second);
+ aIter->setTypeKind(aPosIter->second.nType);
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OKeySet::deleteRow(const ORowSetRow& _rDeleteRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::deleteRow" );
+ Reference<XPropertySet> xSet(_xTable,UNO_QUERY);
+ fillTableName(xSet);
+
+ ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("DELETE FROM ");
+ aSql.append(m_aComposedTableName);
+ aSql.append(::rtl::OUString::createFromAscii(" WHERE "));
+
+ // list all cloumns that should be set
+ ::rtl::OUString aQuote = getIdentifierQuoteString();
+ static ::rtl::OUString aAnd = ::rtl::OUString::createFromAscii(" AND ");
+
+ // use keys and indexes for excat postioning
+ Reference<XNameAccess> xKeyColumns = getKeyColumns();
+ // second the indexes
+ Reference<XIndexesSupplier> xIndexSup(_xTable,UNO_QUERY);
+ Reference<XIndexAccess> xIndexes;
+ if ( xIndexSup.is() )
+ xIndexes.set(xIndexSup->getIndexes(),UNO_QUERY);
+
+ // Reference<XColumnsSupplier>
+ ::std::vector< Reference<XNameAccess> > aAllIndexColumns;
+ lcl_fillIndexColumns(xIndexes,aAllIndexColumns);
+
+ ::rtl::OUString aColumnName;
+ ::rtl::OUStringBuffer sIndexCondition;
+ ::std::vector<sal_Int32> aIndexColumnPositions;
+ SelectColumnsMetaData::const_iterator aIter = m_pColumnNames->begin();
+ SelectColumnsMetaData::const_iterator aEnd = m_pColumnNames->end();
+
+ sal_Int32 i = 1;
+ for(i = 1;aIter != aEnd;++aIter,++i)
+ {
+ if ( m_pKeyColumnNames->find(aIter->first) != m_pKeyColumnNames->end() )
+ {
+ aSql.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ if((_rDeleteRow->get())[aIter->second.nPosition].isNull())
+ {
+ OSL_ENSURE(0,"can a primary key be null");
+ aSql.append(::rtl::OUString::createFromAscii(" IS NULL"));
+ }
+ else
+ aSql.append(::rtl::OUString::createFromAscii(" = ?"));
+ aSql.append(aAnd);
+ }
+ else
+ {
+ ::std::vector< Reference<XNameAccess> >::const_iterator aIndexEnd = aAllIndexColumns.end();
+ for( ::std::vector< Reference<XNameAccess> >::const_iterator aIndexIter = aAllIndexColumns.begin();
+ aIndexIter != aIndexEnd;++aIndexIter)
+ {
+ if((*aIndexIter)->hasByName(aIter->first))
+ {
+ sIndexCondition.append(::dbtools::quoteName( aQuote,aIter->second.sRealName));
+ if((_rDeleteRow->get())[aIter->second.nPosition].isNull())
+ sIndexCondition.append(::rtl::OUString::createFromAscii(" IS NULL"));
+ else
+ {
+ sIndexCondition.append(::rtl::OUString::createFromAscii(" = ?"));
+ aIndexColumnPositions.push_back(aIter->second.nPosition);
+ }
+ sIndexCondition.append(aAnd);
+
+ break;
+ }
+ }
+ }
+ }
+ aSql.append(sIndexCondition.makeStringAndClear());
+ aSql.setLength(aSql.getLength()-5);
+
+ // now create end execute the prepared statement
+ Reference< XPreparedStatement > xPrep(m_xConnection->prepareStatement(aSql.makeStringAndClear()));
+ Reference< XParameters > xParameter(xPrep,UNO_QUERY);
+
+ aIter = (*m_pKeyColumnNames).begin();
+ aEnd = (*m_pKeyColumnNames).end();
+ i = 1;
+ for(;aIter != aEnd;++aIter,++i)
+ {
+ setParameter(i,xParameter,(_rDeleteRow->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();
+ aIter = m_pColumnNames->begin();
+ for(;aIdxColIter != aIdxColEnd;++aIdxColIter,++i,++aIter)
+ {
+ setParameter(i,xParameter,(_rDeleteRow->get())[*aIdxColIter],(_rDeleteRow->get())[*aIdxColIter].getTypeKind(),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 OKeySet::cancelRowUpdates( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::cancelRowUpdates" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OKeySet::moveToInsertRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToInsertRow" );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OKeySet::moveToCurrentRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::moveToCurrentRow" );
+}
+// -------------------------------------------------------------------------
+Reference<XNameAccess> OKeySet::getKeyColumns() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getKeyColumns" );
+ // use keys and indexes for excat postioning
+ // first the keys
+
+ Reference<XIndexAccess> xKeys = m_xTableKeys;
+ if ( !xKeys.is() )
+ {
+ Reference<XPropertySet> xSet(m_xTable,UNO_QUERY);
+ const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xSet);
+ return xPrimaryKeyColumns;
+ }
+
+ 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)
+ {
+ xProp.set(xKeys->getByIndex(i),UNO_QUERY);
+ 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;
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::next( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::isBeforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isBeforeFirst" );
+ return m_aKeyIter == m_aKeyMap.begin();
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::isAfterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isAfterLast" );
+ return m_bRowCountFinal && m_aKeyIter == m_aKeyMap.end();
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::isFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isFirst" );
+ OKeySetMatrix::iterator aTemp = m_aKeyMap.begin();
+ ++aTemp;
+ return m_aKeyIter == aTemp && m_aKeyIter != m_aKeyMap.end();
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::isLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::isLast" );
+ if(!m_bRowCountFinal)
+ return sal_False;
+
+ OKeySetMatrix::iterator aTemp = m_aKeyMap.end();
+ --aTemp;
+ return m_aKeyIter == aTemp;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OKeySet::beforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::beforeFirst" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ m_aKeyIter = m_aKeyMap.begin();
+ m_xRow = NULL;
+ ::comphelper::disposeComponent(m_xSet);
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OKeySet::afterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::afterLast" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ fillAllRows();
+ m_aKeyIter = m_aKeyMap.end();
+ m_xRow = NULL;
+ ::comphelper::disposeComponent(m_xSet);
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::first( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::last( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::getRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::relative" );
+ if(!rows)
+ {
+ refreshRow();
+ return sal_True;
+ }
+ return absolute(getRow()+rows);
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::previous( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 OKeySet::refreshRow() throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::refreshRow" );
+ if(isBeforeFirst() || isAfterLast() || !m_xStatement.is())
+ return;
+
+ m_xRow = NULL;
+ ::comphelper::disposeComponent(m_xSet);
+
+ if ( m_aKeyIter->second.second.second.is() )
+ {
+ m_xRow = m_aKeyIter->second.second.second;
+ return;
+ }
+ // we just areassign 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();
+ }
+
+ 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);
+ aPosIter = (*m_pForeignColumnNames).begin();
+ aPosEnd = (*m_pForeignColumnNames).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 OKeySet::fetchRow()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fetchRow" );
+ // fetch the next row and append on the keyset
+ sal_Bool bRet = sal_False;
+ if ( !m_bRowCountFinal )
+ bRet = m_xDriverSet->next();
+ if ( bRet )
+ {
+ ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >((*m_pKeyColumnNames).size() + m_pForeignColumnNames->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);
+ }
+ // now fetch the values from the missing columns from other tables
+ aPosIter = (*m_pForeignColumnNames).begin();
+ aPosEnd = (*m_pForeignColumnNames).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 OKeySet::fillAllRows()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::fillAllRows" );
+ if(!m_bRowCountFinal)
+ {
+ while(fetchRow())
+ ;
+ }
+}
+// XRow
+sal_Bool SAL_CALL OKeySet::wasNull( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::wasNull" );
+ return m_xRow->wasNull();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OKeySet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getString" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getString(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBoolean" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getBoolean(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int8 SAL_CALL OKeySet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getByte" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getByte(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int16 SAL_CALL OKeySet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getShort" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getShort(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OKeySet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getInt" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getInt(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int64 SAL_CALL OKeySet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getLong" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getLong(columnIndex);
+}
+// -------------------------------------------------------------------------
+float SAL_CALL OKeySet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getFloat" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getFloat(columnIndex);
+}
+// -------------------------------------------------------------------------
+double SAL_CALL OKeySet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDouble" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getDouble(columnIndex);
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL OKeySet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBytes" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getBytes(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Date SAL_CALL OKeySet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getDate" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getDate(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Time SAL_CALL OKeySet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTime" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getTime(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::DateTime SAL_CALL OKeySet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getTimestamp" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getTimestamp(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL OKeySet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBinaryStream" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getBinaryStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL OKeySet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getCharacterStream" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getCharacterStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL OKeySet::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", "OKeySet::getObject" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getObject(columnIndex,typeMap);
+}
+// -------------------------------------------------------------------------
+Reference< XRef > SAL_CALL OKeySet::getRef( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getRef" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getRef(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL OKeySet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getBlob" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getBlob(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XClob > SAL_CALL OKeySet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getClob" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getClob(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XArray > SAL_CALL OKeySet::getArray( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::getArray" );
+ OSL_ENSURE(m_xRow.is(),"m_xRow is null!");
+ return m_xRow->getArray(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::rowUpdated( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowUpdated" );
+ return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 2;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::rowInserted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowInserted" );
+ return m_aKeyIter != m_aKeyMap.begin() && m_aKeyIter != m_aKeyMap.end() && m_aKeyIter->second.second.first == 1;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OKeySet::rowDeleted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::rowDeleted" );
+ sal_Bool bDeleted = m_bDeleted;
+ m_bDeleted = sal_False;
+ return bDeleted;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OKeySet::getComposedTableName(const ::rtl::OUString& _sCatalog,
+ const ::rtl::OUString& _sSchema,
+ const ::rtl::OUString& _sTable)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OKeySet::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 ::com::sun::star::uno::Sequence< ::rtl::OUString >& _aColumnNames,
+ const ::rtl::OUString& _rsUpdateTableName,
+ SelectColumnsMetaData& o_rColumnNames,
+ bool i_bAppendTableName)
+ {
+ // get the real name of the columns
+ Sequence< ::rtl::OUString> aSelNames(_rxQueryColumns->getElementNames());
+ const ::rtl::OUString* pSelIter = aSelNames.getConstArray();
+ const ::rtl::OUString* pSelEnd = pSelIter + aSelNames.getLength();
+
+ const ::rtl::OUString* pTblColumnIter = _aColumnNames.getConstArray();
+ const ::rtl::OUString* pTblColumnEnd = pTblColumnIter + _aColumnNames.getLength();
+
+
+ ::comphelper::UStringMixLess aTmp(o_rColumnNames.key_comp());
+ ::comphelper::UStringMixEqual bCase(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive());
+
+ for(sal_Int32 nPos = 1;pSelIter != pSelEnd;++pSelIter,++nPos)
+ {
+ Reference<XPropertySet> xQueryColumnProp(_rxQueryColumns->getByName(*pSelIter),UNO_QUERY_THROW);
+ ::rtl::OUString sRealName,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(;pTblColumnIter != pTblColumnEnd;++pTblColumnIter)
+ {
+ if(bCase(sRealName,*pTblColumnIter) && bCase(_rsUpdateTableName,sTableName) && o_rColumnNames.find(*pTblColumnIter) == o_rColumnNames.end())
+ {
+ sal_Int32 nType = 0;
+ xQueryColumnProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
+ sal_Int32 nScale = 0;
+ xQueryColumnProp->getPropertyValue(PROPERTY_SCALE) >>= nScale;
+ ::rtl::OUString sColumnDefault;
+ if ( xQueryColumnProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DEFAULTVALUE) )
+ xQueryColumnProp->getPropertyValue(PROPERTY_DEFAULTVALUE) >>= sColumnDefault;
+
+ 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 );
+
+ break;
+ }
+ }
+ pTblColumnIter = _aColumnNames.getConstArray();
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void OKeySet::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,::std::min(sValue.getLength(),nIndex + (i_aMetaData.nScale > 0 ? i_aMetaData.nScale + 1 : 0)));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+// -----------------------------------------------------------------------------
+
diff --git a/dbaccess/source/core/api/KeySet.hxx b/dbaccess/source/core/api/KeySet.hxx
new file mode 100644
index 000000000000..ecb56d7c88b4
--- /dev/null
+++ b/dbaccess/source/core/api/KeySet.hxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_KEYSET_HXX
+#define DBACCESS_CORE_API_KEYSET_HXX
+
+#ifndef DBACCESS_CORE_API_CACHESET_HXX
+#include "CacheSet.hxx"
+#endif
+
+#ifndef _CPPUHELPER_IMPLBASE1_HXX_
+#include <cppuhelper/implbase1.hxx>
+#endif
+#include <memory>
+#include <map>
+
+#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#endif
+#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#ifndef _COMPHELPER_STLTYPES_HXX_
+#include <comphelper/stl_types.hxx>
+#endif
+
+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;
+
+
+
+ SelectColumnDescription()
+ :nPosition( 0 )
+ ,nType( 0 )
+ ,nScale( 0 )
+ ,bNullable(sal_False)
+ {
+ }
+
+ SelectColumnDescription( sal_Int32 _nPosition, sal_Int32 _nType, sal_Int32 _nScale,sal_Bool _bNullable, const ::rtl::OUString& _rDefaultValue )
+ :sDefaultValue( _rDefaultValue )
+ ,nPosition( _nPosition )
+ ,nType( _nType )
+ ,nScale( _nScale )
+ ,bNullable(_bNullable)
+ {
+ }
+ };
+ typedef ::std::map< ::rtl::OUString, SelectColumnDescription, ::comphelper::UStringMixLess > SelectColumnsMetaData;
+
+ // the elements of _rxQueryColumns must have the properties PROPERTY_REALNAME and PROPERTY_TABLENAME
+ 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& 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;
+ typedef ::std::map<sal_Int32,ORowSetValueVector > OUpdatedParameter;
+ // is used when the source supports keys
+ class OKeySet : public OCacheSet
+ {
+ protected:
+ OKeySetMatrix m_aKeyMap;
+ OKeySetMatrix::iterator m_aKeyIter;
+
+ ::std::vector< ::rtl::OUString > m_aAutoColumns; // contains all columns which are autoincrement ones
+
+ 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
+ ::std::auto_ptr<SelectColumnsMetaData> m_pForeignColumnNames; // contains all column names of the rest
+ connectivity::OSQLTable m_xTable; // reference to our table
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess> m_xTableKeys;
+ ::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;
+ ::rtl::OUString m_sUpdateTableName;
+ ::std::vector< ::rtl::OUString > m_aFilterColumns;
+
+ sal_Bool m_bRowCountFinal;
+
+ /**
+ 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);
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > getKeyColumns() const;
+ void fillAllRows();
+ sal_Bool fetchRow();
+
+ 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 ::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,
+ ::std::auto_ptr<SelectColumnsMetaData>& o_pKeyColumnNames);
+ ::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>());
+ void executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName = ::rtl::OUString(),bool bRefetch = false);
+ void executeStatement(::rtl::OUStringBuffer& io_aFilter,const ::rtl::OUString& i_sRowSetFilter,::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer>& io_xAnalyzer);
+
+ virtual ~OKeySet();
+ public:
+ OKeySet(const connectivity::OSQLTable& _xTable,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xTableKeys,
+ const ::rtl::OUString& _rUpdateTableName,
+ 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);
+ };
+}
+#endif // DBACCESS_CORE_API_KEYSET_HXX
+
diff --git a/dbaccess/source/core/api/OptimisticSet.cxx b/dbaccess/source/core/api/OptimisticSet.cxx
new file mode 100644
index 000000000000..837824751f0f
--- /dev/null
+++ b/dbaccess/source/core/api/OptimisticSet.cxx
@@ -0,0 +1,767 @@
+/*************************************************************************
+ *
+ * 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_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)
+ :OKeySet(NULL,NULL,::rtl::OUString(),_xComposer,_aParameterValueForCache)
+ ,m_aSqlParser( _rContext.getLegacyServiceFactory() )
+ ,m_aSqlIterator( i_xConnection, Reference<XTablesSupplier>(_xComposer,UNO_QUERY)->getTables(), m_aSqlParser, NULL )
+ ,m_bResultSetChanged(false)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OptimisticSet::OptimisticSet" );
+ DBG_CTOR(OptimisticSet,NULL);
+}
+// -----------------------------------------------------------------------------
+OptimisticSet::~OptimisticSet()
+{
+ 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);
+ initColumns();
+
+ Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
+ bool bCase = (xMeta.is() && xMeta->storesMixedCaseQuotedIdentifiers()) ? true : false;
+ 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)
+ {
+ ::std::auto_ptr<SelectColumnsMetaData> pKeyColumNames(new SelectColumnsMetaData(bCase));
+ findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),*pTableNameIter,xMeta,xQueryColumns,pKeyColumNames);
+ m_pKeyColumnNames->insert(pKeyColumNames->begin(),pKeyColumNames->end());
+ }
+
+ // 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();
+
+ ::rtl::OUStringBuffer aFilter = createKeyFilter();
+
+ Reference< XSingleSelectQueryComposer> xSourceComposer(m_xComposer,UNO_QUERY);
+ Reference< XMultiServiceFactory > xFactory(m_xConnection, UNO_QUERY_THROW);
+ Reference<XSingleSelectQueryComposer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
+ ::rtl::OUString sQuery = xSourceComposer->getQuery();
+ xAnalyzer->setElementaryQuery(xSourceComposer->getElementaryQuery());
+ // 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);
+}
+// -------------------------------------------------------------------------
+// ::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 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;
+ }
+}
+// -----------------------------------------------------------------------------
+::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;
+}
+// -----------------------------------------------------------------------------
+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 000000000000..ba0a04c8b773
--- /dev/null
+++ b/dbaccess/source/core/api/OptimisticSet.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * 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 "KeySet.hxx"
+#include <cppuhelper/implbase1.hxx>
+
+#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 OKeySet
+ {
+ ::connectivity::OSQLParser m_aSqlParser;
+ ::connectivity::OSQLParseTreeIterator m_aSqlIterator;
+
+ ::std::map<sal_Int32,sal_Int32> m_aJoinedColumns;
+ ::std::map<sal_Int32,sal_Int32> m_aJoinedKeyColumns;
+
+
+ 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);
+
+ void impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData);
+
+ 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::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);
+
+ // 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/PrivateRow.cxx b/dbaccess/source/core/api/PrivateRow.cxx
new file mode 100644
index 000000000000..939e335b4cb3
--- /dev/null
+++ b/dbaccess/source/core/api/PrivateRow.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle andor its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "PrivateRow.hxx"
+
+using namespace dbaccess;
+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;
+
+::sal_Bool SAL_CALL OPrivateRow::wasNull( ) throw (SQLException, RuntimeException)
+ {
+ return m_aRow[m_nPos].isNull();
+ }
+ ::rtl::OUString SAL_CALL OPrivateRow::getString( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::sal_Bool SAL_CALL OPrivateRow::getBoolean( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::sal_Int8 SAL_CALL OPrivateRow::getByte( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::sal_Int16 SAL_CALL OPrivateRow::getShort( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::sal_Int32 SAL_CALL OPrivateRow::getInt( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::sal_Int64 SAL_CALL OPrivateRow::getLong( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ float SAL_CALL OPrivateRow::getFloat( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ double SAL_CALL OPrivateRow::getDouble( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ Sequence< ::sal_Int8 > SAL_CALL OPrivateRow::getBytes( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::com::sun::star::util::Date SAL_CALL OPrivateRow::getDate( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::com::sun::star::util::Time SAL_CALL OPrivateRow::getTime( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ ::com::sun::star::util::DateTime SAL_CALL OPrivateRow::getTimestamp( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos];
+ }
+ Reference< ::com::sun::star::io::XInputStream > SAL_CALL OPrivateRow::getBinaryStream( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return Reference< ::com::sun::star::io::XInputStream >(m_aRow[m_nPos].makeAny(),UNO_QUERY);
+ }
+ Reference< ::com::sun::star::io::XInputStream > SAL_CALL OPrivateRow::getCharacterStream( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return Reference< ::com::sun::star::io::XInputStream >(m_aRow[m_nPos].makeAny(),UNO_QUERY);
+ }
+ Any SAL_CALL OPrivateRow::getObject( ::sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return m_aRow[m_nPos].makeAny();
+ }
+ Reference< XRef > SAL_CALL OPrivateRow::getRef( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return Reference< XRef >(m_aRow[m_nPos].makeAny(),UNO_QUERY);
+ }
+ Reference< XBlob > SAL_CALL OPrivateRow::getBlob( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return Reference< XBlob >(m_aRow[m_nPos].makeAny(),UNO_QUERY);
+ }
+ Reference< XClob > SAL_CALL OPrivateRow::getClob( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return Reference< XClob >(m_aRow[m_nPos].makeAny(),UNO_QUERY);
+ }
+ Reference< XArray > SAL_CALL OPrivateRow::getArray( ::sal_Int32 columnIndex ) throw (SQLException, RuntimeException)
+ {
+ m_nPos = columnIndex;
+ return Reference< XArray >(m_aRow[m_nPos].makeAny(),UNO_QUERY);
+ }
+
diff --git a/dbaccess/source/core/api/PrivateRow.hxx b/dbaccess/source/core/api/PrivateRow.hxx
new file mode 100644
index 000000000000..82dd97232c92
--- /dev/null
+++ b/dbaccess/source/core/api/PrivateRow.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef PRIVATE_ROW_HXX
+#define PRIVATE_ROW_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include "RowSetRow.hxx"
+
+namespace dbaccess
+{
+ class OPrivateRow : public ::cppu::WeakImplHelper1< ::com::sun::star::sdbc::XRow>
+ {
+ ORowSetValueVector::Vector m_aRow;
+ sal_Int32 m_nPos;
+ public:
+ OPrivateRow(const ORowSetValueVector::Vector& i_aRow) : m_aRow(i_aRow),m_nPos(0)
+ {
+ }
+ 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);
+ };
+} // dbaccess
+#endif // PRIVATE_ROW_HXX
diff --git a/dbaccess/source/core/api/RowSet.cxx b/dbaccess/source/core/api/RowSet.cxx
new file mode 100644
index 000000000000..829155709119
--- /dev/null
+++ b/dbaccess/source/core/api/RowSet.cxx
@@ -0,0 +1,3057 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "RowSet.hxx"
+#include "dbastrings.hrc"
+#include "sdbcoretools.hxx"
+#include "SingleSelectQueryComposer.hxx"
+#include "module_dba.hxx"
+#include "sdbcoretools.hxx"
+#include "CRowSetColumn.hxx"
+#include "CRowSetDataColumn.hxx"
+#include "RowSetCache.hxx"
+#include "core_resource.hrc"
+#include "core_resource.hxx"
+#include "tablecontainer.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/ErrorCondition.hpp>
+#include <com/sun/star/sdb/RowChangeAction.hpp>
+#include <com/sun/star/sdb/RowSetVetoException.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdbc/FetchDirection.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdbc/XDriverAccess.hpp>
+#include <com/sun/star/sdbcx/CompareBookmark.hpp>
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
+#include <com/sun/star/uno/XNamingService.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/uno3.hxx>
+#include <connectivity/BlobHelper.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/logfile.hxx>
+#include <unotools/syslocale.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+
+using namespace utl;
+using namespace dbaccess;
+using namespace connectivity;
+using namespace comphelper;
+using namespace dbtools;
+using namespace ::com::sun::star;
+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::task;
+using namespace ::com::sun::star::util;
+using namespace ::cppu;
+using namespace ::osl;
+
+//--------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_ORowSet()
+{
+ static ::dba::OAutoRegistration< ORowSet > aAutoRegistration;
+}
+// -----------------------------------------------------------------------------
+
+#define NOTIFY_LISTERNERS_CHECK(_rListeners,T,method) \
+ Sequence< Reference< XInterface > > aListenerSeq = _rListeners.getElements(); \
+ \
+ const Reference< XInterface >* pxIntBegin = aListenerSeq.getConstArray(); \
+ const Reference< XInterface >* pxInt = pxIntBegin + aListenerSeq.getLength(); \
+ \
+ _rGuard.clear(); \
+ sal_Bool bCheck = sal_True; \
+ while( pxInt > pxIntBegin && bCheck ) \
+ { \
+ try \
+ { \
+ while( pxInt > pxIntBegin && bCheck ) \
+ { \
+ --pxInt; \
+ bCheck = static_cast< T* >( pxInt->get() )->method(aEvt); \
+ } \
+ } \
+ catch( RuntimeException& ) \
+ { \
+ } \
+ } \
+ _rGuard.reset();
+
+
+//..................................................................
+namespace dbaccess
+{
+//..................................................................
+//--------------------------------------------------------------------------
+Reference< XInterface > ORowSet_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory)
+{
+ return *(new ORowSet(_rxFactory));
+}
+//--------------------------------------------------------------------------
+ORowSet::ORowSet( const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB )
+ :ORowSet_BASE1(m_aMutex)
+ ,ORowSetBase( _rxORB, ORowSet_BASE1::rBHelper, &m_aMutex )
+ ,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)
+ ,m_nMaxFieldSize(0)
+ ,m_nMaxRows(0)
+ ,m_nQueryTimeOut(0)
+ ,m_nCommandType(CommandType::COMMAND)
+ ,m_nTransactionIsolation(0)
+ ,m_nPrivileges(0)
+ ,m_nInAppend(0)
+ ,m_bUseEscapeProcessing(sal_True)
+ ,m_bApplyFilter(sal_False)
+ ,m_bCommandFacetsDirty( sal_True )
+ ,m_bModified(sal_False)
+ ,m_bRebuildConnOnExecute(sal_False)
+ ,m_bIsBookmarable(sal_True)
+ ,m_bNew(sal_False)
+ ,m_bCanUpdateInsertedRows(sal_True)
+ ,m_bOwnConnection(sal_False)
+{
+ m_nResultSetType = ResultSetType::SCROLL_SENSITIVE;
+ m_nResultSetConcurrency = ResultSetConcurrency::UPDATABLE;
+ m_pMySelf = this;
+ m_aActiveConnection <<= m_xActiveConnection;
+
+ sal_Int32 nRBT = PropertyAttribute::READONLY | PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT;
+ sal_Int32 nRT = PropertyAttribute::READONLY | PropertyAttribute::TRANSIENT;
+ sal_Int32 nBT = PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT;
+
+ m_aPrematureParamValues.get().resize( 0 );
+
+ // sdb.RowSet Properties
+ registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT|PropertyAttribute::BOUND, &m_aActiveConnection, ::getCppuType(reinterpret_cast< Reference< XConnection >* >(NULL)));
+ registerProperty(PROPERTY_DATASOURCENAME, PROPERTY_ID_DATASOURCENAME, PropertyAttribute::BOUND, &m_aDataSourceName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_COMMAND, PROPERTY_ID_COMMAND, PropertyAttribute::BOUND, &m_aCommand, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_COMMAND_TYPE, PROPERTY_ID_COMMAND_TYPE, PropertyAttribute::BOUND, &m_nCommandType, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_ACTIVECOMMAND, PROPERTY_ID_ACTIVECOMMAND, nRBT, &m_aActiveCommand, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_IGNORERESULT, PROPERTY_ID_IGNORERESULT, PropertyAttribute::BOUND, &m_bIgnoreResult, ::getBooleanCppuType());
+ registerProperty(PROPERTY_FILTER, PROPERTY_ID_FILTER, PropertyAttribute::BOUND, &m_aFilter, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_HAVING_CLAUSE, PROPERTY_ID_HAVING_CLAUSE, PropertyAttribute::BOUND, &m_aHavingClause, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_GROUP_BY, PROPERTY_ID_GROUP_BY, PropertyAttribute::BOUND, &m_aGroupBy, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_APPLYFILTER, PROPERTY_ID_APPLYFILTER, PropertyAttribute::BOUND, &m_bApplyFilter, ::getBooleanCppuType());
+ registerProperty(PROPERTY_ORDER, PROPERTY_ID_ORDER, PropertyAttribute::BOUND, &m_aOrder, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ 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());
+ registerProperty(PROPERTY_CANUPDATEINSERTEDROWS,PROPERTY_ID_CANUPDATEINSERTEDROWS, nRT, &m_bCanUpdateInsertedRows, ::getBooleanCppuType());
+ // sdbc.ResultSet Properties
+ registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::TRANSIENT, &m_nResultSetConcurrency,::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_RESULTSETTYPE, PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::TRANSIENT, &m_nResultSetType, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_FETCHDIRECTION, PROPERTY_ID_FETCHDIRECTION, PropertyAttribute::TRANSIENT, &m_nFetchDirection, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_FETCHSIZE, PROPERTY_ID_FETCHSIZE, PropertyAttribute::TRANSIENT, &m_nFetchSize, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+
+ // sdbc.RowSet Properties
+ registerProperty(PROPERTY_URL, PROPERTY_ID_URL, 0, &m_aURL, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_TRANSACTIONISOLATION, PROPERTY_ID_TRANSACTIONISOLATION, PropertyAttribute::TRANSIENT, &m_nTransactionIsolation,::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerMayBeVoidProperty(PROPERTY_TYPEMAP, PROPERTY_ID_TYPEMAP, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT, &m_aTypeMap, ::getCppuType(reinterpret_cast< Reference< XNameAccess >* >(NULL)));
+ registerProperty(PROPERTY_ESCAPE_PROCESSING,PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::BOUND, &m_bUseEscapeProcessing,::getBooleanCppuType() );
+ registerProperty(PROPERTY_QUERYTIMEOUT, PROPERTY_ID_QUERYTIMEOUT, PropertyAttribute::TRANSIENT, &m_nQueryTimeOut, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_MAXFIELDSIZE, PROPERTY_ID_MAXFIELDSIZE, PropertyAttribute::TRANSIENT, &m_nMaxFieldSize, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_MAXROWS, PROPERTY_ID_MAXROWS, 0, &m_nMaxRows, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)) );
+ registerProperty(PROPERTY_USER, PROPERTY_ID_USER, PropertyAttribute::TRANSIENT, &m_aUser, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_PASSWORD, PROPERTY_ID_PASSWORD, PropertyAttribute::TRANSIENT, &m_aPassword, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+
+ registerProperty(PROPERTY_UPDATE_CATALOGNAME, PROPERTY_ID_UPDATE_CATALOGNAME, PropertyAttribute::BOUND, &m_aUpdateCatalogName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_UPDATE_SCHEMANAME, PROPERTY_ID_UPDATE_SCHEMANAME, PropertyAttribute::BOUND, &m_aUpdateSchemaName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerProperty(PROPERTY_UPDATE_TABLENAME, PROPERTY_ID_UPDATE_TABLENAME, PropertyAttribute::BOUND, &m_aUpdateTableName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+}
+
+ORowSet::~ORowSet()
+{
+ if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
+ {
+ OSL_ENSURE(0, "Please check who doesn't dispose this component!");
+ osl_incrementInterlockedCount( &m_refCount );
+ dispose();
+ }
+}
+
+// -----------------------------------------------------------------------------
+void ORowSet::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const
+{
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_COMMAND_TYPE:
+ _rDefault <<= static_cast<sal_Int32>(CommandType::COMMAND);
+ break;
+ case PROPERTY_ID_IGNORERESULT:
+ _rDefault <<= sal_False;
+ break;
+ case PROPERTY_ID_APPLYFILTER:
+ _rDefault <<= sal_False;
+ break;
+ case PROPERTY_ID_ISMODIFIED:
+ _rDefault <<= sal_False;
+ break;
+ case PROPERTY_ID_ISBOOKMARKABLE:
+ _rDefault <<= sal_True;
+ break;
+ case PROPERTY_ID_CANUPDATEINSERTEDROWS:
+ _rDefault <<= sal_True;
+ break;
+ case PROPERTY_ID_RESULTSETTYPE:
+ _rDefault <<= ResultSetType::SCROLL_INSENSITIVE;
+ break;
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ _rDefault <<= ResultSetConcurrency::UPDATABLE;
+ break;
+ case PROPERTY_ID_FETCHDIRECTION:
+ _rDefault <<= FetchDirection::FORWARD;
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ _rDefault <<= static_cast<sal_Int32>(1);
+ break;
+ case PROPERTY_ID_ESCAPE_PROCESSING:
+ _rDefault <<= sal_True;
+ break;
+ case PROPERTY_ID_MAXROWS:
+ _rDefault <<= sal_Int32( 0 );
+ break;
+ case PROPERTY_ID_FILTER:
+ case PROPERTY_ID_HAVING_CLAUSE:
+ case PROPERTY_ID_GROUP_BY:
+ case PROPERTY_ID_ORDER:
+ case PROPERTY_ID_UPDATE_CATALOGNAME:
+ case PROPERTY_ID_UPDATE_SCHEMANAME:
+ case PROPERTY_ID_UPDATE_TABLENAME:
+ _rDefault <<= ::rtl::OUString();
+ break;
+ }
+}
+// -------------------------------------------------------------------------
+// typedef ::comphelper::OPropertyArrayUsageHelper<ORowSet> ORowSet_Prop;
+
+void SAL_CALL ORowSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
+{
+ switch(nHandle)
+ {
+ case PROPERTY_ID_ISMODIFIED:
+ m_bModified = cppu::any2bool(rValue);
+ break;
+ case PROPERTY_ID_FETCHDIRECTION:
+ if( m_nResultSetType == ResultSetType::FORWARD_ONLY)
+ throw Exception(); // else run through
+ default:
+ OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue);
+ }
+
+ if ( ( nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
+ || ( nHandle == PROPERTY_ID_DATASOURCENAME )
+ || ( nHandle == PROPERTY_ID_COMMAND )
+ || ( nHandle == PROPERTY_ID_COMMAND_TYPE )
+ || ( nHandle == PROPERTY_ID_IGNORERESULT )
+ || ( nHandle == PROPERTY_ID_FILTER )
+ || ( nHandle == PROPERTY_ID_HAVING_CLAUSE )
+ || ( nHandle == PROPERTY_ID_GROUP_BY )
+ || ( nHandle == PROPERTY_ID_APPLYFILTER )
+ || ( nHandle == PROPERTY_ID_ORDER )
+ || ( nHandle == PROPERTY_ID_URL )
+ || ( nHandle == PROPERTY_ID_USER )
+ )
+ {
+ m_bCommandFacetsDirty = sal_True;
+ }
+
+
+ switch(nHandle)
+ {
+ case PROPERTY_ID_ACTIVE_CONNECTION:
+ // the new connection
+ {
+ Reference< XConnection > xNewConnection(m_aActiveConnection,UNO_QUERY);
+ setActiveConnection(xNewConnection, sal_False);
+ }
+
+ m_bOwnConnection = sal_False;
+ m_bRebuildConnOnExecute = sal_False;
+ break;
+
+ case PROPERTY_ID_DATASOURCENAME:
+ if(!m_xStatement.is())
+ {
+ Reference< XConnection > xNewConn;
+ Any aNewConn;
+ aNewConn <<= xNewConn;
+ setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn);
+ }
+ else
+ m_bRebuildConnOnExecute = sal_True;
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ if(m_pCache)
+ {
+ m_pCache->setMaxRowSize(m_nFetchSize);
+ fireRowcount();
+ }
+ break;
+ case PROPERTY_ID_URL:
+ // is the connection-to-be-built determined by the url (which is the case if m_aDataSourceName is empty) ?
+ if (!m_aDataSourceName.getLength())
+ {
+ // are we active at the moment ?
+ if (m_xStatement.is())
+ // yes -> the next execute needs to rebuild our connection because of this new property
+ m_bRebuildConnOnExecute = sal_True;
+ else
+ { // no -> drop our active connection (if we have one) as it doesn't correspond to this new property value anymore
+ Reference< XConnection > xNewConn;
+ Any aNewConn;
+ aNewConn <<= xNewConn;
+ setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn);
+ }
+ }
+ m_bOwnConnection = sal_True;
+ break;
+ case PROPERTY_ID_TYPEMAP:
+ ::cppu::extractInterface(m_xTypeMap,m_aTypeMap);
+ break;
+ default:
+ break;
+ };
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
+{
+ if(m_pCache)
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_ISMODIFIED:
+ rValue.setValue(&m_bModified,::getCppuBooleanType());
+ break;
+ case PROPERTY_ID_ISNEW:
+ rValue.setValue(&m_bNew,::getCppuBooleanType());
+ break;
+ case PROPERTY_ID_PRIVILEGES:
+ rValue <<= m_pCache->m_nPrivileges;
+ break;
+ case PROPERTY_ID_ACTIVE_CONNECTION:
+ rValue <<= m_xActiveConnection;
+ break;
+ case PROPERTY_ID_TYPEMAP:
+ rValue <<= m_xTypeMap;
+ break;
+ default:
+ ORowSetBase::getFastPropertyValue(rValue,nHandle);
+ };
+ }
+ else
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_ACTIVE_CONNECTION:
+ rValue <<= m_xActiveConnection;
+ break;
+ case PROPERTY_ID_TYPEMAP:
+ rValue <<= m_xTypeMap;
+ break;
+ default:
+ ORowSetBase::getFastPropertyValue(rValue,nHandle);
+ }
+ }
+}
+// -------------------------------------------------------------------------
+// com::sun::star::XTypeProvider
+Sequence< Type > SAL_CALL ORowSet::getTypes() throw (RuntimeException)
+{
+ OTypeCollection aTypes(::getCppuType( (const Reference< XPropertySet > *)0 ),
+ ::getCppuType( (const Reference< XFastPropertySet > *)0 ),
+ ::getCppuType( (const Reference< XMultiPropertySet > *)0 ),
+ ::comphelper::concatSequences(ORowSet_BASE1::getTypes(),ORowSetBase::getTypes()));
+ return aTypes.getTypes();
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL ORowSet::getImplementationId() throw (RuntimeException)
+{
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+// -------------------------------------------------------------------------
+
+// com::sun::star::XInterface
+Any SAL_CALL ORowSet::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ return ORowSet_BASE1::queryInterface( rType);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::acquire() throw()
+{
+ ORowSet_BASE1::acquire();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::release() throw()
+{
+ ORowSet_BASE1::release();
+}
+// -------------------------------------------------------------------------
+
+// com::sun::star::XUnoTunnel
+sal_Int64 SAL_CALL ORowSet::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+}
+// -------------------------------------------------------------------------
+// com::sun::star::XAggregation
+Any SAL_CALL ORowSet::queryAggregation( const Type& rType ) throw(RuntimeException)
+{
+ Any aRet(ORowSetBase::queryInterface(rType));
+ if (!aRet.hasValue())
+ aRet = ORowSet_BASE1::queryAggregation(rType);
+ return aRet;
+}
+//------------------------------------------------------------------------------
+rtl::OUString ORowSet::getImplementationName_static( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.comp.dba.ORowSet");
+}
+// -------------------------------------------------------------------------
+// ::com::sun::star::XServiceInfo
+::rtl::OUString SAL_CALL ORowSet::getImplementationName( ) throw(RuntimeException)
+{
+ return getImplementationName_static();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSet::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > ORowSet::getSupportedServiceNames_static( ) throw (RuntimeException)
+{
+ Sequence< rtl::OUString > aSNS( 5 );
+ aSNS[0] = SERVICE_SDBC_RESULTSET;
+ aSNS[1] = SERVICE_SDBC_ROWSET;
+ aSNS[2] = SERVICE_SDBCX_RESULTSET;
+ aSNS[3] = SERVICE_SDB_RESULTSET;
+ aSNS[4] = SERVICE_SDB_ROWSET;
+ return aSNS;
+}
+// -------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL ORowSet::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ return getSupportedServiceNames_static();
+}
+//------------------------------------------------------------------------------
+Reference< XInterface > ORowSet::Create(const Reference< XComponentContext >& _rxContext)
+{
+ ::comphelper::ComponentContext aContext( _rxContext );
+ return ORowSet_CreateInstance( aContext.getLegacyServiceFactory() );
+}
+// -------------------------------------------------------------------------
+// OComponentHelper
+void SAL_CALL ORowSet::disposing()
+{
+ OPropertyStateContainer::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+ EventObject aDisposeEvent;
+ aDisposeEvent.Source = static_cast< XComponent* >(this);
+ m_aRowsetListeners.disposeAndClear( aDisposeEvent );
+ m_aApproveListeners.disposeAndClear( aDisposeEvent );
+ m_aRowsChangeListener.disposeAndClear( aDisposeEvent );
+
+ freeResources( true );
+
+ // remove myself as dispose listener
+ Reference< XComponent > xComponent(m_xActiveConnection, UNO_QUERY);
+ if (xComponent.is())
+ {
+ Reference<XEventListener> xEvt;
+ query_aggregation(this,xEvt);
+ xComponent->removeEventListener(xEvt);
+ }
+
+ m_aActiveConnection = Any(); // the any conatains a reference too
+ if(m_bOwnConnection)
+ ::comphelper::disposeComponent(m_xActiveConnection);
+ m_xActiveConnection = NULL;
+
+
+ ORowSetBase::disposing();
+}
+// -------------------------------------------------------------------------
+void ORowSet::freeResources( bool _bComplete )
+{
+ MutexGuard aGuard(m_aMutex);
+
+ // free all clones
+ connectivity::OWeakRefArray::iterator aEnd = m_aClones.end();
+ for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; i++)
+ {
+ Reference< XComponent > xComp(i->get(), UNO_QUERY);
+ if (xComp.is())
+ xComp->dispose();
+ }
+ m_aClones.clear();
+
+ if ( _bComplete )
+ {
+ // the columns must be disposed before the querycomposer is disposed because
+ // their owner can be the composer
+ TDataColumns().swap(m_aDataColumns);// clear and resize capacity
+ m_xColumns = NULL;
+ if ( m_pColumns )
+ m_pColumns->disposing();
+ // dispose the composer to avoid that everbody knows that the querycomposer is eol
+ try { ::comphelper::disposeComponent( m_xComposer ); }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ m_xComposer = NULL;
+ }
+
+ // let our warnings container forget the reference to the (possibly disposed) old result set
+ m_aWarnings.setExternalWarnings( NULL );
+
+ DELETEZ(m_pCache);
+
+ impl_resetTables_nothrow();
+
+ m_xStatement = NULL;
+ m_xTypeMap = NULL;
+
+ m_aBookmark = Any();
+ m_bBeforeFirst = sal_True;
+ m_bAfterLast = sal_False;
+ m_bNew = sal_False;
+ m_bModified = sal_False;
+ m_bLastKnownRowCountFinal = sal_False;
+ m_nLastKnownRowCount = 0;
+ if ( m_aOldRow.isValid() )
+ m_aOldRow->clearRow();
+
+ impl_disposeParametersContainer_nothrow();
+
+ m_bCommandFacetsDirty = sal_True;
+ }
+}
+
+// -------------------------------------------------------------------------
+void ORowSet::setActiveConnection( Reference< XConnection >& _rxNewConn, sal_Bool _bFireEvent )
+{
+ if (_rxNewConn.get() == m_xActiveConnection.get())
+ // nothing to do
+ return;
+
+ // remove the event listener for the old connection
+ Reference< XComponent > xComponent(m_xActiveConnection, UNO_QUERY);
+ if (xComponent.is())
+ {
+ Reference<XEventListener> xListener;
+ query_aggregation(this, xListener);
+ xComponent->removeEventListener(xListener);
+ }
+
+ // if we owned the connection, remember it for later disposing
+ if(m_bOwnConnection)
+ m_xOldConnection = m_xActiveConnection;
+
+ // for firing the PropertyChangeEvent
+ sal_Int32 nHandle = PROPERTY_ID_ACTIVE_CONNECTION;
+ Any aOldConnection; aOldConnection <<= m_xActiveConnection;
+ Any aNewConnection; aNewConnection <<= _rxNewConn;
+
+ // set the new connection
+ m_xActiveConnection = _rxNewConn;
+ if (m_xActiveConnection.is())
+ m_aActiveConnection <<= m_xActiveConnection;
+ else
+ m_aActiveConnection.clear();
+
+ // fire the event
+ if (_bFireEvent)
+ fire(&nHandle, &aNewConnection, &aOldConnection, 1, sal_False);
+
+ // register as event listener for the new connection
+ xComponent.set(m_xActiveConnection,UNO_QUERY);
+ if (xComponent.is())
+ {
+ Reference<XEventListener> xListener;
+ query_aggregation(this, xListener);
+ xComponent->addEventListener(xListener);
+ }
+}
+
+// -------------------------------------------------------------------------
+// ::com::sun::star::XEventListener
+void SAL_CALL ORowSet::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
+{
+ // close rowset because the connection is going to be deleted (someone told me :-)
+ Reference<XConnection> xCon(Source.Source,UNO_QUERY);
+ if(m_xActiveConnection == xCon)
+ {
+ close();
+ {
+ MutexGuard aGuard( m_aMutex );
+ Reference< XConnection > xXConnection;
+ setActiveConnection( xXConnection );
+ }
+ }
+}
+// -------------------------------------------------------------------------
+
+// XCloseable
+void SAL_CALL ORowSet::close( ) throw(SQLException, RuntimeException)
+{
+ {
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+ }
+ // additionals things to set
+ freeResources( true );
+}
+// -------------------------------------------------------------------------
+// comphelper::OPropertyArrayUsageHelper
+::cppu::IPropertyArrayHelper* ORowSet::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+// -------------------------------------------------------------------------
+// cppu::OPropertySetHelper
+::cppu::IPropertyArrayHelper& SAL_CALL ORowSet::getInfoHelper()
+{
+ typedef ::comphelper::OPropertyArrayUsageHelper<ORowSet> ORowSet_PROP;
+ return *ORowSet_PROP::getArrayHelper();
+}
+// -----------------------------------------------------------------------------
+void ORowSet::updateValue(sal_Int32 columnIndex,const ORowSetValue& x)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkUpdateConditions(columnIndex);
+ checkUpdateIterator();
+
+ ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get());
+ ORowSetNotifier aNotify(this,rRow);
+ m_pCache->updateValue(columnIndex,x,rRow,aNotify.getChangedColumns());
+ aNotify.firePropertyChange();
+}
+// -------------------------------------------------------------------------
+// XRowUpdate
+void SAL_CALL ORowSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkUpdateConditions(columnIndex);
+ checkUpdateIterator();
+
+ 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)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException)
+{
+ updateValue(columnIndex,x);
+}
+// -------------------------------------------------------------------------
+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)
+ //{
+ // ::connectivity::ORowSetValue aOldValue = ((*m_aCurrentRow)->get())[columnIndex];
+ // m_pCache->updateBinaryStream(columnIndex,x,length);
+ // ((*m_aCurrentRow)->get())[columnIndex] = makeAny(x);
+ // ((*m_aCurrentRow)->get())[columnIndex].setTypeKind(DataType::BLOB);
+ // firePropertyChange(columnIndex-1 ,aOldValue);
+ // fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False);
+ //}
+ //else
+ {
+ Sequence<sal_Int8> aSeq;
+ if(x.is())
+ x->readBytes(aSeq,length);
+ updateValue(columnIndex,aSeq);
+ }
+}
+// -------------------------------------------------------------------------
+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();
+ 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;
+
+ if ( m_pColumns )
+ {
+ Reference<XPropertySet> xColumn(m_pColumns->getByIndex(columnIndex-1),UNO_QUERY);
+ sal_Int32 nColType = 0;
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nColType;
+ switch( nColType )
+ {
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ {
+ double nValue = 0;
+ if ( x >>= nValue )
+ {
+ if ( DataType::TIMESTAMP == nColType )
+ aNewValue <<= dbtools::DBTypeConversion::toDateTime( nValue );
+ else if ( DataType::DATE == nColType )
+ aNewValue <<= dbtools::DBTypeConversion::toDate( nValue );
+ else
+ aNewValue <<= dbtools::DBTypeConversion::toTime( nValue );
+ }
+ break;
+ }
+ }
+ }
+
+ if (!::dbtools::implUpdateObject(this, columnIndex, aNewValue))
+ { // there is no other updateXXX call which can handle the value in x
+ 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();
+ ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get());
+ ORowSetNotifier aNotify(this,rRow);
+ m_pCache->updateNumericObject(columnIndex,x,scale,rRow,aNotify.getChangedColumns());
+ aNotify.firePropertyChange();
+}
+// -------------------------------------------------------------------------
+
+// XResultSetUpdate
+void SAL_CALL ORowSet::insertRow( ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+ // insertRow is not allowd when
+ // standing not on the insert row nor
+ // when the row isn't modified
+ // or the concurency is read only
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ if(!m_pCache || !m_bNew || !m_bModified || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
+ throwFunctionSequenceException(*this);
+
+ if(m_bModified)
+ {
+ // remember old value for fire
+ sal_Bool bOld = m_bNew;
+
+ ORowSetRow aOldValues;
+ if ( !m_aCurrentRow.isNull() )
+ aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() );
+ Sequence<Any> aChangedBookmarks;
+ RowsChangeEvent aEvt(*this,RowChangeAction::INSERT,1,aChangedBookmarks);
+ notifyAllListenersRowBeforeChange(aGuard,aEvt);
+
+ ::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);
+
+ // notification order
+ // - 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)
+ fireProperty(PROPERTY_ID_ISMODIFIED,sal_False,sal_True);
+ OSL_ENSURE( !m_bModified, "ORowSet::insertRow: just updated, but _still_ modified?" );
+
+ // - IsNew
+ if(m_bNew != bOld)
+ fireProperty(PROPERTY_ID_ISNEW,m_bNew,bOld);
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ORowSet::getRow( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ // check if we are inserting a row
+ return (m_pCache && ( m_pCache->m_bNew || m_bModified )) ? 0 : ORowSetBase::getRow();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::updateRow( ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+ // not allowed when standing on insert row
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ if ( !m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY || m_bNew || ((m_pCache->m_nPrivileges & Privilege::UPDATE ) != Privilege::UPDATE) )
+ throwFunctionSequenceException(*this);
+
+
+ if(m_bModified)
+ {
+ ORowSetRow aOldValues;
+ if ( !m_aCurrentRow.isNull() )
+ aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() );
+
+ Sequence<Any> aChangedBookmarks;
+ RowsChangeEvent aEvt(*this,RowChangeAction::UPDATE,1,aChangedBookmarks);
+ notifyAllListenersRowBeforeChange(aGuard,aEvt);
+
+ ::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() && (*m_pCache->m_aMatrixIter).isValid() )
+ {
+ 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);
+
+ // - IsModified
+ 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 if ( !m_bAfterLast ) // the update went rong
+ {
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_UPDATE_FAILED ), SQL_INVALID_CURSOR_POSITION, *this );
+ }
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::deleteRow( ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ if ( m_bBeforeFirst || m_bAfterLast )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_BEFORE_AFTER ), SQL_INVALID_CURSOR_POSITION, *this );
+ if ( m_bNew )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_INSERT_ROW ), SQL_INVALID_CURSOR_POSITION, *this );
+ if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_RESULT_IS_READONLY ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
+ if ( ( m_pCache->m_nPrivileges & Privilege::DELETE ) != Privilege::DELETE )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_PRIVILEGE ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
+ if ( rowDeleted() )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
+
+ // this call position the cache indirect
+ Any aBookmarkToDelete( m_aBookmark );
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ sal_Int32 nDeletePosition = m_pCache->getRow();
+
+ notifyRowSetAndClonesRowDelete( aBookmarkToDelete );
+
+ ORowSetRow aOldValues;
+ if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && m_pCache->m_aMatrixIter->isValid() )
+ aOldValues = new ORowSetValueVector( m_pCache->m_aMatrixIter->getBody() );
+
+ Sequence<Any> aChangedBookmarks;
+ RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,1,aChangedBookmarks);
+ notifyAllListenersRowBeforeChange(aGuard,aEvt);
+
+ m_pCache->deleteRow();
+ notifyRowSetAndClonesRowDeleted( aBookmarkToDelete, nDeletePosition );
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ // notification order
+ // - rowChanged
+ notifyAllListenersRowChanged(aGuard,aEvt);
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire( );
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+}
+
+// -------------------------------------------------------------------------
+void ORowSet::implCancelRowUpdates( sal_Bool _bNotifyModified ) SAL_THROW( ( SQLException, RuntimeException ) )
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ if ( m_bBeforeFirst || m_bAfterLast || rowDeleted() )
+ return; // nothing to do so return
+
+ checkCache();
+ // cancelRowUpdates is not allowed when:
+ // - standing on the insert row
+ // - the concurrency is read only
+ // - the current row is deleted
+ if ( m_bNew || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
+ throwFunctionSequenceException(*this);
+
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+
+ ORowSetRow aOldValues;
+ if ( !m_aCurrentRow.isNull() )
+ aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() );
+
+ m_pCache->cancelRowUpdates();
+
+ m_aBookmark = m_pCache->getBookmark();
+ m_aCurrentRow = m_pCache->m_aMatrixIter;
+ m_aCurrentRow.setBookmark(m_aBookmark);
+
+ // notification order
+ // - column values
+ ORowSetBase::firePropertyChange(aOldValues);
+ // IsModified
+ if( !m_bModified && _bNotifyModified )
+ fireProperty(PROPERTY_ID_ISMODIFIED,sal_False,sal_True);
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::cancelRowUpdates( ) throw(SQLException, RuntimeException)
+{
+ implCancelRowUpdates( sal_True );
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::addRowSetListener( const Reference< XRowSetListener >& listener ) throw(RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ if(listener.is())
+ m_aRowsetListeners.addInterface(listener);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::removeRowSetListener( const Reference< XRowSetListener >& listener ) throw(RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ if(listener.is())
+ m_aRowsetListeners.removeInterface(listener);
+}
+// -----------------------------------------------------------------------------
+void ORowSet::notifyAllListeners(::osl::ResettableMutexGuard& _rGuard)
+{
+ EventObject aEvt(*m_pMySelf);
+ _rGuard.clear();
+ m_aRowsetListeners.notifyEach( &XRowSetListener::rowSetChanged, aEvt );
+ _rGuard.reset();
+}
+// -------------------------------------------------------------------------
+void ORowSet::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard)
+{
+ EventObject aEvt(*m_pMySelf);
+ _rGuard.clear();
+ m_aRowsetListeners.notifyEach( &XRowSetListener::cursorMoved, aEvt );
+ _rGuard.reset();
+}
+// -------------------------------------------------------------------------
+void ORowSet::notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard, const RowsChangeEvent& aEvt)
+{
+ _rGuard.clear();
+ m_aRowsetListeners.notifyEach( &XRowSetListener::rowChanged, (EventObject)aEvt );
+ m_aRowsChangeListener.notifyEach( &XRowsChangeListener::rowsChanged, aEvt );
+ _rGuard.reset();
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSet::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard)
+{
+ EventObject aEvt(*m_pMySelf);
+ NOTIFY_LISTERNERS_CHECK(m_aApproveListeners,XRowSetApproveListener,approveCursorMove);
+ return bCheck;
+}
+// -------------------------------------------------------------------------
+void ORowSet::notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const RowChangeEvent &aEvt)
+{
+ NOTIFY_LISTERNERS_CHECK(m_aApproveListeners,XRowSetApproveListener,approveRowChange);
+ if ( !bCheck )
+ m_aErrors.raiseTypedException( sdb::ErrorCondition::ROW_SET_OPERATION_VETOED, *this, ::cppu::UnoType< RowSetVetoException >::get() );
+}
+// -------------------------------------------------------------------------
+void ORowSet::fireRowcount()
+{
+ sal_Int32 nCurrentRowCount( impl_getRowCount() );
+ sal_Bool bCurrentRowCountFinal( m_pCache->m_bRowCountFinal );
+
+ if ( m_nLastKnownRowCount != nCurrentRowCount )
+ {
+ sal_Int32 nHandle = PROPERTY_ID_ROWCOUNT;
+ Any aNew,aOld;
+ aNew <<= nCurrentRowCount; aOld <<= m_nLastKnownRowCount;
+ fire(&nHandle,&aNew,&aOld,1,sal_False);
+ m_nLastKnownRowCount = nCurrentRowCount;
+ }
+ if ( !m_bLastKnownRowCountFinal && ( m_bLastKnownRowCountFinal != bCurrentRowCountFinal ) )
+ {
+ sal_Int32 nHandle = PROPERTY_ID_ISROWCOUNTFINAL;
+ Any aNew,aOld;
+ aNew <<= bCurrentRowCountFinal;
+ aOld <<= m_bLastKnownRowCountFinal;
+ fire(&nHandle,&aNew,&aOld,1,sal_False);
+ m_bLastKnownRowCountFinal = bCurrentRowCountFinal;
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::moveToInsertRow( ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkPositioningAllowed();
+ if ( ( m_pCache->m_nPrivileges & Privilege::INSERT ) != Privilege::INSERT )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_INSERT_PRIVILEGE ), SQL_GENERAL_ERROR, *this );
+
+ if ( notifyAllListenersCursorBeforeMove( aGuard ) )
+ {
+ // remember old value for fire
+ ORowSetRow aOldValues;
+ if ( rowDeleted() )
+ {
+ positionCache( MOVE_FORWARD );
+ m_pCache->next();
+ setCurrentRow( sal_True, sal_False, aOldValues, aGuard);
+ }
+ else
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+
+ // check before because the resultset could be empty
+ if ( !m_bBeforeFirst
+ && !m_bAfterLast
+ && m_pCache->m_aMatrixIter != m_pCache->getEnd()
+ && m_pCache->m_aMatrixIter->isValid()
+ )
+ aOldValues = new ORowSetValueVector( m_pCache->m_aMatrixIter->getBody() );
+
+ const sal_Bool bNewState = m_bNew;
+ const sal_Bool bModState = m_bModified;
+
+ 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);
+
+ // - cursorMoved
+ notifyAllListenersCursorMoved(aGuard);
+
+ // - IsModified
+ if ( bModState != m_bModified )
+ fireProperty( PROPERTY_ID_ISMODIFIED, m_bModified, bModState );
+
+ // - IsNew
+ if ( bNewState != m_bNew )
+ fireProperty( PROPERTY_ID_ISNEW, m_bNew, bNewState );
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+}
+// -------------------------------------------------------------------------
+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);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkPositioningAllowed();
+
+ if ( !m_pCache->m_bNew && !m_bModified )
+ // nothing to do if we're not on the insertion row, and not modified otherwise
+ return;
+
+ if ( rowDeleted() )
+ // this would perhaps even justify a RuntimeException ....
+ // if the current row is deleted, then no write access to this row should be possible. So,
+ // m_bModified should be true. Also, as soon as somebody calls moveToInsertRow,
+ // our current row should not be deleted anymore. So, we should not have survived the above
+ // check "if ( !m_pCache->m_bNew && !m_bModified )"
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
+
+ if ( notifyAllListenersCursorBeforeMove( aGuard ) )
+ {
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+
+ ORowSetNotifier aNotifier( this );
+
+ // notification order
+ // - cursorMoved
+ notifyAllListenersCursorMoved(aGuard);
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+ }
+}
+// -------------------------------------------------------------------------
+// XRow
+sal_Bool SAL_CALL ORowSet::wasNull( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ return ( m_pCache && isInsertRow() ) ? ((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex].isNull() : ORowSetBase::wasNull();
+}
+// -----------------------------------------------------------------------------
+const ORowSetValue& ORowSet::getInsertValue(sal_Int32 columnIndex)
+{
+ checkCache();
+
+ if ( m_pCache && isInsertRow() )
+ return ((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex];
+
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ORowSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int8 SAL_CALL ORowSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int16 SAL_CALL ORowSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ORowSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int64 SAL_CALL ORowSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+float SAL_CALL ORowSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+double SAL_CALL ORowSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL ORowSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Date SAL_CALL ORowSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Time SAL_CALL ORowSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::DateTime SAL_CALL ORowSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ if ( m_pCache && isInsertRow() )
+ {
+ checkCache();
+ return new ::comphelper::SequenceInputStream(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
+ }
+
+ return ORowSetBase::getBinaryStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ if(m_pCache && isInsertRow() )
+ {
+ checkCache();
+ return new ::comphelper::SequenceInputStream(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
+ }
+
+ return ORowSetBase::getCharacterStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL ORowSet::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getInsertValue(columnIndex).makeAny();
+}
+// -------------------------------------------------------------------------
+Reference< XRef > SAL_CALL ORowSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return Reference< XRef >();
+}
+// -------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL ORowSet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ if ( m_pCache && isInsertRow() )
+ {
+ checkCache();
+ return new ::connectivity::BlobHelper(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
+ }
+ return ORowSetBase::getBlob(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< XClob > SAL_CALL ORowSet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return Reference< XClob >(getInsertValue(columnIndex).makeAny(),UNO_QUERY);
+}
+// -------------------------------------------------------------------------
+Reference< XArray > SAL_CALL ORowSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return Reference< XArray >();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::executeWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException)
+{
+ if (!_rxHandler.is())
+ execute();
+
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ // tell everybody that we will change the result set
+ approveExecution();
+
+ ResettableMutexGuard aGuard( m_aMutex );
+
+ try
+ {
+ freeResources( m_bCommandFacetsDirty );
+
+ // calc the connection to be used
+ if (m_xActiveConnection.is() && m_bRebuildConnOnExecute)
+ {
+ // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too
+ Reference< XConnection > xXConnection;
+ setActiveConnection( xXConnection );
+ }
+ calcConnection( _rxHandler );
+ m_bRebuildConnOnExecute = sal_False;
+
+ Reference< XSingleSelectQueryComposer > xComposer = getCurrentSettingsComposer( this, m_aContext.getLegacyServiceFactory() );
+ Reference<XParametersSupplier> xParameters(xComposer, UNO_QUERY);
+
+ Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>();
+ const sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0;
+ if ( m_aParametersSet.size() < (size_t)nParamCount )
+ m_aParametersSet.resize( nParamCount ,false);
+
+ ::dbtools::askForParameters( xComposer, this, m_xActiveConnection, _rxHandler,m_aParametersSet );
+ }
+ // ensure that only the allowed exceptions leave this block
+ catch(SQLException&)
+ {
+ throw;
+ }
+ catch(RuntimeException&)
+ {
+ throw;
+ }
+ catch(Exception&)
+ {
+ DBG_ERROR("ORowSet::executeWithCompletion: caught an unexpected exception type while filling in the parameters!");
+ }
+
+ // we're done with the parameters, now for the real execution
+
+ // do the real execute
+ execute_NoApprove_NoNewConn(aGuard);
+}
+
+// -------------------------------------------------------------------------
+Reference< XIndexAccess > SAL_CALL ORowSet::getParameters( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ if ( m_bCommandFacetsDirty )
+ // need to rebuild the parameters, since some property which contributes to the
+ // complete command, and thus the parameters, changed
+ impl_disposeParametersContainer_nothrow();
+
+ if ( !m_pParameters.get() && m_aCommand.getLength() )
+ {
+ try
+ {
+ ::rtl::OUString sNotInterestedIn;
+ impl_initComposer_throw( sNotInterestedIn );
+ }
+ catch( const Exception& )
+ {
+ // silence it
+ }
+ }
+
+ return m_pParameters.get();
+}
+
+// -------------------------------------------------------------------------
+void ORowSet::approveExecution() throw (RowSetVetoException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ EventObject aEvt(*this);
+
+ OInterfaceIteratorHelper aApproveIter( m_aApproveListeners );
+ while ( aApproveIter.hasMoreElements() )
+ {
+ Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aApproveIter.next() ) );
+ try
+ {
+ if ( xListener.is() && !xListener->approveRowSetChange( aEvt ) )
+ throw RowSetVetoException();
+ }
+ catch ( const DisposedException& e )
+ {
+ if ( e.Context == xListener )
+ aApproveIter.remove();
+ }
+ catch ( const RuntimeException& ) { throw; }
+ catch ( const RowSetVetoException& ) { throw; }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+// -------------------------------------------------------------------------
+// XRowSet
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::execute( ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ // tell everybody that we will change the result set
+ approveExecution();
+
+ ResettableMutexGuard aGuard( m_aMutex );
+ freeResources( m_bCommandFacetsDirty );
+
+ // calc the connection to be used
+ if (m_xActiveConnection.is() && m_bRebuildConnOnExecute) {
+ // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too
+ Reference< XConnection> xXConnection;
+ setActiveConnection( xXConnection );
+ }
+
+ calcConnection(NULL);
+ m_bRebuildConnOnExecute = sal_False;
+
+ // do the real execute
+ execute_NoApprove_NoNewConn(aGuard);
+}
+
+//------------------------------------------------------------------------------
+void ORowSet::setStatementResultSetType( const Reference< XPropertySet >& _rxStatement, sal_Int32 _nDesiredResultSetType, sal_Int32 _nDesiredResultSetConcurrency )
+{
+ OSL_ENSURE( _rxStatement.is(), "ORowSet::setStatementResultSetType: invalid statement - this will crash!" );
+
+ sal_Int32 nResultSetType( _nDesiredResultSetType );
+ sal_Int32 nResultSetConcurrency( _nDesiredResultSetConcurrency );
+
+ // there *might* be a data source setting which tells use to be more defensive with those settings
+ // #i15113# / 2005-02-10 / frank.schoenheit@sun.com
+ sal_Bool bRespectDriverRST = sal_False;
+ Any aSetting;
+ if ( getDataSourceSetting( ::dbaccess::getDataSource( m_xActiveConnection ), "RespectDriverResultSetType", aSetting ) )
+ {
+ OSL_VERIFY( aSetting >>= bRespectDriverRST );
+ }
+
+ if ( bRespectDriverRST )
+ {
+ // try type/concurrency settings with decreasing usefullness, and rely on what the connection claims
+ // to support
+ Reference< XDatabaseMetaData > xMeta( m_xActiveConnection->getMetaData() );
+
+ sal_Int32 nCharacteristics[5][2] =
+ { { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::UPDATABLE },
+ { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::UPDATABLE },
+ { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::READ_ONLY },
+ { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::READ_ONLY },
+ { ResultSetType::FORWARD_ONLY, ResultSetConcurrency::READ_ONLY }
+ };
+ sal_Int32 i=0;
+ if ( m_xActiveConnection->getMetaData()->isReadOnly() )
+ i = 2; // if the database is read-only we only should use read-only concurrency
+
+ for ( ; i<5; ++i )
+ {
+ nResultSetType = nCharacteristics[i][0];
+ nResultSetConcurrency = nCharacteristics[i][1];
+
+ // don't try type/concurrency pairs which are more featured than what our caller requested
+ if ( nResultSetType > _nDesiredResultSetType )
+ continue;
+ if ( nResultSetConcurrency > _nDesiredResultSetConcurrency )
+ continue;
+
+ if ( xMeta.is() && xMeta->supportsResultSetConcurrency( nResultSetType, nResultSetConcurrency ) )
+ break;
+ }
+ }
+
+ _rxStatement->setPropertyValue( PROPERTY_RESULTSETTYPE, makeAny( nResultSetType ) );
+ _rxStatement->setPropertyValue( PROPERTY_RESULTSETCONCURRENCY, makeAny( nResultSetConcurrency ) );
+}
+
+// -----------------------------------------------------------------------------
+Reference< XResultSet > ORowSet::impl_prepareAndExecute_throw()
+{
+ ::rtl::OUString sCommandToExecute;
+ sal_Bool bUseEscapeProcessing = impl_initComposer_throw( sCommandToExecute );
+
+ Reference< XResultSet> xResultSet;
+ try
+ {
+ m_xStatement = m_xActiveConnection->prepareStatement( sCommandToExecute );
+ if ( !m_xStatement.is() )
+ {
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INTERNAL_ERROR ), SQL_GENERAL_ERROR, *this );
+ }
+
+ Reference< XPropertySet > xStatementProps( m_xStatement, UNO_QUERY_THROW );
+ // set the result set type and concurrency
+ try
+ {
+ xStatementProps->setPropertyValue( PROPERTY_USEBOOKMARKS, makeAny( sal_True ) );
+ setStatementResultSetType( xStatementProps, m_nResultSetType, m_nResultSetConcurrency );
+ }
+ catch ( const Exception& )
+ {
+ // this exception doesn't matter here because when we catch an exception
+ // then the driver doesn't support this feature
+ }
+ m_aParameterValueForCache.get().resize(1);
+ Reference< XParameters > xParam( m_xStatement, UNO_QUERY_THROW );
+ size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues.get().size() );
+ for ( size_t i=1; i<=nParamCount; ++i )
+ {
+ ORowSetValue& rParamValue( getParameterStorage( (sal_Int32)i ) );
+ ::dbtools::setObjectWithInfo( xParam, i, rParamValue.makeAny(), rParamValue.getTypeKind() );
+ m_aParameterValueForCache.get().push_back(rParamValue);
+ }
+
+ xResultSet = m_xStatement->executeQuery();
+ }
+ catch( const SQLException& )
+ {
+ SQLExceptionInfo aError( ::cppu::getCaughtException() );
+ OSL_ENSURE( aError.isValid(), "ORowSet::impl_prepareAndExecute_throw: caught an SQLException which we cannot analyze!" );
+
+ // append information about what we were actually going to execute
+ try
+ {
+ String sQuery = bUseEscapeProcessing && m_xComposer.is() ? m_xComposer->getQuery() : m_aActiveCommand;
+ String sInfo( DBA_RES_PARAM( RID_STR_COMMAND_LEADING_TO_ERROR, "$command$", sQuery ) );
+ aError.append( SQLExceptionInfo::SQL_CONTEXT, sInfo );
+ }
+ catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
+
+ // propagate
+ aError.doThrow();
+ }
+
+ return xResultSet;
+}
+
+// -----------------------------------------------------------------------------
+void ORowSet::impl_initializeColumnSettings_nothrow( const Reference< XPropertySet >& _rxTemplateColumn, const Reference< XPropertySet >& _rxRowSetColumn )
+{
+ OSL_ENSURE( _rxTemplateColumn.is() && _rxRowSetColumn.is(),
+ "ORowSet::impl_initializeColumnSettings_nothrow: this will crash!" );
+
+ bool bHaveAnyColumnSetting = false;
+ try
+ {
+ Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_QUERY_THROW );
+
+ // a number of properties is plain copied
+ const ::rtl::OUString aPropertyNames[] = {
+ PROPERTY_ALIGN, PROPERTY_RELATIVEPOSITION, PROPERTY_WIDTH, PROPERTY_HIDDEN, PROPERTY_CONTROLMODEL,
+ PROPERTY_HELPTEXT, PROPERTY_CONTROLDEFAULT
+ };
+ for ( size_t i=0; i<sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i )
+ {
+ if ( xInfo->hasPropertyByName( aPropertyNames[i] ) )
+ {
+ _rxRowSetColumn->setPropertyValue( aPropertyNames[i], _rxTemplateColumn->getPropertyValue( aPropertyNames[i] ) );
+ bHaveAnyColumnSetting = true;
+ }
+ }
+
+ // the format key is slightly more complex
+ sal_Int32 nFormatKey = 0;
+ if( xInfo->hasPropertyByName( PROPERTY_NUMBERFORMAT ) )
+ {
+ _rxTemplateColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) >>= nFormatKey;
+ bHaveAnyColumnSetting = true;
+ }
+ if ( !nFormatKey && m_xNumberFormatTypes.is() )
+ nFormatKey = ::dbtools::getDefaultNumberFormat( _rxTemplateColumn, m_xNumberFormatTypes, SvtSysLocale().GetLocaleData().getLocale() );
+ _rxRowSetColumn->setPropertyValue( PROPERTY_NUMBERFORMAT, makeAny( nFormatKey ) );
+ }
+ catch(Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+
+ if ( bHaveAnyColumnSetting )
+ return;
+
+ // the template column could not provide *any* setting. Okay, probably it's a parser column, which
+ // does not offer those. However, perhaps the template column referes to a table column, which we
+ // can use as new template column
+ try
+ {
+ Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_QUERY_THROW );
+ if ( !xInfo->hasPropertyByName( PROPERTY_TABLENAME ) )
+ // no chance
+ return;
+
+ ::rtl::OUString sTableName;
+ OSL_VERIFY( _rxTemplateColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
+
+ Reference< XNameAccess > xTables( impl_getTables_throw(), UNO_QUERY_THROW );
+ if ( !xTables->hasByName( sTableName ) )
+ // no chance
+ return;
+
+ Reference< XColumnsSupplier > xTableColSup( xTables->getByName( sTableName ), UNO_QUERY_THROW );
+ Reference< XNameAccess > xTableCols( xTableColSup->getColumns(), UNO_QUERY_THROW );
+
+ ::rtl::OUString sTableColumnName;
+
+ // get the "Name" or (preferred) "RealName" property of the column
+ ::rtl::OUString sNamePropertyName( PROPERTY_NAME );
+ if ( xInfo->hasPropertyByName( PROPERTY_REALNAME ) )
+ sNamePropertyName = PROPERTY_REALNAME;
+ OSL_VERIFY( _rxTemplateColumn->getPropertyValue( sNamePropertyName ) >>= sTableColumnName );
+
+ if ( !xTableCols->hasByName( sTableColumnName ) )
+ return;
+
+ Reference< XPropertySet > xTableColumn( xTableCols->getByName( sTableColumnName ), UNO_QUERY_THROW );
+ impl_initializeColumnSettings_nothrow( xTableColumn, _rxRowSetColumn );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+// -----------------------------------------------------------------------------
+void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotification)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "ORowSet::execute_NoApprove_NoNewConn" );
+
+ // now we can dispose our old connection
+ ::comphelper::disposeComponent(m_xOldConnection);
+ m_xOldConnection = NULL;
+
+ // do we need a new statement
+ if ( m_bCommandFacetsDirty )
+ {
+ m_xStatement = NULL;
+ m_xComposer = NULL;
+
+ Reference< XResultSet > xResultSet( impl_prepareAndExecute_throw() );
+
+ // let our warnings container forget the reference to the (possibly disposed) old result set
+ m_aWarnings.setExternalWarnings( NULL );
+ // clear all current warnings
+ m_aWarnings.clearWarnings();
+ // let the warnings container know about the new "external warnings"
+ m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) );
+
+ ::rtl::OUString aComposedUpdateTableName;
+ if ( m_aUpdateTableName.getLength() )
+ aComposedUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), m_aUpdateCatalogName, m_aUpdateSchemaName, m_aUpdateTableName, sal_False, ::dbtools::eInDataManipulation );
+
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "ORowSet::execute_NoApprove_NoNewConn: creating cache" );
+ m_pCache = new ORowSetCache( xResultSet, m_xComposer.get(), m_aContext, aComposedUpdateTableName, m_bModified, m_bNew,m_aParameterValueForCache,m_aFilter );
+ if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
+ {
+ m_nPrivileges = Privilege::SELECT;
+ m_pCache->m_nPrivileges = Privilege::SELECT;
+ }
+ m_pCache->setMaxRowSize(m_nFetchSize);
+ m_aCurrentRow = m_pCache->createIterator(this);
+ m_aOldRow = m_pCache->registerOldRow();
+ }
+
+ // get the locale
+ // ConfigManager* pConfigMgr = ConfigManager::GetConfigManager();
+ Locale aLocale = SvtSysLocale().GetLocaleData().getLocale();
+ // pConfigMgr->GetDirectConfigProperty(ConfigManager::LOCALE) >>= aLocale;
+
+ // get the numberformatTypes
+ OSL_ENSURE(m_xActiveConnection.is(),"No ActiveConnection");
+ Reference< XNumberFormatTypes> xNumberFormatTypes;
+ Reference< XNumberFormatsSupplier> xNumberFormat = ::dbtools::getNumberFormats(m_xActiveConnection);
+ if ( xNumberFormat.is() )
+ m_xNumberFormatTypes.set(xNumberFormat->getNumberFormats(),UNO_QUERY);
+
+ ::vos::ORef< ::connectivity::OSQLColumns> aColumns = new ::connectivity::OSQLColumns();
+ ::std::vector< ::rtl::OUString> aNames;
+ ::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" );
+ // use the meta data
+ Reference<XResultSetMetaDataSupplier> xMetaSup(m_xStatement,UNO_QUERY);
+ try
+ {
+ Reference<XResultSetMetaData> xMetaData = xMetaSup->getMetaData();
+ if ( xMetaData.is() )
+ {
+ sal_Int32 nCount = xMetaData->getColumnCount();
+ m_aDataColumns.reserve(nCount+1);
+ aColumns->get().reserve(nCount+1);
+ DECLARE_STL_USTRINGACCESS_MAP(int,StringMap);
+ StringMap aColumnMap;
+ for (sal_Int32 i = 0 ; i < nCount; ++i)
+ {
+ // retrieve the name of the column
+ ::rtl::OUString sName = xMetaData->getColumnName(i + 1);
+ // check for duplicate entries
+ if(aColumnMap.find(sName) != aColumnMap.end())
+ {
+ ::rtl::OUString sAlias(sName);
+ sal_Int32 searchIndex=1;
+ while(aColumnMap.find(sAlias) != aColumnMap.end())
+ {
+ (sAlias = sName) += ::rtl::OUString::valueOf(searchIndex++);
+ }
+ sName = sAlias;
+ }
+ ORowSetDataColumn* pColumn = new ORowSetDataColumn( getMetaData(),
+ this,
+ this,
+ i+1,
+ m_xActiveConnection->getMetaData(),
+ aDescription,
+ ::rtl::OUString(),
+ m_aCurrentRow);
+ aColumnMap.insert(StringMap::value_type(sName,0));
+ aColumns->get().push_back(pColumn);
+ pColumn->setName(sName);
+ 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;
+ if(m_xNumberFormatTypes.is())
+ nFormatKey = ::dbtools::getDefaultNumberFormat(pColumn,m_xNumberFormatTypes,aLocale);
+
+
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_NUMBERFORMAT,makeAny(nFormatKey));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_RELATIVEPOSITION,makeAny(sal_Int32(i+1)));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_WIDTH,makeAny(sal_Int32(227)));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ALIGN,makeAny((sal_Int32)0));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HIDDEN,::cppu::bool2any(sal_False));
+ }
+ catch(Exception&)
+ {
+ }
+ }
+ }
+ }
+ catch (SQLException&)
+ {
+ }
+ }
+ else
+ {
+ // create the rowset columns
+ Reference< XResultSetMetaData > xMeta( getMetaData(), UNO_QUERY_THROW );
+ sal_Int32 nCount = xMeta->getColumnCount();
+ m_aDataColumns.reserve(nCount+1);
+ aColumns->get().reserve(nCount+1);
+ ::std::set< Reference< XPropertySet > > aAllColumns;
+
+ for(sal_Int32 i=1; i <= nCount ;++i)
+ {
+ ::rtl::OUString sName = xMeta->getColumnName(i);
+ ::rtl::OUString sColumnLabel = xMeta->getColumnLabel(i);
+
+ // retrieve the column number |i|
+ Reference<XPropertySet> xColumn;
+ {
+ sal_Bool bReFetchName = sal_False;
+ if (m_xColumns->hasByName(sColumnLabel))
+ m_xColumns->getByName(sColumnLabel) >>= xColumn;
+ if (!xColumn.is() && m_xColumns->hasByName(sName))
+ m_xColumns->getByName(sName) >>= xColumn;
+
+ // check if column already in the list we need another
+ if ( aAllColumns.find( xColumn ) != aAllColumns.end() )
+ {
+ xColumn = NULL;
+ bReFetchName = sal_True;
+ sColumnLabel = ::rtl::OUString();
+ }
+ if(!xColumn.is())
+ {
+ // no column found so we could look at the position i
+ //bReFetchName = sal_True;
+ //sColumnLabel = ::rtl::OUString();
+ Reference<XIndexAccess> xIndexAccess(m_xColumns,UNO_QUERY);
+ if(xIndexAccess.is() && i <= xIndexAccess->getCount())
+ {
+ xIndexAccess->getByIndex(i-1) >>= xColumn;
+ }
+ else
+ {
+ Sequence< ::rtl::OUString> aSeq = m_xColumns->getElementNames();
+ if( i <= aSeq.getLength())
+ {
+ m_xColumns->getByName(aSeq.getConstArray()[i-1]) >>= xColumn;
+ }
+ }
+ }
+ if(bReFetchName && xColumn.is())
+ xColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
+ aAllColumns.insert( xColumn );
+ }
+
+ // create a RowSetDataColumn
+ {
+ Reference<XPropertySetInfo> xInfo = xColumn.is() ? xColumn->getPropertySetInfo() : Reference<XPropertySetInfo>();
+ 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())
+ xColumn->getPropertyValue(PROPERTY_NAME) >>= sColumnLabel;
+ else
+ sColumnLabel = DBACORE_RESSTRING( RID_STR_EXPRESSION1 );
+ }
+ pColumn->setName(sColumnLabel);
+ aNames.push_back(sColumnLabel);
+ m_aDataColumns.push_back(pColumn);
+
+ if ( xColumn.is() )
+ impl_initializeColumnSettings_nothrow( xColumn, pColumn );
+ }
+ }
+ }
+ // now create the columns we need
+ if(m_pColumns)
+ m_pColumns->assign(aColumns,aNames);
+ else
+ {
+ Reference<XDatabaseMetaData> xMeta = m_xActiveConnection->getMetaData();
+ m_pColumns = new ORowSetDataColumns(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),
+ aColumns,*this,m_aColumnsMutex,aNames);
+ }
+ }
+ checkCache();
+ // notify the rowset listeners
+ notifyAllListeners(_rClearForNotification);
+}
+// -------------------------------------------------------------------------
+// XRowSetApproveBroadcaster
+void SAL_CALL ORowSet::addRowSetApproveListener( const Reference< XRowSetApproveListener >& listener ) throw(RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+
+ m_aApproveListeners.addInterface(listener);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::removeRowSetApproveListener( const Reference< XRowSetApproveListener >& listener ) throw(RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+
+ 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
+Reference< XResultSet > SAL_CALL ORowSet::createResultSet( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+
+ if(m_xStatement.is())
+ {
+ ORowSetClone* pClone = new ORowSetClone( m_aContext, *this, m_pMutex );
+ Reference< XResultSet > xRet(pClone);
+ m_aClones.push_back(WeakReferenceHelper(xRet));
+ return xRet;
+ }
+ return Reference< XResultSet >();
+}
+// -------------------------------------------------------------------------
+
+// ::com::sun::star::util::XCancellable
+void SAL_CALL ORowSet::cancel( ) throw(RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+}
+// -------------------------------------------------------------------------
+
+// ::com::sun::star::sdbcx::XDeleteRows
+Sequence< sal_Int32 > SAL_CALL ORowSet::deleteRows( const Sequence< Any >& rows ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ if(!m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
+ throwFunctionSequenceException(*this);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ Sequence<Any> aChangedBookmarks;
+ RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,rows.getLength(),aChangedBookmarks);
+ // notify the rowset listeners
+ notifyAllListenersRowBeforeChange(aGuard,aEvt);
+
+ Sequence< sal_Int32 > aResults( rows.getLength() );
+ const Any* row = rows.getConstArray();
+ const Any* rowEnd = rows.getConstArray() + rows.getLength();
+ sal_Int32* result = aResults.getArray();
+ for ( ; row != rowEnd; ++row, ++result )
+ {
+ *result = 0;
+ if ( !m_pCache->moveToBookmark( *row ) )
+ continue;
+ sal_Int32 nDeletePosition = m_pCache->getRow();
+
+ // first notify the clones so that they can save their position
+ notifyRowSetAndClonesRowDelete( *row );
+
+ // now delete the row
+ if ( !m_pCache->deleteRow() )
+ continue;
+ *result = 1;
+ // now notify that we have deleted
+ notifyRowSetAndClonesRowDeleted( *row, nDeletePosition );
+ }
+ aEvt.Rows = aResults.getLength();
+
+ // we have to check if we stand on the insert row and if so we have to reset it
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+ // notification order
+ // - rowChanged
+ notifyAllListenersRowChanged(aGuard,aEvt);
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+
+ return aResults;
+}
+// -----------------------------------------------------------------------------
+void ORowSet::notifyRowSetAndClonesRowDelete( const Any& _rBookmark )
+{
+ // notify ourself
+ onDeleteRow( _rBookmark );
+ // notify the clones
+ connectivity::OWeakRefArray::iterator aEnd = m_aClones.end();
+ for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; i++)
+ {
+ Reference< XUnoTunnel > xTunnel(i->get(),UNO_QUERY);
+ if(xTunnel.is())
+ {
+ ORowSetClone* pClone = reinterpret_cast<ORowSetClone*>(xTunnel->getSomething(ORowSetClone::getUnoTunnelImplementationId()));
+ if(pClone)
+ pClone->onDeleteRow( _rBookmark );
+ }
+ }
+}
+//------------------------------------------------------------------------------
+void ORowSet::notifyRowSetAndClonesRowDeleted( const Any& _rBookmark, sal_Int32 _nPos )
+{
+ // notify ourself
+ onDeletedRow( _rBookmark, _nPos );
+ // notify the clones
+ connectivity::OWeakRefArray::iterator aEnd = m_aClones.end();
+ for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; i++)
+ {
+ Reference< XUnoTunnel > xTunnel(i->get(),UNO_QUERY);
+ if(xTunnel.is())
+ {
+ ORowSetClone* pClone = reinterpret_cast<ORowSetClone*>(xTunnel->getSomething(ORowSetClone::getUnoTunnelImplementationId()));
+ if(pClone)
+ pClone->onDeletedRow( _rBookmark, _nPos );
+ }
+ }
+}
+//------------------------------------------------------------------------------
+Reference< XConnection > ORowSet::calcConnection(const Reference< XInteractionHandler >& _rxHandler) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ if (!m_xActiveConnection.is())
+ {
+ Reference< XConnection > xNewConn;
+ if ( m_aDataSourceName.getLength() )
+ {
+ Reference< XNameAccess > xDatabaseContext(
+ m_aContext.createComponent( (::rtl::OUString)SERVICE_SDB_DATABASECONTEXT ),
+ UNO_QUERY_THROW );
+ try
+ {
+ Reference< XDataSource > xDataSource( xDatabaseContext->getByName( m_aDataSourceName ), UNO_QUERY_THROW );
+
+ // try connecting with the interaction handler
+ Reference< XCompletedConnection > xComplConn( xDataSource, UNO_QUERY );
+ if ( _rxHandler.is() && xComplConn.is() )
+ {
+ xNewConn = xComplConn->connectWithCompletion( _rxHandler );
+ }
+ else
+ {
+ xNewConn = xDataSource->getConnection( m_aUser, m_aPassword );
+ }
+ }
+ catch ( const SQLException& e )
+ {
+ throw;
+ }
+ catch ( const Exception& e )
+ {
+ Any aError = ::cppu::getCaughtException();
+ ::rtl::OUString sMessage = ResourceManager::loadString( RID_NO_SUCH_DATA_SOURCE,
+ "$name$", m_aDataSourceName, "$error$", extractExceptionMessage( m_aContext, aError ) );
+ ::dbtools::throwGenericSQLException( sMessage, *this );
+ }
+ }
+ setActiveConnection(xNewConn);
+ m_bOwnConnection = sal_True;
+ }
+ return m_xActiveConnection;
+}
+//------------------------------------------------------------------------------
+Reference< XNameAccess > ORowSet::impl_getTables_throw()
+{
+ Reference< XNameAccess > xTables;
+
+ Reference< XTablesSupplier > xTablesAccess( m_xActiveConnection, UNO_QUERY );
+ if ( xTablesAccess.is() )
+ {
+ xTables.set( xTablesAccess->getTables(), UNO_QUERY_THROW );
+ }
+ else if ( m_pTables )
+ {
+ xTables = m_pTables;
+ }
+ else
+ {
+ if ( !m_xActiveConnection.is() )
+ throw SQLException(DBA_RES(RID_STR_CONNECTION_INVALID),*this,SQLSTATE_GENERAL,1000,Any() );
+
+ sal_Bool bCase = sal_True;
+ try
+ {
+ Reference<XDatabaseMetaData> xMeta = m_xActiveConnection->getMetaData();
+ bCase = xMeta.is() && xMeta->storesMixedCaseQuotedIdentifiers();
+ }
+ catch(SQLException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ m_pTables = new OTableContainer(*this,m_aMutex,m_xActiveConnection,bCase,NULL,NULL,NULL,m_nInAppend);
+ xTables = m_pTables;
+ Sequence< ::rtl::OUString> aTableFilter(1);
+ aTableFilter[0] = ::rtl::OUString::createFromAscii("%");
+ m_pTables->construct(aTableFilter,Sequence< ::rtl::OUString>());
+ }
+
+ return xTables;
+}
+
+//------------------------------------------------------------------------------
+void ORowSet::impl_resetTables_nothrow()
+{
+ if ( !m_pTables )
+ return;
+
+ try
+ {
+ m_pTables->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ DELETEZ( m_pTables );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ORowSet::impl_initComposer_throw( ::rtl::OUString& _out_rCommandToExecute )
+{
+ sal_Bool bUseEscapeProcessing = impl_buildActiveCommand_throw( );
+ _out_rCommandToExecute = m_aActiveCommand;
+ if ( !bUseEscapeProcessing )
+ return bUseEscapeProcessing;
+
+ Reference< XMultiServiceFactory > xFactory( m_xActiveConnection, UNO_QUERY );
+ if ( xFactory.is() )
+ {
+ try
+ {
+ ::comphelper::disposeComponent( m_xComposer );
+ m_xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
+ }
+ catch (const Exception& ) { m_xComposer = NULL; }
+ }
+ if ( !m_xComposer.is() )
+ m_xComposer = new OSingleSelectQueryComposer( impl_getTables_throw(), m_xActiveConnection, m_aContext );
+
+ 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() );
+
+ if ( m_bIgnoreResult )
+ { // append a "0=1" filter
+ // don't simply overwrite an existent filter, this would lead to problems if this existent
+ // filter contains paramters (since a keyset may add parameters itself)
+ // 2003-12-12 - #23418# - fs@openoffice.org
+ m_xComposer->setElementaryQuery( m_xComposer->getQuery( ) );
+ m_xComposer->setFilter( ::rtl::OUString::createFromAscii( "0 = 1" ) );
+ }
+
+ m_xComposer->setOrder( m_aOrder );
+ m_xComposer->setGroup( m_aGroupBy );
+
+ if ( !m_xColumns.is() )
+ {
+ Reference< XColumnsSupplier > xCols( m_xComposer, UNO_QUERY_THROW );
+ m_xColumns = xCols->getColumns();
+ }
+
+ impl_initParametersContainer_nothrow();
+
+ _out_rCommandToExecute = m_xComposer->getQueryWithSubstitution();
+
+ return bUseEscapeProcessing;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ORowSet::impl_buildActiveCommand_throw()
+{
+ // create the sql command
+ // from a table name or get the command out of a query (not a view)
+ // the last use the command as it is
+ sal_Bool bDoEscapeProcessing = m_bUseEscapeProcessing;
+
+ m_aActiveCommand = ::rtl::OUString();
+ ::rtl::OUString sCommand;
+
+ if ( !m_aCommand.getLength() )
+ return bDoEscapeProcessing;
+
+ switch (m_nCommandType)
+ {
+ case CommandType::TABLE:
+ {
+ impl_resetTables_nothrow();
+ if ( bDoEscapeProcessing )
+ {
+ Reference< XNameAccess > xTables( impl_getTables_throw() );
+ if ( xTables->hasByName(m_aCommand) )
+ {
+/*
+ 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 );
+*/
+ }
+ else
+ {
+ String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) );
+ sMessage.SearchAndReplaceAscii( "$table$", m_aCommand );
+ throwGenericSQLException(sMessage,*this);
+ }
+ }
+ 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 );
+ }
+ }
+ break;
+
+ case CommandType::QUERY:
+ {
+ Reference< XQueriesSupplier > xQueriesAccess(m_xActiveConnection, UNO_QUERY);
+ if (xQueriesAccess.is())
+ {
+ Reference< ::com::sun::star::container::XNameAccess > xQueries(xQueriesAccess->getQueries());
+ if (xQueries->hasByName(m_aCommand))
+ {
+ Reference< XPropertySet > xQuery(xQueries->getByName(m_aCommand),UNO_QUERY);
+ OSL_ENSURE(xQuery.is(),"ORowSet::impl_buildActiveCommand_throw: Query is NULL!");
+ if ( xQuery.is() )
+ {
+ xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
+ xQuery->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bDoEscapeProcessing;
+ if ( bDoEscapeProcessing != m_bUseEscapeProcessing )
+ {
+ sal_Bool bOldValue = m_bUseEscapeProcessing;
+ m_bUseEscapeProcessing = bDoEscapeProcessing;
+ fireProperty(PROPERTY_ID_ESCAPE_PROCESSING,bOldValue,bDoEscapeProcessing);
+ }
+
+ ::rtl::OUString aCatalog,aSchema,aTable;
+ xQuery->getPropertyValue(PROPERTY_UPDATE_CATALOGNAME) >>= aCatalog;
+ xQuery->getPropertyValue(PROPERTY_UPDATE_SCHEMANAME) >>= aSchema;
+ 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
+ {
+ String sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) );
+ sMessage.SearchAndReplaceAscii( "$table$", m_aCommand );
+ throwGenericSQLException(sMessage,*this);
+ }
+ }
+ else
+ throw SQLException(DBA_RES(RID_STR_NO_XQUERIESSUPPLIER),*this,::rtl::OUString(),0,Any());
+ }
+ break;
+
+ default:
+ sCommand = m_aCommand;
+ break;
+ }
+
+ m_aActiveCommand = sCommand;
+
+ if ( !m_aActiveCommand.getLength() && !bDoEscapeProcessing )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_SQL_COMMAND ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
+
+ return bDoEscapeProcessing;
+}
+
+//------------------------------------------------------------------------------
+void ORowSet::impl_initParametersContainer_nothrow()
+{
+ OSL_PRECOND( !m_pParameters.is(), "ORowSet::impl_initParametersContainer_nothrow: already initialized the parameters!" );
+
+ m_pParameters = new param::ParameterWrapperContainer( m_xComposer.get() );
+ // copy the premature parameters into the final ones
+ size_t nParamCount( ::std::min( m_pParameters->size(), m_aPrematureParamValues.get().size() ) );
+ for ( size_t i=0; i<nParamCount; ++i )
+ {
+ (*m_pParameters)[i] = m_aPrematureParamValues.get()[i];
+ }
+}
+
+//------------------------------------------------------------------------------
+void ORowSet::impl_disposeParametersContainer_nothrow()
+{
+ if ( !m_pParameters.is() )
+ return;
+
+ // copy the actual values to our "premature" ones, to preserve them for later use
+ size_t nParamCount( m_pParameters->size() );
+ m_aPrematureParamValues.get().resize( nParamCount );
+ for ( size_t i=0; i<nParamCount; ++i )
+ {
+ m_aPrematureParamValues.get()[i] = (*m_pParameters)[i];
+ }
+
+ m_pParameters->dispose();
+ m_pParameters = NULL;
+}
+
+// -----------------------------------------------------------------------------
+ORowSetValue& ORowSet::getParameterStorage(sal_Int32 parameterIndex)
+{
+ ::connectivity::checkDisposed( ORowSet_BASE1::rBHelper.bDisposed );
+ if ( parameterIndex < 1 )
+ throwInvalidIndexException( *this );
+
+ if ( m_aParametersSet.size() < (size_t)parameterIndex )
+ m_aParametersSet.resize( parameterIndex ,false);
+ m_aParametersSet[parameterIndex - 1] = true;
+
+ if ( m_aParametersSet.size() < (size_t)parameterIndex )
+ m_aParametersSet.resize( parameterIndex ,false);
+ m_aParametersSet[parameterIndex - 1] = true;
+
+ if ( m_pParameters.is() )
+ {
+ if ( m_bCommandFacetsDirty )
+ // need to rebuild the parameters, since some property which contributes to the
+ // complete command, and thus the parameters, changed
+ impl_disposeParametersContainer_nothrow();
+ if ( m_pParameters.is() )
+ {
+ if ( (size_t)parameterIndex > m_pParameters->size() )
+ throwInvalidIndexException( *this );
+ return (*m_pParameters)[ parameterIndex - 1 ];
+ }
+ }
+
+ if ( m_aPrematureParamValues.get().size() < (size_t)parameterIndex )
+ m_aPrematureParamValues.get().resize( parameterIndex );
+ return m_aPrematureParamValues.get()[ parameterIndex - 1 ];
+}
+// -------------------------------------------------------------------------
+// XParameters
+void SAL_CALL ORowSet::setNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/ ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+
+ getParameterStorage( parameterIndex ).setNull();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& /*typeName*/ ) throw(SQLException, RuntimeException)
+{
+ setNull( parameterIndex, sqlType );
+}
+// -----------------------------------------------------------------------------
+void ORowSet::setParameter(sal_Int32 parameterIndex, const ORowSetValue& x)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+
+ getParameterStorage( parameterIndex ) = x;
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setTimestamp( sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException)
+{
+ setParameter(parameterIndex,x);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) );
+
+ try
+ {
+ Sequence <sal_Int8> aData;
+ x->readBytes(aData, length);
+ rParamValue = aData;
+ x->closeInput();
+ }
+ catch( Exception& )
+ {
+ throw SQLException();
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) );
+ try
+ {
+ Sequence <sal_Int8> aData;
+ rtl::OUString aDataStr;
+ // the data is given as character data and the length defines the character length
+ sal_Int32 nSize = x->readBytes(aData, length * sizeof(sal_Unicode));
+ if (nSize / sizeof(sal_Unicode))
+ aDataStr = rtl::OUString((sal_Unicode*)aData.getConstArray(), nSize / sizeof(sal_Unicode));
+ rParamValue = aDataStr;
+ rParamValue.setTypeKind( DataType::LONGVARCHAR );
+ x->closeInput();
+ }
+ catch( Exception& )
+ {
+ throw SQLException();
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException)
+{
+ if ( !::dbtools::implSetObject( this, parameterIndex, x ) )
+ { // there is no other setXXX call which can handle the value in x
+ throw SQLException();
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) );
+ setObject( parameterIndex, x );
+ rParamValue.setTypeKind( targetSqlType );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFeatureNotImplementedException( "XParameters::setRef", *this );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFeatureNotImplementedException( "XParameters::setBlob", *this );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFeatureNotImplementedException( "XParameters::setClob", *this );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFeatureNotImplementedException( "XParameters::setArray", *this );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::clearParameters( ) throw(SQLException, RuntimeException)
+{
+ ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+
+ size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues.get().size() );
+ for ( size_t i=1; i<=nParamCount; ++i )
+ getParameterStorage( (sal_Int32)i ).setNull();
+ m_aParametersSet.clear();
+}
+
+// -------------------------------------------------------------------------
+Any SAL_CALL ORowSet::getWarnings( ) throw (SQLException, RuntimeException)
+{
+ return m_aWarnings.getWarnings();
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSet::clearWarnings( ) throw (SQLException, RuntimeException)
+{
+ m_aWarnings.clearWarnings();
+}
+// -----------------------------------------------------------------------------
+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;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSet::isModification( )
+{
+ return isNew();
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSet::isModified( )
+{
+ return m_bModified;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSet::isNew( )
+{
+ return m_bNew;
+}
+
+// -----------------------------------------------------------------------------
+void ORowSet::checkUpdateIterator()
+{
+ if(!m_bModified && !m_bNew)
+ {
+ m_pCache->setUpdateIterator(m_aCurrentRow);
+ m_aCurrentRow = m_pCache->m_aInsertRow;
+ m_bModified = sal_True;
+ } // if(!m_bModified && !m_bNew)
+ else if ( m_bNew ) // here we are modifing a value
+ m_bModified = sal_True;
+}
+// -----------------------------------------------------------------------------
+void ORowSet::checkUpdateConditions(sal_Int32 columnIndex)
+{
+ checkCache();
+ if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_RESULT_IS_READONLY ), SQL_GENERAL_ERROR, *this );
+
+ if ( rowDeleted() )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_INVALID_CURSOR_POSITION, *this );
+
+ if ( m_aCurrentRow.isNull() )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INVALID_CURSOR_STATE ), SQL_INVALID_CURSOR_STATE, *this );
+
+ if ( columnIndex <= 0 || sal_Int32((*m_aCurrentRow)->get().size()) <= columnIndex )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INVALID_INDEX ), SQL_INVALID_DESCRIPTOR_INDEX, *this );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ORowSet::refreshRow( ) throw(SQLException, RuntimeException)
+{
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ // notification order:
+ if ( m_bModified && m_pCache )
+ // - column values
+ implCancelRowUpdates( sal_False ); // do _not_ notify the IsModify - will do this ourself below
+
+ ORowSetBase::refreshRow();
+
+ // - IsModified
+ // - 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
+// ***********************************************************
+DBG_NAME(ORowSetClone);
+//--------------------------------------------------------------------------
+ORowSetClone::ORowSetClone( const ::comphelper::ComponentContext& _rContext, ORowSet& rParent, ::osl::Mutex* _pMutex )
+ :OSubComponent(m_aMutex, rParent)
+ ,ORowSetBase( _rContext, OComponentHelper::rBHelper, _pMutex )
+ ,m_pParent(&rParent)
+ ,m_nFetchDirection(rParent.m_nFetchDirection)
+ ,m_nFetchSize(rParent.m_nFetchSize)
+ ,m_bIsBookmarable(sal_True)
+{
+ DBG_CTOR(ORowSetClone, NULL);
+
+ m_nResultSetType = rParent.m_nResultSetType;
+ m_nResultSetConcurrency = ResultSetConcurrency::READ_ONLY;
+ m_pMySelf = this;
+ m_bClone = sal_True;
+ m_bBeforeFirst = rParent.m_bBeforeFirst;
+ m_bAfterLast = rParent.m_bAfterLast;
+ m_pCache = rParent.m_pCache;
+ m_aBookmark = rParent.m_aBookmark;
+ m_aCurrentRow = m_pCache->createIterator(this);
+ m_xNumberFormatTypes = rParent.m_xNumberFormatTypes;
+
+ m_aOldRow = m_pCache->registerOldRow();
+
+ ::vos::ORef< ::connectivity::OSQLColumns> aColumns = new ::connectivity::OSQLColumns();
+ ::std::vector< ::rtl::OUString> aNames;
+
+ ::rtl::OUString aDescription;
+ // ConfigManager* pConfigMgr = ConfigManager::GetConfigManager();
+ // Locale aLocale;
+ // pConfigMgr->GetDirectConfigProperty(ConfigManager::LOCALE) >>= aLocale;
+ Locale aLocale = SvtSysLocale().GetLocaleData().getLocale();
+
+ if ( rParent.m_pColumns )
+ {
+ Sequence< ::rtl::OUString> aSeq = rParent.m_pColumns->getElementNames();
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ aColumns->get().reserve(aSeq.getLength()+1);
+ for(sal_Int32 i=1;pIter != pEnd ;++pIter,++i)
+ {
+ Reference<XPropertySet> xColumn;
+ 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);
+ aNames.push_back(*pIter);
+ m_aDataColumns.push_back(pColumn);
+
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ALIGN,xColumn->getPropertyValue(PROPERTY_ALIGN));
+ sal_Int32 nFormatKey = 0;
+ xColumn->getPropertyValue(PROPERTY_NUMBERFORMAT) >>= nFormatKey;
+ if(!nFormatKey && xColumn.is() && m_xNumberFormatTypes.is())
+ nFormatKey = ::dbtools::getDefaultNumberFormat(xColumn,m_xNumberFormatTypes,aLocale);
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_NUMBERFORMAT,makeAny(nFormatKey));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_RELATIVEPOSITION,xColumn->getPropertyValue(PROPERTY_RELATIVEPOSITION));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_WIDTH,xColumn->getPropertyValue(PROPERTY_WIDTH));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HIDDEN,xColumn->getPropertyValue(PROPERTY_HIDDEN));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_CONTROLMODEL,xColumn->getPropertyValue(PROPERTY_CONTROLMODEL));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HELPTEXT,xColumn->getPropertyValue(PROPERTY_HELPTEXT));
+ pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_CONTROLDEFAULT,xColumn->getPropertyValue(PROPERTY_CONTROLDEFAULT));
+
+ } // for(sal_Int32 i=1;pIter != pEnd ;++pIter,++i)
+ }
+ Reference<XDatabaseMetaData> xMeta = rParent.m_xActiveConnection->getMetaData();
+ m_pColumns = new ORowSetDataColumns(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),
+ aColumns,*this,m_aMutex,aNames);
+
+ sal_Int32 nRT = PropertyAttribute::READONLY | PropertyAttribute::TRANSIENT;
+
+ // sdb.RowSet Properties
+ // registerProperty(PROPERTY_CURSORNAME, PROPERTY_ID_CURSORNAME, PropertyAttribute::READONLY, &m_aDataSourceName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, &rParent.m_aActiveConnection, ::getCppuType(reinterpret_cast< Reference< XConnection >* >(NULL)));
+ registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::READONLY, &m_nResultSetConcurrency,::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_RESULTSETTYPE, PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::READONLY, &m_nResultSetType, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_FETCHDIRECTION, PROPERTY_ID_FETCHDIRECTION, PropertyAttribute::TRANSIENT, &m_nFetchDirection, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_FETCHSIZE, PROPERTY_ID_FETCHSIZE, PropertyAttribute::TRANSIENT, &m_nFetchSize, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)));
+ registerProperty(PROPERTY_ISBOOKMARKABLE, PROPERTY_ID_ISBOOKMARKABLE, nRT, &m_bIsBookmarable, ::getBooleanCppuType());
+}
+
+//--------------------------------------------------------------------------
+ORowSetClone::~ORowSetClone()
+{
+ DBG_DTOR(ORowSetClone, NULL);
+}
+// com::sun::star::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > ORowSetClone::getTypes() throw (RuntimeException)
+{
+ return ::comphelper::concatSequences(OSubComponent::getTypes(),ORowSetBase::getTypes());
+}
+// com::sun::star::XInterface
+//--------------------------------------------------------------------------
+Any ORowSetClone::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ Any aRet = ORowSetBase::queryInterface(rType);
+ if(!aRet.hasValue())
+ aRet = OSubComponent::queryInterface(rType);
+ return aRet;
+}
+//------------------------------------------------------------------------------
+void ORowSetClone::acquire() throw()
+{
+ OSubComponent::acquire();
+}
+
+//------------------------------------------------------------------------------
+void ORowSetClone::release() throw()
+{
+ OSubComponent::release();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString ORowSetClone::getImplementationName( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.ORowSetClone");
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ORowSetClone::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > ORowSetClone::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = SERVICE_SDBC_RESULTSET;
+ aSNS[1] = SERVICE_SDB_RESULTSET;
+ return aSNS;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void ORowSetClone::disposing()
+{
+ MutexGuard aGuard( m_aMutex );
+ ORowSetBase::disposing();
+
+ m_pParent = NULL;
+ m_pMutex = &m_aMutex; // this must be done here because someone could hold a ref to us and try to do something
+ OSubComponent::disposing();
+}
+
+// XCloseable
+//------------------------------------------------------------------------------
+void ORowSetClone::close(void) throw( SQLException, RuntimeException )
+{
+ {
+ MutexGuard aGuard( m_aMutex );
+ if (OComponentHelper::rBHelper.bDisposed)
+ throw DisposedException();
+ }
+ dispose();
+}
+// -------------------------------------------------------------------------
+
+// comphelper::OPropertyArrayUsageHelper
+::cppu::IPropertyArrayHelper* ORowSetClone::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+// -------------------------------------------------------------------------
+
+// cppu::OPropertySetHelper
+::cppu::IPropertyArrayHelper& SAL_CALL ORowSetClone::getInfoHelper()
+{
+ typedef ::comphelper::OPropertyArrayUsageHelper<ORowSetClone> ORowSetClone_PROP;
+ return *ORowSetClone_PROP::getArrayHelper();
+}
+// -------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > ORowSetClone::getUnoTunnelImplementationId()
+{
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+// -----------------------------------------------------------------------------
+// com::sun::star::XUnoTunnel
+sal_Int64 SAL_CALL ORowSetClone::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ORowSetClone::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
+{
+ if ( nHandle == PROPERTY_ID_FETCHSIZE )
+ {
+ if ( m_pParent )
+ m_pParent->setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ }
+
+ OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue);
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetClone::doCancelModification( )
+{
+ //OSL_ENSURE( sal_False, "ORowSetClone::doCancelModification: invalid call!" );
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetClone::isModification( )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetClone::isModified( )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetClone::isNew( )
+{
+ return sal_False;
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetClone::execute( ) throw(SQLException, RuntimeException)
+{
+ throwFunctionNotSupportedException( "RowSetClone::XRowSet::execute", *this );
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetClone::addRowSetListener( const Reference< XRowSetListener >& ) throw(RuntimeException)
+{
+ throwFunctionNotSupportedException( "RowSetClone::XRowSet", *this );
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetClone::removeRowSetListener( const Reference< XRowSetListener >& ) throw(RuntimeException)
+{
+ throwFunctionNotSupportedException( "RowSetClone::XRowSet", *this );
+}
+
+} // dbaccess
diff --git a/dbaccess/source/core/api/RowSet.hxx b/dbaccess/source/core/api/RowSet.hxx
new file mode 100644
index 000000000000..8a85237cb928
--- /dev/null
+++ b/dbaccess/source/core/api/RowSet.hxx
@@ -0,0 +1,544 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_ROWSET_HXX
+#define DBACCESS_CORE_API_ROWSET_HXX
+
+#include "apitools.hxx"
+#include "RowSetBase.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdbc/XPreparedStatement.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdb/XResultSetAccess.hpp>
+#include <com/sun/star/sdbc/XRowSetListener.hpp>
+#include <com/sun/star/sdbc/XRowUpdate.hpp>
+#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/sdb/XRowSetApproveBroadcaster.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/util/XCancellable.hpp>
+#include <com/sun/star/sdbcx/XDeleteRows.hpp>
+#include <com/sun/star/sdb/XCompletedExecution.hpp>
+#include <com/sun/star/sdb/RowSetVetoException.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/sdb/XRowsChangeBroadcaster.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/compbase12.hxx>
+#include <connectivity/paramwrapper.hxx>
+#include <connectivity/FValue.hxx>
+#include <connectivity/warningscontainer.hxx>
+
+namespace dbaccess
+{
+ 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
+ , ::com::sun::star::sdbc::XResultSetUpdate
+ , ::com::sun::star::sdbc::XRowUpdate
+ , ::com::sun::star::util::XCancellable
+ , ::com::sun::star::sdb::XCompletedExecution
+ , ::com::sun::star::sdb::XParametersSupplier
+ , ::com::sun::star::sdbc::XWarningsSupplier
+ > ORowSet_BASE1;
+
+ class OTableContainer;
+ class ORowSet : public comphelper::OBaseMutex
+ , public ORowSet_BASE1
+ , public ORowSetBase
+ , public ::comphelper::OPropertyArrayUsageHelper<ORowSet>
+ {
+ friend class ORowSetClone;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xOldConnection;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xActiveConnection;
+ ::com::sun::star::uno::Any m_aActiveConnection;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xTypeMap;
+ ::com::sun::star::uno::Any m_aTypeMap;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > m_xStatement;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryComposer > m_xComposer;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xColumns; // the columns from a table or query
+
+ connectivity::OWeakRefArray m_aClones;
+ /** our parameters as XPropertySet instances and ORowSetValue instances
+ */
+ ::dbtools::param::ParametersContainerRef m_pParameters;
+ /** our parameters values, used when we do not yet have a parameters container
+ (since we have not been executed, yet)
+ */
+ 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;
+
+ OTableContainer* m_pTables;
+
+ rtl::OUString m_aCommand;
+ rtl::OUString m_aDataSourceName;
+ rtl::OUString m_aURL;
+ rtl::OUString m_aUser;
+ rtl::OUString m_aPassword;
+ rtl::OUString m_aFilter;
+ rtl::OUString m_aHavingClause;
+ rtl::OUString m_aGroupBy;
+ rtl::OUString m_aOrder;
+ rtl::OUString m_aActiveCommand;
+ rtl::OUString m_aCursorName;
+ rtl::OUString m_aUpdateCatalogName; // is set by a query
+ rtl::OUString m_aUpdateSchemaName; // is set by a query
+ rtl::OUString m_aUpdateTableName; // is set by a query
+
+ sal_Int32 m_nFetchDirection;
+ sal_Int32 m_nFetchSize;
+ sal_Int32 m_nMaxFieldSize;
+ sal_Int32 m_nMaxRows;
+ sal_Int32 m_nQueryTimeOut;
+ sal_Int32 m_nCommandType;
+ sal_Int32 m_nTransactionIsolation;
+ sal_Int32 m_nPrivileges;
+ sal_Int32 m_nLastKnownRowCount;
+ oslInterlockedCount m_nInAppend;
+ sal_Bool m_bLastKnownRowCountFinal;
+ sal_Bool m_bUseEscapeProcessing ;
+ sal_Bool m_bApplyFilter ;
+ sal_Bool m_bCommandFacetsDirty; // any of the facets which define the active command is dirty
+ sal_Bool m_bModified ;
+ sal_Bool m_bRebuildConnOnExecute ;
+ sal_Bool m_bIsBookmarable ;
+ sal_Bool m_bNew ;
+ sal_Bool m_bCanUpdateInsertedRows;
+ sal_Bool m_bOwnConnection;
+
+ private:
+ /** builds m_aActiveCommand from our settings
+
+ @return
+ whether we should use escape processing before executing the actual command. This is determined
+ from our own EscapeProcessing property, and possibly overruled by the respective property
+ of a query we're based on.
+ */
+ sal_Bool impl_buildActiveCommand_throw();
+
+ /** initializes our query composer, and everything which has to do with it
+
+ If we don't use escape processing, then we don't have a composer, and everything
+ related to it. Nonetheless, _out_rCommandToExecute and the return value are properly
+ initialized.
+
+ @param _out_rCommandToExecute
+ The command which is to be executed, according to the current settings -
+ it is built from our active command plus our current filter/order criterions.
+
+ @return
+ whether we should use escape processing before executing the actual command. This is determined
+ from our own EscapeProcessing property, and possibly overruled by the respective property
+ of a query we're based on.
+ Effectively, this value determines whether or not we actually have an composer (m_xComposer)
+ and dependent information (such as the parameters container).
+
+ @precond
+ m_xActiveConnection points to a valid SDB-level connection
+
+ @throws com::sun::star::sdb::SQLException
+ if an database-related error occured
+
+ @throws com::sun::star::uno::RuntimeException
+ if any of the components involved throws a com::sun::star::uno::RuntimeException
+ */
+ sal_Bool impl_initComposer_throw( ::rtl::OUString& _out_rCommandToExecute );
+
+ /** returns the table container of our active connection
+
+ If our connection is able to provide a tables container, this one is returned.
+ Else, if m_pTables is not <NULL/>, this one will returned.
+ Else, m_pTables will be constructed and returned.
+
+ @precond m_xActiveConnection is not <NULL/>
+ @throws ::com::sun::star::sdbc::SQLException
+ if retrieving or constructing the tables container goes wrong
+
+ @see impl_resetTables_nothrow
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
+ impl_getTables_throw();
+
+ /** cleans up m_pTables, and resets it to <NULL/>
+ */
+ void impl_resetTables_nothrow();
+
+ /** prepares and executes our command
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >
+ impl_prepareAndExecute_throw();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > calcConnection(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxHandler) throw( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException );
+ // free clones and ParseTree. Plus, if _bComplete is <TRUE/>, *all* other associated resources
+ void freeResources( bool _bComplete );
+
+ /// 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 );
+
+ /// inform the clones (and ourself) that we have deleted a record with a given bookmark
+ void notifyRowSetAndClonesRowDeleted( const ::com::sun::star::uno::Any& _rBookmark, sal_Int32 _nPos );
+
+ void checkUpdateIterator();
+ const connectivity::ORowSetValue& getInsertValue(sal_Int32 columnIndex);
+ void setParameter(sal_Int32 parameterIndex, const connectivity::ORowSetValue& x);
+ // resizes the parameter vector if nescessary
+ ::connectivity::ORowSetValue& getParameterStorage( sal_Int32 parameterIndex );
+
+ 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);
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue,sal_Int32 nHandle) const;
+ virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _rDefault ) const;
+
+ virtual void fireRowcount();
+ void notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const ::com::sun::star::sdb::RowChangeEvent &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);
+
+ virtual void doCancelModification( );
+ virtual sal_Bool isModification( );
+ virtual sal_Bool isModified( );
+ virtual sal_Bool isNew( );
+
+ virtual ~ORowSet();
+
+ public:
+ ORowSet(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);
+
+ // com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // com::sun::star::lang::XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::uno::XAggregation
+ virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XServiceInfo - static methods
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException );
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XCloseable
+ virtual void SAL_CALL close( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // ::com::sun::star::sdbc::XResultSet
+ virtual sal_Int32 SAL_CALL getRow( ) 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);
+
+ // XCompletedExecution
+ virtual void SAL_CALL executeWithCompletion( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& handler ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // XParametersSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL getParameters( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::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);
+
+ // ::com::sun::star::sdbc::XRowUpdate
+ virtual void SAL_CALL updateNull( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateFloat( sal_Int32 columnIndex, float x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateDouble( sal_Int32 columnIndex, double x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XResultSetUpdate
+ virtual void SAL_CALL insertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deleteRow( ) 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);
+
+ // ::com::sun::star::sdbc::XRowSet
+ virtual void SAL_CALL execute( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdb::XRowSetApproveBroadcaster
+ 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);
+
+ // ::com::sun::star::util::XCancellable
+ virtual void SAL_CALL cancel( ) throw(::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 ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // XParameters
+ virtual void SAL_CALL setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setFloat( sal_Int32 parameterIndex, float x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDouble( sal_Int32 parameterIndex, double x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBytes( sal_Int32 parameterIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setTimestamp( sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBinaryStream( sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setCharacterStream( sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setObject( sal_Int32 parameterIndex, const ::com::sun::star::uno::Any& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setObjectWithInfo( sal_Int32 parameterIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setRef( sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBlob( sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setClob( sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setArray( sal_Int32 parameterIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearParameters( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // XWarningsSupplier
+ virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearWarnings( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ protected:
+ /** implement the <method>execute</method>, without calling the approve listeners and without building a new
+ connection
+ @param _rClearForNotification mutex to clear before doing the final notifications
+ */
+ void execute_NoApprove_NoNewConn(::osl::ResettableMutexGuard& _rClearForNotification);
+
+ /** call the RowSetApproveListeners<p/>
+ throws an RowSetVetoException if one of the listeners vetoed
+ */
+ void approveExecution() throw (::com::sun::star::sdb::RowSetVetoException, ::com::sun::star::uno::RuntimeException);
+
+ /// set m_xActiveConnection, fire a PropertyChangeEvent if necessary, do the event listener handling etc
+ void setActiveConnection( ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxNewConn, sal_Bool _bFireEvent = sal_True );
+
+ void implCancelRowUpdates( sal_Bool _bNotifyModified ) SAL_THROW( ( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException ) );
+
+ /** sets the given result set type/concurrency at the given statement, while respecting
+ possibly related data source settings
+ */
+ void setStatementResultSetType(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxStatement,
+ sal_Int32 _nDesiredResultSetType,
+ sal_Int32 _nDesiredResultSetConcurrency
+ );
+
+ /** initializes a given RowSet column with the ColumnSettings (width, format, hidden, etc.) from a
+ template column.
+
+ If the template column supports any of the known column settings, they're plain copied. If not,
+ the template column is examined for a TableName and Name property, and the table column described
+ by those is used to find and copy the column settings.
+ */
+ void impl_initializeColumnSettings_nothrow(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxTemplateColumn,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxRowSetColumn
+ );
+
+ /** initializes our parameters container (m_pParameters) according to the parameter columns as
+ obtained from our composer
+ */
+ void impl_initParametersContainer_nothrow();
+ /** disposes our parameters container
+ */
+ void impl_disposeParametersContainer_nothrow();
+
+ protected:
+ using ORowSetBase::getFastPropertyValue;
+ using ORowSetBase::firePropertyChange;
+ using ORowSetBase::doCancelModification;
+ using ORowSetBase::isModification;
+ using ORowSetBase::isModified;
+ using ORowSetBase::isNew;
+ };
+
+
+ //************************************************************
+ // ORowSetClone
+ //************************************************************
+ class ORowSetClone : public comphelper::OBaseMutex
+ ,public OSubComponent
+ ,public ORowSetBase
+ ,public ::comphelper::OPropertyArrayUsageHelper < ORowSetClone >
+ {
+ protected:
+ ORowSet* m_pParent;
+ sal_Int32 m_nFetchDirection;
+ sal_Int32 m_nFetchSize;
+ sal_Bool m_bIsBookmarable;
+
+ protected:
+ // the clone can not insert anything
+ virtual void doCancelModification( );
+ virtual sal_Bool isModification( );
+ virtual sal_Bool isModified( );
+ virtual sal_Bool isNew( );
+
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const ::com::sun::star::uno::Any& rValue) throw (::com::sun::star::uno::Exception);
+ public:
+ ORowSetClone( const ::comphelper::ComponentContext& _rContext, ORowSet& rParent, ::osl::Mutex* _pMutex );
+ virtual ~ORowSetClone();
+
+ // com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException)
+ {
+ return getUnoTunnelImplementationId();
+ }
+
+ // com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+ static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // ::com::sun::star::sdbc::XCloseable
+ virtual void SAL_CALL close( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+ }
+
+ // ::com::sun::star::sdbc::XRowSet
+ virtual void SAL_CALL execute( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException);
+
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ protected:
+ using ORowSetBase::doCancelModification;
+ using ORowSetBase::isModification;
+ using ORowSetBase::isModified;
+ using ORowSetBase::isNew;
+ using ORowSetBase::rowDeleted;
+ };
+
+}
+#endif // DBACCESS_CORE_API_ROWSET_HXX
+
diff --git a/dbaccess/source/core/api/RowSetBase.cxx b/dbaccess/source/core/api/RowSetBase.cxx
new file mode 100644
index 000000000000..57157cf4f998
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetBase.cxx
@@ -0,0 +1,1577 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "RowSetBase.hxx"
+#include "CRowSetDataColumn.hxx"
+#include <connectivity/sdbcx/VCollection.hxx>
+#include "RowSetCache.hxx"
+#include "dbastrings.hrc"
+#include "core_resource.hrc"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdbcx/CompareBookmark.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <comphelper/sequence.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/seqstream.hxx>
+#include <connectivity/dbexception.hxx>
+#include <osl/thread.h>
+#include <tools/debug.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+using namespace connectivity;
+using namespace connectivity::sdbcx;
+using namespace comphelper;
+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 ::cppu;
+using namespace ::osl;
+
+namespace dbaccess
+{
+
+// =========================================================================
+// = OEmptyCollection
+// =========================================================================
+// -------------------------------------------------------------------------
+class OEmptyCollection : public sdbcx::OCollection
+{
+protected:
+ virtual void impl_refresh() throw(RuntimeException);
+ virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
+public:
+ OEmptyCollection(::cppu::OWeakObject& _rParent,::osl::Mutex& _rMutex) : OCollection(_rParent,sal_True,_rMutex,::std::vector< ::rtl::OUString>()){}
+};
+// -----------------------------------------------------------------------------
+void OEmptyCollection::impl_refresh() throw(RuntimeException)
+{
+}
+// -----------------------------------------------------------------------------
+connectivity::sdbcx::ObjectType OEmptyCollection::createObject(const ::rtl::OUString& /*_rName*/)
+{
+ return connectivity::sdbcx::ObjectType();
+}
+// -----------------------------------------------------------------------------
+
+// =========================================================================
+// = ORowSetBase
+// =========================================================================
+DBG_NAME(ORowSetBase)
+// -------------------------------------------------------------------------
+ORowSetBase::ORowSetBase( const ::comphelper::ComponentContext& _rContext, ::cppu::OBroadcastHelper& _rBHelper, ::osl::Mutex* _pMutex )
+ :OPropertyStateContainer(_rBHelper)
+ ,m_pMutex(_pMutex)
+ ,m_pCache(NULL)
+ ,m_pColumns(NULL)
+ ,m_rBHelper(_rBHelper)
+ ,m_pEmptyCollection( NULL )
+ ,m_aContext( _rContext )
+ ,m_aErrors( _rContext )
+ ,m_nLastColumnIndex(-1)
+ ,m_nDeletedPosition(-1)
+ ,m_nResultSetType( ResultSetType::FORWARD_ONLY )
+ ,m_nResultSetConcurrency( ResultSetConcurrency::READ_ONLY )
+ ,m_bClone(sal_False)
+ ,m_bIgnoreResult(sal_False)
+ ,m_bBeforeFirst(sal_True) // changed from sal_False
+ ,m_bAfterLast(sal_False)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::ORowSetBase" );
+ DBG_CTOR(ORowSetBase,NULL);
+
+ sal_Int32 nRBT = PropertyAttribute::READONLY | PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT;
+
+ sal_Int32 nInitialRowCountValue = 0;
+ sal_Bool bInitialRowCountFinalValue( sal_False );
+ registerPropertyNoMember( PROPERTY_ROWCOUNT, PROPERTY_ID_ROWCOUNT, nRBT, ::getCppuType( &nInitialRowCountValue ), &nInitialRowCountValue );
+ registerPropertyNoMember( PROPERTY_ISROWCOUNTFINAL, PROPERTY_ID_ISROWCOUNTFINAL, nRBT, ::getBooleanCppuType(), &bInitialRowCountFinalValue );
+}
+// -----------------------------------------------------------------------------
+ORowSetBase::~ORowSetBase()
+{
+ if(m_pColumns)
+ {
+ TDataColumns().swap(m_aDataColumns);
+ m_pColumns->acquire();
+ m_pColumns->disposing();
+ delete m_pColumns;
+ m_pColumns = NULL;
+ }
+
+ if ( m_pEmptyCollection )
+ delete m_pEmptyCollection;
+
+ DBG_DTOR(ORowSetBase,NULL);
+}
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > ORowSetBase::getTypes() throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTypes" );
+ return ::comphelper::concatSequences(ORowSetBase_BASE::getTypes(),OPropertyStateContainer::getTypes());
+}
+// com::sun::star::uno::XInterface
+//--------------------------------------------------------------------------
+Any ORowSetBase::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::queryInterface" );
+ Any aRet = ORowSetBase_BASE::queryInterface(rType);
+ if(!aRet.hasValue())
+ aRet = OPropertyStateContainer::queryInterface(rType);
+ return aRet;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetBase::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getFastPropertyValue" );
+ if(m_pCache)
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_ROWCOUNT:
+ rValue <<= impl_getRowCount();
+ break;
+ case PROPERTY_ID_ISROWCOUNTFINAL:
+ rValue.setValue(&m_pCache->m_bRowCountFinal,::getCppuBooleanType());
+ break;
+ default:
+ OPropertyStateContainer::getFastPropertyValue(rValue,nHandle);
+ };
+ }
+ else
+ OPropertyStateContainer::getFastPropertyValue(rValue,nHandle);
+}
+// -------------------------------------------------------------------------
+// OComponentHelper
+void SAL_CALL ORowSetBase::disposing(void)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::disposing" );
+ MutexGuard aGuard(*m_pMutex);
+
+ if ( m_pColumns )
+ {
+ TDataColumns().swap(m_aDataColumns);
+ m_pColumns->disposing();
+ }
+ if ( m_pCache )
+ {
+ m_pCache->deregisterOldRow(m_aOldRow);
+ m_pCache->deleteIterator(this);
+ }
+ m_pCache = NULL;
+}
+// -------------------------------------------------------------------------
+// comphelper::OPropertyArrayUsageHelper
+::cppu::IPropertyArrayHelper* ORowSetBase::createArrayHelper( ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::createArrayHelper" );
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+// -------------------------------------------------------------------------
+// cppu::OPropertySetHelper
+::cppu::IPropertyArrayHelper& SAL_CALL ORowSetBase::getInfoHelper()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getInfoHelper" );
+ return *const_cast<ORowSetBase*>(this)->getArrayHelper();
+}
+// -------------------------------------------------------------------------
+// XRow
+sal_Bool SAL_CALL ORowSetBase::wasNull( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::wasNull" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ return impl_wasNull();
+}
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetBase::impl_wasNull()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_wasNull" );
+ return ((m_nLastColumnIndex != -1) && !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid()) ? ((*m_aCurrentRow)->get())[m_nLastColumnIndex].isNull() : sal_True;
+}
+
+// -----------------------------------------------------------------------------
+const ORowSetValue& ORowSetBase::getValue(sal_Int32 columnIndex)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getValue" );
+ checkCache();
+ return impl_getValue(columnIndex);
+}
+// -----------------------------------------------------------------------------
+const ORowSetValue& ORowSetBase::impl_getValue(sal_Int32 columnIndex)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getValue" );
+ if ( m_bBeforeFirst || m_bAfterLast )
+ {
+ OSL_ENSURE(0,"ORowSetBase::getValue: Illegal call here (we're before first or after last)!");
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
+ }
+
+ if ( impl_rowDeleted() )
+ {
+ return m_aEmptyValue;
+ }
+
+ bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
+ if ( !bValidCurrentRow )
+ {
+ // currentrow is null when the clone moves the window
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ m_aCurrentRow = m_pCache->m_aMatrixIter;
+ OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null.");
+
+ bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
+ }
+
+ if ( bValidCurrentRow )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ ORowSetMatrix::iterator aCacheEnd;
+ ORowSetMatrix::iterator aCurrentRow;
+ aCacheEnd = m_pCache->getEnd();
+ aCurrentRow = m_aCurrentRow;
+ ORowSetCacheMap::iterator aCacheIter = m_aCurrentRow.getIter();
+ sal_Int32 n = aCacheIter->first;
+ n = n;
+ ORowSetCacheIterator_Helper aHelper = aCacheIter->second;
+ ORowSetMatrix::iterator k = aHelper.aIterator;
+ for (; k != m_pCache->getEnd(); ++k)
+ {
+ ORowSetValueVector* pTemp = k->getBodyPtr();
+ OSL_ENSURE( pTemp != (void*)0xfeeefeee,"HALT!" );
+ }
+#endif
+ OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow < m_pCache->getEnd() && aCacheIter != m_pCache->m_aCacheIterators.end(),"Invalid iterator set for currentrow!");
+#if OSL_DEBUG_LEVEL > 0
+ ORowSetRow rRow = (*m_aCurrentRow);
+ OSL_ENSURE(rRow.isValid() && static_cast<sal_uInt16>(columnIndex) < (rRow->get()).size(),"Invalid size of vector!");
+#endif
+ return ((*m_aCurrentRow)->get())[m_nLastColumnIndex = columnIndex];
+ }
+
+ // we should normally never reach this
+ return m_aEmptyValue;
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ORowSetBase::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getString" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBoolean" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int8 SAL_CALL ORowSetBase::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getByte" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int16 SAL_CALL ORowSetBase::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getShort" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ORowSetBase::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getInt" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+sal_Int64 SAL_CALL ORowSetBase::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getLong" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+float SAL_CALL ORowSetBase::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getFloat" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+double SAL_CALL ORowSetBase::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getDouble" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL ORowSetBase::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBytes" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Date SAL_CALL ORowSetBase::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getDate" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::Time SAL_CALL ORowSetBase::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTime" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+::com::sun::star::util::DateTime SAL_CALL ORowSetBase::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTimestamp" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSetBase::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBinaryStream" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ if ( m_bBeforeFirst || m_bAfterLast )
+ {
+ OSL_ENSURE(0,"ORowSetBase::getBinaryStream: Illegal call here (we're before first or after last)!");
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
+ }
+
+ if ( impl_rowDeleted() )
+ {
+ return NULL;
+ }
+
+ bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
+ if ( !bValidCurrentRow )
+ {
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ m_aCurrentRow = m_pCache->m_aMatrixIter;
+ OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getBinaryStream: we don't stand on a valid row! Row is null.");
+
+ bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
+ }
+
+ if ( bValidCurrentRow )
+ return new ::comphelper::SequenceInputStream(((*m_aCurrentRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
+
+ // we should normally never reach this
+ return Reference< ::com::sun::star::io::XInputStream >();
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSetBase::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getCharacterStream" );
+ return getBinaryStream(columnIndex);
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL ORowSetBase::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getObject" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ return getValue(columnIndex).makeAny();
+}
+// -------------------------------------------------------------------------
+Reference< XRef > SAL_CALL ORowSetBase::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getRef" );
+ ::dbtools::throwFeatureNotImplementedException( "XRow::getRef", *m_pMySelf );
+ return NULL;
+}
+// -------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL ORowSetBase::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBlob" );
+ return Reference< XBlob >(getValue(columnIndex).makeAny(),UNO_QUERY);
+}
+// -------------------------------------------------------------------------
+Reference< XClob > SAL_CALL ORowSetBase::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getClob" );
+ return Reference< XClob >(getValue(columnIndex).makeAny(),UNO_QUERY);
+}
+// -------------------------------------------------------------------------
+Reference< XArray > SAL_CALL ORowSetBase::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getArray" );
+ ::dbtools::throwFeatureNotImplementedException( "XRow::getArray", *m_pMySelf );
+ return NULL;
+}
+// -------------------------------------------------------------------------
+// ::com::sun::star::sdbcx::XRowLocate
+Any SAL_CALL ORowSetBase::getBookmark( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBookmark" );
+ DBG_TRACE2("DBACCESS ORowSetBase::getBookmark() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ if ( m_bBeforeFirst || m_bAfterLast )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
+
+ if ( impl_rowDeleted() )
+ ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_DELETED ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
+
+ OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::getBookmark: bookmark has no value!" );
+ return m_aBookmark;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::moveToBookmark" );
+ DBG_TRACE2("DBACCESS ORowSetBase::moveToBookmark(Any) Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ OSL_ENSURE(bookmark.hasValue(),"ORowSetBase::moveToBookmark bookmark has no value!");
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ if(!bookmark.hasValue() || m_nResultSetType == ResultSetType::FORWARD_ONLY)
+ {
+ if(bookmark.hasValue())
+ OSL_ENSURE(0,"MoveToBookmark is not possible when we are only forward");
+ else
+ OSL_ENSURE(0,"Bookmark is not valid");
+ throwFunctionSequenceException(*m_pMySelf);
+ }
+
+
+ checkCache();
+
+ sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
+ if ( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ bRet = m_pCache->moveToBookmark(bookmark);
+ doCancelModification( );
+ if(bRet)
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+ }
+ else
+ {
+ movementFailed();
+ }
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire( );
+ }
+ DBG_TRACE2("DBACCESS ORowSetBase::moveToBookmark(Any) = %i Clone = %i\n",bRet,m_bClone);
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::moveRelativeToBookmark" );
+ DBG_TRACE2("DBACCESS ORowSetBase::moveRelativeToBookmark(Any,%i) Clone = %i\n",rows,m_bClone);
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ checkPositioningAllowed();
+
+ sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
+ if ( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ bRet = m_pCache->moveRelativeToBookmark(bookmark,rows);
+ doCancelModification( );
+ if(bRet)
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+ }
+ else
+ movementFailed();
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire( );
+
+ // RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ DBG_TRACE3("DBACCESS ORowSetBase::moveRelativeToBookmark(Any,%i) = %i Clone = %i\n",rows,bRet,m_bClone);
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ORowSetBase::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::compareBookmarks" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ return m_pCache->compareBookmarks(_first,_second);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::hasOrderedBookmarks" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ return m_pCache->hasOrderedBookmarks();
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ORowSetBase::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::hashBookmark" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ return m_pCache->hashBookmark(bookmark);
+}
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+// XResultSetMetaDataSupplier
+Reference< XResultSetMetaData > SAL_CALL ORowSetBase::getMetaData( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getMetaData" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+
+ Reference< XResultSetMetaData > xMeta;
+ if(m_pCache)
+ xMeta = m_pCache->getMetaData();
+
+ return xMeta;
+}
+// -------------------------------------------------------------------------
+
+// XColumnLocate
+sal_Int32 SAL_CALL ORowSetBase::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::findColumn" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ // it is possible to save some time her when we remember the names - position relation in a map
+ return m_pColumns ? m_pColumns->findColumn(columnName) : sal_Int32(0);
+}
+// -------------------------------------------------------------------------
+
+// ::com::sun::star::sdbcx::XColumnsSupplier
+Reference< XNameAccess > SAL_CALL ORowSetBase::getColumns( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getColumns" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aColumnsMutex );
+ if(!m_pColumns)
+ {
+ if (!m_pEmptyCollection)
+ m_pEmptyCollection = new OEmptyCollection(*m_pMySelf,m_aColumnsMutex);
+ return m_pEmptyCollection;
+ }
+
+ return m_pColumns;
+}
+// -------------------------------------------------------------------------
+// XResultSet
+sal_Bool SAL_CALL ORowSetBase::next( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::next" );
+ DBG_TRACE2("DBACCESS ORowSetBase::next() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
+ if ( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ positionCache( MOVE_FORWARD );
+ sal_Bool bAfterLast = m_pCache->isAfterLast();
+ bRet = m_pCache->next();
+ doCancelModification( );
+
+
+ if ( bRet || bAfterLast != m_pCache->isAfterLast() )
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( bRet, sal_True, aOldValues, aGuard );
+ OSL_ENSURE(!m_bBeforeFirst,"BeforeFirst is true. I don't know why?");
+ }
+ else
+ {
+ // moved after the last row
+ movementFailed();
+ OSL_ENSURE(m_bAfterLast,"AfterLast is false. I don't know why?");
+ }
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ DBG_TRACE3("DBACCESS ORowSetBase::next() = %i Clone = %i ID = %i\n",bRet,m_bClone,osl_getThreadIdentifier(NULL));
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::isBeforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isBeforeFirst" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ DBG_TRACE2("DBACCESS ORowSetBase::isBeforeFirst() = %i Clone = %i\n",m_bBeforeFirst,m_bClone);
+
+ return m_bBeforeFirst;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::isAfterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isAfterLast" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ DBG_TRACE2("DBACCESS ORowSetBase::isAfterLast() = %i Clone = %i\n",m_bAfterLast,m_bClone);
+
+ return m_bAfterLast;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetBase::isOnFirst()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isOnFirst" );
+ return isFirst();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::isFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isFirst" );
+ DBG_TRACE2("DBACCESS ORowSetBase::isFirst() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ if ( m_bBeforeFirst || m_bAfterLast )
+ return sal_False;
+
+ if ( impl_rowDeleted() )
+ return ( m_nDeletedPosition == 1 );
+
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ sal_Bool bIsFirst = m_pCache->isFirst();
+
+ DBG_TRACE2("DBACCESS ORowSetBase::isFirst() = %i Clone = %i\n",bIsFirst,m_bClone);
+ return bIsFirst;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetBase::isOnLast()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isOnLast" );
+ return isLast();
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::isLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isLast" );
+ DBG_TRACE2("DBACCESS ORowSetBase::isLast() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ if ( m_bBeforeFirst || m_bAfterLast )
+ return sal_False;
+
+ if ( impl_rowDeleted() )
+ {
+ if ( !m_pCache->m_bRowCountFinal )
+ return sal_False;
+ else
+ return ( m_nDeletedPosition == impl_getRowCount() );
+ }
+
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ sal_Bool bIsLast = m_pCache->isLast();
+
+ DBG_TRACE2("DBACCESS ORowSetBase::isLast() = %i Clone = %i\n",bIsLast,m_bClone);
+ return bIsLast;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetBase::beforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::beforeFirst" );
+ DBG_TRACE2("DBACCESS ORowSetBase::beforeFirst() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ checkPositioningAllowed();
+
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
+
+ if((bWasNew || !m_bBeforeFirst) && notifyAllListenersCursorBeforeMove(aGuard) )
+ {
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ if ( !m_bBeforeFirst )
+ {
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+ m_pCache->beforeFirst();
+ doCancelModification( );
+
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+
+ // - IsModified
+ // - Isnew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+
+ // to be done _after_ the notifications!
+ m_aOldRow->clearRow();
+ }
+ DBG_TRACE2("DBACCESS ORowSetBase::beforeFirst() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetBase::afterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::afterLast" );
+ DBG_TRACE2("DBACCESS ORowSetBase::afterLast() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkPositioningAllowed();
+
+ sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
+
+ if((bWasNew || !m_bAfterLast) && notifyAllListenersCursorBeforeMove(aGuard) )
+ {
+ // check if we are inserting a row
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ if(!m_bAfterLast)
+ {
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ m_pCache->afterLast();
+ doCancelModification( );
+
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+
+ // - IsModified
+ // - Isnew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ }
+ DBG_TRACE2("DBACCESS ORowSetBase::afterLast() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::move( ::std::mem_fun_t<sal_Bool,ORowSetBase>& _aCheckFunctor,
+ ::std::mem_fun_t<sal_Bool,ORowSetCache>& _aMovementFunctor)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::move" );
+ DBG_TRACE2("DBACCESS ORowSetBase::move() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkPositioningAllowed();
+
+ sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
+ if( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ sal_Bool bMoved = ( bWasNew || !_aCheckFunctor(this) );
+
+ bRet = _aMovementFunctor(m_pCache);
+ doCancelModification( );
+
+ if ( bRet )
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( bMoved, sal_True, aOldValues, aGuard );
+ }
+ else
+ { // first goes wrong so there is no row
+ movementFailed();
+ }
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ DBG_TRACE2("DBACCESS ORowSetBase::move() = %i Clone = %i\n",bRet,m_bClone);
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::first( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::first" );
+ DBG_TRACE2("DBACCESS ORowSetBase::first() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::std::mem_fun_t<sal_Bool,ORowSetBase> ioF_tmp(&ORowSetBase::isOnFirst);
+ ::std::mem_fun_t<sal_Bool,ORowSetCache> F_tmp(&ORowSetCache::first);
+ return move(ioF_tmp,F_tmp);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::last( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::last" );
+ DBG_TRACE2("DBACCESS ORowSetBase::last() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::std::mem_fun_t<sal_Bool,ORowSetBase> ioL_tmp(&ORowSetBase::isOnLast);
+ ::std::mem_fun_t<sal_Bool,ORowSetCache> L_tmp(&ORowSetCache::last);
+ return move(ioL_tmp,L_tmp);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ORowSetBase::getRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getRow" );
+ DBG_TRACE2("DBACCESS ORowSetBase::getRow() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::osl::MutexGuard aGuard( *m_pMutex );
+
+ checkCache();
+ return impl_getRow();
+}
+// -------------------------------------------------------------------------
+sal_Int32 ORowSetBase::impl_getRow()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getRow" );
+ sal_Int32 nPos = 0;
+ if ( m_bBeforeFirst )
+ nPos = 0;
+ else if ( m_bAfterLast )
+ nPos = impl_getRowCount() + 1;
+ else if ( impl_rowDeleted() )
+ nPos = m_nDeletedPosition;
+ else if ( !m_bClone && m_pCache->m_bNew )
+ nPos = 0;
+ else
+ {
+ if ( m_pCache->isAfterLast()
+ || m_pCache->isBeforeFirst()
+ || ( m_pCache->compareBookmarks( m_aBookmark, m_pCache->getBookmark() ) != CompareBookmark::EQUAL )
+ )
+ {
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ }
+ nPos = m_pCache->getRow();
+ }
+ DBG_TRACE3("DBACCESS ORowSetBase::impl_getRow() = %i Clone = %i ID = %i\n",nPos,m_bClone,osl_getThreadIdentifier(NULL));
+ return nPos;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::absolute" );
+ DBG_TRACE2("DBACCESS ORowSetBase::absolute(%i) Clone = %i\n",row,m_bClone);
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+ checkPositioningAllowed();
+
+ sal_Bool bRet = ( row > 0 )
+ && notifyAllListenersCursorBeforeMove( aGuard );
+ if ( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ bRet = m_pCache->absolute(row);
+ doCancelModification( );
+
+ if(bRet)
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+ }
+ else
+ { // absolute movement goes wrong we stand left or right side of the rows
+ movementFailed();
+ }
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ DBG_TRACE3("DBACCESS ORowSetBase::absolute(%i) = %i Clone = %i\n",row,bRet,m_bClone);
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::relative" );
+ DBG_TRACE2("DBACCESS ORowSetBase::relative(%i) Clone = %i\n",rows,m_bClone);
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ if(!rows)
+ return sal_True; // in this case do nothing
+
+ checkPositioningAllowed();
+
+ sal_Bool bRet =
+ ( ( !m_bAfterLast || rows <= 0 )
+ && ( !m_bBeforeFirst || rows >= 0 )
+ && notifyAllListenersCursorBeforeMove( aGuard )
+ );
+
+ if ( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ positionCache( rows > 0 ? MOVE_FORWARD : MOVE_BACKWARD );
+ bRet = m_pCache->relative(rows);
+ doCancelModification( );
+
+ if(bRet)
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+ }
+ else
+ {
+ movementFailed();
+ }
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ DBG_TRACE3("DBACCESS ORowSetBase::relative(%i) = %i Clone = %i\n",rows,bRet,m_bClone);
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::previous( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::previous" );
+ DBG_TRACE2("DBACCESS ORowSetBase::previous() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::ResettableMutexGuard aGuard( *m_pMutex );
+
+ checkPositioningAllowed();
+
+ sal_Bool bRet = !m_bBeforeFirst
+ && notifyAllListenersCursorBeforeMove(aGuard);
+
+ if ( bRet )
+ {
+ // check if we are inserting a row
+ sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
+
+ ORowSetNotifier aNotifier( this );
+ // this will call cancelRowModification on the cache if necessary
+
+ ORowSetRow aOldValues = getOldRow(bWasNew);
+
+ positionCache( MOVE_BACKWARD );
+ bRet = m_pCache->previous();
+ doCancelModification( );
+
+ // if m_bBeforeFirst is false and bRet is false than we stood on the first row
+ if(!m_bBeforeFirst || bRet)
+ {
+ // notification order
+ // - column values
+ // - cursorMoved
+ setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
+ }
+ else
+ {
+ DBG_ERROR( "ORowSetBase::previous: inconsistency!" );
+ // we should never reach this place, as we should not get into this whole branch if m_bBeforeFirst
+ // was |true| from the beginning
+ movementFailed();
+ }
+
+ // - IsModified
+ // - IsNew
+ aNotifier.fire();
+
+ // - RowCount/IsRowCountFinal
+ fireRowcount();
+ }
+ DBG_TRACE2("DBACCESS ORowSetBase::previous() = %i Clone = %i\n",bRet,m_bClone);
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::setCurrentRow" );
+ DBG_TRACE2("DBACCESS ORowSetBase::setCurrentRow() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ m_bBeforeFirst = m_pCache->isBeforeFirst();
+ m_bAfterLast = m_pCache->isAfterLast();
+ //m_pCache->resetInsertRow(sal_True);
+
+ if(!(m_bBeforeFirst || m_bAfterLast))
+ {
+ m_aBookmark = m_pCache->getBookmark();
+ OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!");
+ m_aCurrentRow = m_pCache->m_aMatrixIter;
+ OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is null!");
+ m_aCurrentRow.setBookmark(m_aBookmark);
+ OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd(),"Position of matrix iterator isn't valid!");
+ OSL_ENSURE(m_aCurrentRow->isValid(),"Currentrow isn't valid");
+ OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!");
+
+#if OSL_DEBUG_LEVEL > 0
+ sal_Int32 nOldRow = m_pCache->getRow();
+#endif
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+#if OSL_DEBUG_LEVEL > 0
+ sal_Int32 nNewRow = m_pCache->getRow();
+#endif
+ OSL_ENSURE(nOldRow == nNewRow,"Old position is not equal to new postion");
+ m_aCurrentRow = m_pCache->m_aMatrixIter;
+ OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!");
+#if OSL_DEBUG_LEVEL > 0
+ ORowSetRow rRow = (*m_aCurrentRow);
+ OSL_ENSURE(rRow.isValid() ,"Invalid size of vector!");
+#endif
+ // the cache could repositioned so we need to adjust the cache
+ // #104144# OJ
+ if ( _bMoved && m_aCurrentRow.isNull() )
+ {
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ m_aCurrentRow = m_pCache->m_aMatrixIter;
+ OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!");
+ }
+ }
+ else
+ {
+ m_aOldRow->clearRow();
+ m_aCurrentRow = m_pCache->getEnd();
+ m_aBookmark = Any();
+ m_aCurrentRow.setBookmark(m_aBookmark);
+ }
+
+ // notification order
+ // - column values
+ if ( _bDoNotify )
+ firePropertyChange(_rOldValues);
+
+ // TODO: can this be done before the notifications?
+ if(!(m_bBeforeFirst || m_bAfterLast) && !m_aCurrentRow.isNull() && m_aCurrentRow->isValid() && m_aCurrentRow != m_pCache->getEnd())
+ m_aOldRow->setRow(new ORowSetValueVector(m_aCurrentRow->getBody()));
+
+ if ( _bMoved && _bDoNotify )
+ // - cursorMoved
+ notifyAllListenersCursorMoved( _rGuard );
+
+ DBG_TRACE2("DBACCESS ORowSetBase::setCurrentRow() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::checkPositioningAllowed() throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::checkPositioningAllowed" );
+ if(!m_pCache || m_nResultSetType == ResultSetType::FORWARD_ONLY)
+ throwFunctionSequenceException(*m_pMySelf);
+}
+//------------------------------------------------------------------------------
+Reference< XInterface > ORowSetBase::getStatement(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getStatement" );
+ return NULL;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetBase::refreshRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::refreshRow" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ if ( impl_rowDeleted() )
+ throwSQLException( "The current row is deleted", SQL_INVALID_CURSOR_STATE, Reference< XRowSet >( this ) );
+
+ if(!(m_bBeforeFirst || m_bAfterLast))
+ {
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ m_pCache->refreshRow();
+ }
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::rowUpdated( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowUpdated" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+
+ if ( impl_rowDeleted() )
+ return sal_False;
+
+ return m_pCache->rowUpdated();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::rowInserted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowInserted" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+
+ checkCache();
+
+ if ( impl_rowDeleted() )
+ return sal_False;
+
+ return m_pCache->rowInserted();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ORowSetBase::rowDeleted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowDeleted" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ checkCache();
+ return impl_rowDeleted();
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetBase::impl_rowDeleted( )
+{
+ return !m_aBookmark.hasValue() && !m_bBeforeFirst && !m_bAfterLast;
+}
+// -------------------------------------------------------------------------
+// XWarningsSupplier
+Any SAL_CALL ORowSetBase::getWarnings( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getWarnings" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+
+ if ( m_pCache )
+ {
+ Reference< XWarningsSupplier > xWarnings( m_pCache->m_xSet.get(), UNO_QUERY );
+ if ( xWarnings.is() )
+ return xWarnings->getWarnings();
+ }
+
+ return Any();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ORowSetBase::clearWarnings( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::clearWarnings" );
+ ::osl::MutexGuard aGuard( *m_pMutex );
+
+ if ( m_pCache )
+ {
+ Reference< XWarningsSupplier > xWarnings( m_pCache->m_xSet.get(), UNO_QUERY );
+ if ( xWarnings.is() )
+ xWarnings->clearWarnings();
+ }
+}
+// -------------------------------------------------------------------------
+void ORowSetBase::firePropertyChange(const ORowSetRow& _rOldRow)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::firePropertyChange" );
+ DBG_TRACE2("DBACCESS ORowSetBase::firePropertyChange() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ OSL_ENSURE(m_pColumns,"Columns can not be NULL here!");
+#if OSL_DEBUG_LEVEL > 1
+ sal_Bool bNull;
+ ORowSetMatrix::iterator atest;
+ bNull = m_aCurrentRow.isNull();
+ atest = m_aCurrentRow;
+#endif
+ sal_Int32 i=0;
+ try
+ {
+ TDataColumns::iterator aEnd = m_aDataColumns.end();
+ for(TDataColumns::iterator aIter = m_aDataColumns.begin();aIter != aEnd;++aIter,++i) // #104278# OJ ++i inserted
+ (*aIter)->fireValueChange(_rOldRow.isValid() ? (_rOldRow->get())[i+1] : ::connectivity::ORowSetValue());
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(0,"firePropertyChange: Exception");
+ }
+ 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()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::fireRowcount" );
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetBase::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& /*_rGuard*/)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListenersCursorBeforeMove" );
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetBase::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& /*_rGuard*/)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListenersCursorMoved" );
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetBase::notifyAllListeners(::osl::ResettableMutexGuard& /*_rGuard*/)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListeners" );
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetBase::fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::fireProperty" );
+ Any aNew = bool2any( _bNew );
+ Any aOld = bool2any( _bOld );
+ fire( &_nProperty, &aNew, &aOld, 1, sal_False );
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetBase::positionCache( CursorMoveDirection _ePrepareForDirection )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::positionCache" );
+ DBG_TRACE2("DBACCESS ORowSetBase::positionCache() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+
+ sal_Bool bSuccess = sal_False;
+ if ( m_aBookmark.hasValue() )
+ {
+ bSuccess = m_pCache->moveToBookmark( m_aBookmark );
+ }
+ else
+ {
+ if ( m_bBeforeFirst )
+ {
+ bSuccess = m_pCache->beforeFirst();
+ }
+ else if ( m_bAfterLast )
+ {
+ bSuccess = m_pCache->afterLast();
+ }
+ else
+ {
+ OSL_ENSURE( m_nDeletedPosition >= 1, "ORowSetBase::positionCache: no bookmark, and no valid 'deleted position'!" );
+ switch ( _ePrepareForDirection )
+ {
+ case MOVE_FORWARD:
+ if ( m_nDeletedPosition > 1 )
+ bSuccess = m_pCache->absolute( m_nDeletedPosition - 1 );
+ else
+ {
+ m_pCache->beforeFirst();
+ bSuccess = sal_True;
+ }
+ break;
+
+ case MOVE_BACKWARD:
+ if ( m_pCache->m_bRowCountFinal && ( m_nDeletedPosition == impl_getRowCount() ) )
+ {
+ m_pCache->afterLast();
+ bSuccess = sal_True;
+ }
+ else
+ bSuccess = m_pCache->absolute( m_nDeletedPosition );
+ break;
+
+ case MOVE_NONE_REFRESH_ONLY:
+ bSuccess = sal_False; // will be asserted below
+ break;
+ }
+ }
+ }
+ OSL_ENSURE( bSuccess, "ORowSetBase::positionCache: failed!" );
+
+ DBG_TRACE2("DBACCESS ORowSetBase::positionCache() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::checkCache()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::checkCache" );
+ ::connectivity::checkDisposed(m_rBHelper.bDisposed);
+ if(!m_pCache)
+ throwFunctionSequenceException(*m_pMySelf);
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::movementFailed()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::movementFailed" );
+ DBG_TRACE2("DBACCESS ORowSetBase::movementFailed() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+ m_aOldRow->clearRow();
+ m_aCurrentRow = m_pCache->getEnd();
+ m_bBeforeFirst = m_pCache->isBeforeFirst();
+ m_bAfterLast = m_pCache->isAfterLast();
+ m_aBookmark = Any();
+ m_aCurrentRow.setBookmark(m_aBookmark);
+ OSL_ENSURE(m_bBeforeFirst || m_bAfterLast,"BeforeFirst or AfterLast is wrong!");
+ DBG_TRACE2("DBACCESS ORowSetBase::movementFailed() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
+}
+// -----------------------------------------------------------------------------
+ORowSetRow ORowSetBase::getOldRow(sal_Bool _bWasNew)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getOldRow" );
+ OSL_ENSURE(m_aOldRow.isValid(),"RowSetRowHElper isn't valid!");
+ ORowSetRow aOldValues;
+ if ( !_bWasNew && m_aOldRow->getRow().isValid() )
+ aOldValues = new ORowSetValueVector( m_aOldRow->getRow().getBody()); // remember the old values
+ return aOldValues;
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getPropertyDefaultByHandle" );
+ _rDefault.clear();
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::onDeleteRow( const Any& _rBookmark )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::onDeleteRow" );
+ if ( rowDeleted() )
+ // not interested in
+ return;
+
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ //OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::onDeleteRow: Bookmark isn't valid!" );
+ if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 )
+ {
+ positionCache( MOVE_NONE_REFRESH_ONLY );
+ m_nDeletedPosition = m_pCache->getRow();
+ }
+}
+// -----------------------------------------------------------------------------
+void ORowSetBase::onDeletedRow( const Any& _rBookmark, sal_Int32 _nPos )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::onDeletedRow" );
+ if ( rowDeleted() )
+ {
+ // if we're a clone, and on a deleted row, and the main RowSet deleted another
+ // row (only the main RowSet can, clones can't), which is *before* our
+ // deleted position, then we have to adjust this position
+ if ( m_bClone && ( _nPos < m_nDeletedPosition ) )
+ --m_nDeletedPosition;
+ return;
+ }
+
+ ::osl::MutexGuard aGuard( *m_pMutex );
+ if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 )
+ {
+ m_aOldRow->clearRow();
+ m_aCurrentRow = m_pCache->getEnd();
+ m_aBookmark = Any();
+ m_aCurrentRow.setBookmark( m_aBookmark );
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Int32 ORowSetBase::impl_getRowCount() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getRowCount" );
+ sal_Int32 nRowCount( m_pCache->m_nRowCount );
+ if ( const_cast< ORowSetBase* >( this )->rowDeleted() && !m_pCache->m_bNew )
+ ++nRowCount;
+ return nRowCount;
+}
+// =============================================================================
+struct ORowSetNotifierImpl
+{
+ ::std::vector<sal_Int32> aChangedColumns;
+ ::std::vector<Any> aChangedBookmarks;
+ ORowSetValueVector::Vector aRow;
+
+};
+DBG_NAME(ORowSetNotifier)
+// -----------------------------------------------------------------------------
+ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet )
+ :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." );
+
+ // remember the "inserted" and "modified" state for later firing
+ m_bWasNew = m_pRowSet->isNew( ORowSetBase::GrantNotifierAccess() );
+ m_bWasModified = m_pRowSet->isModified( ORowSetBase::GrantNotifierAccess() );
+
+ // if the row set is on the insert row, then we need to cancel this
+ 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( )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetNotifier::~ORowSetNotifier" );
+ DBG_DTOR(ORowSetNotifier,NULL);
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetNotifier::fire()
+{
+ // we're not interested in firing changes FALSE->TRUE, only TRUE->FALSE.
+ // (the former would be quite pathological, e.g. after a failed movement)
+
+ if ( m_bWasModified
+ && ( m_bWasModified != m_pRowSet->isModified( ORowSetBase::GrantNotifierAccess() ) )
+ )
+ m_pRowSet->fireProperty( PROPERTY_ID_ISMODIFIED, sal_False, sal_True, ORowSetBase::GrantNotifierAccess() );
+
+ if ( m_bWasNew
+ && ( m_bWasNew != m_pRowSet->isNew( ORowSetBase::GrantNotifierAccess() ) )
+ )
+ m_pRowSet->fireProperty( PROPERTY_ID_ISNEW, sal_False, sal_True, ORowSetBase::GrantNotifierAccess() );
+
+#ifdef DBG_UTIL
+ 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
new file mode 100644
index 000000000000..9a7e9182e1d0
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetBase.hxx
@@ -0,0 +1,463 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_ROWSETBASE_HXX
+#define DBACCESS_CORE_API_ROWSETBASE_HXX
+
+#ifndef _CPPUHELPER_IMPLBASE10_HXX_
+#include <cppuhelper/implbase10.hxx>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_
+#include <com/sun/star/sdbc/XColumnLocate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCLOSEABLE_HPP_
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP_
+#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#endif
+#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
+#include <cppuhelper/interfacecontainer.h>
+#endif
+#ifndef CONNECTIVITY_SQLERROR_HXX
+#include <connectivity/sqlerror.hxx>
+#endif
+#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
+#include <connectivity/CommonTools.hxx>
+#endif
+#ifndef COMPHELPER_PROPERTYSTATECONTAINER_HXX
+#include <comphelper/propertystatecontainer.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
+#include <comphelper/proparrhlp.hxx>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROWSET_HPP_
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
+#include <com/sun/star/container/XNameAccess.hpp>
+#endif
+#ifndef DBACCESS_CORE_API_ROWSETROW_HXX
+#include "RowSetRow.hxx"
+#endif
+#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
+#include <comphelper/broadcasthelper.hxx>
+#endif
+#ifndef DBACCESS_ROWSETCACHEITERATOR_HXX
+#include "RowSetCacheIterator.hxx"
+#endif
+#include "core_resource.hxx"
+#include <comphelper/componentcontext.hxx>
+
+#include <functional>
+
+
+namespace com { namespace sun { namespace star {
+ namespace sdb { struct RowChangeEvent; }
+ namespace lang { struct Locale; }
+} } }
+
+namespace dbaccess
+{
+ class OEmptyCollection;
+
+ typedef ::cppu::ImplHelper10< ::com::sun::star::sdbcx::XRowLocate,
+ ::com::sun::star::sdbc::XRow,
+ ::com::sun::star::sdbc::XResultSetMetaDataSupplier,
+ ::com::sun::star::sdbc::XWarningsSupplier,
+ ::com::sun::star::sdbc::XColumnLocate,
+ ::com::sun::star::sdbcx::XColumnsSupplier,
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::sdbc::XRowSet,
+ ::com::sun::star::sdbc::XCloseable,
+ ::com::sun::star::lang::XUnoTunnel> ORowSetBase_BASE;
+
+ class ORowSetCache;
+ class ORowSetDataColumns;
+ class ORowSetCacheIterator;
+ class ORowSetDataColumn;
+ class ORowSetBase : public ORowSetBase_BASE,
+ public ::comphelper::OPropertyStateContainer,
+ public ::comphelper::OPropertyArrayUsageHelper<ORowSetBase> // this class hold the static property info
+ {
+ OModuleClient m_aModuleClient;
+ protected:
+ typedef ::std::vector<ORowSetDataColumn*> TDataColumns;
+ ::osl::Mutex* m_pMutex; // this the mutex form the rowset itself
+ ::osl::Mutex m_aRowCountMutex, // mutex for rowcount changes
+ // we need a extra mutex for columns to prevend deadlock when setting new values
+ // for a row
+ m_aColumnsMutex;
+
+ ::com::sun::star::uno::Any m_aBookmark;
+ ORowSetCacheIterator m_aCurrentRow; // contains the actual fetched row
+ TORowSetOldRowHelperRef m_aOldRow;
+ TDataColumns m_aDataColumns; // holds the columns as m_pColumns but know the implementation class
+ connectivity::ORowSetValue m_aEmptyValue; // only for error case
+
+ ::cppu::OWeakObject* m_pMySelf; // set by derived classes
+ ORowSetCache* m_pCache; // the cache is used by the rowset and his clone (shared)
+ ORowSetDataColumns* m_pColumns; // represent the select columns
+ ::cppu::OBroadcastHelper& m_rBHelper; // must be set from the derived classes
+ // is used when the formatkey for database types is set
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatTypes> m_xNumberFormatTypes;
+ OEmptyCollection* m_pEmptyCollection;
+
+ ::comphelper::ComponentContext m_aContext;
+ ::connectivity::SQLError m_aErrors;
+
+ sal_Int32 m_nLastColumnIndex; // the last column ask for, used for wasNull()
+ sal_Int32 m_nDeletedPosition; // is set only when a row was deleted
+ sal_Int32 m_nResultSetType; // fetch property
+ sal_Int32 m_nResultSetConcurrency;
+ sal_Bool m_bClone; // I'm clone or not
+ sal_Bool m_bIgnoreResult ;
+ sal_Bool m_bBeforeFirst : 1;
+ sal_Bool m_bAfterLast : 1;
+
+ protected:
+ ORowSetBase(
+ const ::comphelper::ComponentContext& _rContext,
+ ::cppu::OBroadcastHelper& _rBHelper,
+ ::osl::Mutex* _pMutex
+ );
+
+ // 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();
+ // notify row changed
+ virtual sal_Bool notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard);
+ // notify cursor moved
+ virtual void notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard);
+ // notify all that rowset changed
+ virtual void notifyAllListeners(::osl::ResettableMutexGuard& _rGuard);
+
+ // cancel the insertion, if necessary (means if we're on the insert row)
+ virtual void doCancelModification( ) = 0;
+ // return <TRUE/> if and only if we're using the insert row (means: we're updating _or_ inserting)
+ virtual sal_Bool isModification( ) = 0;
+ // return <TRUE/> if and only if the current row is modified
+ // TODO: isn't this the same as isModification?
+ virtual sal_Bool isModified( ) = 0;
+ // return <TRUE/> if and only if the current row is the insert row
+ virtual sal_Bool isNew( ) = 0;
+ // notify the change of a boolean property
+ void fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld );
+
+ // OPropertyStateContainer
+ virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _rDefault ) const;
+ virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue,sal_Int32 nHandle) const;
+
+ enum CursorMoveDirection
+ {
+ /// denotes a cursor move forward
+ MOVE_FORWARD,
+ /// denotes a cursor move backwards
+ MOVE_BACKWARD,
+ /// denotes no cursor move at all, used when the current row is to be refreshed only
+ MOVE_NONE_REFRESH_ONLY
+ };
+ /** positions the cache in preparation of a cursor move
+
+ Normally, the cache is simply moved to our bookmark (m_aBookmark). If however the current
+ row is deleted, then the cache is properly positioned for a following cursor movement in the
+ given direction.
+
+ @param _ePrepareForDirection
+ the direction into which the cursor should be moved after the call. If we're currently not on
+ a deleted row, this parameter is ignored, since in this case the cache is simply moved to
+ m_aBookmark.</br>
+ If, however, we're currently on a deleted row, this is used to properly position the cache
+ using <member>m_nDeletedPosition</member>.<br/>
+ In this case, MOVE_NONE_REFRESH_ONLY is not supported. This is because the deleted row
+ (to which the RowSet currently points to) is not present in the cache. So, you cannot move the
+ cache to this row.
+ */
+ void positionCache( CursorMoveDirection _ePrepareForDirection );
+
+ // returns a value of a column of the current row
+ const connectivity::ORowSetValue& getValue(sal_Int32 columnIndex);
+ // the cache has to be checked before calling this method
+ const connectivity::ORowSetValue& impl_getValue(sal_Int32 columnIndex);
+ // sets the current and the bookmark
+ void setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard);
+ void checkPositioningAllowed() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ // checks if the cache is null
+ void checkCache();
+ // sets the bookmark to Any()
+ // m_aCurrentRow to end of matrix
+ // m_aOldRow to NULL
+ void movementFailed();
+
+ ORowSetRow getOldRow(sal_Bool _bWasNew);
+ /** move the cache the postion defined by the member functor
+ @param _aCheckFunctor
+ Return <TRUE/> when we already stand on the row we want to.
+ @param _aMovementFunctor
+ The mehtod used to move.
+ @return
+ <TRUE/> if movement was successful.
+ */
+ sal_Bool SAL_CALL move( ::std::mem_fun_t<sal_Bool,ORowSetBase>& _aCheckFunctor,
+ ::std::mem_fun_t<sal_Bool,ORowSetCache>& _aMovementFunctor);
+
+ /** same meaning as isFirst. Only need by mem_fun
+ @return
+ <TRUE/> if so.
+ */
+ sal_Bool isOnFirst();
+ /** same meaning as isLast. Only need by mem_fun
+ @return
+ <TRUE/> if so.
+ */
+ sal_Bool isOnLast();
+
+ /** returns the current row count
+
+ This function takes into account that we might actually be positioned on a
+ deleted row, so that m_pCache->m_nRowCount does not really reflect the actual
+ count.
+
+ @precond
+ Our mutext is locked.
+ */
+ sal_Int32 impl_getRowCount() const;
+
+ // the checkCache has to be called before calling this methods
+ sal_Bool impl_wasNull();
+ sal_Int32 impl_getRow();
+ sal_Bool impl_rowDeleted();
+
+ public:
+ virtual ~ORowSetBase();
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+ }
+
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XWarningsSupplier
+ virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XResultSetMetaDataSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XColumnLocate
+ virtual sal_Int32 SAL_CALL findColumn( const ::rtl::OUString& columnName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbcx::XColumnsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::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);
+
+ // ::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::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);
+ 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);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getStatement( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XRowSet
+ virtual void SAL_CALL execute( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0;
+ virtual void SAL_CALL addRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) = 0;
+ virtual void SAL_CALL removeRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) = 0;
+
+ // is called when the rowset is going to delete this bookmark _rBookmark
+ void onDeleteRow( const ::com::sun::star::uno::Any& _rBookmark );
+ // is called when the rowset has deleted this bookmark _rBookmark
+ void onDeletedRow( const ::com::sun::star::uno::Any& _rBookmark, sal_Int32 _nPos );
+
+ // ==========================================================
+ // granular access control
+ struct GrantNotifierAccess { friend class ORowSetNotifier; private: GrantNotifierAccess () { } };
+
+ // cancel the insertion, if necessary (means if we're on the insert row)
+ inline void doCancelModification( const GrantNotifierAccess& ) { doCancelModification(); }
+ inline sal_Bool isModification( const GrantNotifierAccess& ) { return isModification(); }
+ inline sal_Bool isModified( const GrantNotifierAccess& ) { return isModified(); }
+ inline sal_Bool isNew( const GrantNotifierAccess& ) { return isNew(); }
+ inline sal_Bool isInsertRow() { return isNew() || isModified(); }
+ inline void fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld, const GrantNotifierAccess& )
+ {
+ 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; }
+ };
+
+ // ========================================================================
+ /** eases the handling of the doCancelModification and notifyCancelInsert methods
+
+ <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
+
+ public:
+ /** constructs the object, and cancels the insertion
+
+ @see ORowSetBase::doCancelModification
+ */
+ 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( );
+
+ /** notifies the insertion
+
+ <p>This has <em>not</em> been put into the destructor by intention!<br/>
+
+ The destructor is called during stack unwinding in case of an exception, so if we would do
+ listener notification there, this would have the potential of another exception during stack
+ unwinding, which would terminate the application.</p>
+
+ @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
+
+#endif // DBACCESS_CORE_API_ROWSETBASE_HXX
+
diff --git a/dbaccess/source/core/api/RowSetCache.cxx b/dbaccess/source/core/api/RowSetCache.cxx
new file mode 100644
index 000000000000..e4e468b13779
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetCache.cxx
@@ -0,0 +1,1685 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "BookmarkSet.hxx"
+#include "CRowSetColumn.hxx"
+#include "CRowSetDataColumn.hxx"
+#include "KeySet.hxx"
+#include "OptimisticSet.hxx"
+#include "RowSetBase.hxx"
+#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/dbtools.hxx>
+#include <connectivity/sqliterator.hxx>
+#include <connectivity/sqlnode.hxx>
+#include <connectivity/sqlparse.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+
+using namespace dbaccess;
+using namespace dbtools;
+using namespace connectivity;
+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;
+
+#define CHECK_MATRIX_POS(M) OSL_ENSURE(((M) >= static_cast<ORowSetMatrix::difference_type>(0)) && ((M) < static_cast<sal_Int32>(m_pMatrix->size())),"Position is invalid!")
+
+DBG_NAME(ORowSetCache)
+// -------------------------------------------------------------------------
+ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs,
+ const Reference< XSingleSelectQueryAnalyzer >& _xAnalyzer,
+ const ::comphelper::ComponentContext& _rContext,
+ const ::rtl::OUString& _rUpdateTableName,
+ sal_Bool& _bModified,
+ sal_Bool& _bNew,
+ const ORowSetValueVector& _aParameterValueForCache,
+ const ::rtl::OUString& i_sRowSetFilter)
+ :m_xSet(_xRs)
+ ,m_xMetaData(Reference< XResultSetMetaDataSupplier >(_xRs,UNO_QUERY)->getMetaData())
+ ,m_aContext( _rContext )
+ ,m_pCacheSet(NULL)
+ ,m_pMatrix(NULL)
+ ,m_pInsertMatrix(NULL)
+ ,m_nLastColumnIndex(0)
+ ,m_nFetchSize(0)
+ ,m_nRowCount(0)
+ ,m_nPrivileges( Privilege::SELECT )
+ ,m_nPosition(0)
+ ,m_nStartPos(0)
+ ,m_nEndPos(0)
+ ,m_bRowCountFinal(sal_False)
+ ,m_bBeforeFirst(sal_True)
+ ,m_bAfterLast( sal_False )
+ ,m_bUpdated(sal_False)
+ ,m_bModified(_bModified)
+ ,m_bNew(_bNew)
+{
+ 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);
+ Reference< XPropertySet> xProp(_xRs,UNO_QUERY);
+ Reference< XPropertySetInfo > xPropInfo = xProp->getPropertySetInfo();
+ sal_Bool bBookmarkable = xPropInfo->hasPropertyByName(PROPERTY_ISBOOKMARKABLE) &&
+ any2bool(xProp->getPropertyValue(PROPERTY_ISBOOKMARKABLE)) && Reference< XRowLocate >(_xRs, UNO_QUERY).is();
+ if ( bBookmarkable )
+ {
+ 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& ex)
+ {
+ (void)ex;
+ }
+ _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;
+ // first we need a connection
+ Reference< XStatement> xStmt(_xRs->getStatement(),UNO_QUERY);
+ if(xStmt.is())
+ xConnection = xStmt->getConnection();
+ else
+ {
+ Reference< XPreparedStatement> xPrepStmt(_xRs->getStatement(),UNO_QUERY);
+ xConnection = xPrepStmt->getConnection();
+ }
+ OSL_ENSURE(xConnection.is(),"No connection!");
+ if(_xAnalyzer.is())
+ {
+ try
+ {
+ Reference<XTablesSupplier> xTabSup(_xAnalyzer,UNO_QUERY);
+ OSL_ENSURE(xTabSup.is(),"ORowSet::execute composer isn't a tablesupplier!");
+ Reference<XNameAccess> xTables = xTabSup->getTables();
+ 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&)
+ {
+ // DBG_UNHANDLED_EXCEPTION();
+ }
+ m_pCacheSet = NULL;
+ m_xCacheSet.clear();
+ }
+ else
+ {
+ 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;
+ }
+ 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<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> 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();
+ }
+ }
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ }
+
+ // first check if resultset is bookmarkable
+ if(!bNeedKeySet)
+ {
+ try
+ {
+ m_pCacheSet = new OBookmarkSet();
+ m_xCacheSet = m_pCacheSet;
+ m_pCacheSet->construct(_xRs,i_sRowSetFilter);
+
+ // check privileges
+ m_nPrivileges = Privilege::SELECT;
+ if(Reference<XResultSetUpdate>(_xRs,UNO_QUERY).is()) // this interface is optional so we have to check it
+ {
+ Reference<XPropertySet> xTable(m_aUpdateTable,UNO_QUERY);
+ if(xTable.is() && xTable->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES))
+ {
+ m_nPrivileges = 0;
+ xTable->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
+ if(!m_nPrivileges)
+ m_nPrivileges = Privilege::SELECT;
+ }
+ }
+ }
+ catch(const SQLException&)
+ {
+ bNeedKeySet = sal_True;
+ }
+
+ }
+ if(bNeedKeySet)
+ {
+ // need to check if we could handle this select clause
+ bAllKeysFound = bAllKeysFound && (nTablesCount == 1 || checkJoin(xConnection,_xAnalyzer,aUpdateTableName));
+
+ // || !(comphelper::hasProperty(PROPERTY_CANUPDATEINSERTEDROWS,xProp) && any2bool(xProp->getPropertyValue(PROPERTY_CANUPDATEINSERTEDROWS)))
+
+ // oj removed because keyset uses only the next// || (xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_RESULTSETTYPE) && comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETTYPE)) == ResultSetType::FORWARD_ONLY)
+ if(!bAllKeysFound )
+ {
+ m_pCacheSet = new OStaticSet();
+ m_xCacheSet = m_pCacheSet;
+ m_pCacheSet->construct(_xRs,i_sRowSetFilter);
+ m_nPrivileges = Privilege::SELECT;
+ }
+ else
+ {
+ Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
+ SelectColumnsMetaData aColumnNames(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() ? true : false);
+ Reference<XColumnsSupplier> xColSup(_xAnalyzer,UNO_QUERY);
+ Reference<XNameAccess> xSelColumns = xColSup->getColumns();
+ Reference<XNameAccess> xColumns = m_aUpdateTable->getColumns();
+ ::dbaccess::getColumnPositions(xSelColumns,xColumns->getElementNames(),aUpdateTableName,aColumnNames);
+
+ // check privileges
+ m_nPrivileges = Privilege::SELECT;
+ sal_Bool bNoInsert = sal_False;
+
+ Sequence< ::rtl::OUString> aNames(xColumns->getElementNames());
+ const ::rtl::OUString* pIter = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aNames.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ Reference<XPropertySet> xColumn(xColumns->getByName(*pIter),UNO_QUERY);
+ OSL_ENSURE(xColumn.is(),"Column in table is null!");
+ if(xColumn.is())
+ {
+ sal_Int32 nNullable = 0;
+ xColumn->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullable;
+ if(nNullable == ColumnValue::NO_NULLS && aColumnNames.find(*pIter) == aColumnNames.end())
+ { // we found a column where null is not allowed so we can't insert new values
+ bNoInsert = sal_True;
+ break; // one column is enough
+ }
+ }
+ }
+
+ OKeySet* pKeySet = new OKeySet(m_aUpdateTable,xUpdateTableKeys,aUpdateTableName ,_xAnalyzer,_aParameterValueForCache);
+ try
+ {
+ m_pCacheSet = pKeySet;
+ m_xCacheSet = m_pCacheSet;
+ pKeySet->construct(_xRs,i_sRowSetFilter);
+
+ if(Reference<XResultSetUpdate>(_xRs,UNO_QUERY).is()) // this interface is optional so we have to check it
+ {
+ Reference<XPropertySet> xTable(m_aUpdateTable,UNO_QUERY);
+ if(xTable.is() && xTable->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES))
+ {
+ m_nPrivileges = 0;
+ xTable->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
+ if(!m_nPrivileges)
+ m_nPrivileges = Privilege::SELECT;
+ }
+ }
+ if(bNoInsert)
+ m_nPrivileges |= ~Privilege::INSERT; // remove the insert privilege
+ }
+ catch(const SQLException&)
+ {
+ // we couldn't create a keyset here so we have to create a static cache
+ if ( m_pCacheSet )
+ m_pCacheSet = NULL;
+ m_xCacheSet = NULL;
+ m_pCacheSet = new OStaticSet();
+ m_xCacheSet = m_pCacheSet;
+ m_pCacheSet->construct(_xRs,i_sRowSetFilter);
+ m_nPrivileges = Privilege::SELECT;
+ }
+ }
+
+ }
+ // last check
+ if(!bAllKeysFound && xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_RESULTSETCONCURRENCY) &&
+ ::comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETCONCURRENCY)) == ResultSetConcurrency::READ_ONLY)
+ m_nPrivileges = Privilege::SELECT;
+}
+
+// -------------------------------------------------------------------------
+ORowSetCache::~ORowSetCache()
+{
+ m_pCacheSet = NULL;
+ m_xCacheSet = NULL;
+ if(m_pMatrix)
+ {
+ m_pMatrix->clear();
+ delete m_pMatrix;
+ }
+
+ if(m_pInsertMatrix)
+ {
+ m_pInsertMatrix->clear();
+ delete m_pInsertMatrix;
+ }
+ m_xSet = WeakReference< XResultSet>();
+ m_xMetaData = NULL;
+ m_aUpdateTable = NULL;
+
+ DBG_DTOR(ORowSetCache,NULL);
+}
+
+// -------------------------------------------------------------------------
+void ORowSetCache::setMaxRowSize(sal_Int32 _nSize)
+{
+
+ if(_nSize == m_nFetchSize)
+ return;
+
+ m_nFetchSize = _nSize;
+ if(!m_pMatrix)
+ {
+ m_pMatrix = new ORowSetMatrix(_nSize);
+ m_aMatrixIter = m_pMatrix->end();
+ m_aMatrixEnd = m_pMatrix->end();
+
+ m_pInsertMatrix = new ORowSetMatrix(1); // a little bit overkill but ??? :-)
+ m_aInsertRow = m_pInsertMatrix->end();
+ }
+ else
+ {
+ // now correct the iterator in our iterator vector
+ ::std::vector<sal_Int32> aPositions;
+ ::std::map<sal_Int32,sal_Bool> aCacheIterToChange;
+ // first get the positions where they stand now
+ ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
+ ORowSetCacheMap::iterator aCacheEnd = m_aCacheIterators.end();
+ for(;aCacheIter != aCacheEnd;++aCacheIter)
+ {
+ aCacheIterToChange[aCacheIter->first] = sal_False;
+ if ( !aCacheIter->second.pRowSet->isInsertRow()
+ /*&& aCacheIter->second.aIterator != m_pMatrix->end()*/ && !m_bModified )
+ {
+ ptrdiff_t nDist = (aCacheIter->second.aIterator - m_pMatrix->begin());
+ aPositions.push_back(nDist);
+ aCacheIterToChange[aCacheIter->first] = sal_True;
+ }
+ }
+ sal_Int32 nKeyPos = (m_aMatrixIter - m_pMatrix->begin());
+ m_pMatrix->resize(_nSize);
+
+ if ( nKeyPos < _nSize )
+ m_aMatrixIter = m_pMatrix->begin() + nKeyPos;
+ else
+ m_aMatrixIter = m_pMatrix->end();
+ m_aMatrixEnd = m_pMatrix->end();
+
+ // now adjust their positions because a resize invalid all iterators
+ ::std::vector<sal_Int32>::const_iterator aIter = aPositions.begin();
+ ::std::map<sal_Int32,sal_Bool>::const_iterator aPosChangeIter = aCacheIterToChange.begin();
+ for( aCacheIter = m_aCacheIterators.begin();
+ aPosChangeIter != aCacheIterToChange.end();
+ ++aPosChangeIter,++aCacheIter)
+ {
+ if ( aPosChangeIter->second )
+ {
+ CHECK_MATRIX_POS(*aIter);
+ if ( *aIter < _nSize )
+ aCacheIter->second.aIterator = m_pMatrix->begin() + *aIter++;
+ else
+ aCacheIter->second.aIterator = m_pMatrix->end();
+ }
+ }
+ }
+ if(!m_nPosition)
+ {
+ sal_Int32 nNewSt = 1;
+ fillMatrix(nNewSt,_nSize+1);
+ m_nStartPos = 0;
+ m_nEndPos = _nSize;
+ }
+}
+// -------------------------------------------------------------------------
+
+// XResultSetMetaDataSupplier
+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( )
+{
+
+ if(m_bAfterLast)
+ throwFunctionSequenceException(m_xSet.get());
+
+ if ( m_aMatrixIter >= m_pMatrix->end() || m_aMatrixIter < m_pMatrix->begin() || !(*m_aMatrixIter).isValid())
+ {
+ return Any(); // this is allowed here because the rowset knowns what it is doing
+ }
+
+ return lcl_getBookmark(((*m_aMatrixIter)->get())[0],m_pCacheSet);
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::moveToBookmark( const Any& bookmark )
+{
+ if ( m_pCacheSet->moveToBookmark(bookmark) )
+ {
+ m_bBeforeFirst = sal_False;
+ m_nPosition = m_pCacheSet->getRow();
+
+ checkPositionFlags();
+
+ if(!m_bAfterLast)
+ {
+ moveWindow();
+ checkPositionFlags();
+ if ( !m_bAfterLast )
+ {
+ m_aMatrixIter = calcPosition();
+ OSL_ENSURE(m_aMatrixIter->isValid(),"Iterator after moveToBookmark not valid");
+ }
+ else
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ else
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ else
+ return sal_False;
+
+ return m_aMatrixIter != m_pMatrix->end() && (*m_aMatrixIter).isValid();
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows )
+{
+ sal_Bool bRet( moveToBookmark( bookmark ) );
+ if ( bRet )
+ {
+ m_nPosition = m_pCacheSet->getRow() + rows;
+ absolute(m_nPosition);
+ // for(sal_Int32 i=0;i<rows && m_aMatrixIter != m_pMatrix->end();++i,++m_aMatrixIter) ;
+
+ bRet = m_aMatrixIter != m_pMatrix->end() && (*m_aMatrixIter).isValid();
+ }
+
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Int32 ORowSetCache::compareBookmarks( const Any& _first, const Any& _second )
+{
+ return (!_first.hasValue() || !_second.hasValue()) ? CompareBookmark::NOT_COMPARABLE : m_pCacheSet->compareBookmarks(_first,_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,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].setNull();
+ rInsert[columnIndex].setModified();
+ io_aRow[columnIndex].setNull();
+
+ m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns);
+ impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns);
+}
+// -----------------------------------------------------------------------------
+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];
+
+ 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,ORowSetValueVector::Vector& io_aRow
+ ,::std::vector<sal_Int32>& o_ChangedColumns
+ )
+{
+ checkUpdateConditions(columnIndex);
+
+ Sequence<sal_Int8> aSeq;
+ if(x.is())
+ x->readBytes(aSeq,length);
+
+ 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
+ ,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_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*/
+ ,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_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;
+ ++m_nPosition;
+
+ // after we increment the position we have to check if we are already after the last row
+ checkPositionFlags();
+ if(!m_bAfterLast)
+ {
+ moveWindow();
+
+ OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ m_aMatrixIter = calcPosition();
+ checkPositionFlags();
+ }
+ }
+
+ return !m_bAfterLast;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::isBeforeFirst( )
+{
+ // return !m_nPosition;
+
+ return m_bBeforeFirst;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::isAfterLast( )
+{
+
+ return m_bAfterLast;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::isFirst( )
+{
+
+ return m_nPosition == 1; // ask resultset for
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::isLast( )
+{
+ // return m_bRowCountFinal ? (m_nPosition==m_nRowCount) : m_pCacheSet->isLast();
+
+ return m_nPosition == m_nRowCount;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::beforeFirst( )
+{
+
+
+ if(!m_bBeforeFirst)
+ {
+ m_bAfterLast = sal_False;
+ m_nPosition = 0;
+ m_bBeforeFirst = sal_True;
+ m_pCacheSet->beforeFirst();
+ moveWindow();
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::afterLast( )
+{
+
+
+ if(!m_bAfterLast)
+ {
+ m_bBeforeFirst = sal_False;
+ m_bAfterLast = sal_True;
+
+ if(!m_bRowCountFinal)
+ {
+ m_pCacheSet->last();
+ m_bRowCountFinal = sal_True;
+ m_nRowCount = m_pCacheSet->getRow();// + 1 removed
+ }
+ m_pCacheSet->afterLast();
+
+ m_nPosition = 0;
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos)
+{
+ OSL_ENSURE(_nNewStartPos != _nNewEndPos,"ORowSetCache::fillMatrix: StartPos and EndPos can not be equal!");
+ // fill the whole window with new data
+ ORowSetMatrix::iterator aIter = m_pMatrix->begin();
+ sal_Bool bCheck = m_pCacheSet->absolute(_nNewStartPos); // -1 no need to
+
+ sal_Int32 i=_nNewStartPos;
+ for(;i<_nNewEndPos;++i,++aIter)
+ {
+ if(bCheck)
+ {
+ if(!aIter->isValid())
+ *aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
+ m_pCacheSet->fillValueRow(*aIter,i);
+ }
+ else
+ { // there are no more rows found so we can fetch some before start
+
+ if(!m_bRowCountFinal)
+ {
+ if(m_pCacheSet->previous()) // because we stand after the last row
+ m_nRowCount = m_pCacheSet->getRow(); // here we have the row count
+ if(!m_nRowCount)
+ m_nRowCount = i-1; // it can be that getRow return zero
+ m_bRowCountFinal = sal_True;
+ }
+ if(m_nRowCount > m_nFetchSize)
+ {
+ ORowSetMatrix::iterator aEnd = aIter;
+ ORowSetMatrix::iterator aRealEnd = m_pMatrix->end();
+ sal_Int32 nPos = m_nRowCount - m_nFetchSize + 1;
+ _nNewStartPos = nPos;
+ bCheck = m_pCacheSet->absolute(_nNewStartPos);
+
+ for(;bCheck && aIter != aRealEnd;++aIter)
+ {
+ if(bCheck)
+ {
+ if(!aIter->isValid())
+ *aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
+ m_pCacheSet->fillValueRow(*aIter,nPos++);
+ }
+ bCheck = m_pCacheSet->next();
+ }
+ if(aIter != aEnd)
+ ::std::rotate(m_pMatrix->begin(),aEnd,aRealEnd);
+ }
+ break;
+ }
+ bCheck = m_pCacheSet->next();
+ }
+ // m_nStartPos = _nNewStartPos;
+ // we have to read one row forward to enshure that we know when we are on last row
+ // but only when we don't know it already
+ if(!m_bRowCountFinal)
+ {
+ if(!m_pCacheSet->next())
+ {
+ if(m_pCacheSet->previous()) // because we stand after the last row
+ m_nRowCount = m_pCacheSet->getRow(); // here we have the row count
+ m_bRowCountFinal = sal_True;
+ }
+ else
+ m_nRowCount = std::max(i,m_nRowCount);
+
+ }
+ return bCheck;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::moveWindow()
+{
+
+ sal_Bool bRet = sal_True;
+
+ sal_Int32 nDiff = (sal_Int32)(m_nFetchSize*0.5 -0.5);
+ sal_Int32 nNewStartPos = (m_nPosition - nDiff);
+ // sal_Int32 nNewEndPos = (m_nPosition+m_nFetchSize*0.5);
+ sal_Int32 nNewEndPos = nNewStartPos + m_nFetchSize;
+
+ if ( m_nPosition <= m_nStartPos )
+ { // the window is behind the new start pos
+ if(!m_nStartPos)
+ return sal_False;
+ // the new position should be the nPos - nFetchSize/2
+ if ( nNewEndPos > m_nStartPos )
+ { // but the two regions are overlapping
+ // fill the rows behind the new end
+
+ ORowSetMatrix::iterator aEnd; // the iterator we need for rotate
+ ORowSetMatrix::iterator aIter; // the iterator we fill with new values
+
+ sal_Bool bCheck = sal_True;
+ if ( nNewStartPos < 1 )
+ {
+ bCheck = m_pCacheSet->first();
+ // aEnd = m_pMatrix->begin() + (sal_Int32)(m_nFetchSize*0.5);
+ OSL_ENSURE((nNewEndPos - m_nStartPos - nNewStartPos) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ aEnd = m_pMatrix->begin() + (nNewEndPos - m_nStartPos - nNewStartPos);
+ aIter = aEnd;
+ m_nStartPos = 0;
+ }
+ else
+ {
+ OSL_ENSURE((nNewEndPos - m_nStartPos -1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ aEnd = m_pMatrix->begin() + ((nNewEndPos - m_nStartPos)-1);
+ aIter = m_pMatrix->begin() + ((nNewEndPos - m_nStartPos)-1);
+ bCheck = m_pCacheSet->absolute(nNewStartPos);
+ m_nStartPos = nNewStartPos -1;
+ }
+
+ if ( bCheck )
+ {
+ sal_Int32 nPos = m_nStartPos;
+ bCheck = fill(aIter,m_pMatrix->end(),nPos,bCheck);
+
+ ::std::rotate(m_pMatrix->begin(),aEnd,m_pMatrix->end());
+ // now correct the iterator in our iterator vector
+ // rotateCacheIterator(aEnd-m_pMatrix->begin()); //can't be used because they decrement and here we need to increment
+ ptrdiff_t nNewDist = aEnd - m_pMatrix->begin();
+ ptrdiff_t nOffSet = m_pMatrix->end() - aEnd;
+ ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
+ ORowSetCacheMap::iterator aCacheEnd = m_aCacheIterators.end();
+ for(;aCacheIter != aCacheEnd;++aCacheIter)
+ {
+ if ( !aCacheIter->second.pRowSet->isInsertRow()
+ && aCacheIter->second.aIterator != m_pMatrix->end() && !m_bModified )
+ {
+ ptrdiff_t nDist = (aCacheIter->second.aIterator - m_pMatrix->begin());
+ if ( nDist >= nNewDist )
+ {
+ aCacheIter->second.aIterator = m_pMatrix->end();
+ }
+ else
+ {
+#if OSL_DEBUG_LEVEL > 0
+ ORowSetMatrix::iterator aOldPos;
+ aOldPos = aCacheIter->second.aIterator;
+#endif
+ CHECK_MATRIX_POS( ((aOldPos - m_pMatrix->begin()) + nOffSet) );
+ aCacheIter->second.aIterator += nOffSet;
+#if OSL_DEBUG_LEVEL > 0
+ ORowSetMatrix::iterator aCurrentPos;
+ aCurrentPos = aCacheIter->second.aIterator;
+#endif
+ OSL_ENSURE(aCacheIter->second.aIterator >= m_pMatrix->begin()
+ && aCacheIter->second.aIterator < m_pMatrix->end(),"Iterator out of area!");
+ }
+ }
+ }
+ }
+ else
+ { // normaly this should never happen
+ OSL_ENSURE(0,"What the hell is happen here!");
+ return sal_False;
+ }
+ }
+ else
+ {// no rows can be reused so fill again
+ if(nNewStartPos < 1) // special case
+ {
+ m_nStartPos = 0;
+
+ rotateCacheIterator(static_cast<sal_Int16>(m_nFetchSize+1)); // static_cast<sal_Int16>(m_nFetchSize+1)
+
+ m_pCacheSet->beforeFirst();
+
+ sal_Bool bCheck;
+ ORowSetMatrix::iterator aIter = m_pMatrix->begin();
+ for(sal_Int32 i=0;i<m_nFetchSize;++i,++aIter)
+ {
+ bCheck = m_pCacheSet->next();
+ if ( bCheck )
+ {
+ if(!aIter->isValid())
+ *aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
+ m_pCacheSet->fillValueRow(*aIter,i+1);
+ }
+ else
+ *aIter = NULL;
+ }
+ }
+ else
+ bRet = reFillMatrix(nNewStartPos,nNewEndPos);
+ }
+ }
+ else if(m_nPosition > m_nStartPos)
+ { // the new start pos is above the startpos of the window
+
+ if(m_nPosition <= (m_nStartPos+m_nFetchSize))
+ { // position in window
+ OSL_ENSURE((m_nPosition - m_nStartPos -1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ m_aMatrixIter = calcPosition();
+ if(!m_aMatrixIter->isValid())
+ {
+ sal_Bool bOk( m_pCacheSet->absolute( m_nPosition ) );
+ if ( bOk )
+ {
+ *m_aMatrixIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
+ m_pCacheSet->fillValueRow(*m_aMatrixIter,m_nPosition);
+ // we have to read one row forward to ensure that we know when we are on last row
+ // but only when we don't know it already
+ if ( !m_bRowCountFinal )
+ {
+ bOk = m_pCacheSet->absolute( m_nPosition + 1 );
+ if ( bOk )
+ m_nRowCount = std::max(sal_Int32(m_nPosition+1),m_nRowCount);
+ }
+ }
+ if(!bOk)
+ {
+ if(!m_bRowCountFinal)
+ {
+ // because we stand after the last row
+ m_nRowCount = m_pCacheSet->previous() ? m_pCacheSet->getRow() : 0;// + 1 removed
+ m_bRowCountFinal = sal_True;
+ }
+ }
+ }
+ }
+ else if(nNewStartPos < (m_nStartPos+m_nFetchSize))
+ { // position behind window but the region is overlapping
+ // the rows from begin() to (begin + nNewStartPos - m_nStartPos) can be refilled with the new rows
+ // the rows behind this can be reused
+ ORowSetMatrix::iterator aIter = m_pMatrix->begin();
+ CHECK_MATRIX_POS(nNewStartPos - m_nStartPos - 1);
+ ORowSetMatrix::iterator aEnd = m_pMatrix->begin() + (nNewStartPos - m_nStartPos - 1);
+
+ sal_Int32 nPos = m_nStartPos + m_nFetchSize + 1;
+ sal_Bool bCheck = m_pCacheSet->absolute(nPos);
+ bCheck = fill(aIter,aEnd,nPos,bCheck); // refill the region wew don't need anymore
+
+// // we know that this is the current maximal rowcount here
+// if ( !m_bRowCountFinal && bCheck )
+// m_nRowCount = std::max(nPos,m_nRowCount);
+ // we have to read one row forward to enshure that we know when we are on last row
+ // but only when we don't know it already
+ sal_Bool bOk = sal_True;
+ if(bCheck && !m_bRowCountFinal)
+ bOk = m_pCacheSet->next();
+ // bind end to front
+ if(bCheck)
+ { // rotate the end to the front
+ ::std::rotate(m_pMatrix->begin(),aIter,m_pMatrix->end());
+ // now correct the iterator in our iterator vector
+ rotateCacheIterator( (sal_Int16)( aIter - m_pMatrix->begin() ) );
+ m_nStartPos = nNewStartPos - 1; // must be -1
+ // now I can say how many rows we have
+ if(!bOk)
+ {
+ m_pCacheSet->previous(); // because we stand after the last row
+ m_nRowCount = nPos; // here we have the row count
+ m_bRowCountFinal = sal_True;
+ }
+ else if(!m_bRowCountFinal)
+ m_nRowCount = std::max(++nPos,m_nRowCount);
+ }
+ else
+ { // the end was reached before end() so we can set the start before nNewStartPos
+
+ m_nStartPos += (aIter - m_pMatrix->begin());
+ // m_nStartPos = (aIter - m_pMatrix->begin());
+ ::std::rotate(m_pMatrix->begin(),aIter,m_pMatrix->end());
+ // now correct the iterator in our iterator vector
+ rotateCacheIterator( (sal_Int16)( aIter - m_pMatrix->begin() ) );
+
+ if ( !m_bRowCountFinal )
+ {
+ m_pCacheSet->previous(); // because we stand after the last row
+ m_nRowCount = std::max(m_nRowCount,--nPos); // here we have the row count
+ OSL_ENSURE(nPos == m_pCacheSet->getRow(),"nPos isn't valid!");
+ m_bRowCountFinal = sal_True;
+ }
+ // TODO check
+ // m_nStartPos = (nNewStartPos+m_nRowCount) - m_nFetchSize ;
+ if(m_nStartPos < 0)
+ m_nStartPos = 0;
+ }
+ // here we need only to check if the begining row is valid. If not we have to fetch it.
+ if(!m_pMatrix->begin()->isValid())
+ {
+ aIter = m_pMatrix->begin();
+
+ nPos = m_nStartPos;
+ bCheck = m_pCacheSet->absolute(m_nStartPos);
+ for(; !aIter->isValid() && bCheck;++aIter)
+ {
+ OSL_ENSURE(aIter != m_pMatrix->end(),"Invalid iterator");
+ bCheck = m_pCacheSet->next();
+ if ( bCheck ) // resultset stands on right position
+ {
+ *aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
+ m_pCacheSet->fillValueRow(*aIter,++nPos);
+ }
+ }
+ }
+ }
+ else // no rows can be reused so fill again
+ bRet = reFillMatrix(nNewStartPos,nNewEndPos);
+ }
+
+ if(!m_bRowCountFinal)
+ m_nRowCount = std::max(m_nPosition,m_nRowCount);
+ OSL_ENSURE(m_nStartPos >= 0,"ORowSetCache::moveWindow: m_nStartPos is less than 0!");
+
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::first( )
+{
+ // first move to the first row
+ // then check if the cache window is at the begining
+ // when not postionize the window and fill it with data
+ // smart moving of the window -> clear only the rows whom are out of range
+ sal_Bool bRet = m_pCacheSet->first();
+ if(bRet)
+ {
+ m_bBeforeFirst = m_bAfterLast = sal_False;
+ m_nPosition = 1;
+ moveWindow();
+ m_aMatrixIter = m_pMatrix->begin();
+ }
+ else
+ {
+ m_bRowCountFinal = m_bBeforeFirst = m_bAfterLast = sal_True;
+ m_nRowCount = m_nPosition = 0;
+
+ OSL_ENSURE(m_bBeforeFirst || m_bNew,"ORowSetCache::first return false and BeforeFirst isn't true");
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::last( )
+{
+ sal_Bool bRet = m_pCacheSet->last();
+ if(bRet)
+ {
+ m_bBeforeFirst = m_bAfterLast = sal_False;
+ if(!m_bRowCountFinal)
+ {
+ m_bRowCountFinal = sal_True;
+ m_nRowCount = m_nPosition = m_pCacheSet->getRow(); // not + 1
+ }
+ m_nPosition = m_pCacheSet->getRow();
+ moveWindow();
+ // we have to repositioning because moveWindow can modify the cache
+ m_pCacheSet->last();
+// if(m_nPosition > m_nFetchSize)
+// m_aMatrixIter = m_pMatrix->end() -1;
+// else
+// m_aMatrixIter = m_pMatrix->begin() + m_nPosition - 1;
+ OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ m_aMatrixIter = calcPosition();
+ }
+ else
+ {
+ m_bRowCountFinal = m_bBeforeFirst = m_bAfterLast = sal_True;
+ m_nRowCount = m_nPosition = 0;
+ OSL_ENSURE(m_bBeforeFirst,"ORowSetCache::last return false and BeforeFirst isn't true");
+ m_aMatrixIter = m_pMatrix->end();
+ }
+#if OSL_DEBUG_LEVEL > 1
+ if(bRet)
+ {
+ OSL_ENSURE((*m_aMatrixIter).isValid(),"ORowSetCache::last: Row not valid!");
+ }
+#endif
+
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Int32 ORowSetCache::getRow( )
+{
+ return (isBeforeFirst() || isAfterLast()) ? 0 : m_nPosition;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::absolute( sal_Int32 row )
+{
+ if(!row )
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NO_ABS_ZERO),NULL,SQLSTATE_GENERAL,1000,Any() );
+
+ if(row < 0)
+ {
+ // here we have to scroll from the last row to backward so we have to go to last row and
+ // and two the previous
+ if(m_bRowCountFinal || last())
+ {
+ m_nPosition = m_nRowCount + row + 1; // + row because row is negative and +1 because row==-1 means last row
+ if(m_nPosition < 1)
+ {
+ m_bBeforeFirst = sal_True;
+ m_bAfterLast = sal_False;
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ else
+ {
+ m_bBeforeFirst = sal_False;
+ m_bAfterLast = m_nPosition > m_nRowCount;
+ moveWindow();
+ OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ m_aMatrixIter = calcPosition();
+ }
+ }
+ else
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ else
+ {
+ m_nPosition = row;
+ // the position flags
+ m_bBeforeFirst = sal_False;
+ checkPositionFlags();
+
+ if(!m_bAfterLast)
+ {
+ moveWindow();
+ checkPositionFlags();
+ if(!m_bAfterLast)
+ m_aMatrixIter = calcPosition();
+ else
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ else
+ m_aMatrixIter = m_pMatrix->end();
+ }
+
+ return !(m_bAfterLast || m_bBeforeFirst);
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::relative( sal_Int32 rows )
+{
+ sal_Bool bErg = sal_True;
+ if(rows)
+ {
+ sal_Int32 nNewPosition = m_nPosition + rows;
+
+ if ( m_bBeforeFirst && rows > 0 )
+ nNewPosition = rows;
+ else if ( m_bRowCountFinal && m_bAfterLast && rows < 0 )
+ nNewPosition = m_nRowCount + 1 + rows;
+ else
+ if ( m_bBeforeFirst || ( m_bRowCountFinal && m_bAfterLast ) )
+ throw SQLException( DBACORE_RESSTRING( RID_STR_NO_RELATIVE ), NULL, SQLSTATE_GENERAL, 1000, Any() );
+ if ( nNewPosition )
+ {
+ bErg = absolute( nNewPosition );
+ bErg = bErg && !isAfterLast() && !isBeforeFirst();
+ }
+ else
+ {
+ m_bBeforeFirst = sal_True;
+ bErg = sal_False;
+ }
+ }
+ return bErg;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::previous( )
+{
+ sal_Bool bRet = sal_False;
+ if(!isBeforeFirst())
+ {
+ if(m_bAfterLast) // we stand after the last row so one before is the last row
+ bRet = last();
+ else
+ {
+ m_bAfterLast = sal_False;
+ --m_nPosition;
+ moveWindow();
+ OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+
+ checkPositionFlags();
+
+ if(!m_nPosition)
+ {
+ m_bBeforeFirst = sal_True;
+ m_aMatrixIter = m_pMatrix->end();
+ }
+ else
+ {
+ m_aMatrixIter = calcPosition();
+ bRet = (*m_aMatrixIter).isValid();
+ }
+ }
+ }
+ return bRet;
+}
+// -------------------------------------------------------------------------
+void ORowSetCache::refreshRow( )
+{
+ if(isAfterLast())
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NO_REFESH_AFTERLAST),NULL,SQLSTATE_GENERAL,1000,Any() );
+ OSL_ENSURE(m_aMatrixIter != m_pMatrix->end(),"refreshRow() called for invalid row!");
+ m_pCacheSet->refreshRow();
+ m_pCacheSet->fillValueRow(*m_aMatrixIter,m_nPosition);
+ if ( m_bNew )
+ {
+ cancelRowModification();
+ }
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::rowUpdated( )
+{
+ return m_pCacheSet->rowUpdated();
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetCache::rowInserted( )
+{
+ return m_pCacheSet->rowInserted();
+}
+// -------------------------------------------------------------------------
+// XResultSetUpdate
+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() );
+
+ m_pCacheSet->insertRow(*m_aInsertRow,m_aUpdateTable);
+
+ sal_Bool bRet( rowInserted() );
+ if ( bRet )
+ {
+ ++m_nRowCount;
+ 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!");
+ }
+ }
+ return bRet;
+}
+// -------------------------------------------------------------------------
+void ORowSetCache::resetInsertRow(sal_Bool _bClearInsertRow)
+{
+ if ( _bClearInsertRow )
+ clearInsertRow();
+ m_bNew = sal_False;
+ m_bModified = sal_False;
+}
+// -------------------------------------------------------------------------
+void ORowSetCache::cancelRowModification()
+{
+ // clear the insertrow references -> implies that the current row of the rowset changes as well
+ ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
+ ORowSetCacheMap::iterator aCacheEnd = m_aCacheIterators.end();
+ for(;aCacheIter != aCacheEnd;++aCacheIter)
+ {
+ if ( aCacheIter->second.pRowSet->isInsertRow() && aCacheIter->second.aIterator == m_aInsertRow )
+ aCacheIter->second.aIterator = m_pMatrix->end();
+ } // for(;aCacheIter != aCacheEnd;++aCacheIter)
+ resetInsertRow(sal_False);
+}
+// -------------------------------------------------------------------------
+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() );
+
+ Any aBookmark = ((*_rUpdateRow)->get())[0].makeAny();
+ OSL_ENSURE(aBookmark.hasValue(),"Bookmark must have a value!");
+ // here we don't have to reposition our CacheSet, when we try to update a row,
+ // the row was already fetched
+ moveToBookmark(aBookmark);
+ m_pCacheSet->updateRow(*_rUpdateRow,*m_aMatrixIter,m_aUpdateTable);
+ // refetch the whole row
+ (*m_aMatrixIter) = NULL;
+
+ 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));
+ }
+ }
+ }
+
+ m_bModified = sal_False;
+}
+// -------------------------------------------------------------------------
+bool ORowSetCache::deleteRow( )
+{
+ if(isAfterLast() || isBeforeFirst())
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NO_DELETEROW),NULL,SQLSTATE_GENERAL,1000,Any() );
+
+ // m_pCacheSet->absolute(m_nPosition);
+ m_pCacheSet->deleteRow(*m_aMatrixIter,m_aUpdateTable);
+ if ( !m_pCacheSet->rowDeleted() )
+ return false;
+
+ --m_nRowCount;
+ OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
+ ORowSetMatrix::iterator aPos = calcPosition();
+ (*aPos) = NULL;
+
+ ORowSetMatrix::iterator aEnd = m_pMatrix->end();
+ for(++aPos;aPos != aEnd && aPos->isValid();++aPos)
+ {
+ *(aPos-1) = *aPos;
+ (*aPos) = NULL;
+ }
+ m_aMatrixIter = m_pMatrix->end();
+
+ --m_nPosition;
+ return true;
+}
+// -------------------------------------------------------------------------
+void ORowSetCache::cancelRowUpdates( )
+{
+ m_bNew = m_bModified = sal_False;
+ if(!m_nPosition)
+ {
+ OSL_ENSURE(0,"cancelRowUpdates:Invalid positions pos == 0");
+ ::dbtools::throwFunctionSequenceException(NULL);
+ }
+
+ if(m_pCacheSet->absolute(m_nPosition))
+ m_pCacheSet->fillValueRow(*m_aMatrixIter,m_nPosition);
+ else
+ {
+ OSL_ENSURE(0,"cancelRowUpdates couldn't position right with absolute");
+ ::dbtools::throwFunctionSequenceException(NULL);
+ }
+}
+// -------------------------------------------------------------------------
+void ORowSetCache::moveToInsertRow( )
+{
+ m_bNew = sal_True;
+ m_bUpdated = m_bAfterLast = sal_False;
+
+ m_aInsertRow = m_pInsertMatrix->begin();
+ if(!m_aInsertRow->isValid())
+ *m_aInsertRow = new ORowSetValueVector(m_xMetaData->getColumnCount());
+
+ // we don't unbound the bookmark column
+ ORowSetValueVector::Vector::iterator aIter = (*m_aInsertRow)->get().begin()+1;
+ ORowSetValueVector::Vector::iterator aEnd = (*m_aInsertRow)->get().end();
+ for(sal_Int32 i = 1;aIter != aEnd;++aIter,++i)
+ {
+ aIter->setBound(sal_False);
+ aIter->setModified(sal_False);
+ aIter->setNull();
+ aIter->setTypeKind(m_xMetaData->getColumnType(i));
+ }
+}
+// -------------------------------------------------------------------------
+ORowSetCacheIterator ORowSetCache::createIterator(ORowSetBase* _pRowSet)
+{
+
+ ORowSetCacheIterator_Helper aHelper;
+ aHelper.aIterator = m_pMatrix->end();
+ aHelper.pRowSet = _pRowSet;
+ return ORowSetCacheIterator(m_aCacheIterators.insert(m_aCacheIterators.begin(),ORowSetCacheMap::value_type(m_aCacheIterators.size()+1,aHelper)),this,_pRowSet);
+}
+// -----------------------------------------------------------------------------
+void ORowSetCache::deleteIterator(const ORowSetBase* _pRowSet)
+{
+ ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
+ for(;aCacheIter != m_aCacheIterators.end();)
+ {
+ if ( aCacheIter->second.pRowSet == _pRowSet )
+ {
+ m_aCacheIterators.erase(aCacheIter);
+ aCacheIter = m_aCacheIterators.begin();
+ } // if ( aCacheIter->second.pRowSet == _pRowSet )
+ else
+ ++aCacheIter;
+ }
+}
+// -----------------------------------------------------------------------------
+void ORowSetCache::rotateCacheIterator(ORowSetMatrix::difference_type _nDist)
+{
+ if(_nDist)
+ {
+ // now correct the iterator in our iterator vector
+ ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
+ ORowSetCacheMap::iterator aCacheEnd = m_aCacheIterators.end();
+ for(;aCacheIter != aCacheEnd;++aCacheIter)
+ {
+ if ( !aCacheIter->second.pRowSet->isInsertRow()
+ && aCacheIter->second.aIterator != m_pMatrix->end() && !m_bModified )
+ {
+ ptrdiff_t nDist = (aCacheIter->second.aIterator - m_pMatrix->begin());
+ if(nDist < _nDist)
+ {
+ aCacheIter->second.aIterator = m_pMatrix->end();
+ }
+ else
+ {
+ OSL_ENSURE((aCacheIter->second.aIterator - m_pMatrix->begin()) >= _nDist,"Invalid Dist value!");
+ aCacheIter->second.aIterator -= _nDist;
+ OSL_ENSURE(aCacheIter->second.aIterator >= m_pMatrix->begin()
+ && aCacheIter->second.aIterator < m_pMatrix->end(),"Iterator out of area!");
+ }
+ }
+ }
+ }
+}
+// -------------------------------------------------------------------------
+void ORowSetCache::setUpdateIterator(const ORowSetMatrix::iterator& _rOriginalRow)
+{
+ m_aInsertRow = m_pInsertMatrix->begin();
+ if(!m_aInsertRow->isValid())
+ *m_aInsertRow = new ORowSetValueVector(m_xMetaData->getColumnCount());
+
+ (*(*m_aInsertRow)) = (*(*_rOriginalRow));
+ // we don't unbound the bookmark column
+ ORowSetValueVector::Vector::iterator aIter = (*m_aInsertRow)->get().begin();
+ ORowSetValueVector::Vector::iterator aEnd = (*m_aInsertRow)->get().end();
+ for(;aIter != aEnd;++aIter)
+ aIter->setModified(sal_False);
+}
+// -----------------------------------------------------------------------------
+void ORowSetCache::checkPositionFlags()
+{
+ if(m_bRowCountFinal)
+ {
+ m_bAfterLast = m_nPosition > m_nRowCount;
+ if(m_bAfterLast)
+ m_nPosition = 0;//m_nRowCount;
+ }
+}
+// -----------------------------------------------------------------------------
+void ORowSetCache::checkUpdateConditions(sal_Int32 columnIndex)
+{
+ if(m_bAfterLast || columnIndex >= (sal_Int32)(*m_aInsertRow)->get().size())
+ throwFunctionSequenceException(m_xSet.get());
+}
+//------------------------------------------------------------------------------
+sal_Bool ORowSetCache::checkInnerJoin(const ::connectivity::OSQLParseNode *pNode,const Reference< XConnection>& _xConnection,const ::rtl::OUString& _sUpdateTableName)
+{
+ sal_Bool bOk = sal_False;
+ if (pNode->count() == 3 && // Ausdruck is geklammert
+ SQL_ISPUNCTUATION(pNode->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pNode->getChild(2),")"))
+ {
+ bOk = checkInnerJoin(pNode->getChild(1),_xConnection,_sUpdateTableName);
+ }
+ else if ((SQL_ISRULE(pNode,search_condition) || SQL_ISRULE(pNode,boolean_term)) && // AND/OR-Verknuepfung:
+ pNode->count() == 3)
+ {
+ // nur AND Verknüpfung zulassen
+ if ( SQL_ISTOKEN(pNode->getChild(1),AND) )
+ bOk = checkInnerJoin(pNode->getChild(0),_xConnection,_sUpdateTableName)
+ && checkInnerJoin(pNode->getChild(2),_xConnection,_sUpdateTableName);
+ }
+ else if (SQL_ISRULE(pNode,comparison_predicate))
+ {
+ // only the comparison of columns is allowed
+ DBG_ASSERT(pNode->count() == 3,"checkInnerJoin: Fehler im Parse Tree");
+ if (!(SQL_ISRULE(pNode->getChild(0),column_ref) &&
+ SQL_ISRULE(pNode->getChild(2),column_ref) &&
+ pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL))
+ {
+ bOk = sal_False;
+ }
+ ::rtl::OUString sColumnName,sTableRange;
+ OSQLParseTreeIterator::getColumnRange( pNode->getChild(0), _xConnection, sColumnName, sTableRange );
+ bOk = sTableRange == _sUpdateTableName;
+ if ( !bOk )
+ {
+ OSQLParseTreeIterator::getColumnRange( pNode->getChild(2), _xConnection, sColumnName, sTableRange );
+ bOk = sTableRange == _sUpdateTableName;
+ }
+ }
+ return bOk;
+}
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetCache::checkJoin(const Reference< XConnection>& _xConnection,
+ const Reference< XSingleSelectQueryAnalyzer >& _xAnalyzer,
+ const ::rtl::OUString& _sUpdateTableName )
+{
+ sal_Bool bOk = sal_False;
+ ::rtl::OUString sSql = _xAnalyzer->getQuery();
+ ::rtl::OUString sErrorMsg;
+ ::connectivity::OSQLParser aSqlParser( m_aContext.getLegacyServiceFactory() );
+ ::std::auto_ptr< ::connectivity::OSQLParseNode> pSqlParseNode( aSqlParser.parseTree(sErrorMsg,sSql));
+ if ( pSqlParseNode.get() && SQL_ISRULE(pSqlParseNode, select_statement) )
+ {
+ OSQLParseNode* pTableRefCommalist = pSqlParseNode->getByRule(::connectivity::OSQLParseNode::table_ref_commalist);
+ OSL_ENSURE(pTableRefCommalist,"NO tables why!?");
+ if(pTableRefCommalist && pTableRefCommalist->count() == 1)
+ {
+ // we found only one element so it must some kind of join here
+ OSQLParseNode* pJoin = pTableRefCommalist->getByRule(::connectivity::OSQLParseNode::qualified_join);
+ if(pJoin)
+ { // we are only intereseted in qualified joins like RIGHT or LEFT
+ OSQLParseNode* pJoinType = pJoin->getChild(1);
+ OSQLParseNode* pOuterType = NULL;
+ if(SQL_ISRULE(pJoinType,join_type) && pJoinType->count() == 2)
+ pOuterType = pJoinType->getChild(0);
+ else if(SQL_ISRULE(pJoinType,outer_join_type))
+ pOuterType = pJoinType;
+
+ sal_Bool bCheck = sal_False;
+ sal_Bool bLeftSide = sal_False;
+ if(pOuterType)
+ { // found outer join
+ bLeftSide = SQL_ISTOKEN(pOuterType->getChild(0),LEFT);
+ bCheck = bLeftSide || SQL_ISTOKEN(pOuterType->getChild(0),RIGHT);
+ }
+
+ if(bCheck)
+ { // here we know that we have to check on which side our table resides
+ const OSQLParseNode* pTableRef = pJoin->getByRule(::connectivity::OSQLParseNode::qualified_join);
+ if(bLeftSide)
+ pTableRef = pJoin->getChild(0);
+ else
+ pTableRef = pJoin->getChild(3);
+ OSL_ENSURE(SQL_ISRULE(pTableRef,table_ref),"Must be a tableref here!");
+
+ ::rtl::OUString sTableRange = OSQLParseNode::getTableRange(pTableRef);
+ if(!sTableRange.getLength())
+ pTableRef->getChild(0)->parseNodeToStr( sTableRange, _xConnection, NULL, sal_False, sal_False );
+ bOk = sTableRange == _sUpdateTableName;
+ }
+ }
+ }
+ else
+ {
+ OSQLParseNode* pWhereOpt = pSqlParseNode->getChild(3)->getChild(1);
+ if ( pWhereOpt && !pWhereOpt->isLeaf() )
+ bOk = checkInnerJoin(pWhereOpt->getChild(1),_xConnection,_sUpdateTableName);
+ }
+ }
+ return bOk;
+}
+// -----------------------------------------------------------------------------
+void ORowSetCache::clearInsertRow()
+{
+ // we don't unbound the bookmark column
+ if ( m_aInsertRow != m_pInsertMatrix->end() && m_aInsertRow->isValid() )
+ {
+ ORowSetValueVector::Vector::iterator aIter = (*m_aInsertRow)->get().begin()+1;
+ ORowSetValueVector::Vector::iterator aEnd = (*m_aInsertRow)->get().end();
+ for(;aIter != aEnd;++aIter)
+ {
+ aIter->setBound(sal_False);
+ aIter->setModified(sal_False);
+ aIter->setNull();
+ } // for(;aIter != (*m_aInsertRow)->end();++aIter)
+ }
+}
+// -----------------------------------------------------------------------------
+ORowSetMatrix::iterator ORowSetCache::calcPosition() const
+{
+ sal_Int32 nValue = (m_nPosition - m_nStartPos) - 1;
+ CHECK_MATRIX_POS(nValue);
+ return ( nValue < 0 || nValue >= static_cast<sal_Int32>(m_pMatrix->size()) ) ? m_pMatrix->end() : (m_pMatrix->begin() + nValue);
+}
+// -----------------------------------------------------------------------------
+
+TORowSetOldRowHelperRef ORowSetCache::registerOldRow()
+{
+ TORowSetOldRowHelperRef pRef = new ORowSetOldRowHelper(ORowSetRow());
+ m_aOldRows.push_back(pRef);
+ return pRef;
+}
+// -----------------------------------------------------------------------------
+void ORowSetCache::deregisterOldRow(const TORowSetOldRowHelperRef& _rRow)
+{
+ TOldRowSetRows::iterator aOldRowEnd = m_aOldRows.end();
+ for (TOldRowSetRows::iterator aOldRowIter = m_aOldRows.begin(); aOldRowIter != aOldRowEnd; ++aOldRowIter)
+ {
+ if ( aOldRowIter->getBodyPtr() == _rRow.getBodyPtr() )
+ {
+ m_aOldRows.erase(aOldRowIter);
+ break;
+ }
+
+ }
+}
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetCache::reFillMatrix(sal_Int32 _nNewStartPos,sal_Int32 _nNewEndPos)
+{
+ TOldRowSetRows::iterator aOldRowEnd = m_aOldRows.end();
+ for (TOldRowSetRows::iterator aOldRowIter = m_aOldRows.begin(); aOldRowIter != aOldRowEnd; ++aOldRowIter)
+ {
+ if ( aOldRowIter->isValid() && aOldRowIter->getBody().getRow().isValid() )
+ aOldRowIter->getBody().setRow(new ORowSetValueVector(aOldRowIter->getBody().getRow().getBody()) );
+ }
+ sal_Int32 nNewSt = _nNewStartPos;
+ sal_Bool bRet = fillMatrix(nNewSt,_nNewEndPos);
+ m_nStartPos = nNewSt - 1;
+ rotateCacheIterator(static_cast<sal_Int16>(m_nFetchSize+1)); // forces that every iterator will be set to null
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetCache::fill(ORowSetMatrix::iterator& _aIter,const ORowSetMatrix::iterator& _aEnd,sal_Int32& _nPos,sal_Bool _bCheck)
+{
+ sal_Int32 nColumnCount = m_xMetaData->getColumnCount();
+ for(; _bCheck && _aIter != _aEnd;)
+ {
+ if ( !_aIter->isValid() )
+ *_aIter = new ORowSetValueVector(nColumnCount);
+ else
+ {
+ TOldRowSetRows::iterator aOldRowEnd = m_aOldRows.end();
+ for (TOldRowSetRows::iterator aOldRowIter = m_aOldRows.begin(); aOldRowIter != aOldRowEnd; ++aOldRowIter)
+ {
+ if ( aOldRowIter->getBody().getRow().isEqualBody(*_aIter) )
+ *_aIter = new ORowSetValueVector(nColumnCount);
+ }
+ }
+ m_pCacheSet->fillValueRow(*_aIter++,++_nPos);
+ _bCheck = m_pCacheSet->next();
+ }
+ 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
new file mode 100644
index 000000000000..76e1d7145752
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetCache.hxx
@@ -0,0 +1,273 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_ROWSETCACHE_HXX
+#define DBACCESS_CORE_API_ROWSETCACHE_HXX
+
+#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
+#include <connectivity/CommonTools.hxx>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#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_XSINGLESELECTQUERYANALYZER_HPP_
+#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYANALYZER_HPP_
+#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP_
+#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDB_XRESULTSETACCESS_HPP_
+#include <com/sun/star/sdb/XResultSetAccess.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_
+#include <com/sun/star/sdbc/XColumnLocate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
+#include <com/sun/star/sdbcx/XRowLocate.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_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_SDBCX_XDELETEROWS_HPP_
+#include <com/sun/star/sdbcx/XDeleteRows.hpp>
+#endif
+#ifndef _CPPUHELPER_COMPBASE11_HXX_
+#include <cppuhelper/compbase11.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTYCONTAINER_HXX_
+#include <comphelper/propertycontainer.hxx>
+#endif
+#ifndef COMPHELPER_COMPONENTCONTEXT_HXX
+#include <comphelper/componentcontext.hxx>
+#endif
+#ifndef _CPPUHELPER_IMPLBASE5_HXX_
+#include <cppuhelper/implbase5.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
+#include <comphelper/proparrhlp.hxx>
+#endif
+#ifndef DBACCESS_CORE_API_ROWSETROW_HXX
+#include "RowSetRow.hxx"
+#endif
+#ifndef DBACCESS_ROWSETCACHEITERATOR_HXX
+#include "RowSetCacheIterator.hxx"
+#endif
+
+namespace connectivity
+{
+ class OSQLParseNode;
+}
+namespace dbaccess
+{
+ class OCacheSet;
+ class ORowSetDataColumns;
+ class ORowSetCacheClone;
+
+ class ORowSetCache
+ {
+ friend class ORowSetBase;
+ friend class ORowSet;
+ friend class ORowSetClone;
+ friend class ORowSetCacheIterator;
+
+ 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
+ ::comphelper::ComponentContext m_aContext;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow> m_xCacheSet;
+
+ OCacheSet* m_pCacheSet; // is a bookmarkable, keyset or static resultset
+ ORowSetMatrix* m_pMatrix; // represent the table struct
+ ORowSetMatrix::iterator m_aMatrixIter; // represent a row of the table
+ ORowSetMatrix::iterator m_aMatrixEnd; // present the row behind the last row of the table
+ ORowSetCacheMap m_aCacheIterators;
+ TOldRowSetRows m_aOldRows;
+
+ ORowSetMatrix* m_pInsertMatrix; // represent the rows which should be inserted normally this is only one
+ ORowSetMatrix::iterator m_aInsertRow; // represent a insert row
+
+ // ORowSetRow m_aInsertRow; // present the row that should be inserted
+ sal_Int32 m_nLastColumnIndex; // the last column ask for, used for wasNull()
+
+ connectivity::OSQLTable m_aUpdateTable; // used for updates/deletes and inserts
+
+ sal_Int32 m_nFetchSize;
+ sal_Int32 m_nRowCount;
+ sal_Int32 m_nPrivileges;
+ sal_Int32 m_nPosition; // 0 means beforefirst
+
+ sal_Int32 m_nStartPos; // start pos of the window zero based
+ sal_Int32 m_nEndPos; // end pos of the window zero based
+
+ sal_Bool m_bRowCountFinal ;
+ sal_Bool m_bBeforeFirst ;
+ sal_Bool m_bAfterLast ;
+ sal_Bool m_bUpdated ;
+ sal_Bool& m_bModified ; // points to the rowset member m_bModified
+ sal_Bool& m_bNew ; // points to the rowset member m_bNew
+
+ sal_Bool fill(ORowSetMatrix::iterator& _aIter,const ORowSetMatrix::iterator& _aEnd,sal_Int32& _nPos,sal_Bool _bCheck);
+ sal_Bool reFillMatrix(sal_Int32 _nNewStartPos,sal_Int32 nNewEndPos);
+ sal_Bool fillMatrix(sal_Int32 &_nNewStartPos,sal_Int32 _nNewEndPos);
+ sal_Bool moveWindow();
+ // returns true when a keyset needs to be created.
+ sal_Bool impl_createBookmarkSet_nothrow(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& _xRs);
+
+ void firePropertyChange(sal_Int32 _nColumnIndex,const ::connectivity::ORowSetValue& _rOldValue);
+
+ void rotateCacheIterator(ORowSetMatrix::difference_type _nDist);
+ 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);
+ sal_Bool checkJoin( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xConnection,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryAnalyzer >& _xComposer,
+ const ::rtl::OUString& _sUpdateTableName);
+ sal_Bool checkInnerJoin(const ::connectivity::OSQLParseNode *pNode
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xConnection
+ ,const ::rtl::OUString& _sUpdateTableName);
+
+ // clears the insert row
+ void clearInsertRow();
+ ORowSetMatrix::iterator calcPosition() const;
+
+ protected:
+ ORowSetMatrix::iterator& getEnd() { return m_aMatrixEnd;}
+ // is called when after a moveToInsertRow a movement (next, etc) was called
+ void cancelRowModification();
+ public:
+ ORowSetCache(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& _xRs,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSingleSelectQueryAnalyzer >& _xAnalyzer,
+ const ::comphelper::ComponentContext& _rContext,
+ const ::rtl::OUString& _rUpdateTableName,
+ sal_Bool& _bModified,
+ sal_Bool& _bNew,
+ const ORowSetValueVector& _aParameterValueForCache,
+ const ::rtl::OUString& i_sRowSetFilter);
+ ~ORowSetCache();
+
+
+ // called from the rowset when a updateXXX was called for the first time
+ void setUpdateIterator(const ORowSetMatrix::iterator& _rOriginalRow);
+ ORowSetCacheIterator createIterator(ORowSetBase* _pRowSet);
+ void deleteIterator(const ORowSetBase* _pRowSet);
+ // sets the size of the matrix
+ void setMaxRowSize(sal_Int32 _nSize);
+
+ TORowSetOldRowHelperRef registerOldRow();
+ void deregisterOldRow(const TORowSetOldRowHelperRef& _rRow);
+
+ // ::com::sun::star::sdbc::XResultSetMetaDataSupplier
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > getMetaData( );
+
+ // ::com::sun::star::sdbcx::XRowLocate
+ ::com::sun::star::uno::Any getBookmark( );
+ sal_Bool moveToBookmark( const ::com::sun::star::uno::Any& bookmark );
+ sal_Bool moveRelativeToBookmark( const ::com::sun::star::uno::Any& bookmark, sal_Int32 rows );
+ sal_Int32 compareBookmarks( const ::com::sun::star::uno::Any& first, const ::com::sun::star::uno::Any& second );
+ sal_Bool hasOrderedBookmarks( );
+ sal_Int32 hashBookmark( const ::com::sun::star::uno::Any& bookmark );
+
+ // ::com::sun::star::sdbc::XRowUpdate
+ 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( );
+ sal_Bool isBeforeFirst( );
+ sal_Bool isAfterLast( );
+ sal_Bool isFirst( );
+ sal_Bool isLast( );
+ sal_Bool beforeFirst( );
+ sal_Bool afterLast( );
+ sal_Bool first( );
+ sal_Bool last( );
+ sal_Int32 getRow( );
+ sal_Bool absolute( sal_Int32 row );
+ sal_Bool relative( sal_Int32 rows );
+ sal_Bool previous( );
+ void refreshRow( );
+ sal_Bool rowUpdated( );
+ sal_Bool rowInserted( );
+
+ // ::com::sun::star::sdbc::XResultSetUpdate
+ sal_Bool insertRow(::std::vector< ::com::sun::star::uno::Any >& o_aBookmarks);
+ void resetInsertRow(sal_Bool _bClearInsertRow);
+
+ 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/RowSetCacheIterator.cxx b/dbaccess/source/core/api/RowSetCacheIterator.cxx
new file mode 100644
index 000000000000..29d3f38278f4
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetCacheIterator.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef DBACCESS_ROWSETCACHEITERATOR_HXX
+#include "RowSetCacheIterator.hxx"
+#endif
+#ifndef DBACCESS_CORE_API_ROWSETCACHE_HXX
+#include "RowSetCache.hxx"
+#endif
+#ifndef DBACCESS_CORE_API_ROWSETBASE_HXX
+#include "RowSetBase.hxx"
+#endif
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+ORowSetCacheIterator::ORowSetCacheIterator(const ORowSetCacheIterator& _rRH)
+: m_aIter(_rRH.m_aIter)
+, m_pCache(_rRH.m_pCache)
+,m_pRowSet(_rRH.m_pRowSet)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetCacheIterator::ORowSetCacheIterator" );
+}
+// -----------------------------------------------------------------------------
+ORowSetCacheIterator::operator ORowSetMatrix::iterator()
+{
+ return m_aIter->second.aIterator;
+}
+// -----------------------------------------------------------------------------
+ORowSetCacheIterator& ORowSetCacheIterator::operator =(const ORowSetCacheIterator& _rRH)
+{
+ if(this == &_rRH)
+ return *this;
+
+ m_pCache = _rRH.m_pCache;
+ m_aIter = _rRH.m_aIter;
+ m_pRowSet = _rRH.m_pRowSet;
+
+ return *this;
+}
+// -----------------------------------------------------------------------------
+ORowSetCacheIterator& ORowSetCacheIterator::operator =(const ORowSetMatrix::iterator& _rIter)
+{
+ m_aIter->second.aIterator = _rIter;
+ return *this;
+}
+// -----------------------------------------------------------------------------
+ORowSetRow& ORowSetCacheIterator::operator *()
+{
+ return *m_aIter->second.aIterator;
+}
+// -----------------------------------------------------------------------------
+const ORowSetRow& ORowSetCacheIterator::operator *() const
+{
+ if ( !m_pRowSet->isInsertRow() && m_aIter->second.aIterator == m_pCache->m_pMatrix->end() )
+ {
+ OSL_ENSURE(m_aIter->second.aBookmark.hasValue(),"bookmark has no value!");
+ OSL_VERIFY(m_pCache->moveToBookmark(m_aIter->second.aBookmark));
+ m_aIter->second.aIterator = m_pCache->m_aMatrixIter;
+ }
+ return *m_aIter->second.aIterator;
+}
+// -----------------------------------------------------------------------------
+ORowSetMatrix::iterator& ORowSetCacheIterator::operator ->()
+{
+ return m_aIter->second.aIterator;
+}
+// -----------------------------------------------------------------------------
+const ORowSetMatrix::iterator& ORowSetCacheIterator::operator ->() const
+{
+ if ( !m_pRowSet->isInsertRow() && m_aIter->second.aIterator == m_pCache->m_pMatrix->end() )
+ {
+ OSL_ENSURE(m_aIter->second.aBookmark.hasValue(),"bookmark has no value!");
+ OSL_VERIFY(m_pCache->moveToBookmark(m_aIter->second.aBookmark));
+ m_aIter->second.aIterator = m_pCache->m_aMatrixIter;
+ }
+ return m_aIter->second.aIterator;
+}
+// -----------------------------------------------------------------------------
+bool ORowSetCacheIterator::operator <=(const ORowSetMatrix::iterator& _rRH) const
+{
+ return m_aIter->second.aIterator <= _rRH;
+}
+// -----------------------------------------------------------------------------
+bool ORowSetCacheIterator::operator <(const ORowSetMatrix::iterator& _rRH) const
+{
+ return m_aIter->second.aIterator < _rRH;
+}
+// -----------------------------------------------------------------------------
+bool ORowSetCacheIterator::operator !=(const ORowSetMatrix::iterator& _rRH) const
+{
+ return m_aIter->second.aIterator != _rRH;
+}
+// -----------------------------------------------------------------------------
+bool ORowSetCacheIterator::operator ==(const ORowSetMatrix::iterator& _rRH) const
+{
+ return m_aIter->second.aIterator == _rRH;
+}
+// -----------------------------------------------------------------------------
+void ORowSetCacheIterator::setBookmark(const ::com::sun::star::uno::Any& _rBookmark)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetCacheIterator::setBookmark" );
+ m_aIter->second.aBookmark = _rBookmark;
+}
+// -----------------------------------------------------------------------------
+sal_Bool ORowSetCacheIterator::isNull() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetCacheIterator::isNull" );
+ sal_Bool bRet = !m_pCache || !m_pRowSet || m_aIter == m_pCache->m_aCacheIterators.end();
+ if ( !bRet )
+ {
+ ORowSetCacheIterator_Helper aHelper = m_aIter->second;
+ bRet = ( m_pRowSet->isInsertRow()
+ ?
+ m_aIter->second.aIterator == m_pCache->m_pInsertMatrix->end()
+ :
+ m_aIter->second.aIterator == m_pCache->m_pMatrix->end()
+ );
+ }
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+::osl::Mutex* ORowSetCacheIterator::getMutex() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetCacheIterator::getMutex" );
+ return m_pRowSet ? m_pRowSet->getMutex() : NULL;
+}
diff --git a/dbaccess/source/core/api/RowSetCacheIterator.hxx b/dbaccess/source/core/api/RowSetCacheIterator.hxx
new file mode 100644
index 000000000000..6c4c1a8576ce
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetCacheIterator.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_ROWSETCACHEITERATOR_HXX
+#define DBACCESS_ROWSETCACHEITERATOR_HXX
+
+#ifndef DBACCESS_CORE_API_ROWSETROW_HXX
+#include "RowSetRow.hxx"
+#endif
+#ifndef _COMPHELPER_STLTYPES_HXX_
+#include <comphelper/stl_types.hxx>
+#endif
+
+namespace dbaccess
+{
+ class ORowSetBase;
+ typedef struct
+ {
+ ORowSetMatrix::iterator aIterator;
+ ::com::sun::star::uno::Any aBookmark;
+ ORowSetBase* pRowSet;
+ } ORowSetCacheIterator_Helper;
+
+ DECLARE_STL_STDKEY_MAP(sal_Int32,ORowSetCacheIterator_Helper,ORowSetCacheMap);
+
+ class ORowSetCache;
+ class ORowSetCacheIterator
+ {
+ friend class ORowSetCache;
+ ORowSetCacheMap::iterator m_aIter;
+ ORowSetCache* m_pCache;
+ ORowSetBase* m_pRowSet;
+ protected:
+ ORowSetCacheIterator(const ORowSetCacheMap::iterator& _rIter,ORowSetCache* _pCache,ORowSetBase* _pRowSet)
+ : m_aIter(_rIter)
+ ,m_pCache(_pCache)
+ ,m_pRowSet(_pRowSet)
+ {
+ }
+ public:
+ ORowSetCacheIterator() :m_aIter(),m_pCache(NULL),m_pRowSet(NULL){}
+ ORowSetCacheIterator(const ORowSetCacheIterator& _rRH);
+ ORowSetCacheIterator& operator =(const ORowSetCacheIterator&);
+
+ sal_Bool isNull() const;
+ ORowSetCacheIterator& operator =(const ORowSetMatrix::iterator&);
+ operator ORowSetMatrix::iterator();
+
+ ORowSetRow& operator *();
+ const ORowSetRow& operator *() const;
+
+ ORowSetMatrix::iterator& operator ->();
+ const ORowSetMatrix::iterator& operator ->() const;
+
+ bool operator <=(const ORowSetMatrix::iterator& _rRH) const;
+ bool operator <(const ORowSetMatrix::iterator& _rRH) const;
+ bool operator !=(const ORowSetMatrix::iterator& _rRH) const;
+ bool operator ==(const ORowSetMatrix::iterator& _rRH) const;
+
+ void setBookmark(const ::com::sun::star::uno::Any& _rBookmark);
+ ::com::sun::star::uno::Any getBookmark() const { return m_aIter->second.aBookmark; }
+ ::osl::Mutex* getMutex() const;
+
+ ORowSetCacheMap::iterator getIter() const { return m_aIter; }
+ };
+}
+#endif // DBACCESS_ROWSETCACHEITERATOR_HXX
+
+
diff --git a/dbaccess/source/core/api/RowSetRow.hxx b/dbaccess/source/core/api/RowSetRow.hxx
new file mode 100644
index 000000000000..1178c2990b83
--- /dev/null
+++ b/dbaccess/source/core/api/RowSetRow.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_ROWSETROW_HXX
+#define DBACCESS_CORE_API_ROWSETROW_HXX
+
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+#endif
+#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
+#include <connectivity/CommonTools.hxx>
+#endif
+#ifndef _CONNECTIVITY_FILE_VALUE_HXX_
+#include "connectivity/FValue.hxx"
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+
+namespace dbaccess
+{
+ typedef connectivity::ORowVector< connectivity::ORowSetValue > ORowSetValueVector;
+ typedef ::vos::ORef< ORowSetValueVector > ORowSetRow;
+ typedef ::std::vector< ORowSetRow > ORowSetMatrix;
+
+ class ORowSetOldRowHelper
+ {
+ oslInterlockedCount m_refCount;
+ ORowSetRow m_aRow;
+
+ ORowSetOldRowHelper& operator=(const ORowSetOldRowHelper& _rRH);
+ ORowSetOldRowHelper(const ORowSetOldRowHelper& _rRh);
+ public:
+ ORowSetOldRowHelper() : m_refCount(0){}
+ ORowSetOldRowHelper(const ORowSetRow& _rRow)
+ : m_refCount(0)
+ , m_aRow(_rRow)
+ {}
+// ORowSetOldRowHelper(const ORowSetOldRowHelper& _rRh)
+// : m_refCount(0)
+// , m_aRow(_rRh.m_aRow)
+// {}
+
+ void acquire()
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ }
+ void release()
+ {
+ if (! osl_decrementInterlockedCount( &m_refCount ))
+ delete this;
+ }
+ inline ORowSetRow getRow() const { return m_aRow; }
+ inline void clearRow() { m_aRow = NULL; }
+ inline void setRow(const ORowSetRow& _rRow) { m_aRow = _rRow; }
+ };
+
+ typedef ::vos::ORef< ORowSetOldRowHelper > TORowSetOldRowHelperRef;
+
+ class ORowSetValueCompare
+ {
+ const ::com::sun::star::uno::Any& m_rAny;
+ public:
+ ORowSetValueCompare(const ::com::sun::star::uno::Any& _rAny) : m_rAny(_rAny){}
+
+ sal_Bool operator ()(const ORowSetRow& _rRH)
+ {
+ switch((_rRH->get())[0].getTypeKind())
+ {
+ case ::com::sun::star::sdbc::DataType::TINYINT:
+ case ::com::sun::star::sdbc::DataType::SMALLINT:
+ case ::com::sun::star::sdbc::DataType::INTEGER:
+ return comphelper::getINT32(m_rAny) == (sal_Int32)(_rRH->get())[0];
+ default:
+ {
+ ::com::sun::star::uno::Sequence<sal_Int8> aSeq;
+ m_rAny >>= aSeq;
+ return aSeq == (_rRH->get())[0];
+ }
+ }
+ }
+ };
+}
+#endif // DBACCESS_CORE_API_ROWSETROW_HXX
+
diff --git a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx
new file mode 100644
index 000000000000..2f9a58c975b7
--- /dev/null
+++ b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx
@@ -0,0 +1,1875 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "composertools.hxx"
+#include "core_resource.hrc"
+#include "core_resource.hxx"
+#include "dbastrings.hrc"
+#include "HelperCollections.hxx"
+#include "SingleSelectQueryComposer.hxx"
+#include "sdbcoretools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/i18n/XLocaleData.hpp>
+#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>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/uno/XAggregation.hpp>
+#include <com/sun/star/util/XNumberFormatter.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <rtl/logfile.hxx>
+#include <unotools/syslocale.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+#include <unotools/sharedunocomponent.hxx>
+
+#include <memory>
+
+using namespace ::dbaccess;
+using namespace ::dbtools;
+using namespace ::comphelper;
+using namespace ::connectivity;
+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::i18n;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::util;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::utl;
+
+namespace dbaccess {
+namespace BooleanComparisonMode = ::com::sun::star::sdb::BooleanComparisonMode;
+}
+
+#define STR_SELECT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT "))
+#define STR_FROM ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM "))
+#define STR_WHERE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE "))
+#define STR_GROUP_BY ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" GROUP BY "))
+#define STR_HAVING ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" HAVING "))
+#define STR_ORDER_BY ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ORDER BY "))
+#define STR_AND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" AND "))
+#define STR_OR ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" OR "))
+#define STR_LIKE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))
+#define STR_EQUAL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))
+#define L_BRACKET ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("("))
+#define R_BRACKET ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"))
+#define COMMA ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","))
+
+// -------------------------------------------------------------------------
+namespace
+{
+ // .....................................................................
+ /** parses the given statement, using the given parser, returns a parse node representing
+ the statement
+
+ If the statement cannot be parsed, an error is thrown.
+ */
+ const OSQLParseNode* parseStatement_throwError( OSQLParser& _rParser, const ::rtl::OUString& _rStatement, const Reference< XInterface >& _rxContext )
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "SingleSelectQueryComposer.cxx::parseStatement_throwError" );
+ ::rtl::OUString aErrorMsg;
+ const OSQLParseNode* pNewSqlParseNode = _rParser.parseTree( aErrorMsg, _rStatement );
+ if ( !pNewSqlParseNode )
+ {
+ ::rtl::OUString sSQLStateGeneralError( getStandardSQLState( SQL_GENERAL_ERROR ) );
+ SQLException aError2( aErrorMsg, _rxContext, sSQLStateGeneralError, 1000, Any() );
+ SQLException aError1( _rStatement, _rxContext, sSQLStateGeneralError, 1000, makeAny( aError2 ) );
+ throw SQLException(_rParser.getContext().getErrorMessage(OParseContext::ERROR_GENERAL),_rxContext,sSQLStateGeneralError,1000,makeAny(aError1));
+ }
+ return pNewSqlParseNode;
+ }
+
+ // .....................................................................
+ /** checks whether the given parse node describes a valid single select statement, throws
+ an error if not
+ */
+ void checkForSingleSelect_throwError( const OSQLParseNode* pStatementNode, OSQLParseTreeIterator& _rIterator,
+ const Reference< XInterface >& _rxContext, const ::rtl::OUString& _rOriginatingCommand )
+ {
+ const OSQLParseNode* pOldNode = _rIterator.getParseTree();
+
+ // determine the statement type
+ _rIterator.setParseTree( pStatementNode );
+ _rIterator.traverseAll();
+ bool bIsSingleSelect = ( _rIterator.getStatementType() == SQL_STATEMENT_SELECT );
+
+ // throw the error, if necessary
+ if ( !bIsSingleSelect || SQL_ISRULE( pStatementNode, union_statement ) ) // #i4229# OJ
+ {
+ // restore the old node before throwing the exception
+ _rIterator.setParseTree( pOldNode );
+ // and now really ...
+ SQLException aError1( _rOriginatingCommand, _rxContext, getStandardSQLState( SQL_GENERAL_ERROR ), 1000, Any() );
+ throw SQLException( DBACORE_RESSTRING( RID_STR_ONLY_QUERY ), _rxContext,
+ getStandardSQLState( SQL_GENERAL_ERROR ), 1000, makeAny( aError1 ) );
+ }
+
+ delete pOldNode;
+ }
+
+ // .....................................................................
+ /** combines parseStatement_throwError and checkForSingleSelect_throwError
+ */
+ void parseAndCheck_throwError( OSQLParser& _rParser, const ::rtl::OUString& _rStatement,
+ OSQLParseTreeIterator& _rIterator, const Reference< XInterface >& _rxContext )
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "SingleSelectQueryComposer.cxx::parseAndCheck_throwError" );
+ const OSQLParseNode* pNode = parseStatement_throwError( _rParser, _rStatement, _rxContext );
+ checkForSingleSelect_throwError( pNode, _rIterator, _rxContext, _rStatement );
+ }
+
+ // .....................................................................
+ /** transforms a parse node describing a complete statement into a pure select
+ statement, without any filter/order/groupby/having clauses
+ */
+ ::rtl::OUString getPureSelectStatement( const OSQLParseNode* _pRootNode, Reference< XConnection > _rxConnection )
+ {
+ ::rtl::OUString sSQL = STR_SELECT;
+ _pRootNode->getChild(1)->parseNodeToStr( sSQL, _rxConnection );
+ _pRootNode->getChild(2)->parseNodeToStr( sSQL, _rxConnection );
+ sSQL += STR_FROM;
+ _pRootNode->getChild(3)->getChild(0)->getChild(1)->parseNodeToStr( sSQL, _rxConnection );
+ return sSQL;
+ }
+
+ /** resets an SQL iterator, including deletion of the parse tree, and disposal if desired
+ */
+ void resetIterator( OSQLParseTreeIterator& _rIterator, bool _bDispose )
+ {
+ const OSQLParseNode* pSqlParseNode = _rIterator.getParseTree();
+ _rIterator.setParseTree(NULL);
+ delete pSqlParseNode;
+ 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)
+// -------------------------------------------------------------------------
+OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAccess>& _rxTables,
+ const Reference< XConnection>& _xConnection,
+ const ::comphelper::ComponentContext& _rContext )
+ :OSubComponent(m_aMutex,_xConnection)
+ ,OPropertyContainer(m_aBHelper)
+ ,m_aSqlParser( _rContext.getLegacyServiceFactory() )
+ ,m_aSqlIterator( _xConnection, _rxTables, m_aSqlParser, NULL )
+ ,m_aAdditiveIterator( _xConnection, _rxTables, m_aSqlParser, NULL )
+ ,m_aElementaryParts( (size_t)SQLPartCount )
+ ,m_xConnection(_xConnection)
+ ,m_xMetaData(_xConnection->getMetaData())
+ ,m_xConnectionTables( _rxTables )
+ ,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);
+
+ if ( !m_aContext.is() || !m_xConnection.is() || !m_xConnectionTables.is() )
+ throw IllegalArgumentException();
+
+ registerProperty(PROPERTY_ORIGINAL,PROPERTY_ID_ORIGINAL,PropertyAttribute::BOUND|PropertyAttribute::READONLY,&m_sOrignal,::getCppuType(&m_sOrignal));
+
+ m_aCurrentColumns.resize(4);
+
+ m_aLocale = SvtSysLocale().GetLocaleData().getLocale();
+ m_xNumberFormatsSupplier = dbtools::getNumberFormats( m_xConnection, sal_True, m_aContext.getLegacyServiceFactory() );
+ Reference< XLocaleData > xLocaleData;
+ m_aContext.createComponent( "com.sun.star.i18n.LocaleData", xLocaleData );
+ LocaleDataItem aData = xLocaleData->getLocaleItem(m_aLocale);
+ m_sDecimalSep = aData.decimalSeparator;
+ OSL_ENSURE(m_sDecimalSep.getLength() == 1,"OSingleSelectQueryComposer::OSingleSelectQueryComposer decimal separator is not 1 length");
+ try
+ {
+ Any aValue;
+ Reference<XInterface> xDs = dbaccess::getDataSource(_xConnection);
+ if ( dbtools::getDataSourceSetting(xDs,static_cast <rtl::OUString> (PROPERTY_BOOLEANCOMPARISONMODE),aValue) )
+ {
+ OSL_VERIFY( aValue >>= m_nBoolCompareMode );
+ }
+ Reference< XQueriesSupplier > xQueriesAccess(m_xConnection, UNO_QUERY);
+ if (xQueriesAccess.is())
+ m_xConnectionQueries = xQueriesAccess->getQueries();
+ }
+ catch(Exception&)
+ {
+ }
+}
+// -------------------------------------------------------------------------
+OSingleSelectQueryComposer::~OSingleSelectQueryComposer()
+{
+ DBG_DTOR(OSingleSelectQueryComposer,NULL);
+ ::std::vector<OPrivateColumns*>::iterator aColIter = m_aColumnsCollection.begin();
+ ::std::vector<OPrivateColumns*>::iterator aEnd = m_aColumnsCollection.end();
+ for(;aColIter != aEnd;++aColIter)
+ delete *aColIter;
+
+ ::std::vector<OPrivateTables*>::iterator aTabIter = m_aTablesCollection.begin();
+ ::std::vector<OPrivateTables*>::iterator aTabEnd = m_aTablesCollection.end();
+ for(;aTabIter != aTabEnd;++aTabIter)
+ delete *aTabIter;
+}
+// -------------------------------------------------------------------------
+// OComponentHelper
+void SAL_CALL OSingleSelectQueryComposer::disposing(void)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::disposing" );
+ OSubComponent::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+
+ resetIterator( m_aSqlIterator, true );
+ resetIterator( m_aAdditiveIterator, true );
+
+ m_xConnectionTables = NULL;
+ m_xConnection = NULL;
+
+ clearCurrentCollections();
+}
+IMPLEMENT_FORWARD_XINTERFACE3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer)
+IMPLEMENT_SERVICE_INFO1(OSingleSelectQueryComposer,"org.openoffice.comp.dba.OSingleSelectQueryComposer",SERVICE_NAME_SINGLESELECTQUERYCOMPOSER)
+IMPLEMENT_TYPEPROVIDER3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer)
+IMPLEMENT_PROPERTYCONTAINER_DEFAULTS(OSingleSelectQueryComposer)
+
+// -------------------------------------------------------------------------
+// com::sun::star::lang::XUnoTunnel
+sal_Int64 SAL_CALL OSingleSelectQueryComposer::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getSomething" );
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return sal_Int64(0);
+}
+
+// -------------------------------------------------------------------------
+// XSingleSelectQueryAnalyzer
+::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getQuery( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getQuery" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ TGetParseNode F_tmp(&OSQLParseTreeIterator::getParseTree);
+ return getStatementPart(F_tmp,m_aSqlIterator);
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setQuery( const ::rtl::OUString& command ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "OSingleSelectQueryComposer::setQuery" );
+ ::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
+ setQuery_Impl(command);
+ m_sOrignal = command;
+
+ // 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 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 )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "OSingleSelectQueryComposer::setQuery_Impl" );
+ // parse this
+ parseAndCheck_throwError( m_aSqlParser, command, m_aSqlIterator, *this );
+
+ // strip it from all clauses, to have the pure SELECT statement
+ m_aPureSelectSQL = getPureSelectStatement( m_aSqlIterator.getParseTree(), m_xConnection );
+
+ // update columns and tables
+ // why? Shouldn't this be done on request only?
+ // otherwise nothing is working anymore :-)
+// getColumns();
+ getTables();
+}
+// -----------------------------------------------------------------------------
+Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getStructuredHavingClause( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredHavingClause" );
+ TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleHavingTree);
+ return getStructuredCondition(F_tmp);
+}
+// -------------------------------------------------------------------------
+Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getStructuredFilter( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredFilter" );
+ TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree);
+ return getStructuredCondition(F_tmp);
+}
+// -----------------------------------------------------------------------------
+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,filterOperator);
+}
+// -----------------------------------------------------------------------------
+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,filterOperator);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column)
+{
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ getColumns();
+ if ( !column.is()
+ || !m_aCurrentColumns[SelectColumns]
+ || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
+ )
+ {
+ String sError(DBACORE_RESSTRING(RID_STR_COLUMN_UNKNOWN_PROP));
+ sError.SearchAndReplaceAscii("%value", ::rtl::OUString(PROPERTY_NAME));
+ SQLException aErr(sError,*this,SQLSTATE_GENERAL,1000,Any() );
+ throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) );
+ }
+
+ ::rtl::OUString aName,aNewName;
+ column->getPropertyValue(PROPERTY_NAME) >>= aName;
+
+ if ( !m_xMetaData->supportsOrderByUnrelated() && m_aCurrentColumns[SelectColumns] && !m_aCurrentColumns[SelectColumns]->hasByName(aName))
+ {
+ String sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE));
+ sError.SearchAndReplaceAscii("%name", aName);
+ throw SQLException(sError,*this,SQLSTATE_GENERAL,1000,Any() );
+ }
+
+ // filter anhaengen
+ // select ohne where und order by aufbauen
+ ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString();
+ if ( m_aCurrentColumns[SelectColumns]->hasByName(aName) )
+ {
+ Reference<XPropertySet> xColumn;
+ m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn;
+ OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
+ OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
+ OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function"))),"Property FUNCTION not available!");
+
+ ::rtl::OUString sRealName,sTableName;
+ xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
+ xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
+ sal_Bool bFunction = sal_False;
+ xColumn->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function"))) >>= bFunction;
+ if ( sRealName == aName )
+ {
+ if ( bFunction )
+ aNewName = aName;
+ else
+ {
+ if(sTableName.indexOf('.',0) != -1)
+ {
+ ::rtl::OUString aCatlog,aSchema,aTable;
+ ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation);
+ sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation );
+ }
+ else
+ sTableName = ::dbtools::quoteName(aQuote,sTableName);
+
+ aNewName = sTableName;
+ aNewName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("."));
+ aNewName += ::dbtools::quoteName(aQuote,sRealName);
+ }
+ }
+ else
+ aNewName = ::dbtools::quoteName(aQuote,aName);
+ }
+ else
+ aNewName = getTableAlias(column) + ::dbtools::quoteName(aQuote,aName);
+ return aNewName;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::appendOrderByColumn( const Reference< XPropertySet >& column, sal_Bool ascending ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendOrderByColumn" );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::rtl::OUString sColumnName( impl_getColumnName_throw(column) );
+ ::rtl::OUString sOrder = getOrder();
+ if ( (sOrder.getLength() != 0) && sColumnName.getLength() )
+ sOrder += COMMA;
+ sOrder += sColumnName;
+ if ( !ascending && sColumnName.getLength() )
+ sOrder += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DESC "));
+
+ setOrder(sOrder);
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::appendGroupByColumn( const Reference< XPropertySet >& column) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendGroupByColumn" );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::rtl::OUString sColumnName( impl_getColumnName_throw(column) );
+ OrderCreator aComposer;
+ aComposer.append( getGroup() );
+ aComposer.append( sColumnName );
+ setGroup( aComposer.getComposedAndClear() );
+}
+// -------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::composeStatementFromParts( const ::std::vector< ::rtl::OUString >& _rParts )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::composeStatementFromParts" );
+ DBG_ASSERT( _rParts.size() == (size_t)SQLPartCount, "OSingleSelectQueryComposer::composeStatementFromParts: invalid parts array!" );
+
+ ::rtl::OUStringBuffer aSql( m_aPureSelectSQL );
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ if ( _rParts[ eLoopParts ].getLength() )
+ {
+ aSql.append( getKeyword( eLoopParts ) );
+ aSql.append( _rParts[ eLoopParts ] );
+ }
+
+ return aSql.makeStringAndClear();
+}
+
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getElementaryQuery() throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getElementaryQuery" );
+ return composeStatementFromParts( m_aElementaryParts );
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setElementaryQuery( const ::rtl::OUString& _rElementary ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "OSingleSelectQueryComposer::setElementaryQuery" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // remember the 4 current "additive" clauses
+ ::std::vector< ::rtl::OUString > aAdditiveClauses( SQLPartCount );
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ aAdditiveClauses[ eLoopParts ] = getSQLPart( eLoopParts, m_aAdditiveIterator, sal_False );
+
+ // clear the tables and columns
+ clearCurrentCollections();
+ // set and parse the new query
+ setQuery_Impl( _rElementary );
+
+ // get the 4 elementary parts of the statement
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ m_aElementaryParts[ eLoopParts ] = getSQLPart( eLoopParts, m_aSqlIterator, sal_False );
+
+ // reset the the AdditiveIterator: m_aPureSelectSQL may have changed
+ try
+ {
+ parseAndCheck_throwError( m_aSqlParser, composeStatementFromParts( aAdditiveClauses ), m_aAdditiveIterator, *this );
+ }
+ catch( const Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "OSingleSelectQueryComposer::setElementaryQuery: there should be no error anymore for the additive statement!" );
+ // every part of the additive statement should have passed other tests already, and should not
+ // be able to cause any errors ... me thinks
+ }
+}
+
+// -------------------------------------------------------------------------
+namespace
+{
+ ::rtl::OUString getComposedClause( const ::rtl::OUString _rElementaryClause, const ::rtl::OUString _rAdditionalClause,
+ TokenComposer& _rComposer, const ::rtl::OUString _rKeyword )
+ {
+ _rComposer.clear();
+ _rComposer.append( _rElementaryClause );
+ _rComposer.append( _rAdditionalClause );
+ ::rtl::OUString sComposed = _rComposer.getComposedAndClear();
+ if ( sComposed.getLength() )
+ sComposed = _rKeyword + sComposed;
+ return sComposed;
+ }
+}
+
+// -------------------------------------------------------------------------
+void OSingleSelectQueryComposer::setSingleAdditiveClause( SQLPart _ePart, const ::rtl::OUString& _rClause )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setSingleAdditiveClause" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // if nothing is changed, do nothing
+ if ( getSQLPart( _ePart, m_aAdditiveIterator, sal_False ) == _rClause )
+ return;
+
+ // collect the 4 single parts as they're currently set
+ ::std::vector< ::rtl::OUString > aClauses;
+ aClauses.reserve( (size_t)SQLPartCount );
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ aClauses.push_back( getSQLPart( eLoopParts, m_aSqlIterator, sal_True ) );
+
+ // overwrite the one part in question here
+ ::std::auto_ptr< TokenComposer > pComposer;
+ if ( ( _ePart == Where ) || ( _ePart == Having ) )
+ pComposer.reset( new FilterCreator );
+ else
+ pComposer.reset( new OrderCreator );
+ aClauses[ _ePart ] = getComposedClause( m_aElementaryParts[ _ePart ], _rClause,
+ *pComposer, getKeyword( _ePart ) );
+
+ // construct the complete statement
+ ::rtl::OUStringBuffer aSql(m_aPureSelectSQL);
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ aSql.append(aClauses[ eLoopParts ]);
+
+ // set the query
+ setQuery_Impl(aSql.makeStringAndClear());
+
+ // clear column collections which (might) have changed
+ clearColumns( ParameterColumns );
+ if ( _ePart == Order )
+ clearColumns( OrderColumns );
+ if ( _ePart == Group )
+ clearColumns( GroupByColumns );
+
+ // also, since the "additive filter" change, we need to rebuild our "additive" statement
+ aSql = m_aPureSelectSQL;
+ // again, first get all the old additive parts
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ aClauses[ eLoopParts ] = getSQLPart( eLoopParts, m_aAdditiveIterator, sal_True );
+ // then overwrite the one in question
+ aClauses[ _ePart ] = getComposedClause( ::rtl::OUString(), _rClause, *pComposer, getKeyword( _ePart ) );
+ // and parse it, so that m_aAdditiveIterator is up to date
+ for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
+ aSql.append(aClauses[ eLoopParts ]);
+ try
+ {
+ parseAndCheck_throwError( m_aSqlParser, aSql.makeStringAndClear(), m_aAdditiveIterator, *this );
+ }
+ catch( const Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "OSingleSelectQueryComposer::setSingleAdditiveClause: there should be no error anymore for the additive statement!" );
+ // every part of the additive statement should have passed other tests already, and should not
+ // be able to cause any errors ... me thinks
+ }
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setFilter( const ::rtl::OUString& filter ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setFilter" );
+ setSingleAdditiveClause( Where, filter );
+}
+
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setOrder( const ::rtl::OUString& order ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setOrder" );
+ setSingleAdditiveClause( Order, order );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setGroup( const ::rtl::OUString& group ) throw (SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setGroup" );
+ setSingleAdditiveClause( Group, group );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setHavingClause( const ::rtl::OUString& filter ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setHavingClause" );
+ setSingleAdditiveClause( Having, filter );
+}
+
+// -------------------------------------------------------------------------
+// XTablesSupplier
+Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getTables( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getTables" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_pTables )
+ {
+ const OSQLTables& aTables = m_aSqlIterator.getTables();
+ ::std::vector< ::rtl::OUString> aNames;
+ OSQLTables::const_iterator aEnd = aTables.end();
+ for(OSQLTables::const_iterator aIter = aTables.begin(); aIter != aEnd;++aIter)
+ aNames.push_back(aIter->first);
+
+ m_pTables = new OPrivateTables(aTables,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames);
+ }
+
+ return m_pTables;
+}
+// -------------------------------------------------------------------------
+// XColumnsSupplier
+Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getColumns" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !!m_aCurrentColumns[SelectColumns] )
+ return m_aCurrentColumns[SelectColumns];
+
+ ::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 {
+
+ try
+ {
+ SharedUNOComponent< XStatement, DisposableComponent > xStatement;
+ SharedUNOComponent< XPreparedStatement, DisposableComponent > xPreparedStatement;
+
+ bCase = m_xMetaData->supportsMixedCaseQuotedIdentifiers();
+ aSelectColumns = m_aSqlIterator.getSelectColumns();
+
+ ::rtl::OUStringBuffer aSQL;
+ aSQL.append( m_aPureSelectSQL );
+ aSQL.append( STR_WHERE );
+
+ // preserve the original WHERE clause
+ // #i102234# / 2009-06-02 / frank.schoenheit@sun.com
+ ::rtl::OUString sOriginalWhereClause = getSQLPart( Where, m_aSqlIterator, sal_False );
+ if ( sOriginalWhereClause.getLength() )
+ {
+ aSQL.appendAscii( " ( 0 = 1 ) AND ( " );
+ aSQL.append( sOriginalWhereClause );
+ aSQL.appendAscii( " ) " );
+ }
+ else
+ {
+ aSQL.appendAscii( " ( 0 = 1 ) " );
+ }
+
+ ::rtl::OUString sGroupBy = getSQLPart( Group, m_aSqlIterator, sal_True );
+ if ( sGroupBy.getLength() )
+ aSQL.append( sGroupBy );
+
+ ::rtl::OUString sSQL( aSQL.makeStringAndClear() );
+ // normalize the statement so that it doesn't contain any application-level features anymore
+ ::rtl::OUString sError;
+ const ::std::auto_ptr< OSQLParseNode > pStatementTree( m_aSqlParser.parseTree( sError, sSQL, false ) );
+ DBG_ASSERT( pStatementTree.get(), "OSingleSelectQueryComposer::getColumns: could not parse the column retrieval statement!" );
+ if ( pStatementTree.get() )
+ if ( !pStatementTree->parseNodeToExecutableStatement( sSQL, m_xConnection, m_aSqlParser, NULL ) )
+ break;
+
+ Reference< XResultSetMetaData > xResultSetMeta;
+ Reference< XResultSetMetaDataSupplier > xResMetaDataSup;
+ try
+ {
+ xPreparedStatement.set( m_xConnection->prepareStatement( sSQL ), UNO_QUERY_THROW );
+ xResMetaDataSup.set( xPreparedStatement, UNO_QUERY_THROW );
+ xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW );
+ }
+ catch( const Exception& ) { }
+
+ try
+ {
+ if ( !xResultSetMeta.is() )
+ {
+ xStatement.reset( Reference< XStatement >( m_xConnection->createStatement(), UNO_QUERY_THROW ) );
+ Reference< XPropertySet > xStatementProps( xStatement, UNO_QUERY_THROW );
+ try { xStatementProps->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( sal_False ) ); }
+ catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
+ xResMetaDataSup.set( xStatement->executeQuery( sSQL ), UNO_QUERY_THROW );
+ xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW );
+ }
+ }
+ catch( const Exception& )
+ {
+ //@see issue http://qa.openoffice.org/issues/show_bug.cgi?id=110111
+ // access returns a different order of column names when executing select * from
+ // and asking the columns from the metadata.
+ Reference< XParameters > xParameters( xPreparedStatement, UNO_QUERY_THROW );
+ Reference< XIndexAccess > xPara = getParameters();
+ for(sal_Int32 i = 1;i <= xPara->getCount();++i)
+ xParameters->setNull(i,DataType::VARCHAR);
+ xResMetaDataSup.set(xPreparedStatement->executeQuery(), UNO_QUERY_THROW );
+ xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW );
+ }
+
+ if ( aSelectColumns->get().empty() )
+ {
+ // 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 ,xQueryColumns);
+ break;
+ }
+
+ const ::comphelper::UStringMixEqual aCaseCompare( bCase );
+ 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;
+ 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();
+ if ( aFind != aSelectColumns->get().end() )
+ {
+ if ( aUsedSelectColumns.find( nFoundSelectColumnPos ) != aUsedSelectColumns.end() )
+ { // we found a column name which exists twice
+ // so we start after the first found
+ do
+ {
+ aFind = ::connectivity::findRealName(++aFind,aSelectColumns->get().end(),sColumnName,aCaseCompare);
+ nFoundSelectColumnPos = aFind - aSelectColumns->get().begin();
+ }
+ while ( ( aUsedSelectColumns.find( nFoundSelectColumnPos ) != aUsedSelectColumns.end() )
+ && ( aFind != aSelectColumns->get().end() )
+ );
+ }
+ if ( aFind != aSelectColumns->get().end() )
+ {
+ (*aFind)->getPropertyValue(PROPERTY_NAME) >>= sColumnName;
+ aUsedSelectColumns.insert( nFoundSelectColumnPos );
+ aNames.push_back(sColumnName);
+ bFound = sal_True;
+ }
+ }
+
+ if ( bFound )
+ continue;
+
+ OSQLColumns::Vector::const_iterator aRealFind = ::connectivity::findRealName(
+ aSelectColumns->get().begin(), aSelectColumns->get().end(), sColumnName, aCaseCompare );
+
+ if ( i > static_cast< sal_Int32>( aSelectColumns->get().size() ) )
+ {
+ aSelectColumns->get().push_back(
+ ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ,aColumnNames)
+ );
+ OSL_ENSURE( aSelectColumns->get().size() == (size_t)i, "OSingleSelectQueryComposer::getColumns: inconsistency!" );
+ }
+ else if ( aRealFind == aSelectColumns->get().end() )
+ {
+ // we can now only look if we found it under the realname propertery
+ // here we have to make the assumption that the position is correct
+ OSQLColumns::Vector::iterator aFind2 = aSelectColumns->get().begin() + i-1;
+ Reference<XPropertySet> xProp(*aFind2,UNO_QUERY);
+ if ( !xProp.is() || !xProp->getPropertySetInfo()->hasPropertyByName( PROPERTY_REALNAME ) )
+ continue;
+
+ ::connectivity::parse::OParseColumn* pColumn = new ::connectivity::parse::OParseColumn(xProp,bCase);
+ pColumn->setFunction(::comphelper::getBOOL(xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function")))));
+ pColumn->setAggregateFunction(::comphelper::getBOOL(xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction")))));
+
+ ::rtl::OUString sRealName;
+ xProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
+ ::std::vector< ::rtl::OUString>::iterator aFindName;
+ if ( !sColumnName.getLength() )
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sColumnName;
+
+
+ aFindName = ::std::find_if(aNames.begin(),aNames.end(),::std::bind2nd(aCaseCompareFunctor,sColumnName));
+ sal_Int32 j = 0;
+ while ( aFindName != aNames.end() )
+ {
+ sColumnName += ::rtl::OUString::valueOf(++j);
+ aFindName = ::std::find_if(aNames.begin(),aNames.end(),::std::bind2nd(aCaseCompareFunctor,sColumnName));
+ }
+
+ pColumn->setName(sColumnName);
+ pColumn->setRealName(sRealName);
+ pColumn->setTableName(::comphelper::getString(xProp->getPropertyValue(PROPERTY_TABLENAME)));
+
+ (aSelectColumns->get())[i-1] = pColumn;
+ }
+ else
+ continue;
+
+ aUsedSelectColumns.insert( (size_t)(i - 1) );
+ aNames.push_back( sColumnName );
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+
+ } while ( false );
+
+ if ( aNames.empty() )
+ m_aCurrentColumns[ SelectColumns ] = OPrivateColumns::createWithIntrinsicNames( aSelectColumns, bCase, *this, m_aMutex );
+ else
+ m_aCurrentColumns[ SelectColumns ] = new OPrivateColumns( aSelectColumns, bCase, *this, m_aMutex, aNames );
+
+ return m_aCurrentColumns[SelectColumns];
+}
+// -------------------------------------------------------------------------
+sal_Bool OSingleSelectQueryComposer::setORCriteria(OSQLParseNode* pCondition, OSQLParseTreeIterator& _rIterator,
+ ::std::vector< ::std::vector < PropertyValue > >& rFilters, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setORCriteria" );
+ // Runde Klammern um den Ausdruck
+ if (pCondition->count() == 3 &&
+ SQL_ISPUNCTUATION(pCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pCondition->getChild(2),")"))
+ {
+ return setORCriteria(pCondition->getChild(1), _rIterator, rFilters, xFormatter);
+ }
+ // oder Verknuepfung
+ // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term
+ else if (SQL_ISRULE(pCondition,search_condition))
+ {
+ sal_Bool bResult = sal_True;
+ for (int i = 0; bResult && i < 3; i+=2)
+ {
+ // Ist das erste Element wieder eine OR-Verknuepfung?
+ // Dann rekursiv absteigen ...
+ //if (!i && SQL_ISRULE(pCondition->getChild(i),search_condition))
+ if (SQL_ISRULE(pCondition->getChild(i),search_condition))
+ bResult = setORCriteria(pCondition->getChild(i), _rIterator, rFilters, xFormatter);
+ else
+ {
+ rFilters.push_back( ::std::vector < PropertyValue >());
+ bResult = setANDCriteria(pCondition->getChild(i), _rIterator, rFilters[rFilters.size() - 1], xFormatter);
+ }
+ }
+ return bResult;
+ }
+ else
+ {
+ rFilters.push_back(::std::vector < PropertyValue >());
+ return setANDCriteria(pCondition, _rIterator, rFilters[rFilters.size() - 1], xFormatter);
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+sal_Bool OSingleSelectQueryComposer::setANDCriteria( OSQLParseNode * pCondition,
+ OSQLParseTreeIterator& _rIterator, ::std::vector < PropertyValue >& rFilter, const Reference< XNumberFormatter > & xFormatter) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setANDCriteria" );
+ // Runde Klammern
+ if (SQL_ISRULE(pCondition,boolean_primary))
+ {
+ // this should not occur
+ DBG_ERROR("boolean_primary in And-Criteria");
+ return sal_False;
+ }
+ // Das erste Element ist (wieder) eine AND-Verknuepfung
+ else if ( SQL_ISRULE(pCondition,boolean_term) && pCondition->count() == 3 )
+ {
+ return setANDCriteria(pCondition->getChild(0), _rIterator, rFilter, xFormatter) &&
+ setANDCriteria(pCondition->getChild(2), _rIterator, rFilter, xFormatter);
+ }
+ else if (SQL_ISRULE(pCondition, comparison_predicate))
+ {
+ return setComparsionPredicate(pCondition,_rIterator,rFilter,xFormatter);
+ }
+ else if (SQL_ISRULE(pCondition,like_predicate) ||
+ SQL_ISRULE(pCondition,test_for_null) ||
+ SQL_ISRULE(pCondition,in_predicate) ||
+ SQL_ISRULE(pCondition,all_or_any_predicate) ||
+ SQL_ISRULE(pCondition,between_predicate))
+ {
+ if (SQL_ISRULE(pCondition->getChild(0), column_ref))
+ {
+ PropertyValue aItem;
+ ::rtl::OUString aValue;
+ ::rtl::OUString aColumnName;
+
+
+ // pCondition->parseNodeToStr(aValue,m_xMetaData, xFormatter, m_aLocale,static_cast<sal_Char>(m_sDecimalSep.toChar()));
+ pCondition->parseNodeToStr( aValue, m_xConnection, NULL );
+ // pCondition->getChild(0)->parseNodeToStr(aColumnName,m_xMetaData, xFormatter, m_aLocale,static_cast<sal_Char>(m_sDecimalSep.toChar()));
+ pCondition->getChild(0)->parseNodeToStr( aColumnName, m_xConnection, NULL );
+
+ // don't display the column name
+ aValue = aValue.copy(aColumnName.getLength());
+ aValue = aValue.trim();
+
+ 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_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(1)->getChild(2),NOT) )
+ aItem.Handle = SQLFilterOperator::NOT_SQLNULL;
+ else
+ aItem.Handle = SQLFilterOperator::SQLNULL;
+ }
+ else if (SQL_ISRULE(pCondition,in_predicate))
+ {
+ OSL_ENSURE( false, "OSingleSelectQueryComposer::setANDCriteria: in_predicate not implemented!" );
+ }
+ else if (SQL_ISRULE(pCondition,all_or_any_predicate))
+ {
+ OSL_ENSURE( false, "OSingleSelectQueryComposer::setANDCriteria: all_or_any_predicate not implemented!" );
+ }
+ else if (SQL_ISRULE(pCondition,between_predicate))
+ {
+ OSL_ENSURE( false, "OSingleSelectQueryComposer::setANDCriteria: between_predicate not implemented!" );
+ }
+
+ rFilter.push_back(aItem);
+ }
+ else
+ return sal_False;
+ }
+ else if (SQL_ISRULE(pCondition,existence_test) ||
+ SQL_ISRULE(pCondition,unique_test))
+ {
+ // this couldn't be handled here, too complex
+ // as we need a field name
+ return sal_False;
+ }
+ else
+ return sal_False;
+
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+sal_Int32 OSingleSelectQueryComposer::getPredicateType(OSQLParseNode * _pPredicate) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getPredicateType" );
+ sal_Int32 nPredicate = SQLFilterOperator::EQUAL;
+ switch (_pPredicate->getNodeType())
+ {
+ case SQL_NODE_EQUAL:
+ nPredicate = SQLFilterOperator::EQUAL;
+ break;
+ case SQL_NODE_NOTEQUAL:
+ nPredicate = SQLFilterOperator::NOT_EQUAL;
+ break;
+ case SQL_NODE_LESS:
+ nPredicate = SQLFilterOperator::LESS;
+ break;
+ case SQL_NODE_LESSEQ:
+ nPredicate = SQLFilterOperator::LESS_EQUAL;
+ break;
+ case SQL_NODE_GREAT:
+ nPredicate = SQLFilterOperator::GREATER;
+ break;
+ case SQL_NODE_GREATEQ:
+ nPredicate = SQLFilterOperator::GREATER_EQUAL;
+ break;
+ default:
+ OSL_ENSURE(0,"Wrong NodeType!");
+ }
+ return nPredicate;
+}
+//------------------------------------------------------------------------------
+sal_Bool OSingleSelectQueryComposer::setComparsionPredicate(OSQLParseNode * pCondition, OSQLParseTreeIterator& _rIterator,
+ ::std::vector < PropertyValue >& rFilter, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setComparsionPredicate" );
+ DBG_ASSERT(SQL_ISRULE(pCondition, comparison_predicate),"setComparsionPredicate: pCondition ist kein ComparsionPredicate");
+ if (SQL_ISRULE(pCondition->getChild(0), column_ref) ||
+ SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref))
+ {
+ PropertyValue aItem;
+ ::rtl::OUString aValue;
+ sal_uInt32 nPos;
+ if (SQL_ISRULE(pCondition->getChild(0), column_ref))
+ {
+ nPos = 0;
+ sal_uInt32 i=1;
+
+ aItem.Handle = getPredicateType(pCondition->getChild(i));
+ // don't display the equal
+ if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL)
+ i++;
+
+ // go forward
+ for (;i < pCondition->count();i++)
+ pCondition->getChild(i)->parseNodeToPredicateStr(
+ aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>(m_sDecimalSep.toChar() ) );
+ }
+ else if (SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref))
+ {
+ nPos = pCondition->count()-1;
+
+ sal_Int32 i = pCondition->count() - 2;
+ switch (pCondition->getChild(i)->getNodeType())
+ {
+ case SQL_NODE_EQUAL:
+ // don't display the equal
+ i--;
+ aItem.Handle = SQLFilterOperator::EQUAL;
+ break;
+ case SQL_NODE_NOTEQUAL:
+ i--;
+ aItem.Handle = SQLFilterOperator::NOT_EQUAL;
+ break;
+ case SQL_NODE_LESS:
+ // take the opposite as we change the order
+ i--;
+ aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
+ aItem.Handle = SQLFilterOperator::GREATER_EQUAL;
+ break;
+ case SQL_NODE_LESSEQ:
+ // take the opposite as we change the order
+ i--;
+ aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
+ aItem.Handle = SQLFilterOperator::GREATER;
+ break;
+ case SQL_NODE_GREAT:
+ // take the opposite as we change the order
+ i--;
+ aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
+ aItem.Handle = SQLFilterOperator::LESS_EQUAL;
+ break;
+ case SQL_NODE_GREATEQ:
+ // take the opposite as we change the order
+ i--;
+ aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
+ aItem.Handle = SQLFilterOperator::LESS;
+ break;
+ default:
+ break;
+ }
+
+ // go backward
+ for (; i >= 0; i--)
+ pCondition->getChild(i)->parseNodeToPredicateStr(
+ aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
+ }
+ else
+ return sal_False;
+
+ aItem.Name = getColumnName(pCondition->getChild(nPos),_rIterator);
+ aItem.Value <<= aValue;
+ rFilter.push_back(aItem);
+ }
+ else if (SQL_ISRULE(pCondition->getChild(0), set_fct_spec ) ||
+ SQL_ISRULE(pCondition->getChild(0), general_set_fct))
+ {
+ PropertyValue aItem;
+ ::rtl::OUString aValue;
+ ::rtl::OUString aColumnName;
+
+ pCondition->parseNodeToPredicateStr(aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
+ pCondition->getChild(0)->parseNodeToPredicateStr( aColumnName, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep .toChar() ) );
+
+ // don't display the column name
+ aValue = aValue.copy(aColumnName.getLength());
+ aValue.trim();
+
+ aItem.Name = getColumnName(pCondition->getChild(0),_rIterator);
+ aItem.Value <<= aValue;
+ aItem.Handle = pCondition->getNodeType();
+ rFilter.push_back(aItem);
+ }
+ else // kann sich nur um einen Expr. Ausdruck handeln
+ {
+ PropertyValue aItem;
+ ::rtl::OUString aName, aValue;
+
+ OSQLParseNode *pLhs = pCondition->getChild(0);
+ OSQLParseNode *pRhs = pCondition->getChild(2);
+
+ // Feldnamen
+ sal_uInt16 i;
+ for (i=0;i< pLhs->count();i++)
+ pLhs->getChild(i)->parseNodeToPredicateStr( aName, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
+
+ // Kriterium
+ aItem.Handle = pCondition->getChild(1)->getNodeType();
+ aValue = pCondition->getChild(1)->getTokenValue();
+ for(i=0;i< pRhs->count();i++)
+ pRhs->getChild(i)->parseNodeToPredicateStr(aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
+
+ aItem.Name = aName;
+ aItem.Value <<= aValue;
+ rFilter.push_back(aItem);
+ }
+ return sal_True;
+}
+// functions for analysing SQL
+//--------------------------------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::getColumnName( ::connectivity::OSQLParseNode* pColumnRef, OSQLParseTreeIterator& _rIterator ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getColumnName" );
+ ::rtl::OUString aTableRange, aColumnName;
+ _rIterator.getColumnRange(pColumnRef,aColumnName,aTableRange);
+ return aColumnName;
+}
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getFilter( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getFilter" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return getSQLPart(Where,m_aAdditiveIterator,sal_False);
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getOrder( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getOrder" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return getSQLPart(Order,m_aAdditiveIterator,sal_False);
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getGroup( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getGroup" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return getSQLPart(Group,m_aAdditiveIterator,sal_False);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::getHavingClause() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getHavingClause" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return getSQLPart(Having,m_aAdditiveIterator,sal_False);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::getTableAlias(const Reference< XPropertySet >& column) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getTableAlias" );
+ ::rtl::OUString sReturn;
+ if(m_pTables && m_pTables->getCount() > 1)
+ {
+ ::rtl::OUString aCatalog,aSchema,aTable,aComposedName,aColumnName;
+ column->getPropertyValue(PROPERTY_CATALOGNAME) >>= aCatalog;
+ column->getPropertyValue(PROPERTY_SCHEMANAME) >>= aSchema;
+ column->getPropertyValue(PROPERTY_TABLENAME) >>= aTable;
+ column->getPropertyValue(PROPERTY_NAME) >>= aColumnName;
+
+ Sequence< ::rtl::OUString> aNames(m_pTables->getElementNames());
+ const ::rtl::OUString* pBegin = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pBegin + aNames.getLength();
+
+ if(!aTable.getLength())
+ { // we don't found a table name, now we must search every table for this column
+ for(;pBegin != pEnd;++pBegin)
+ {
+ Reference<XColumnsSupplier> xColumnsSupp;
+ m_pTables->getByName(*pBegin) >>= xColumnsSupp;
+
+ if(xColumnsSupp.is() && xColumnsSupp->getColumns()->hasByName(aColumnName))
+ {
+// Reference<XPropertySet> xTableProp(xColumnsSupp,UNO_QUERY);
+// xTableProp->getPropertyValue(PROPERTY_CATALOGNAME) >>= aCatalog;
+// xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= aSchema;
+// xTableProp->getPropertyValue(PROPERTY_NAME) >>= aTable;
+ aTable = *pBegin;
+ break;
+ }
+ }
+ }
+ else
+ {
+ aComposedName = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, sal_False, ::dbtools::eInDataManipulation );
+
+ // first check if this is the table we want to or has it a tablealias
+
+ if(!m_pTables->hasByName(aComposedName))
+ {
+ ::comphelper::UStringMixLess aTmp(m_aAdditiveIterator.getTables().key_comp());
+ ::comphelper::UStringMixEqual aComp(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive());
+ for(;pBegin != pEnd;++pBegin)
+ {
+ Reference<XPropertySet> xTableProp;
+ m_pTables->getByName(*pBegin) >>= xTableProp;
+ OSL_ENSURE(xTableProp.is(),"Table isn't a propertyset!");
+ if(xTableProp.is())
+ {
+ ::rtl::OUString aCatalog2,aSchema2,aTable2;
+ xTableProp->getPropertyValue(PROPERTY_CATALOGNAME) >>= aCatalog2;
+ xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= aSchema2;
+ xTableProp->getPropertyValue(PROPERTY_NAME) >>= aTable2;
+ if(aComp(aCatalog,aCatalog2) && aComp(aSchema,aSchema2) && aComp(aTable,aTable2))
+ {
+ aCatalog = aCatalog2;
+ aSchema = aSchema2;
+ aTable = aTable2;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(pBegin != pEnd)
+ {
+ sReturn = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation );
+ sReturn += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("."));
+ }
+ }
+ return sReturn;
+}
+// -----------------------------------------------------------------------------
+Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getParameters( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getParameters" );
+ // now set the Parameters
+ if ( !m_aCurrentColumns[ParameterColumns] )
+ {
+ ::vos::ORef< OSQLColumns> aCols = m_aSqlIterator.getParameters();
+ ::std::vector< ::rtl::OUString> aNames;
+ OSQLColumns::Vector::const_iterator aEnd = aCols->get().end();
+ for(OSQLColumns::Vector::const_iterator aIter = aCols->get().begin(); aIter != aEnd;++aIter)
+ aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME)));
+ m_aCurrentColumns[ParameterColumns] = new OPrivateColumns(aCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,sal_True);
+ }
+
+ return m_aCurrentColumns[ParameterColumns];
+}
+// -----------------------------------------------------------------------------
+void OSingleSelectQueryComposer::clearColumns( const EColumnType _eType )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::clearColumns" );
+ OPrivateColumns* pColumns = m_aCurrentColumns[ _eType ];
+ if ( pColumns != NULL )
+ {
+ pColumns->disposing();
+ m_aColumnsCollection.push_back( pColumns );
+ m_aCurrentColumns[ _eType ] = NULL;
+ }
+}
+// -----------------------------------------------------------------------------
+void OSingleSelectQueryComposer::clearCurrentCollections()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::clearCurrentCollections" );
+ ::std::vector<OPrivateColumns*>::iterator aIter = m_aCurrentColumns.begin();
+ ::std::vector<OPrivateColumns*>::iterator aEnd = m_aCurrentColumns.end();
+ for (;aIter != aEnd;++aIter)
+ {
+ if ( *aIter )
+ {
+ (*aIter)->disposing();
+ m_aColumnsCollection.push_back(*aIter);
+ *aIter = NULL;
+ }
+ }
+
+ if(m_pTables)
+ {
+ m_pTables->disposing();
+ m_aTablesCollection.push_back(m_pTables);
+ m_pTables = NULL;
+ }
+}
+// -----------------------------------------------------------------------------
+Reference< XIndexAccess > OSingleSelectQueryComposer::setCurrentColumns( EColumnType _eType,
+ const ::vos::ORef< OSQLColumns >& _rCols )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setCurrentColumns" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ // now set the group columns
+ if ( !m_aCurrentColumns[_eType] )
+ {
+ ::std::vector< ::rtl::OUString> aNames;
+ OSQLColumns::Vector::const_iterator aEnd = _rCols->get().end();
+ for(OSQLColumns::Vector::const_iterator aIter = _rCols->get().begin(); aIter != aEnd;++aIter)
+ aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME)));
+ m_aCurrentColumns[_eType] = new OPrivateColumns(_rCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,sal_True);
+ }
+
+ return m_aCurrentColumns[_eType];
+}
+// -----------------------------------------------------------------------------
+Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getGroupColumns( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getGroupColumns" );
+ return setCurrentColumns( GroupByColumns, m_aAdditiveIterator.getGroupColumns() );
+}
+// -------------------------------------------------------------------------
+Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getOrderColumns( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getOrderColumns" );
+ return setCurrentColumns( OrderColumns, m_aAdditiveIterator.getOrderColumns() );
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getQueryWithSubstitution( ) throw (SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getQueryWithSubstitution" );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::rtl::OUString sSqlStatement( getQuery() );
+
+ const OSQLParseNode* pStatementNode = m_aSqlIterator.getParseTree();
+ if ( pStatementNode )
+ {
+ SQLException aError;
+ if ( !pStatementNode->parseNodeToExecutableStatement( sSqlStatement, m_xConnection, m_aSqlParser, &aError ) )
+ throw SQLException( aError );
+ }
+
+ return sSqlStatement;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::getStatementPart( TGetParseNode& _aGetFunctor, OSQLParseTreeIterator& _rIterator )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStatementPart" );
+ ::rtl::OUString sResult;
+
+ const OSQLParseNode* pNode = _aGetFunctor( &_rIterator );
+ if ( pNode )
+ pNode->parseNodeToStr( sResult, m_xConnection );
+
+ return sResult;
+}
+// -----------------------------------------------------------------------------
+namespace
+{
+ ::rtl::OUString lcl_getCondition(const Sequence< Sequence< PropertyValue > >& filter )
+ {
+ ::rtl::OUStringBuffer sRet;
+ const Sequence< PropertyValue >* pOrIter = filter.getConstArray();
+ const Sequence< PropertyValue >* pOrEnd = pOrIter + filter.getLength();
+ while ( pOrIter != pOrEnd )
+ {
+ if ( pOrIter->getLength() )
+ {
+ sRet.append(L_BRACKET);
+ const PropertyValue* pAndIter = pOrIter->getConstArray();
+ const PropertyValue* pAndEnd = pAndIter + pOrIter->getLength();
+ while ( pAndIter != pAndEnd )
+ {
+ sRet.append(pAndIter->Name);
+ ::rtl::OUString sValue;
+ pAndIter->Value >>= sValue;
+ lcl_addFilterCriteria_throw(pAndIter->Handle,sValue,sRet);
+ ++pAndIter;
+ if ( pAndIter != pAndEnd )
+ sRet.append(STR_AND);
+ }
+ sRet.append(R_BRACKET);
+ }
+ ++pOrIter;
+ if ( pOrIter != pOrEnd && sRet.getLength() )
+ sRet.append(STR_OR);
+ }
+ return sRet.makeStringAndClear();
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setStructuredFilter( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, ::com::sun::star::lang::IllegalArgumentException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setStructuredFilter" );
+ setFilter(lcl_getCondition(filter));
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OSingleSelectQueryComposer::setStructuredHavingClause( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setStructuredHavingClause" );
+ setHavingClause(lcl_getCondition(filter));
+}
+// -----------------------------------------------------------------------------
+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);
+
+ if ( !column.is()
+ || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE)
+ || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
+ || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE))
+ throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,Any() );
+
+ sal_Int32 nType = 0;
+ column->getPropertyValue(PROPERTY_TYPE) >>= nType;
+ sal_Int32 nSearchable = dbtools::getSearchColumnFlag(m_xConnection,nType);
+ if(nSearchable == ColumnSearch::NONE)
+ throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_SEARCHABLE),*this,SQLSTATE_GENERAL,1000,Any() );
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::rtl::OUString aName;
+ column->getPropertyValue(PROPERTY_NAME) >>= aName;
+
+ Any aValue;
+ column->getPropertyValue(PROPERTY_VALUE) >>= aValue;
+
+ ::rtl::OUStringBuffer aSQL;
+ const ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString();
+ getColumns();
+
+ if ( m_aCurrentColumns[SelectColumns] && m_aCurrentColumns[SelectColumns]->hasByName(aName) )
+ {
+ Reference<XPropertySet> xColumn;
+ m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn;
+ OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
+ OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
+ OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction"))),"Property AggregateFunctionnot available!");
+
+ ::rtl::OUString sRealName,sTableName;
+ xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
+ xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
+ if(sTableName.indexOf('.',0) != -1)
+ {
+ ::rtl::OUString aCatlog,aSchema,aTable;
+ ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation);
+ sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation );
+ }
+ else
+ sTableName = ::dbtools::quoteName(aQuote,sTableName);
+
+ if ( !::comphelper::getBOOL(xColumn->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function")))) )
+ {
+ aSQL = sTableName;
+ aSQL.appendAscii( "." );
+ aSQL.append( ::dbtools::quoteName( aQuote, sRealName ) );
+ }
+ else
+ aSQL = sRealName;
+
+ }
+ else
+ {
+ aSQL = getTableAlias( column );
+ 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( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) );
+ break;
+ case DataType::CLOB:
+ {
+ Reference< XClob > xClob(aValue,UNO_QUERY);
+ if ( xClob.is() )
+ {
+ const ::sal_Int64 nLength = xClob->length();
+ if ( sal_Int64(nLength + aSQL.getLength() + STR_LIKE.getLength() ) < sal_Int64(SAL_MAX_INT32) )
+ {
+ aSQL.appendAscii("'");
+ aSQL.append( xClob->getSubString(1,(sal_Int32)nLength) );
+ aSQL.appendAscii("'");
+ }
+ }
+ else
+ {
+ aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) );
+ }
+ }
+ break;
+ case DataType::VARBINARY:
+ case DataType::BINARY:
+ case DataType::LONGVARBINARY:
+ {
+ Sequence<sal_Int8> aSeq;
+ if(aValue >>= aSeq)
+ {
+ if(nSearchable == ColumnSearch::CHAR)
+ {
+ aSQL.appendAscii( "\'" );
+ }
+ aSQL.appendAscii( "0x" );
+ const sal_Int8* pBegin = aSeq.getConstArray();
+ const sal_Int8* pEnd = pBegin + aSeq.getLength();
+ for(;pBegin != pEnd;++pBegin)
+ {
+ aSQL.append( (sal_Int32)*pBegin, 16 ).getStr();
+ }
+ if(nSearchable == ColumnSearch::CHAR)
+ aSQL.appendAscii( "\'" );
+ }
+ else
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NOT_SEQUENCE_INT8),*this,SQLSTATE_GENERAL,1000,Any() );
+ }
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ {
+ sal_Bool bValue = sal_False;
+ m_xTypeConverter->convertToSimpleType(aValue, TypeClass_BOOLEAN) >>= bValue;
+
+ ::rtl::OUString sColumnExp = aSQL.makeStringAndClear();
+ getBoleanComparisonPredicate( sColumnExp, bValue, m_nBoolCompareMode, aSQL );
+ }
+ break;
+ default:
+ aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) );
+ break;
+ }
+ }
+ else
+ {
+ 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
+ ::rtl::OUString sFilter = getFilter();
+
+ if ( sFilter.getLength() && aSQL.getLength() )
+ {
+ ::rtl::OUString sTemp(L_BRACKET);
+ sTemp += sFilter;
+ sTemp += R_BRACKET;
+ sTemp += andCriteria ? STR_AND : STR_OR;
+ sFilter = sTemp;
+ }
+ sFilter += aSQL.makeStringAndClear();
+
+ // add the filter and the sort order
+ _aSetFunctor(this,sFilter);
+}
+// -----------------------------------------------------------------------------
+Sequence< Sequence< PropertyValue > > OSingleSelectQueryComposer::getStructuredCondition( TGetParseNode& _aGetFunctor )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredCondition" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ MutexGuard aGuard(m_aMutex);
+
+ Sequence< Sequence< PropertyValue > > aFilterSeq;
+ ::rtl::OUString sFilter = getStatementPart( _aGetFunctor, m_aAdditiveIterator );
+
+ if ( sFilter.getLength() != 0 )
+ {
+ ::rtl::OUString aSql(m_aPureSelectSQL);
+ // build a temporary parse node
+ const OSQLParseNode* pTempNode = m_aAdditiveIterator.getParseTree();
+
+ aSql += STR_WHERE;
+ aSql += sFilter;
+
+ ::rtl::OUString aErrorMsg;
+ ::std::auto_ptr<OSQLParseNode> pSqlParseNode( m_aSqlParser.parseTree(aErrorMsg,aSql));
+ if ( pSqlParseNode.get() )
+ {
+ m_aAdditiveIterator.setParseTree(pSqlParseNode.get());
+ // normalize the filter
+ OSQLParseNode* pWhereNode = const_cast<OSQLParseNode*>(m_aAdditiveIterator.getWhereTree());
+
+ OSQLParseNode* pCondition = pWhereNode->getChild(1);
+ #if OSL_DEBUG_LEVEL > 0
+ ::rtl::OUString sCondition;
+ pCondition->parseNodeToStr( sCondition, m_xConnection );
+ #endif
+ OSQLParseNode::negateSearchCondition(pCondition);
+
+ pCondition = pWhereNode->getChild(1);
+ #if OSL_DEBUG_LEVEL > 0
+ sCondition = ::rtl::OUString();
+ pCondition->parseNodeToStr( sCondition, m_xConnection );
+ #endif
+ OSQLParseNode::disjunctiveNormalForm(pCondition);
+
+ pCondition = pWhereNode->getChild(1);
+ #if OSL_DEBUG_LEVEL > 0
+ sCondition = ::rtl::OUString();
+ pCondition->parseNodeToStr( sCondition, m_xConnection );
+ #endif
+ OSQLParseNode::absorptions(pCondition);
+
+ pCondition = pWhereNode->getChild(1);
+ #if OSL_DEBUG_LEVEL > 0
+ sCondition = ::rtl::OUString();
+ pCondition->parseNodeToStr( sCondition, m_xConnection );
+ #endif
+ if ( pCondition )
+ {
+ ::std::vector< ::std::vector < PropertyValue > > aFilters;
+ Reference< XNumberFormatter > xFormatter;
+ m_aContext.createComponent( "com.sun.star.util.NumberFormatter", xFormatter );
+ xFormatter->attachNumberFormatsSupplier( m_xNumberFormatsSupplier );
+
+ if (setORCriteria(pCondition, m_aAdditiveIterator, aFilters, xFormatter))
+ {
+ aFilterSeq.realloc(aFilters.size());
+ Sequence<PropertyValue>* pFilters = aFilterSeq.getArray();
+ ::std::vector< ::std::vector < PropertyValue > >::const_iterator aEnd = aFilters.end();
+ ::std::vector< ::std::vector < PropertyValue > >::const_iterator i = aFilters.begin();
+ for ( ; i != aEnd ; ++i)
+ {
+ const ::std::vector < PropertyValue >& rProperties = *i;
+ pFilters->realloc(rProperties.size());
+ PropertyValue* pFilter = pFilters->getArray();
+ ::std::vector < PropertyValue >::const_iterator j = rProperties.begin();
+ ::std::vector < PropertyValue >::const_iterator aEnd2 = rProperties.end();
+ for ( ; j != aEnd2 ; ++j)
+ {
+ *pFilter = *j;
+ ++pFilter;
+ }
+ ++pFilters;
+ }
+ }
+ }
+ // restore
+ m_aAdditiveIterator.setParseTree(pTempNode);
+ }
+ }
+ return aFilterSeq;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::getKeyword( SQLPart _ePart ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getKeyword" );
+ ::rtl::OUString sKeyword;
+ switch(_ePart)
+ {
+ default:
+ OSL_ENSURE( 0, "OSingleSelectQueryComposer::getKeyWord: Invalid enum value!" );
+ // no break, fallback to WHERE
+ case Where:
+ sKeyword = STR_WHERE;
+ break;
+ case Group:
+ sKeyword = STR_GROUP_BY;
+ break;
+ case Having:
+ sKeyword = STR_HAVING;
+ break;
+ case Order:
+ sKeyword = STR_ORDER_BY;
+ break;
+ }
+ return sKeyword;
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString OSingleSelectQueryComposer::getSQLPart( SQLPart _ePart, OSQLParseTreeIterator& _rIterator, sal_Bool _bWithKeyword )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getSQLPart" );
+ TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree);
+ ::rtl::OUString sKeyword( getKeyword( _ePart ) );
+ switch(_ePart)
+ {
+ case Where:
+ F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleWhereTree);
+ break;
+ case Group:
+ F_tmp = TGetParseNode (&OSQLParseTreeIterator::getSimpleGroupByTree);
+ break;
+ case Having:
+ F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleHavingTree);
+ break;
+ case Order:
+ F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleOrderTree);
+ break;
+ default:
+ OSL_ENSURE(0,"Invalid enum value!");
+ }
+
+ ::rtl::OUString sRet = getStatementPart( F_tmp, _rIterator );
+ if ( _bWithKeyword && sRet.getLength() )
+ sRet = sKeyword + sRet;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
diff --git a/dbaccess/source/core/api/StaticSet.cxx b/dbaccess/source/core/api/StaticSet.cxx
new file mode 100644
index 000000000000..de768b6ceb8e
--- /dev/null
+++ b/dbaccess/source/core/api/StaticSet.cxx
@@ -0,0 +1,392 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef DBACCESS_CORE_API_STATICSET_HXX
+#include "StaticSet.hxx"
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_COMPAREBOOKMARK_HPP_
+#include <com/sun/star/sdbcx/CompareBookmark.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XPREPAREDSTATEMENT_HPP_
+#include <com/sun/star/sdbc/XPreparedStatement.hpp>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
+#include <connectivity/CommonTools.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+using namespace connectivity;
+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 OStaticSet::fillValueRow(ORowSetRow& _rRow,sal_Int32 /*_nPosition*/)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::fillValueRow" );
+ _rRow = *m_aSetIter;
+}
+// -------------------------------------------------------------------------
+// ::com::sun::star::sdbcx::XRowLocate
+Any SAL_CALL OStaticSet::getBookmark() throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::getBookmark" );
+ return makeAny(getRow());
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::moveToBookmark" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return absolute(::comphelper::getINT32(bookmark));
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::moveRelativeToBookmark" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ return absolute(::comphelper::getINT32(bookmark)+rows);
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OStaticSet::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::compareBookmarks" );
+ sal_Int32 nFirst = 0, nSecond = 0;
+ _first >>= nFirst;
+ _second >>= nSecond;
+ return (nFirst < nSecond) ? CompareBookmark::LESS : ((nFirst > nSecond) ? CompareBookmark::GREATER : CompareBookmark::EQUAL);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::hasOrderedBookmarks" );
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OStaticSet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::hashBookmark" );
+ return ::comphelper::getINT32(bookmark);
+}
+// -------------------------------------------------------------------------
+sal_Bool OStaticSet::fetchRow()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::fetchRow" );
+ sal_Bool bRet = sal_False;
+ if ( !m_bEnd )
+ bRet = m_xDriverSet->next();
+ if ( bRet )
+ {
+ m_aSet.push_back(new connectivity::ORowVector< connectivity::ORowSetValue >(m_xSetMetaData->getColumnCount()));
+ m_aSetIter = m_aSet.end() - 1;
+ ((*m_aSetIter)->get())[0] = getRow();
+ OCacheSet::fillValueRow(*m_aSetIter,((*m_aSetIter)->get())[0]);
+ }
+ else
+ m_bEnd = sal_True;
+ return bRet;
+}
+// -------------------------------------------------------------------------
+void OStaticSet::fillAllRows()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::fillAllRows" );
+ if(!m_bEnd)
+ {
+ while(m_xDriverSet->next())
+ {
+ ORowSetRow pRow = new connectivity::ORowVector< connectivity::ORowSetValue >(m_xSetMetaData->getColumnCount());
+ m_aSet.push_back(pRow);
+ m_aSetIter = m_aSet.end() - 1;
+ (pRow->get())[0] = getRow();
+ OCacheSet::fillValueRow(pRow,(pRow->get())[0]);
+ }
+ m_bEnd = sal_True;
+ }
+}
+// -------------------------------------------------------------------------
+// XResultSet
+sal_Bool SAL_CALL OStaticSet::next( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::next" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+
+ if(isAfterLast())
+ return sal_False;
+ if(!m_bEnd) // not yet all records fetched
+ {
+ ++m_aSetIter;
+ if(m_aSetIter == m_aSet.end() && !fetchRow())
+ m_aSetIter = m_aSet.end();
+ }
+ else if(!isAfterLast())
+ ++m_aSetIter;
+ return !isAfterLast();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::isBeforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::isBeforeFirst" );
+ return m_aSetIter == m_aSet.begin();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::isAfterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::isAfterLast" );
+ return m_aSetIter == m_aSet.end() && m_bEnd;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::isFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::isFirst" );
+ return m_aSetIter == m_aSet.begin()+1;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::isLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::isLast" );
+ return m_aSetIter == m_aSet.end()-1 && m_bEnd;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::beforeFirst( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::beforeFirst" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ m_aSetIter = m_aSet.begin();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::afterLast( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::afterLast" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ fillAllRows();
+ m_aSetIter = m_aSet.end();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::first( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::first" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ m_aSetIter = m_aSet.begin()+1;
+ if(m_aSetIter == m_aSet.end() && !fetchRow())
+ m_aSetIter = m_aSet.end();
+
+ return m_aSetIter != m_aSet.end();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::last( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::last" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ fillAllRows();
+ m_aSetIter = m_aSet.end()-1;
+
+ return !isBeforeFirst() && !isAfterLast();
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL OStaticSet::getRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::getRow" );
+ OSL_ENSURE(!isAfterLast(),"getRow is not allowed when afterlast record!");
+ OSL_ENSURE(!isBeforeFirst(),"getRow is not allowed when beforefirst record!");
+
+ sal_Int32 nPos = m_aSet.size() - (m_aSet.end() - m_aSetIter);
+ OSL_ENSURE(nPos > 0,"RowPos is < 0");
+ return nPos;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::absolute" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+ OSL_ENSURE(row,"OStaticSet::absolute: INVALID row number!");
+ // if row greater 0 than count from end - row means last
+ if(row < 0)
+ {
+ if(!m_bEnd)
+ fillAllRows();
+
+ sal_Int32 nRow = getRow();
+ nRow += row;
+ if(nRow <= (sal_Int32)m_aSet.size())
+ m_aSetIter = m_aSet.begin() + nRow;
+ else
+ m_aSetIter = m_aSet.begin();
+ }
+ else if(row > 0)
+ {
+ if(row >= (sal_Int32)m_aSet.size())
+ {
+ if(!m_bEnd)
+ {
+ sal_Bool bNext = sal_True;
+ for(sal_Int32 i=m_aSet.size()-1;i < row && bNext;++i)
+ bNext = fetchRow();
+ }
+
+ if(row > (sal_Int32)m_aSet.size())
+ m_aSetIter = m_aSet.end(); // check again
+ else
+ m_aSetIter = m_aSet.begin() + row;
+ }
+ else
+ m_aSetIter = m_aSet.begin() + row;
+ }
+
+ return m_aSetIter != m_aSet.end() && m_aSetIter != m_aSet.begin();
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::relative" );
+ if(!rows)
+ return sal_True;
+
+ sal_Int32 nCurPos = getRow();
+ return absolute(nCurPos+rows);
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::previous( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::previous" );
+ m_bInserted = m_bUpdated = m_bDeleted = sal_False;
+
+ if(m_aSetIter != m_aSet.begin())
+ --m_aSetIter;
+
+ return m_aSetIter != m_aSet.begin();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::refreshRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::refreshRow" );
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::rowUpdated( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::rowUpdated" );
+ return m_bUpdated;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::rowInserted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::rowInserted" );
+ return m_bInserted;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL OStaticSet::rowDeleted( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::rowDeleted" );
+ return m_bDeleted;
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int32 > SAL_CALL OStaticSet::deleteRows( const Sequence< Any >& rows,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::deleteRows" );
+ Sequence< sal_Int32 > aRet(rows.getLength());
+ const Any* pBegin = rows.getConstArray();
+ const Any* pEnd = pBegin + rows.getLength();
+ for(sal_Int32 i=0;pBegin != pEnd; ++pBegin,++i)
+ {
+ deleteRow(*(m_aSet.begin() + comphelper::getINT32(*pBegin)),_xTable);
+ aRet.getArray()[i] = m_bDeleted;
+ }
+ return aRet;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::insertRow( const ORowSetRow& _rInsertRow,const connectivity::OSQLTable& _xTable ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::insertRow" );
+ OCacheSet::insertRow( _rInsertRow,_xTable);
+ if(m_bInserted)
+ {
+ m_aSet.push_back(new ORowVector< ORowSetValue >(*_rInsertRow)); // we don't know where the new row is so we append it to the current rows
+ m_aSetIter = m_aSet.end() - 1;
+ ((*m_aSetIter)->get())[0] = (_rInsertRow->get())[0] = getBookmark();
+ m_bEnd = sal_False;
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::updateRow(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::updateRow" );
+ OCacheSet::updateRow( _rInsertRow,_rOrginalRow,_xTable);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::deleteRow(const ORowSetRow& _rDeleteRow ,const connectivity::OSQLTable& _xTable ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::deleteRow" );
+ OCacheSet::deleteRow(_rDeleteRow,_xTable);
+ if(m_bDeleted)
+ {
+ ORowSetMatrix::iterator aPos = m_aSet.begin()+(_rDeleteRow->get())[0].getInt32();
+ if(aPos == (m_aSet.end()-1))
+ m_aSetIter = m_aSet.end();
+ m_aSet.erase(aPos);
+ }
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::cancelRowUpdates( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::cancelRowUpdates" );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::moveToInsertRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::moveToInsertRow" );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OStaticSet::moveToCurrentRow( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStaticSet::moveToCurrentRow" );
+}
+// -------------------------------------------------------------------------
+
diff --git a/dbaccess/source/core/api/StaticSet.hxx b/dbaccess/source/core/api/StaticSet.hxx
new file mode 100644
index 000000000000..676044cb61f9
--- /dev/null
+++ b/dbaccess/source/core/api/StaticSet.hxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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_STATICSET_HXX
+#define DBACCESS_CORE_API_STATICSET_HXX
+
+#ifndef DBACCESS_CORE_API_CACHESET_HXX
+#include "CacheSet.hxx"
+#endif
+
+namespace dbaccess
+{
+ // is used when nothing is supported by the driver
+ // we use a snapshot
+ class OStaticSet : public OCacheSet
+ {
+ ORowSetMatrix m_aSet;
+ ORowSetMatrix::iterator m_aSetIter;
+ sal_Bool m_bEnd;
+ sal_Bool fetchRow();
+ void fillAllRows();
+ public:
+ OStaticSet()
+ : m_aSetIter(m_aSet.end())
+ , m_bEnd(sal_False)
+ {
+ m_aSet.push_back(NULL); // this is the beforefirst record
+ }
+
+ 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::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);
+ 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::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_STATICSET_HXX
+
diff --git a/dbaccess/source/core/api/TableDeco.cxx b/dbaccess/source/core/api/TableDeco.cxx
new file mode 100644
index 000000000000..a296833ab6ef
--- /dev/null
+++ b/dbaccess/source/core/api/TableDeco.cxx
@@ -0,0 +1,758 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _DBA_CORE_TABLEDECORATOR_HXX_
+#include "TableDeco.hxx"
+#endif
+#ifndef _DBACORE_DEFINITIONCOLUMN_HXX_
+#include <definitioncolumn.hxx>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HXX_
+#include "core_resource.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HRC_
+#include "core_resource.hrc"
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COMPHELPER_ENUMHELPER_HXX_
+#include <comphelper/enumhelper.hxx>
+#endif
+#ifndef _COMPHELPER_CONTAINER_HXX_
+#include <comphelper/container.hxx>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XREFRESHLISTENER_HPP_
+#include <com/sun/star/util/XRefreshListener.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
+#include <com/sun/star/sdbc/XConnection.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _DBHELPER_DBEXCEPTION_HXX_
+#include <connectivity/dbexception.hxx>
+#endif
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _COMPHELPER_EXTRACT_HXX_
+#include <comphelper/extract.hxx>
+#endif
+#ifndef DBA_CONTAINERMEDIATOR_HXX
+#include "ContainerMediator.hxx"
+#endif
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::dbtools;
+using namespace ::cppu;
+
+//==========================================================================
+//= ODBTableDecorator
+//==========================================================================
+DBG_NAME(ODBTableDecorator)
+// -----------------------------------------------------------------------------
+ODBTableDecorator::ODBTableDecorator( const Reference< XConnection >& _rxConnection, const Reference< XColumnsSupplier >& _rxNewTable,
+ const Reference< XNumberFormatsSupplier >& _rxNumberFormats, const Reference< XNameAccess >& _xColumnDefinitions ) throw(SQLException)
+ :OTableDescriptor_BASE(m_aMutex)
+ ,ODataSettings(OTableDescriptor_BASE::rBHelper)
+ ,m_xTable(_rxNewTable)
+ ,m_xColumnDefinitions(_xColumnDefinitions)
+ ,m_xConnection( _rxConnection )
+ ,m_xMetaData( _rxConnection.is() ? _rxConnection->getMetaData() : Reference< XDatabaseMetaData >() )
+ ,m_xNumberFormats( _rxNumberFormats )
+ ,m_nPrivileges(-1)
+ ,m_pColumns(NULL)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::ODBTableDecorator" );
+ DBG_CTOR(ODBTableDecorator, NULL);
+ ODataSettings::registerPropertiesFor(this);
+}
+// -------------------------------------------------------------------------
+ODBTableDecorator::~ODBTableDecorator()
+{
+ DBG_DTOR(ODBTableDecorator, NULL);
+ if ( m_pColumns )
+ delete m_pColumns;
+}
+
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > ODBTableDecorator::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getImplementationId" );
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::disposing" );
+ OPropertySetHelper::disposing();
+ OTableDescriptor_BASE::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+ m_xTable = NULL;
+ m_xMetaData = NULL;
+ m_pTables = NULL;
+ m_xColumnDefinitions = NULL;
+ m_xNumberFormats = NULL;
+ if ( m_pColumns )
+ m_pColumns->disposing();
+ m_xColumnMediator = NULL;
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODBTableDecorator::convertFastPropertyValue(
+ Any & rConvertedValue,
+ Any & rOldValue,
+ sal_Int32 nHandle,
+ const Any& rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::convertFastPropertyValue" );
+ sal_Bool bRet = sal_True;
+ switch(nHandle)
+ {
+ case PROPERTY_ID_PRIVILEGES:
+ case PROPERTY_ID_FILTER:
+ case PROPERTY_ID_ORDER:
+ case PROPERTY_ID_APPLYFILTER:
+ case PROPERTY_ID_FONT:
+ case PROPERTY_ID_ROW_HEIGHT:
+ case PROPERTY_ID_TEXTCOLOR:
+ case PROPERTY_ID_TEXTLINECOLOR:
+ case PROPERTY_ID_TEXTEMPHASIS:
+ case PROPERTY_ID_TEXTRELIEF:
+ case PROPERTY_ID_FONTCHARWIDTH:
+ case PROPERTY_ID_FONTCHARSET:
+ case PROPERTY_ID_FONTFAMILY:
+ case PROPERTY_ID_FONTHEIGHT:
+ case PROPERTY_ID_FONTKERNING:
+ case PROPERTY_ID_FONTNAME:
+ case PROPERTY_ID_FONTORIENTATION:
+ case PROPERTY_ID_FONTPITCH:
+ case PROPERTY_ID_FONTSLANT:
+ case PROPERTY_ID_FONTSTRIKEOUT:
+ case PROPERTY_ID_FONTSTYLENAME:
+ case PROPERTY_ID_FONTUNDERLINE:
+ case PROPERTY_ID_FONTWEIGHT:
+ case PROPERTY_ID_FONTWIDTH:
+ case PROPERTY_ID_FONTWORDLINEMODE:
+ case PROPERTY_ID_FONTTYPE:
+ bRet = ODataSettings::convertFastPropertyValue(rConvertedValue, rOldValue,nHandle,rValue);
+ break;
+
+ default:
+ {
+ Any aValue;
+ getFastPropertyValue(aValue,nHandle);
+ bRet = ::comphelper::tryPropertyValue(rConvertedValue,rOldValue,rValue,aValue,::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
+ }
+ break; // we assume that it works
+ }
+ return bRet;
+}
+// -----------------------------------------------------------------------------
+void ODBTableDecorator::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::setFastPropertyValue_NoBroadcast" );
+ switch(_nHandle)
+ {
+ case PROPERTY_ID_PRIVILEGES:
+ OSL_ENSURE(0,"Property is readonly!");
+ case PROPERTY_ID_FILTER:
+ case PROPERTY_ID_ORDER:
+ case PROPERTY_ID_APPLYFILTER:
+ case PROPERTY_ID_FONT:
+ case PROPERTY_ID_ROW_HEIGHT:
+ case PROPERTY_ID_TEXTCOLOR:
+ case PROPERTY_ID_TEXTLINECOLOR:
+ case PROPERTY_ID_TEXTEMPHASIS:
+ case PROPERTY_ID_TEXTRELIEF:
+ case PROPERTY_ID_FONTCHARWIDTH:
+ case PROPERTY_ID_FONTCHARSET:
+ case PROPERTY_ID_FONTFAMILY:
+ case PROPERTY_ID_FONTHEIGHT:
+ case PROPERTY_ID_FONTKERNING:
+ case PROPERTY_ID_FONTNAME:
+ case PROPERTY_ID_FONTORIENTATION:
+ case PROPERTY_ID_FONTPITCH:
+ case PROPERTY_ID_FONTSLANT:
+ case PROPERTY_ID_FONTSTRIKEOUT:
+ case PROPERTY_ID_FONTSTYLENAME:
+ case PROPERTY_ID_FONTUNDERLINE:
+ case PROPERTY_ID_FONTWEIGHT:
+ case PROPERTY_ID_FONTWIDTH:
+ case PROPERTY_ID_FONTWORDLINEMODE:
+ case PROPERTY_ID_FONTTYPE:
+
+ ODataSettings::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+ break;
+ case PROPERTY_ID_CATALOGNAME:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ xProp->setPropertyValue(PROPERTY_CATALOGNAME,_rValue);
+ }
+ break;
+ case PROPERTY_ID_SCHEMANAME:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ xProp->setPropertyValue(PROPERTY_SCHEMANAME,_rValue);
+ }
+ break;
+ case PROPERTY_ID_NAME:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ xProp->setPropertyValue(PROPERTY_NAME,_rValue);
+ }
+ break;
+ case PROPERTY_ID_DESCRIPTION:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ xProp->setPropertyValue(PROPERTY_DESCRIPTION,_rValue);
+ }
+ break;
+ case PROPERTY_ID_TYPE:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ xProp->setPropertyValue(PROPERTY_TYPE,_rValue);
+ }
+ break;
+ }
+}
+//------------------------------------------------------------------------------
+void ODBTableDecorator::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getFastPropertyValue" );
+ switch(_nHandle)
+ {
+ case PROPERTY_ID_PRIVILEGES:
+ {
+ if ( -1 == m_nPrivileges )
+ fillPrivileges();
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ if ( xInfo->hasPropertyByName(PROPERTY_PRIVILEGES) )
+ {
+ _rValue <<= m_nPrivileges;
+ break;
+ }
+ }
+ // run through
+
+ case PROPERTY_ID_FILTER:
+ case PROPERTY_ID_ORDER:
+ case PROPERTY_ID_APPLYFILTER:
+ case PROPERTY_ID_FONT:
+ case PROPERTY_ID_ROW_HEIGHT:
+ case PROPERTY_ID_TEXTCOLOR:
+ case PROPERTY_ID_TEXTLINECOLOR:
+ case PROPERTY_ID_TEXTEMPHASIS:
+ case PROPERTY_ID_TEXTRELIEF:
+ case PROPERTY_ID_FONTCHARWIDTH:
+ case PROPERTY_ID_FONTCHARSET:
+ case PROPERTY_ID_FONTFAMILY:
+ case PROPERTY_ID_FONTHEIGHT:
+ case PROPERTY_ID_FONTKERNING:
+ case PROPERTY_ID_FONTNAME:
+ case PROPERTY_ID_FONTORIENTATION:
+ case PROPERTY_ID_FONTPITCH:
+ case PROPERTY_ID_FONTSLANT:
+ case PROPERTY_ID_FONTSTRIKEOUT:
+ case PROPERTY_ID_FONTSTYLENAME:
+ case PROPERTY_ID_FONTUNDERLINE:
+ case PROPERTY_ID_FONTWEIGHT:
+ case PROPERTY_ID_FONTWIDTH:
+ case PROPERTY_ID_FONTWORDLINEMODE:
+ case PROPERTY_ID_FONTTYPE:
+ ODataSettings::getFastPropertyValue(_rValue, _nHandle);
+ break;
+ case PROPERTY_ID_CATALOGNAME:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ _rValue = xProp->getPropertyValue(PROPERTY_CATALOGNAME);
+ }
+ break;
+ case PROPERTY_ID_SCHEMANAME:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ _rValue = xProp->getPropertyValue(PROPERTY_SCHEMANAME);
+ }
+ break;
+ case PROPERTY_ID_NAME:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ _rValue = xProp->getPropertyValue(PROPERTY_NAME);
+ }
+ break;
+ case PROPERTY_ID_DESCRIPTION:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ _rValue = xProp->getPropertyValue(PROPERTY_DESCRIPTION);
+ }
+ break;
+ case PROPERTY_ID_TYPE:
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ _rValue = xProp->getPropertyValue(PROPERTY_TYPE);
+ }
+ break;
+ default:
+ OSL_ENSURE(0,"Invalid Handle for table");
+ }
+}
+// -------------------------------------------------------------------------
+void ODBTableDecorator::construct()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::construct" );
+ sal_Bool bNotFound = sal_True;
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ if ( xProp.is() )
+ {
+ Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ bNotFound = !xInfo->hasPropertyByName(PROPERTY_PRIVILEGES);
+ }
+ if ( bNotFound )
+ registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, PropertyAttribute::BOUND | PropertyAttribute::READONLY,
+ &m_nPrivileges, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+}
+// -----------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* ODBTableDecorator::createArrayHelper(sal_Int32 /*_nId*/) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createArrayHelper" );
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+
+ Sequence< Property > aTableProps = xInfo->getProperties();
+ Property* pIter = aTableProps.getArray();
+ Property* pEnd = pIter + aTableProps.getLength();
+ for (;pIter != pEnd ; ++pIter)
+ {
+ if (0 == pIter->Name.compareToAscii(PROPERTY_CATALOGNAME))
+ pIter->Handle = PROPERTY_ID_CATALOGNAME;
+ else if (0 ==pIter->Name.compareToAscii(PROPERTY_SCHEMANAME))
+ pIter->Handle = PROPERTY_ID_SCHEMANAME;
+ else if (0 ==pIter->Name.compareToAscii(PROPERTY_NAME))
+ pIter->Handle = PROPERTY_ID_NAME;
+ else if (0 ==pIter->Name.compareToAscii(PROPERTY_DESCRIPTION))
+ pIter->Handle = PROPERTY_ID_DESCRIPTION;
+ else if (0 ==pIter->Name.compareToAscii(PROPERTY_TYPE))
+ pIter->Handle = PROPERTY_ID_TYPE;
+ else if (0 ==pIter->Name.compareToAscii(PROPERTY_PRIVILEGES))
+ pIter->Handle = PROPERTY_ID_PRIVILEGES;
+ }
+
+ describeProperties(aTableProps);
+
+ return new ::cppu::OPropertyArrayHelper(aTableProps);
+}
+// -----------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper & SAL_CALL ODBTableDecorator::getInfoHelper()
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getInfoHelper" );
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+
+ Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ bool bIsDescriptor = (xInfo->getPropertyByName(PROPERTY_NAME).Attributes & PropertyAttribute::READONLY) == 0;
+
+ return *ODBTableDecorator_PROP::getArrayHelper( bIsDescriptor ? 0 : 1 );
+
+ // TODO: this is a HACK, and prone to errors
+ // The OIdPropertyArrayUsageHelper is intended for classes where there exists a known, limited
+ // number of different property set infos (distinguished by the ID), all implemented by this very
+ // same class.
+ // However, in this case here we have an unknown, potentially unlimited number of different
+ // property set infos: Depending on the table for which we act as decorator, different property
+ // sets might exist.
+}
+// -------------------------------------------------------------------------
+// XServiceInfo
+IMPLEMENT_SERVICE_INFO1(ODBTableDecorator, "com.sun.star.sdb.dbaccess.ODBTableDecorator", SERVICE_SDBCX_TABLE)
+// -------------------------------------------------------------------------
+Any SAL_CALL ODBTableDecorator::queryInterface( const Type & rType ) throw(RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::queryInterface" );
+ Any aRet;
+ if(m_xTable.is())
+ {
+ aRet = m_xTable->queryInterface(rType);
+ if(aRet.hasValue())
+ { // now we know that our table supports this type so we return ourself
+ aRet = OTableDescriptor_BASE::queryInterface(rType);
+ if(!aRet.hasValue())
+ aRet = ODataSettings::queryInterface(rType);
+ }
+ }
+
+ return aRet;
+}
+// -------------------------------------------------------------------------
+Sequence< Type > SAL_CALL ODBTableDecorator::getTypes( ) throw(RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getTypes" );
+ Reference<XTypeProvider> xTypes(m_xTable,UNO_QUERY);
+ OSL_ENSURE(xTypes.is(),"Table must be a TypePropvider!");
+ return xTypes->getTypes();
+}
+
+// -----------------------------------------------------------------------------
+// XRename,
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::rename( const ::rtl::OUString& _rNewName ) throw(SQLException, ElementExistException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::rename" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+ Reference<XRename> xRename(m_xTable,UNO_QUERY);
+ if(xRename.is())
+ {
+// ::rtl::OUString sOldName;
+// Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+// xProp->getPropertyValue(PROPERTY_NAME) >>= sOldName;
+ xRename->rename(_rNewName);
+ }
+ else // not supported
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NO_TABLE_RENAME),*this,SQLSTATE_GENERAL,1000,Any() );
+}
+
+// XAlterTable,
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::alterColumnByName( const ::rtl::OUString& _rName, const Reference< XPropertySet >& _rxDescriptor ) throw(SQLException, NoSuchElementException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::alterColumnByName" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+ Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY);
+ if(xAlter.is())
+ {
+ xAlter->alterColumnByName(_rName,_rxDescriptor);
+ }
+ else
+ throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_ALTER_BY_NAME),*this,SQLSTATE_GENERAL,1000,Any() );
+ if(m_pColumns)
+ m_pColumns->refresh();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::alterColumnByIndex( sal_Int32 _nIndex, const Reference< XPropertySet >& _rxDescriptor ) throw(SQLException, IndexOutOfBoundsException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::alterColumnByIndex" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+ Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY);
+ if(xAlter.is())
+ {
+ xAlter->alterColumnByIndex(_nIndex,_rxDescriptor);
+ if(m_pColumns)
+ m_pColumns->refresh();
+ }
+ else // not supported
+ throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_ALTER_BY_INDEX),*this,SQLSTATE_GENERAL,1000,Any() );
+}
+// -----------------------------------------------------------------------------
+Reference< XNameAccess> ODBTableDecorator::getIndexes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getIndexes" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+ return Reference< XIndexesSupplier>(m_xTable,UNO_QUERY)->getIndexes();
+}
+// -------------------------------------------------------------------------
+Reference< XIndexAccess> ODBTableDecorator::getKeys() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getKeys" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+ return Reference< XKeysSupplier>(m_xTable,UNO_QUERY)->getKeys();
+}
+// -------------------------------------------------------------------------
+Reference< XNameAccess> ODBTableDecorator::getColumns() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getColumns" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+
+ if(!m_pColumns)
+ refreshColumns();
+
+ return m_pColumns;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODBTableDecorator::getName() throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getName" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+ Reference<XNamed> xName(m_xTable,UNO_QUERY);
+ OSL_ENSURE(xName.is(),"Table should support the XNamed interface");
+ return xName->getName();
+}
+// -----------------------------------------------------------------------------
+sal_Int64 SAL_CALL ODBTableDecorator::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getSomething" );
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ sal_Int64 nRet = 0;
+ Reference<XUnoTunnel> xTunnel(m_xTable,UNO_QUERY);
+ if(xTunnel.is())
+ nRet = xTunnel->getSomething(rId);
+ return nRet;
+}
+// -----------------------------------------------------------------------------
+Sequence< sal_Int8 > ODBTableDecorator::getUnoTunnelImplementationId()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getUnoTunnelImplementationId" );
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+// -----------------------------------------------------------------------------
+void ODBTableDecorator::fillPrivileges() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::fillPrivileges" );
+ // somebody is asking for the privileges an we do not know them, yet
+ m_nPrivileges = 0;
+ try
+ {
+ Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
+ if ( xProp.is() )
+ {
+ if ( xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES) )
+ {
+ xProp->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
+ }
+ if ( m_nPrivileges == 0 ) // second chance
+ {
+ ::rtl::OUString sCatalog,sSchema,sName;
+ xProp->getPropertyValue(PROPERTY_CATALOGNAME) >>= sCatalog;
+ xProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema;
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
+ m_nPrivileges = ::dbtools::getTablePrivileges(getMetaData(),sCatalog,sSchema, sName);
+ }
+ }
+ }
+ catch(const SQLException& e)
+ {
+ (void)e;
+ DBG_ERROR("ODBTableDecorator::ODBTableDecorator : could not collect the privileges !");
+ }
+}
+// -----------------------------------------------------------------------------
+Reference< XPropertySet > SAL_CALL ODBTableDecorator::createDataDescriptor( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createDataDescriptor" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+
+ Reference< XDataDescriptorFactory > xFactory( m_xTable, UNO_QUERY );
+ DBG_ASSERT( xFactory.is(), "ODBTableDecorator::createDataDescriptor: invalid table!" );
+ Reference< XColumnsSupplier > xColsSupp;
+ if ( xFactory.is() )
+ xColsSupp = xColsSupp.query( xFactory->createDataDescriptor() );
+
+ return new ODBTableDecorator(
+ m_xConnection,
+ xColsSupp,
+ m_xNumberFormats,
+ NULL
+ );
+}
+// -----------------------------------------------------------------------------
+Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL ODBTableDecorator::getPropertySetInfo( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getPropertySetInfo" );
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+}
+// -----------------------------------------------------------------------------
+void ODBTableDecorator::refreshColumns()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::refreshColumns" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
+
+ ::std::vector< ::rtl::OUString> aVector;
+
+ Reference<XNameAccess> xNames;
+ if(m_xTable.is())
+ {
+ xNames = m_xTable->getColumns();
+ if(xNames.is())
+ {
+ Sequence< ::rtl::OUString> aNames = xNames->getElementNames();
+ const ::rtl::OUString* pIter = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aNames.getLength();
+ for(;pIter != pEnd;++pIter)
+ aVector.push_back(*pIter);
+ }
+ }
+ if(!m_pColumns)
+ {
+ OColumns* pCol = new OColumns(*this,m_aMutex,xNames,m_xMetaData.is() && m_xMetaData->supportsMixedCaseQuotedIdentifiers(),aVector,
+ this,this,
+ m_xMetaData.is() && m_xMetaData->supportsAlterTableWithAddColumn(),
+ m_xMetaData.is() && m_xMetaData->supportsAlterTableWithDropColumn());
+
+ pCol->setParent(*this);
+ OContainerMediator* pMediator = new OContainerMediator( pCol, m_xColumnDefinitions, m_xConnection, OContainerMediator::eColumns );
+ m_xColumnMediator = pMediator;
+ pCol->setMediator( pMediator );
+ m_pColumns = pCol;
+ }
+ else
+ m_pColumns->reFill(aVector);
+}
+// -----------------------------------------------------------------------------
+OColumn* ODBTableDecorator::createColumn(const ::rtl::OUString& _rName) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createColumn" );
+ OColumn* pReturn = NULL;
+
+ Reference<XNameAccess> xNames;
+ if ( m_xTable.is() )
+ {
+ xNames = m_xTable->getColumns();
+
+ if ( xNames.is() && xNames->hasByName(_rName) )
+ {
+ Reference<XPropertySet> xProp(xNames->getByName(_rName),UNO_QUERY);
+
+ Reference<XPropertySet> xColumnDefintion;
+ if ( m_xColumnDefinitions.is() && m_xColumnDefinitions->hasByName(_rName))
+ xColumnDefintion.set(m_xColumnDefinitions->getByName(_rName),UNO_QUERY);
+
+ pReturn = new OTableColumnWrapper( xProp, xColumnDefintion, false );
+ }
+ }
+ return pReturn;
+}
+// -----------------------------------------------------------------------------
+void ODBTableDecorator::columnAppended( const Reference< XPropertySet >& /*_rxSourceDescriptor*/ )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::columnAppended" );
+ // not interested in
+}
+// -----------------------------------------------------------------------------
+void ODBTableDecorator::columnDropped(const ::rtl::OUString& _sName)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::columnDropped" );
+ Reference<XDrop> xDrop(m_xColumnDefinitions,UNO_QUERY);
+ if ( xDrop.is() && m_xColumnDefinitions->hasByName(_sName) )
+ xDrop->dropByName(_sName);
+}
+
+// -----------------------------------------------------------------------------
+Reference< XPropertySet > ODBTableDecorator::createColumnDescriptor()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createColumnDescriptor" );
+ Reference<XDataDescriptorFactory> xNames;
+ if(m_xTable.is())
+ xNames.set(m_xTable->getColumns(),UNO_QUERY);
+ Reference< XPropertySet > xRet;
+ if ( xNames.is() )
+ xRet = new OTableColumnDescriptorWrapper( xNames->createDataDescriptor(), false, true );
+ return xRet;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::acquire() throw()
+{
+ OTableDescriptor_BASE::acquire();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::release() throw()
+{
+ OTableDescriptor_BASE::release();
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL ODBTableDecorator::setName( const ::rtl::OUString& /*aName*/ ) throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::setName" );
+ throwFunctionNotSupportedException( "XNamed::setName", *this );
+}
+
+// -----------------------------------------------------------------------------
+
+
diff --git a/dbaccess/source/core/api/View.cxx b/dbaccess/source/core/api/View.cxx
new file mode 100644
index 000000000000..fa528d203466
--- /dev/null
+++ b/dbaccess/source/core/api/View.cxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * 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: View.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * 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 "View.hxx"
+#include "dbastrings.hrc"
+
+#include "connectivity/dbexception.hxx"
+#include "connectivity/dbtools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/exc_hlp.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/sharedunocomponent.hxx>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using namespace ::com::sun::star::uno;
+ using ::com::sun::star::sdbc::XDatabaseMetaData;
+ using ::com::sun::star::sdbc::SQLException;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::lang::WrappedTargetException;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::sdbc::XResultSet;
+ using ::com::sun::star::sdbc::XStatement;
+ using ::com::sun::star::lang::DisposedException;
+ using ::com::sun::star::sdbc::XRow;
+ /** === end UNO using === **/
+
+ ::rtl::OUString lcl_getServiceNameForSetting(const Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,const ::rtl::OUString& i_sSetting)
+ {
+ ::rtl::OUString sSupportService;
+ Any aValue;
+ if ( dbtools::getDataSourceSetting(_xConnection,i_sSetting,aValue) )
+ {
+ aValue >>= sSupportService;
+ }
+ return sSupportService;
+ }
+ //====================================================================
+ //= View
+ //====================================================================
+ //--------------------------------------------------------------------
+ View::View( const Reference< XConnection >& _rxConnection, sal_Bool _bCaseSensitive,
+ const ::rtl::OUString& _rCatalogName,const ::rtl::OUString& _rSchemaName, const ::rtl::OUString& _rName )
+ :View_Base( _bCaseSensitive, _rName, _rxConnection->getMetaData(), 0, ::rtl::OUString(), _rSchemaName, _rCatalogName )
+ {
+ m_nCommandHandle = getProperty(PROPERTY_COMMAND).Handle;
+ try
+ {
+ Reference<XMultiServiceFactory> xFac(_rxConnection,UNO_QUERY_THROW);
+ static const ::rtl::OUString s_sViewAccess(RTL_CONSTASCII_USTRINGPARAM("ViewAccessServiceName"));
+ m_xViewAccess.set(xFac->createInstance(lcl_getServiceNameForSetting(_rxConnection,s_sViewAccess)),UNO_QUERY);
+ }
+ catch(const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ View::~View()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_FORWARD_REFCOUNT( View, View_Base )
+ IMPLEMENT_GET_IMPLEMENTATION_ID( View )
+ // -------------------------------------------------------------------------
+ Any SAL_CALL View::queryInterface( const Type & _rType ) throw(RuntimeException)
+ {
+ if(_rType == getCppuType( (Reference<XAlterView>*)0) && !m_xViewAccess.is() )
+ return Any();
+ Any aReturn = View_Base::queryInterface( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = View_IBASE::queryInterface( _rType );
+ return aReturn;
+ }
+ // -------------------------------------------------------------------------
+ Sequence< Type > SAL_CALL View::getTypes( ) throw(RuntimeException)
+ {
+ Type aAlterType = getCppuType( (Reference<XAlterView>*)0);
+
+ Sequence< Type > aTypes( ::comphelper::concatSequences(View_Base::getTypes(),View_IBASE::getTypes()) );
+ ::std::vector<Type> aOwnTypes;
+ aOwnTypes.reserve(aTypes.getLength());
+
+ const Type* pIter = aTypes.getConstArray();
+ const Type* pEnd = pIter + aTypes.getLength();
+ for(;pIter != pEnd ;++pIter)
+ {
+ if( (*pIter != aAlterType || m_xViewAccess.is()) )
+ aOwnTypes.push_back(*pIter);
+ }
+
+ Type* pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
+ return Sequence< Type >(pTypes, aOwnTypes.size());
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL View::alterCommand( const ::rtl::OUString& _rNewCommand ) throw (SQLException, RuntimeException)
+ {
+ OSL_ENSURE(m_xViewAccess.is(),"Illegal call to AlterView!");
+ m_xViewAccess->alterCommand(this,_rNewCommand);
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL View::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+ {
+ if ( _nHandle == m_nCommandHandle && m_xViewAccess.is() )
+ {
+ // retrieve the very current command, don't rely on the base classes cached value
+ // (which we initialized empty, anyway)
+ _rValue <<= m_xViewAccess->getCommand(const_cast<View*>(this));
+ return;
+ }
+
+ View_Base::getFastPropertyValue( _rValue, _nHandle );
+ }
+ // -----------------------------------------------------------------------------
+//........................................................................
+} // namespace dbaccess
+//........................................................................
diff --git a/dbaccess/source/core/api/WrappedResultSet.cxx b/dbaccess/source/core/api/WrappedResultSet.cxx
new file mode 100644
index 000000000000..22e8f61383ac
--- /dev/null
+++ b/dbaccess/source/core/api/WrappedResultSet.cxx
@@ -0,0 +1,255 @@
+/*************************************************************************
+ *
+ * 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" );
+ if ( m_xRowLocate.is() )
+ {
+ return m_xRowLocate->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" );
+ return m_xRowLocate->moveToBookmark( bookmark );
+}
+// -------------------------------------------------------------------------
+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" );
+ return m_xRowLocate->moveRelativeToBookmark( bookmark,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 m_xRowLocate->compareBookmarks( _first,_second );
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL WrappedResultSet::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::hasOrderedBookmarks" );
+ return m_xRowLocate->hasOrderedBookmarks();
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL WrappedResultSet::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "WrappedResultSet::hashBookmark" );
+ return m_xRowLocate->hashBookmark(bookmark);
+}
+// -------------------------------------------------------------------------
+// ::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()) = getBookmark();
+}
+// -------------------------------------------------------------------------
+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" );
+ m_xUpd->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 000000000000..082811748e6a
--- /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/callablestatement.cxx b/dbaccess/source/core/api/callablestatement.cxx
new file mode 100644
index 000000000000..22057ff7a9f6
--- /dev/null
+++ b/dbaccess/source/core/api/callablestatement.cxx
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef _DBA_COREAPI_CALLABLESTATEMENT_HXX_
+#include <callablestatement.hxx>
+#endif
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::cppu;
+using namespace ::osl;
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > OCallableStatement::getTypes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getTypes" );
+ OTypeCollection aTypes(::getCppuType( (const Reference< XRow > *)0 ),
+ ::getCppuType( (const Reference< XOutParameters > *)0 ),
+ OPreparedStatement::getTypes() );
+
+ return aTypes.getTypes();
+}
+
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > OCallableStatement::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getImplementationId" );
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// com::sun::star::uno::XInterface
+//--------------------------------------------------------------------------
+Any OCallableStatement::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::queryInterface" );
+ Any aIface = OPreparedStatement::queryInterface( rType );
+ if (!aIface.hasValue())
+ aIface = ::cppu::queryInterface(
+ rType,
+ static_cast< XRow * >( this ),
+ static_cast< XOutParameters * >( this ));
+ return aIface;
+}
+
+//--------------------------------------------------------------------------
+void OCallableStatement::acquire() throw ()
+{
+ OPreparedStatement::acquire();
+}
+
+//--------------------------------------------------------------------------
+void OCallableStatement::release() throw ()
+{
+ OPreparedStatement::release();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OCallableStatement::getImplementationName( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getImplementationName" );
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OCallableStatement");
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OCallableStatement::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getSupportedServiceNames" );
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS.getArray()[0] = SERVICE_SDBC_CALLABLESTATEMENT;
+ aSNS.getArray()[1] = SERVICE_SDB_CALLABLESTATEMENT;
+ return aSNS;
+}
+
+// XOutParameters
+//------------------------------------------------------------------------------
+void SAL_CALL OCallableStatement::registerOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::registerOutParameter" );
+ MutexGuard aGuard(m_aMutex);
+
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+
+ Reference< XOutParameters >(m_xAggregateAsSet, UNO_QUERY)->registerOutParameter( parameterIndex, sqlType, typeName );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OCallableStatement::registerNumericOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, sal_Int32 scale ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::registerNumericOutParameter" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ Reference< XOutParameters >(m_xAggregateAsSet, UNO_QUERY)->registerNumericOutParameter( parameterIndex, sqlType, scale );
+}
+
+// XRow
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OCallableStatement::wasNull( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::wasNull" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->wasNull();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OCallableStatement::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getString" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getString( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OCallableStatement::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getBoolean" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getBoolean( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+sal_Int8 SAL_CALL OCallableStatement::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getByte" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getByte( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 SAL_CALL OCallableStatement::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getShort" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getShort( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OCallableStatement::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getInt" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getInt( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+sal_Int64 SAL_CALL OCallableStatement::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getLong" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getLong( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+float SAL_CALL OCallableStatement::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getFloat" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getFloat( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+double SAL_CALL OCallableStatement::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getDouble" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getDouble( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL OCallableStatement::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getBytes" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getBytes( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+::com::sun::star::util::Date SAL_CALL OCallableStatement::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getDate" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getDate( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+::com::sun::star::util::Time SAL_CALL OCallableStatement::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getTime" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getTime( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+::com::sun::star::util::DateTime SAL_CALL OCallableStatement::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getTimestamp" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getTimestamp( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL OCallableStatement::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getBinaryStream" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getBinaryStream( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL OCallableStatement::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getCharacterStream" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getCharacterStream( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL OCallableStatement::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", "OCallableStatement::getObject" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getObject( columnIndex, typeMap );
+}
+
+//------------------------------------------------------------------------------
+Reference< XRef > SAL_CALL OCallableStatement::getRef( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getRef" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getRef( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL OCallableStatement::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getBlob" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getBlob( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Reference< XClob > SAL_CALL OCallableStatement::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getClob" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getClob( columnIndex );
+}
+
+//------------------------------------------------------------------------------
+Reference< XArray > SAL_CALL OCallableStatement::getArray( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OCallableStatement::getArray" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XRow >(m_xAggregateAsSet, UNO_QUERY)->getArray( columnIndex );
+}
+
+
diff --git a/dbaccess/source/core/api/column.cxx b/dbaccess/source/core/api/column.cxx
new file mode 100644
index 000000000000..292bf5694793
--- /dev/null
+++ b/dbaccess/source/core/api/column.cxx
@@ -0,0 +1,481 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "ContainerMediator.hxx"
+#include "apitools.hxx"
+#include "column.hxx"
+#include "core_resource.hrc"
+#include "core_resource.hxx"
+#include "dbastrings.hrc"
+#include "sdbcoretools.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+
+#include <comphelper/basicio.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/TTableHelper.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+
+#include <algorithm>
+
+using namespace dbaccess;
+using namespace connectivity;
+using namespace connectivity;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+DBG_NAME(OColumn)
+
+//============================================================
+//= OColumn
+//============================================================
+//--------------------------------------------------------------------------
+OColumn::OColumn( const bool _bNameIsReadOnly )
+ :OColumnBase( m_aMutex )
+ ,::comphelper::OPropertyContainer( OColumnBase::rBHelper )
+{
+ DBG_CTOR(OColumn, NULL);
+
+ registerProperty( PROPERTY_NAME, PROPERTY_ID_NAME, _bNameIsReadOnly ? PropertyAttribute::READONLY : 0,
+ &m_sName, ::getCppuType( &m_sName ) );
+}
+
+//--------------------------------------------------------------------------
+OColumn::~OColumn()
+{
+ DBG_DTOR(OColumn, NULL);
+}
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > OColumn::getTypes() throw (RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ OColumnBase::getTypes(),
+ ::comphelper::OPropertyContainer::getTypes()
+ );
+}
+
+// com::sun::star::uno::XInterface
+IMPLEMENT_FORWARD_XINTERFACE2( OColumn, OColumnBase, ::comphelper::OPropertyContainer )
+
+// ::com::sun::star::lang::XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OColumn::getImplementationName( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OColumn");
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OColumn::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OColumn::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS[0] = SERVICE_SDBCX_COLUMN;
+ return aSNS;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OColumn::disposing()
+{
+ OPropertyContainer::disposing();
+}
+
+// com::sun::star::beans::XPropertySet
+//------------------------------------------------------------------------------
+Reference< XPropertySetInfo > OColumn::getPropertySetInfo() throw (RuntimeException)
+{
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OColumn::getName( ) throw(::com::sun::star::uno::RuntimeException)
+{
+ return m_sName;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OColumn::setName( const ::rtl::OUString& _rName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ m_sName = _rName;
+}
+
+// -----------------------------------------------------------------------------
+void OColumn::fireValueChange(const ::connectivity::ORowSetValue& /*_rOldValue*/)
+{
+ DBG_ERROR( "OColumn::fireValueChange: not implemented!" );
+}
+
+//------------------------------------------------------------------------------
+void OColumn::registerProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void* _pPointerToMember, const Type& _rMemberType )
+{
+ ::comphelper::OPropertyContainer::registerProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rMemberType );
+}
+
+//------------------------------------------------------------------------------
+void OColumn::registerMayBeVoidProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, Any* _pPointerToMember, const Type& _rExpectedType )
+{
+ ::comphelper::OPropertyContainer::registerMayBeVoidProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rExpectedType );
+}
+
+//------------------------------------------------------------------------------
+void OColumn::registerPropertyNoMember( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Type& _rType, const void* _pInitialValue )
+{
+ ::comphelper::OPropertyContainer::registerPropertyNoMember( _rName, _nHandle, _nAttributes, _rType, _pInitialValue );
+}
+
+//============================================================
+//= OColumns
+//============================================================
+DBG_NAME(OColumns);
+
+//--------------------------------------------------------------------------
+OColumns::OColumns(::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ sal_Bool _bCaseSensitive,const ::std::vector< ::rtl::OUString> &_rVector,
+ IColumnFactory* _pColFactory,
+ ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
+ sal_Bool _bAddColumn,
+ sal_Bool _bDropColumn,
+ sal_Bool _bUseHardRef)
+ : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
+ ,m_pMediator(NULL)
+ ,m_xDrvColumns(NULL)
+ ,m_pColFactoryImpl(_pColFactory)
+ ,m_pRefreshColumns(_pRefresh)
+ ,m_bInitialized(sal_False)
+ ,m_bAddColumn(_bAddColumn)
+ ,m_bDropColumn(_bDropColumn)
+{
+ DBG_CTOR(OColumns, NULL);
+}
+
+// -------------------------------------------------------------------------
+OColumns::OColumns(::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxDrvColumns,
+ sal_Bool _bCaseSensitive,const ::std::vector< ::rtl::OUString> &_rVector,
+ IColumnFactory* _pColFactory,
+ ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
+ sal_Bool _bAddColumn,
+ sal_Bool _bDropColumn,
+ sal_Bool _bUseHardRef)
+ : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
+ ,m_pMediator(NULL)
+ ,m_xDrvColumns(_rxDrvColumns)
+ ,m_pColFactoryImpl(_pColFactory)
+ ,m_pRefreshColumns(_pRefresh)
+ ,m_bInitialized(sal_False)
+ ,m_bAddColumn(_bAddColumn)
+ ,m_bDropColumn(_bDropColumn)
+{
+ DBG_CTOR(OColumns, NULL);
+}
+//--------------------------------------------------------------------------
+OColumns::~OColumns()
+{
+ DBG_DTOR(OColumns, NULL);
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OColumns::getImplementationName( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OColumns");
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OColumns::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OColumns::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS[0] = SERVICE_SDBCX_CONTAINER;
+ return aSNS;
+}
+
+//------------------------------------------------------------------
+void OColumns::append( const ::rtl::OUString& _rName, OColumn* _pColumn )
+{
+ MutexGuard aGuard(m_rMutex);
+
+ OSL_ENSURE( _pColumn, "OColumns::append: invalid column!" );
+ OSL_ENSURE( !m_pElements->exists( _rName ),"OColumns::append: Column already exists");
+
+ _pColumn->m_sName = _rName;
+
+ // now really insert the column
+ insertElement( _rName, _pColumn );
+}
+
+//------------------------------------------------------------------
+void OColumns::clearColumns()
+{
+ MutexGuard aGuard(m_rMutex);
+ disposing();
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL OColumns::disposing(void)
+{
+ MutexGuard aGuard(m_rMutex);
+ m_xDrvColumns = NULL;
+ m_pMediator = NULL;
+ m_pColFactoryImpl = NULL;
+ OColumns_BASE::disposing();
+}
+
+// -------------------------------------------------------------------------
+void OColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
+{
+ if (m_pRefreshColumns)
+ m_pRefreshColumns->refreshColumns();
+}
+
+// -------------------------------------------------------------------------
+connectivity::sdbcx::ObjectType OColumns::createObject(const ::rtl::OUString& _rName)
+{
+ OSL_ENSURE(m_pColFactoryImpl, "OColumns::createObject: no column factory!");
+
+ connectivity::sdbcx::ObjectType xRet;
+ if ( m_pColFactoryImpl )
+ {
+ xRet = m_pColFactoryImpl->createColumn(_rName);
+ Reference<XChild> xChild(xRet,UNO_QUERY);
+ if ( xChild.is() )
+ xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
+ }
+
+ Reference<XPropertySet> xDest(xRet,UNO_QUERY);
+ if ( m_pMediator && xDest.is() )
+ m_pMediator->notifyElementCreated(_rName,xDest);
+
+ return xRet;
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OColumns::createDescriptor()
+{
+ if ( m_pColFactoryImpl )
+ {
+ Reference<XPropertySet> xRet = m_pColFactoryImpl->createColumnDescriptor();
+ Reference<XChild> xChild(xRet,UNO_QUERY);
+ if ( xChild.is() )
+ xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
+ return xRet;
+ }
+ else
+ return Reference< XPropertySet >();
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL OColumns::queryInterface( const Type & rType ) throw(RuntimeException)
+{
+ Any aRet;
+ if(m_xDrvColumns.is())
+ {
+ aRet = m_xDrvColumns->queryInterface(rType);
+ if ( aRet.hasValue() )
+ aRet = OColumns_BASE::queryInterface( rType);
+ if ( !aRet.hasValue() )
+ aRet = TXChild::queryInterface( rType);
+ return aRet;
+ }
+ else if(!m_pTable || (m_pTable && !m_pTable->isNew()))
+ {
+ if(!m_bAddColumn && rType == getCppuType( (Reference<XAppend>*)0))
+ return Any();
+ if(!m_bDropColumn && rType == getCppuType( (Reference<XDrop>*)0))
+ return Any();
+ }
+
+ aRet = OColumns_BASE::queryInterface( rType);
+ if ( !aRet.hasValue() )
+ aRet = TXChild::queryInterface( rType);
+ return aRet;
+}
+// -------------------------------------------------------------------------
+Sequence< Type > SAL_CALL OColumns::getTypes( ) throw(RuntimeException)
+{
+ sal_Bool bAppendFound = sal_False,bDropFound = sal_False;
+
+ sal_Int32 nSize = 0;
+ Type aAppendType = getCppuType( (Reference<XAppend>*)0);
+ Type aDropType = getCppuType( (Reference<XDrop>*)0);
+ if(m_xDrvColumns.is())
+ {
+ Reference<XTypeProvider> xTypes(m_xDrvColumns,UNO_QUERY);
+ Sequence< Type > aTypes(xTypes->getTypes());
+
+ Sequence< Type > aSecTypes(OColumns_BASE::getTypes());
+
+
+ const Type* pBegin = aTypes.getConstArray();
+ const Type* pEnd = pBegin + aTypes.getLength();
+ for (;pBegin != pEnd ; ++pBegin)
+ {
+ if(aAppendType == *pBegin)
+ bAppendFound = sal_True;
+ else if(aDropType == *pBegin)
+ bDropFound = sal_True;
+ }
+ nSize = (bDropFound ? (bAppendFound ? 0 : 1) : (bAppendFound ? 1 : 2));
+ }
+ else
+ {
+ nSize = ((m_pTable && m_pTable->isNew()) ? 0 :
+ ((m_bDropColumn ?
+ (m_bAddColumn ? 0 : 1) : (m_bAddColumn ? 1 : 2))));
+ bDropFound = (m_pTable && m_pTable->isNew()) || m_bDropColumn;
+ bAppendFound = (m_pTable && m_pTable->isNew()) || m_bAddColumn;
+ }
+ Sequence< Type > aTypes(::comphelper::concatSequences(OColumns_BASE::getTypes(),TXChild::getTypes()));
+ Sequence< Type > aRet(aTypes.getLength() - nSize);
+
+ const Type* pBegin = aTypes.getConstArray();
+ const Type* pEnd = pBegin + aTypes.getLength();
+ for(sal_Int32 i=0;pBegin != pEnd ;++pBegin)
+ {
+ if(*pBegin != aAppendType && *pBegin != aDropType)
+ aRet.getArray()[i++] = *pBegin;
+ else if(bDropFound && *pBegin == aDropType)
+ aRet.getArray()[i++] = *pBegin;
+ else if(bAppendFound && *pBegin == aAppendType)
+ aRet.getArray()[i++] = *pBegin;
+ }
+ return aRet;
+}
+// -------------------------------------------------------------------------
+// XAppend
+sdbcx::ObjectType OColumns::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ sdbcx::ObjectType xReturn;
+
+ Reference< XAppend > xAppend( m_xDrvColumns, UNO_QUERY );
+ if ( xAppend.is() )
+ {
+ xAppend->appendByDescriptor(descriptor);
+ xReturn = createObject( _rForName );
+ }
+ else if ( m_pTable && !m_pTable->isNew() )
+ {
+ if ( m_bAddColumn )
+ {
+ Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
+ if ( xAlterService.is() )
+ {
+ xAlterService->addColumn(m_pTable,descriptor);
+ xReturn = createObject( _rForName );
+ }
+ else
+ xReturn = OColumns_BASE::appendObject( _rForName, descriptor );
+ }
+ else
+ ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_ADD ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
+ }
+ else
+ xReturn = cloneDescriptor( descriptor );
+
+ if ( m_pColFactoryImpl )
+ m_pColFactoryImpl->columnAppended( descriptor );
+
+ ::dbaccess::notifyDataSourceModified(m_xParent,sal_True);
+
+ return xReturn;
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OColumns::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
+{
+ Reference< XDrop > xDrop( m_xDrvColumns, UNO_QUERY );
+ if ( xDrop.is() )
+ {
+ xDrop->dropByName( _sElementName );
+ }
+ else if ( m_pTable && !m_pTable->isNew() )
+ {
+ if ( m_bDropColumn )
+ {
+ Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
+ if ( xAlterService.is() )
+ xAlterService->dropColumn(m_pTable,_sElementName);
+ else
+ OColumns_BASE::dropObject(_nPos,_sElementName);
+ }
+ else
+ ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_DROP ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
+ }
+
+ if ( m_pColFactoryImpl )
+ m_pColFactoryImpl->columnDropped(_sElementName);
+
+ ::dbaccess::notifyDataSourceModified(m_xParent,sal_True);
+}
+// -----------------------------------------------------------------------------
+
+Reference< XInterface > SAL_CALL OColumns::getParent( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_rMutex);
+ return m_xParent;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OColumns::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_rMutex);
+ m_xParent = _xParent;
+}
+// -----------------------------------------------------------------------------
diff --git a/dbaccess/source/core/api/columnsettings.cxx b/dbaccess/source/core/api/columnsettings.cxx
new file mode 100644
index 000000000000..a88879ca5eb8
--- /dev/null
+++ b/dbaccess/source/core/api/columnsettings.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "columnsettings.hxx"
+#include "dbastrings.hrc"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/property.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ /** === end UNO using === **/
+ namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
+
+ //==============================================================================
+ //= OColumnSettings
+ //==============================================================================
+ DBG_NAME( OColumnSettings )
+ //------------------------------------------------------------------------------
+ OColumnSettings::OColumnSettings()
+ :m_bHidden(sal_False)
+ {
+ DBG_CTOR( OColumnSettings, NULL );
+ }
+
+ //------------------------------------------------------------------------------
+ OColumnSettings::~OColumnSettings()
+ {
+ DBG_DTOR( OColumnSettings, NULL );
+ }
+
+ //------------------------------------------------------------------------------
+ void OColumnSettings::registerProperties( IPropertyContainer& _rPropertyContainer )
+ {
+ const sal_Int32 nBoundAttr = PropertyAttribute::BOUND;
+ const sal_Int32 nMayBeVoidAttr = PropertyAttribute::MAYBEVOID | nBoundAttr;
+
+ const Type& rSalInt32Type = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
+ const Type& rStringType = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
+
+ _rPropertyContainer.registerMayBeVoidProperty( PROPERTY_ALIGN, PROPERTY_ID_ALIGN, nMayBeVoidAttr, &m_aAlignment, rSalInt32Type );
+ _rPropertyContainer.registerMayBeVoidProperty( PROPERTY_NUMBERFORMAT, PROPERTY_ID_NUMBERFORMAT, nMayBeVoidAttr, &m_aFormatKey, rSalInt32Type );
+ _rPropertyContainer.registerMayBeVoidProperty( PROPERTY_RELATIVEPOSITION, PROPERTY_ID_RELATIVEPOSITION, nMayBeVoidAttr, &m_aRelativePosition, rSalInt32Type );
+ _rPropertyContainer.registerMayBeVoidProperty( PROPERTY_WIDTH, PROPERTY_ID_WIDTH, nMayBeVoidAttr, &m_aWidth, rSalInt32Type );
+ _rPropertyContainer.registerMayBeVoidProperty( PROPERTY_HELPTEXT, PROPERTY_ID_HELPTEXT, nMayBeVoidAttr, &m_aHelpText, rStringType );
+ _rPropertyContainer.registerMayBeVoidProperty( PROPERTY_CONTROLDEFAULT, PROPERTY_ID_CONTROLDEFAULT, nMayBeVoidAttr, &m_aControlDefault, rStringType );
+ _rPropertyContainer.registerProperty( PROPERTY_CONTROLMODEL, PROPERTY_ID_CONTROLMODEL, nBoundAttr, &m_xControlModel, ::getCppuType( &m_xControlModel ) );
+ _rPropertyContainer.registerProperty( PROPERTY_HIDDEN, PROPERTY_ID_HIDDEN, nBoundAttr, &m_bHidden, ::getCppuType( &m_bHidden ) );
+ }
+
+ //------------------------------------------------------------------------------
+ bool OColumnSettings::isColumnSettingProperty( const sal_Int32 _nPropertyHandle )
+ {
+ return ( _nPropertyHandle == PROPERTY_ID_ALIGN )
+ || ( _nPropertyHandle == PROPERTY_ID_NUMBERFORMAT )
+ || ( _nPropertyHandle == PROPERTY_ID_RELATIVEPOSITION )
+ || ( _nPropertyHandle == PROPERTY_ID_WIDTH )
+ || ( _nPropertyHandle == PROPERTY_ID_HELPTEXT )
+ || ( _nPropertyHandle == PROPERTY_ID_CONTROLDEFAULT )
+ || ( _nPropertyHandle == PROPERTY_ID_CONTROLMODEL )
+ || ( _nPropertyHandle == PROPERTY_ID_HIDDEN );
+ }
+
+ //------------------------------------------------------------------------------
+ bool OColumnSettings::isDefaulted( const sal_Int32 _nPropertyHandle, const Any& _rPropertyValue )
+ {
+ switch ( _nPropertyHandle )
+ {
+ case PROPERTY_ID_ALIGN:
+ case PROPERTY_ID_NUMBERFORMAT:
+ case PROPERTY_ID_RELATIVEPOSITION:
+ case PROPERTY_ID_WIDTH:
+ case PROPERTY_ID_HELPTEXT:
+ case PROPERTY_ID_CONTROLDEFAULT:
+ return !_rPropertyValue.hasValue();
+
+ case PROPERTY_ID_CONTROLMODEL:
+ return !Reference< XPropertySet >( _rPropertyValue, UNO_QUERY ).is();
+
+ case PROPERTY_ID_HIDDEN:
+ {
+ sal_Bool bHidden = sal_False;
+ OSL_VERIFY( _rPropertyValue >>= bHidden );
+ return !bHidden;
+ }
+ }
+ OSL_ENSURE( false, "OColumnSettings::isDefaulted: illegal property handle!" );
+ return sal_False;
+ }
+
+ //------------------------------------------------------------------------------
+ bool OColumnSettings::hasDefaultSettings( const Reference< XPropertySet >& _rxColumn )
+ {
+ ENSURE_OR_THROW( _rxColumn.is(), "illegal column" );
+ try
+ {
+ Reference< XPropertySetInfo > xPSI( _rxColumn->getPropertySetInfo(), UNO_SET_THROW );
+
+ struct PropertyDescriptor
+ {
+ ::rtl::OUString sName;
+ sal_Int32 nHandle;
+ };
+ PropertyDescriptor aProps[] =
+ {
+ { PROPERTY_ALIGN, PROPERTY_ID_ALIGN },
+ { PROPERTY_NUMBERFORMAT, PROPERTY_ID_NUMBERFORMAT },
+ { PROPERTY_RELATIVEPOSITION, PROPERTY_ID_RELATIVEPOSITION },
+ { PROPERTY_WIDTH, PROPERTY_ID_WIDTH },
+ { PROPERTY_HELPTEXT, PROPERTY_ID_HELPTEXT },
+ { PROPERTY_CONTROLDEFAULT, PROPERTY_ID_CONTROLDEFAULT },
+ { PROPERTY_CONTROLMODEL, PROPERTY_ID_CONTROLMODEL },
+ { PROPERTY_HIDDEN, PROPERTY_ID_HIDDEN }
+ };
+
+ for ( size_t i=0; i < sizeof( aProps ) / sizeof( aProps[0] ); ++i )
+ {
+ if ( xPSI->hasPropertyByName( aProps[i].sName ) )
+ if ( !isDefaulted( aProps[i].nHandle, _rxColumn->getPropertyValue( aProps[i].sName ) ) )
+ return false;
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return true;
+ }
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
diff --git a/dbaccess/source/core/api/datacolumn.cxx b/dbaccess/source/core/api/datacolumn.cxx
new file mode 100644
index 000000000000..cb1be701cb99
--- /dev/null
+++ b/dbaccess/source/core/api/datacolumn.cxx
@@ -0,0 +1,485 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef _DBACORE_DATACOLUMN_HXX_
+#include "datacolumn.hxx"
+#endif
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
+#include <com/sun/star/sdbc/DataType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+
+using namespace dbaccess;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+DBG_NAME(ODataColumn)
+//--------------------------------------------------------------------------
+ODataColumn::ODataColumn(
+ const Reference < XResultSetMetaData >& _xMetaData,
+ const Reference < XRow >& _xRow,
+ const Reference < XRowUpdate >& _xRowUpdate,
+ sal_Int32 _nPos,
+ const Reference< XDatabaseMetaData >& _rxDBMeta)
+ :OResultColumn(_xMetaData, _nPos, _rxDBMeta)
+ ,m_xRow(_xRow)
+ ,m_xRowUpdate(_xRowUpdate)
+{
+ DBG_CTOR(ODataColumn,NULL);
+}
+// -----------------------------------------------------------------------------
+ODataColumn::~ODataColumn()
+{
+ DBG_DTOR(ODataColumn,NULL);
+}
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > ODataColumn::getTypes() throw (RuntimeException)
+{
+ OTypeCollection aTypes(::getCppuType( (const Reference< XColumn > *)0 ),
+ ::getCppuType( (const Reference< XColumnUpdate > *)0 ),
+ OColumn::getTypes());
+ return aTypes.getTypes();
+}
+
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > ODataColumn::getImplementationId() throw (RuntimeException)
+{
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+//------------------------------------------------------------------------------
+Any SAL_CALL ODataColumn::queryInterface( const Type & _rType ) throw (RuntimeException)
+{
+ Any aReturn = OResultColumn::queryInterface(_rType);
+ if (!aReturn.hasValue())
+ aReturn = ::cppu::queryInterface(_rType,
+ static_cast< XColumn* >(this),
+ static_cast< XColumnUpdate* >(this)
+ );
+ return aReturn;
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString ODataColumn::getImplementationName( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.ODataColumn");
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > ODataColumn::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 3 );
+ aSNS[0] = SERVICE_SDBCX_COLUMN;
+ aSNS[1] = SERVICE_SDB_RESULTCOLUMN;
+ aSNS[2] = SERVICE_SDB_DATACOLUMN;
+ return aSNS;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void ODataColumn::disposing()
+{
+ OResultColumn::disposing();
+
+ m_xRow = NULL;
+ m_xRowUpdate = NULL;
+}
+
+// ::com::sun::star::sdb::XColumn
+//------------------------------------------------------------------------------
+sal_Bool ODataColumn::wasNull(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->wasNull();
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ODataColumn::getString(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getString(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ODataColumn::getBoolean(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getBoolean(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+sal_Int8 ODataColumn::getByte(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getByte(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 ODataColumn::getShort(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getShort(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ODataColumn::getInt(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getInt(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+sal_Int64 ODataColumn::getLong(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getLong(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+float ODataColumn::getFloat(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getFloat(m_nPos);
+}
+//------------------------------------------------------------------------------
+double ODataColumn::getDouble(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getDouble(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Sequence< sal_Int8 > ODataColumn::getBytes(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getBytes(m_nPos);
+}
+//------------------------------------------------------------------------------
+com::sun::star::util::Date ODataColumn::getDate(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getDate(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+com::sun::star::util::Time ODataColumn::getTime(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getTime(m_nPos);
+}
+//------------------------------------------------------------------------------
+com::sun::star::util::DateTime ODataColumn::getTimestamp(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getTimestamp(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > ODataColumn::getBinaryStream(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getBinaryStream(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > ODataColumn::getCharacterStream(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getCharacterStream(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Any ODataColumn::getObject(const Reference< ::com::sun::star::container::XNameAccess > & typeMap) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getObject(m_nPos, typeMap);
+}
+
+//------------------------------------------------------------------------------
+Reference< XRef > ODataColumn::getRef(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getRef(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Reference< XBlob > ODataColumn::getBlob(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getBlob(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Reference< XClob > ODataColumn::getClob(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getClob(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+Reference< XArray > ODataColumn::getArray(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(!m_xRow.is());
+
+ return m_xRow->getArray(m_nPos);
+}
+
+// ::com::sun::star::sdb::XColumnUpdate
+//------------------------------------------------------------------------------
+void ODataColumn::updateNull(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateNull(m_nPos);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateBoolean(sal_Bool x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateBoolean(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateByte(sal_Int8 x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateByte(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateShort(sal_Int16 x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateShort(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateInt(sal_Int32 x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateInt(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateLong(sal_Int64 x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateLong(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateFloat(float x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateFloat(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateDouble(double x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateDouble(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateString(const rtl::OUString& x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateString(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateBytes(const Sequence< sal_Int8 >& x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateBytes(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateDate(const com::sun::star::util::Date& x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateDate(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateTime(const ::com::sun::star::util::Time& x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateTime(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateTimestamp(const ::com::sun::star::util::DateTime& x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateTimestamp(m_nPos, x);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateCharacterStream(const Reference< ::com::sun::star::io::XInputStream > & x, sal_Int32 length) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateCharacterStream(m_nPos, x, length);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateBinaryStream(const Reference< ::com::sun::star::io::XInputStream > & x, sal_Int32 length) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateBinaryStream(m_nPos, x, length);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateNumericObject(const Any& x, sal_Int32 scale) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateNumericObject(m_nPos, x, scale);
+}
+
+//------------------------------------------------------------------------------
+void ODataColumn::updateObject(const Any& x) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(!m_xRowUpdate.is());
+
+ m_xRowUpdate->updateObject(m_nPos, x);
+}
+
diff --git a/dbaccess/source/core/api/datacolumn.hxx b/dbaccess/source/core/api/datacolumn.hxx
new file mode 100644
index 000000000000..3c18fd4d830d
--- /dev/null
+++ b/dbaccess/source/core/api/datacolumn.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 _DBACORE_DATACOLUMN_HXX_
+#define _DBACORE_DATACOLUMN_HXX_
+
+#ifndef _COM_SUN_STAR_SDBC_XROWUPDATE_HPP_
+#include <com/sun/star/sdbc/XRowUpdate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HDL_
+#include <com/sun/star/sdbc/XResultSetMetaData.hdl>
+#endif
+#ifndef _COM_SUN_STAR_SDB_XCOLUMN_HPP_
+#include <com/sun/star/sdb/XColumn.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDB_XCOLUMNUPDATE_HPP_
+#include <com/sun/star/sdb/XColumnUpdate.hpp>
+#endif
+#ifndef _DBA_COREAPI_RESULTCOLUMN_HXX_
+#include <resultcolumn.hxx>
+#endif
+namespace dbaccess
+{
+ //************************************************************
+ // ODataColumn
+ //************************************************************
+ class ODataColumn : public OResultColumn,
+ public ::com::sun::star::sdb::XColumn,
+ public ::com::sun::star::sdb::XColumnUpdate
+ {
+ protected:
+ ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRow > m_xRow;
+ ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRowUpdate > m_xRowUpdate;
+
+ virtual ~ODataColumn();
+ public:
+ ODataColumn (const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData >& _xMetaData,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRow >& _xRow,
+ const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XRowUpdate >& _xRowUpdate,
+ sal_Int32 _nPos,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMeta);
+
+ // com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw() { OResultColumn::acquire(); }
+ virtual void SAL_CALL release() throw() { OResultColumn::release(); }
+
+ // ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // cppu::OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // ::com::sun::star::sdb::XColumn
+ virtual sal_Bool SAL_CALL wasNull( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getString( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL getBoolean( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int8 SAL_CALL getByte( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getShort( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getInt( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int64 SAL_CALL getLong( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual float SAL_CALL getFloat( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual double SAL_CALL getDouble( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getBytes( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::util::Date SAL_CALL getDate( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::util::Time SAL_CALL getTime( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::util::DateTime SAL_CALL getTimestamp( ) 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( ) 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( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL getObject( 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( ) 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( ) 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( ) 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( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdb::XColumnUpdate
+ virtual void SAL_CALL updateNull( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBoolean( sal_Bool x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateByte( sal_Int8 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateShort( sal_Int16 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateInt( sal_Int32 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateLong( sal_Int64 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateFloat( float x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateDouble( double x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateString( const ::rtl::OUString& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateDate( const ::com::sun::star::util::Date& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTime( const ::com::sun::star::util::Time& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTimestamp( const ::com::sun::star::util::DateTime& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBinaryStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateCharacterStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateObject( const ::com::sun::star::uno::Any& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateNumericObject( const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ };
+}
+#endif // _DBACORE_RESULTCOLUMN_HXX_
+
diff --git a/dbaccess/source/core/api/datasettings.cxx b/dbaccess/source/core/api/datasettings.cxx
new file mode 100644
index 000000000000..2f5a01fd7004
--- /dev/null
+++ b/dbaccess/source/core/api/datasettings.cxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _DBA_CORE_DATASETTINGS_HXX_
+#include "datasettings.hxx"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _OSL_DIAGNOSE_H_
+#include <osl/diagnose.h>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _COM_SUN_STAR_AWT_FONTWEIGHT_HPP_
+#include <com/sun/star/awt/FontWeight.hpp>
+#endif
+#ifndef _COM_SUN_STAR_AWT_FONTEMPHASISMARK_HPP_
+#include <com/sun/star/awt/FontEmphasisMark.hpp>
+#endif
+#ifndef _COM_SUN_STAR_AWT_FONTRELIEF_HPP_
+#include <com/sun/star/awt/FontRelief.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_AWT_FONTWIDTH_HPP_
+#include <com/sun/star/awt/FontWidth.hpp>
+#endif
+
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+//........................................................................
+namespace dbaccess
+{
+//==========================================================================
+//= ODataSettings
+//==========================================================================
+//--------------------------------------------------------------------------
+void ODataSettings::registerPropertiesFor(ODataSettings_Base* _pItem)
+{
+ if ( m_bQuery )
+ {
+ registerProperty(PROPERTY_HAVING_CLAUSE, PROPERTY_ID_HAVING_CLAUSE, PropertyAttribute::BOUND,
+ &_pItem->m_sHavingClause, ::getCppuType(&_pItem->m_sHavingClause));
+
+ registerProperty(PROPERTY_GROUP_BY, PROPERTY_ID_GROUP_BY, PropertyAttribute::BOUND,
+ &_pItem->m_sGroupBy, ::getCppuType(&_pItem->m_sGroupBy));
+ }
+
+ registerProperty(PROPERTY_FILTER, PROPERTY_ID_FILTER, PropertyAttribute::BOUND,
+ &_pItem->m_sFilter, ::getCppuType(&_pItem->m_sFilter));
+
+ registerProperty(PROPERTY_ORDER, PROPERTY_ID_ORDER, PropertyAttribute::BOUND,
+ &_pItem->m_sOrder, ::getCppuType(&_pItem->m_sOrder));
+
+ registerProperty(PROPERTY_APPLYFILTER, PROPERTY_ID_APPLYFILTER, PropertyAttribute::BOUND,
+ &_pItem->m_bApplyFilter, ::getBooleanCppuType());
+
+ registerProperty(PROPERTY_FONT, PROPERTY_ID_FONT, PropertyAttribute::BOUND,
+ &_pItem->m_aFont, ::getCppuType(&_pItem->m_aFont));
+
+ registerMayBeVoidProperty(PROPERTY_ROW_HEIGHT, PROPERTY_ID_ROW_HEIGHT, PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
+ &_pItem->m_aRowHeight, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerMayBeVoidProperty(PROPERTY_TEXTCOLOR, PROPERTY_ID_TEXTCOLOR, PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
+ &_pItem->m_aTextColor, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerMayBeVoidProperty(PROPERTY_TEXTLINECOLOR, PROPERTY_ID_TEXTLINECOLOR, PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
+ &_pItem->m_aTextLineColor, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerProperty(PROPERTY_TEXTEMPHASIS, PROPERTY_ID_TEXTEMPHASIS, PropertyAttribute::BOUND,
+ &_pItem->m_nFontEmphasis, ::getCppuType(&_pItem->m_nFontEmphasis));
+
+ registerProperty(PROPERTY_TEXTRELIEF, PROPERTY_ID_TEXTRELIEF, PropertyAttribute::BOUND,&_pItem->m_nFontRelief, ::getCppuType(&_pItem->m_nFontRelief));
+
+ registerProperty(PROPERTY_FONTNAME, PROPERTY_ID_FONTNAME, PropertyAttribute::BOUND,&_pItem->m_aFont.Name, ::getCppuType(&_pItem->m_aFont.Name));
+ registerProperty(PROPERTY_FONTHEIGHT, PROPERTY_ID_FONTHEIGHT, PropertyAttribute::BOUND,&_pItem->m_aFont.Height, ::getCppuType(&_pItem->m_aFont.Height));
+ registerProperty(PROPERTY_FONTWIDTH, PROPERTY_ID_FONTWIDTH, PropertyAttribute::BOUND,&_pItem->m_aFont.Width, ::getCppuType(&_pItem->m_aFont.Width));
+ registerProperty(PROPERTY_FONTSTYLENAME, PROPERTY_ID_FONTSTYLENAME, PropertyAttribute::BOUND,&_pItem->m_aFont.StyleName, ::getCppuType(&_pItem->m_aFont.StyleName));
+ registerProperty(PROPERTY_FONTFAMILY, PROPERTY_ID_FONTFAMILY, PropertyAttribute::BOUND,&_pItem->m_aFont.Family, ::getCppuType(&_pItem->m_aFont.Family));
+ registerProperty(PROPERTY_FONTCHARSET, PROPERTY_ID_FONTCHARSET, PropertyAttribute::BOUND,&_pItem->m_aFont.CharSet, ::getCppuType(&_pItem->m_aFont.CharSet));
+ registerProperty(PROPERTY_FONTPITCH, PROPERTY_ID_FONTPITCH, PropertyAttribute::BOUND,&_pItem->m_aFont.Pitch, ::getCppuType(&_pItem->m_aFont.Pitch));
+ registerProperty(PROPERTY_FONTCHARWIDTH, PROPERTY_ID_FONTCHARWIDTH, PropertyAttribute::BOUND,&_pItem->m_aFont.CharacterWidth, ::getCppuType(&_pItem->m_aFont.CharacterWidth));
+ registerProperty(PROPERTY_FONTWEIGHT, PROPERTY_ID_FONTWEIGHT, PropertyAttribute::BOUND,&_pItem->m_aFont.Weight, ::getCppuType(&_pItem->m_aFont.Weight));
+ registerProperty(PROPERTY_FONTSLANT, PROPERTY_ID_FONTSLANT, PropertyAttribute::BOUND,&_pItem->m_aFont.Slant, ::getCppuType(&_pItem->m_aFont.Slant));
+ registerProperty(PROPERTY_FONTUNDERLINE, PROPERTY_ID_FONTUNDERLINE, PropertyAttribute::BOUND,&_pItem->m_aFont.Underline, ::getCppuType(&_pItem->m_aFont.Underline));
+ registerProperty(PROPERTY_FONTSTRIKEOUT, PROPERTY_ID_FONTSTRIKEOUT, PropertyAttribute::BOUND,&_pItem->m_aFont.Strikeout, ::getCppuType(&_pItem->m_aFont.Strikeout));
+ registerProperty(PROPERTY_FONTORIENTATION, PROPERTY_ID_FONTORIENTATION, PropertyAttribute::BOUND,&_pItem->m_aFont.Orientation, ::getCppuType(&_pItem->m_aFont.Orientation));
+ registerProperty(PROPERTY_FONTKERNING, PROPERTY_ID_FONTKERNING, PropertyAttribute::BOUND,&_pItem->m_aFont.Kerning, ::getCppuType(&_pItem->m_aFont.Kerning));
+ registerProperty(PROPERTY_FONTWORDLINEMODE, PROPERTY_ID_FONTWORDLINEMODE,PropertyAttribute::BOUND,&_pItem->m_aFont.WordLineMode, ::getCppuType(&_pItem->m_aFont.WordLineMode));
+ registerProperty(PROPERTY_FONTTYPE, PROPERTY_ID_FONTTYPE, PropertyAttribute::BOUND,&_pItem->m_aFont.Type, ::getCppuType(&_pItem->m_aFont.Type));
+}
+
+//--------------------------------------------------------------------------
+ODataSettings::ODataSettings(OBroadcastHelper& _rBHelper,sal_Bool _bQuery)
+ :OPropertyStateContainer(_rBHelper)
+ ,ODataSettings_Base()
+ ,m_bQuery(_bQuery)
+{
+}
+
+//--------------------------------------------------------------------------
+ODataSettings_Base::ODataSettings_Base()
+ :m_bApplyFilter(sal_False)
+ ,m_aFont(::comphelper::getDefaultFont())
+ ,m_nFontEmphasis(::com::sun::star::awt::FontEmphasisMark::NONE)
+ ,m_nFontRelief(::com::sun::star::awt::FontRelief::NONE)
+{
+}
+
+//--------------------------------------------------------------------------
+ODataSettings_Base::ODataSettings_Base(const ODataSettings_Base& _rSource)
+ :m_sFilter( _rSource.m_sFilter )
+ ,m_sHavingClause( _rSource.m_sHavingClause )
+ ,m_sGroupBy( _rSource.m_sGroupBy )
+ ,m_sOrder( _rSource.m_sOrder )
+ ,m_bApplyFilter( _rSource.m_bApplyFilter )
+ ,m_aFont( _rSource.m_aFont )
+ ,m_aRowHeight( _rSource.m_aRowHeight )
+ ,m_aTextColor( _rSource.m_aTextColor )
+ ,m_aTextLineColor( _rSource.m_aTextLineColor )
+ ,m_nFontEmphasis( _rSource.m_nFontEmphasis )
+ ,m_nFontRelief( _rSource.m_nFontRelief )
+{
+}
+
+// -----------------------------------------------------------------------------
+ODataSettings_Base::~ODataSettings_Base()
+{
+}
+
+// -----------------------------------------------------------------------------
+void ODataSettings::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const
+{
+ static ::com::sun::star::awt::FontDescriptor aFD = ::comphelper::getDefaultFont();
+ switch( _nHandle )
+ {
+ case PROPERTY_ID_HAVING_CLAUSE:
+ case PROPERTY_ID_GROUP_BY:
+ case PROPERTY_ID_FILTER:
+ case PROPERTY_ID_ORDER:
+ _rDefault <<= ::rtl::OUString();
+ break;
+ case PROPERTY_ID_FONT:
+ _rDefault <<= ::comphelper::getDefaultFont();
+ break;
+ case PROPERTY_ID_APPLYFILTER:
+ _rDefault <<= sal_False;
+ break;
+ case PROPERTY_ID_TEXTRELIEF:
+ _rDefault <<= ::com::sun::star::awt::FontRelief::NONE;
+ break;
+ case PROPERTY_ID_TEXTEMPHASIS:
+ _rDefault <<= ::com::sun::star::awt::FontEmphasisMark::NONE;
+ break;
+ case PROPERTY_ID_FONTNAME:
+ _rDefault <<= aFD.Name;
+ break;
+ case PROPERTY_ID_FONTHEIGHT:
+ _rDefault <<= aFD.Height;
+ break;
+ case PROPERTY_ID_FONTWIDTH:
+ _rDefault <<= aFD.Width;
+ break;
+ case PROPERTY_ID_FONTSTYLENAME:
+ _rDefault <<= aFD.StyleName;
+ break;
+ case PROPERTY_ID_FONTFAMILY:
+ _rDefault <<= aFD.Family;
+ break;
+ case PROPERTY_ID_FONTCHARSET:
+ _rDefault <<= aFD.CharSet;
+ break;
+ case PROPERTY_ID_FONTPITCH:
+ _rDefault <<= aFD.Pitch;
+ break;
+ case PROPERTY_ID_FONTCHARWIDTH:
+ _rDefault <<= aFD.CharacterWidth;
+ break;
+ case PROPERTY_ID_FONTWEIGHT:
+ _rDefault <<= aFD.Weight;
+ break;
+ case PROPERTY_ID_FONTSLANT:
+ _rDefault <<= aFD.Slant;
+ break;
+ case PROPERTY_ID_FONTUNDERLINE:
+ _rDefault <<= aFD.Underline;
+ break;
+ case PROPERTY_ID_FONTSTRIKEOUT:
+ _rDefault <<= aFD.Strikeout;
+ break;
+ case PROPERTY_ID_FONTORIENTATION:
+ _rDefault <<= aFD.Orientation;
+ break;
+ case PROPERTY_ID_FONTKERNING:
+ _rDefault <<= aFD.Kerning;
+ break;
+ case PROPERTY_ID_FONTWORDLINEMODE:
+ _rDefault <<= aFD.WordLineMode;
+ break;
+ case PROPERTY_ID_FONTTYPE:
+ _rDefault <<= aFD.Type;
+ break;
+ }
+}
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
diff --git a/dbaccess/source/core/api/definitioncolumn.cxx b/dbaccess/source/core/api/definitioncolumn.cxx
new file mode 100644
index 000000000000..4620abd661f3
--- /dev/null
+++ b/dbaccess/source/core/api/definitioncolumn.cxx
@@ -0,0 +1,673 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "apitools.hxx"
+#include "dbastrings.hrc"
+#include "definitioncolumn.hxx"
+#include "sdbcoretools.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/property.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::cppu;
+using namespace ::comphelper;
+using namespace ::osl;
+using namespace dbaccess;
+
+#define HAS_DESCRIPTION 0x00000001
+#define HAS_DEFAULTVALUE 0x00000002
+#define HAS_ROWVERSION 0x00000004
+#define HAS_AUTOINCREMENT_CREATION 0x00000008
+
+//============================================================
+//= OTableColumnDescriptor
+//============================================================
+IMPLEMENT_FORWARD_XINTERFACE2(OTableColumnDescriptor,OColumn,TXChild)
+
+//------------------------------------------------------------------------------
+void OTableColumnDescriptor::impl_registerProperties()
+{
+ sal_Int32 nDefaultAttr = m_bActAsDescriptor ? 0 : PropertyAttribute::READONLY;
+
+ registerProperty( PROPERTY_TYPENAME, PROPERTY_ID_TYPENAME, nDefaultAttr, &m_aTypeName, ::getCppuType( &m_aTypeName ) );
+ registerProperty( PROPERTY_DESCRIPTION, PROPERTY_ID_DESCRIPTION, nDefaultAttr, &m_aDescription, ::getCppuType( &m_aDescription ) );
+ registerProperty( PROPERTY_DEFAULTVALUE, PROPERTY_ID_DEFAULTVALUE, nDefaultAttr, &m_aDefaultValue, ::getCppuType( &m_aDefaultValue ) );
+
+ if ( m_bActAsDescriptor )
+ registerProperty( PROPERTY_AUTOINCREMENTCREATION, PROPERTY_ID_AUTOINCREMENTCREATION, nDefaultAttr, &m_aAutoIncrementValue, ::getCppuType( &m_aAutoIncrementValue ) );
+
+ registerProperty( PROPERTY_TYPE, PROPERTY_ID_TYPE, nDefaultAttr, &m_nType, ::getCppuType( &m_nType ) );
+ registerProperty( PROPERTY_PRECISION, PROPERTY_ID_PRECISION, nDefaultAttr, &m_nPrecision, ::getCppuType( &m_nPrecision ) );
+ registerProperty( PROPERTY_SCALE, PROPERTY_ID_SCALE, nDefaultAttr, &m_nScale, ::getCppuType( &m_nScale ) );
+ registerProperty( PROPERTY_ISNULLABLE, PROPERTY_ID_ISNULLABLE, nDefaultAttr, &m_nIsNullable, ::getCppuType( &m_nIsNullable ) );
+ registerProperty( PROPERTY_ISAUTOINCREMENT, PROPERTY_ID_ISAUTOINCREMENT, nDefaultAttr, &m_bAutoIncrement, ::getCppuType( &m_bAutoIncrement ) );
+ registerProperty( PROPERTY_ISROWVERSION, PROPERTY_ID_ISROWVERSION, nDefaultAttr, &m_bRowVersion, ::getCppuType( &m_bRowVersion ) );
+ registerProperty( PROPERTY_ISCURRENCY, PROPERTY_ID_ISCURRENCY, nDefaultAttr, &m_bCurrency, ::getCppuType( &m_bCurrency ) );
+
+ OColumnSettings::registerProperties( *this );
+}
+
+//--------------------------------------------------------------------------
+IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumnDescriptor )
+
+// ::com::sun::star::lang::XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OTableColumnDescriptor::getImplementationName( ) throw (RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OTableColumnDescriptor");
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OTableColumnDescriptor::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = m_bActAsDescriptor ? SERVICE_SDBCX_COLUMNDESCRIPTOR : SERVICE_SDBCX_COLUMN;
+ aSNS[1] = SERVICE_SDB_COLUMNSETTINGS;
+ return aSNS;
+}
+
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OTableColumnDescriptor::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+}
+
+// cppu::OPropertySetHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OTableColumnDescriptor::getInfoHelper()
+{
+ return *static_cast< ::comphelper::OPropertyArrayUsageHelper< OTableColumnDescriptor >* >(this)->getArrayHelper();
+}
+
+//------------------------------------------------------------------------------
+void OTableColumnDescriptor::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ OColumn::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ ::dbaccess::notifyDataSourceModified( m_xParent, sal_True );
+}
+
+// -----------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL OTableColumnDescriptor::getParent( ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_xParent;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableColumnDescriptor::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ m_xParent = _xParent;
+}
+//============================================================
+//= OTableColumn
+//============================================================
+DBG_NAME(OTableColumn);
+
+// -------------------------------------------------------------------------
+OTableColumn::OTableColumn( const ::rtl::OUString& _rName )
+ :OTableColumnDescriptor( false /* do not act as descriptor */ )
+{
+ DBG_CTOR(OTableColumn,NULL);
+ m_sName = _rName;
+}
+
+// -----------------------------------------------------------------------------
+OTableColumn::~OTableColumn()
+{
+ DBG_DTOR(OTableColumn,NULL);
+}
+
+//--------------------------------------------------------------------------
+IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumn )
+
+//------------------------------------------------------------------------------
+rtl::OUString OTableColumn::getImplementationName( ) throw (RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OTableColumn");
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& SAL_CALL OTableColumn::getInfoHelper()
+{
+ return *OTableColumn_PBase::getArrayHelper();
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OTableColumn::createArrayHelper( ) const
+{
+ return OTableColumnDescriptor::createArrayHelper();
+}
+
+// =========================================================================
+//= OQueryColumn
+// =========================================================================
+DBG_NAME( OQueryColumn );
+
+// -------------------------------------------------------------------------
+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 );
+
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_TYPENAME ) >>= m_aTypeName );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= m_nIsNullable );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_PRECISION ) >>= m_nPrecision );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_SCALE ) >>= m_nScale );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_TYPE ) >>= m_nType );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= m_bAutoIncrement );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_ISCURRENCY ) >>= m_bCurrency );
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_NAME ) >>= m_sName );
+
+ m_bRowVersion = sal_False;
+
+ Reference< XPropertySetInfo > xPSI( _rxParserColumn->getPropertySetInfo(), UNO_SET_THROW );
+ if ( xPSI->hasPropertyByName( PROPERTY_DEFAULTVALUE ) )
+ OSL_VERIFY( _rxParserColumn->getPropertyValue( PROPERTY_DEFAULTVALUE ) >>= m_aDefaultValue );
+
+ // copy some optional properties from the parser column
+ struct PropertyDescriptor
+ {
+ ::rtl::OUString sName;
+ sal_Int32 nHandle;
+ };
+ PropertyDescriptor aProps[] =
+ {
+ { PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME },
+ { PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME },
+ { PROPERTY_TABLENAME, PROPERTY_ID_TABLENAME },
+ { PROPERTY_REALNAME, PROPERTY_ID_REALNAME }
+ };
+ for ( size_t i=0; i < sizeof( aProps ) / sizeof( aProps[0] ); ++i )
+ {
+ if ( xPSI->hasPropertyByName( aProps[i].sName ) )
+ setFastPropertyValue_NoBroadcast( aProps[i].nHandle, _rxParserColumn->getPropertyValue( aProps[i].sName ) );
+ }
+
+ // determine the table column we're based on
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ m_xOriginalTableColumn = impl_determineOriginalTableColumn( _rxConnection );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+//--------------------------------------------------------------------------
+OQueryColumn::~OQueryColumn()
+{
+ DBG_DTOR( OQueryColumn, NULL );
+}
+
+//--------------------------------------------------------------------------
+Reference< XPropertySet > OQueryColumn::impl_determineOriginalTableColumn( const Reference< XConnection >& _rxConnection )
+{
+ OSL_PRECOND( _rxConnection.is(), "OQueryColumn::impl_determineOriginalTableColumn: illegal connection!" );
+ if ( !_rxConnection.is() )
+ return NULL;
+
+ Reference< XPropertySet > xOriginalTableColumn;
+ try
+ {
+ // determine the composed table name, plus the column name, as indicated by the
+ // respective properties
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ OSL_VERIFY( getPropertyValue( PROPERTY_CATALOGNAME ) >>= sCatalog );
+ OSL_VERIFY( getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema );
+ OSL_VERIFY( getPropertyValue( PROPERTY_TABLENAME ) >>= sTable );
+ if ( !sCatalog.getLength() && !sSchema.getLength() && !sTable.getLength() )
+ return NULL;
+
+ ::rtl::OUString sComposedTableName = ::dbtools::composeTableName(
+ _rxConnection->getMetaData(), sCatalog, sSchema, sTable, sal_False, ::dbtools::eComplete );
+
+ // retrieve the table in question
+ Reference< XTablesSupplier > xSuppTables( _rxConnection, UNO_QUERY_THROW );
+ Reference< XNameAccess > xTables( xSuppTables->getTables(), UNO_QUERY_THROW );
+ if ( !xTables->hasByName( sComposedTableName ) )
+ return NULL;
+
+ Reference< XColumnsSupplier > xSuppCols( xTables->getByName( sComposedTableName ), UNO_QUERY_THROW );
+ Reference< XNameAccess > xColumns( xSuppCols->getColumns(), UNO_QUERY_THROW );
+
+ ::rtl::OUString sColumn;
+ OSL_VERIFY( getPropertyValue( PROPERTY_REALNAME ) >>= sColumn );
+ if ( !xColumns->hasByName( sColumn ) )
+ return NULL;
+
+ xOriginalTableColumn.set( xColumns->getByName( sColumn ), UNO_QUERY );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return xOriginalTableColumn;
+}
+
+//--------------------------------------------------------------------------
+IMPLEMENT_GET_IMPLEMENTATION_ID( OQueryColumn )
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OQueryColumn::getImplementationName( ) throw(RuntimeException)
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.dbaccess.OQueryColumn" ) );
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& SAL_CALL OQueryColumn::getInfoHelper()
+{
+ return *OQueryColumn_PBase::getArrayHelper();
+}
+
+//--------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OQueryColumn::createArrayHelper() const
+{
+ return OTableColumnDescriptor::createArrayHelper();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OQueryColumn::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
+{
+ OTableColumnDescriptor::getFastPropertyValue( _rValue, _nHandle );
+
+ // special treatment for column settings:
+ if ( !OColumnSettings::isColumnSettingProperty( _nHandle ) )
+ return;
+
+ // If the setting has its default value, then try to obtain the value from the table column which
+ // this query column is based on
+ if ( !OColumnSettings::isDefaulted( _nHandle, _rValue ) )
+ return;
+
+ if ( !m_xOriginalTableColumn.is() )
+ return;
+
+ try
+ {
+ // determine original property name
+ ::rtl::OUString sPropName;
+ sal_Int16 nAttributes( 0 );
+ const_cast< OQueryColumn* >( this )->getInfoHelper().fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle );
+ OSL_ENSURE( sPropName.getLength(), "OColumnWrapper::impl_getPropertyNameFromHandle: property not found!" );
+
+ _rValue = m_xOriginalTableColumn->getPropertyValue( sPropName );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+//==========================================================================
+//= OColumnWrapper
+//==========================================================================
+DBG_NAME(OColumnWrapper);
+//--------------------------------------------------------------------------
+OColumnWrapper::OColumnWrapper( const Reference< XPropertySet > & rCol, const bool _bNameIsReadOnly )
+ :OColumn( _bNameIsReadOnly )
+ ,m_xAggregate(rCol)
+ ,m_nColTypeID(-1)
+{
+ DBG_CTOR(OColumnWrapper,NULL);
+ // which type of aggregate property do we have?
+ // we distingish the properties by the containment of optional properties
+ m_nColTypeID = 0;
+ if ( m_xAggregate.is() )
+ {
+ Reference <XPropertySetInfo > xInfo(m_xAggregate->getPropertySetInfo());
+ m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_DESCRIPTION) ? HAS_DESCRIPTION : 0;
+ m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_DEFAULTVALUE) ? HAS_DEFAULTVALUE : 0;
+ m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_ISROWVERSION) ? HAS_ROWVERSION : 0;
+ m_nColTypeID |= xInfo->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION) ? HAS_AUTOINCREMENT_CREATION : 0;
+
+ m_xAggregate->getPropertyValue(PROPERTY_NAME) >>= m_sName;
+ }
+}
+// -----------------------------------------------------------------------------
+OColumnWrapper::~OColumnWrapper()
+{
+ DBG_DTOR(OColumnWrapper,NULL);
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString OColumnWrapper::impl_getPropertyNameFromHandle( const sal_Int32 _nHandle ) const
+{
+ ::rtl::OUString sPropName;
+ sal_Int16 nAttributes( 0 );
+ const_cast< OColumnWrapper* >( this )->getInfoHelper().fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle );
+ OSL_ENSURE( sPropName.getLength(), "OColumnWrapper::impl_getPropertyNameFromHandle: property not found!" );
+ return sPropName;
+}
+
+//------------------------------------------------------------------------------
+void OColumnWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ // derived classes are free to either use the OPropertyContainer(Helper) mechanisms for properties,
+ // or to declare additional properties which are to be forwarded to the wrapped object. So we need
+ // to distinguish those cases.
+ if ( OColumn::isRegisteredProperty( nHandle ) )
+ {
+ OColumn::getFastPropertyValue( rValue, nHandle );
+ }
+ else
+ {
+ rValue = m_xAggregate->getPropertyValue( impl_getPropertyNameFromHandle( nHandle ) );
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OColumnWrapper::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle,
+ const Any& rValue ) throw (IllegalArgumentException)
+{
+ sal_Bool bModified( sal_False );
+ if ( OColumn::isRegisteredProperty( nHandle ) )
+ {
+ bModified = OColumn::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
+ }
+ else
+ {
+ getFastPropertyValue( rOldValue, nHandle );
+ if ( rOldValue != rValue )
+ {
+ rConvertedValue = rValue;
+ bModified = sal_True;
+ }
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OColumnWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ if ( OColumn::isRegisteredProperty( nHandle ) )
+ {
+ OColumn::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ }
+ else
+ {
+ m_xAggregate->setPropertyValue( impl_getPropertyNameFromHandle( nHandle ), rValue );
+ }
+}
+
+// -----------------------------------------------------------------------------
+sal_Int64 SAL_CALL OColumnWrapper::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw(RuntimeException)
+{
+ Reference< XUnoTunnel > xTunnel( m_xAggregate, UNO_QUERY);
+ if ( xTunnel.is() )
+ return xTunnel->getSomething( aIdentifier );
+ return 0;
+}
+
+//============================================================
+//= OTableColumnDescriptorWrapper
+//============================================================
+//--------------------------------------------------------------------------
+OTableColumnDescriptorWrapper::OTableColumnDescriptorWrapper( const Reference< XPropertySet >& _rCol, const bool _bPureWrap, const bool _bIsDescriptor )
+ :OColumnWrapper( _rCol, !_bIsDescriptor )
+ ,m_bPureWrap( _bPureWrap )
+ ,m_bIsDescriptor( _bIsDescriptor )
+{
+ // let the ColumnSettings register its properties
+ OColumnSettings::registerProperties( *this );
+}
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumnDescriptorWrapper )
+
+// ::com::sun::star::lang::XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OTableColumnDescriptorWrapper::getImplementationName( ) throw (RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OTableColumnDescriptorWrapper");
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OTableColumnDescriptorWrapper::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = SERVICE_SDBCX_COLUMNDESCRIPTOR;
+ aSNS[1] = SERVICE_SDB_COLUMNSETTINGS;
+ return aSNS;
+}
+
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OTableColumnDescriptorWrapper::createArrayHelper( sal_Int32 nId ) const
+{
+ const sal_Int32 nHaveAlways = 7;
+
+ // Which optional properties are contained?
+ sal_Int32 nHaveOptionally = 0;
+ if (nId & HAS_DESCRIPTION)
+ ++nHaveOptionally;
+ if (nId & HAS_DEFAULTVALUE)
+ ++nHaveOptionally;
+ if (nId & HAS_ROWVERSION)
+ ++nHaveOptionally;
+ if ( nId & HAS_AUTOINCREMENT_CREATION )
+ ++nHaveOptionally;
+
+ const sal_Int32 nPropertyCount( nHaveAlways + nHaveOptionally );
+ Sequence< Property > aTableDescProperties( nPropertyCount );
+ Property* pDesc = aTableDescProperties.getArray();
+ sal_Int32 nPos = 0;
+
+ DECL_PROP0_BOOL( ISAUTOINCREMENT );
+ DECL_PROP0_BOOL( ISCURRENCY );
+ DECL_PROP0( ISNULLABLE, sal_Int32 );
+ DECL_PROP0( PRECISION, sal_Int32 );
+ DECL_PROP0( SCALE, sal_Int32 );
+ DECL_PROP0( TYPE, sal_Int32 );
+ DECL_PROP0( TYPENAME, ::rtl::OUString );
+
+ if ( nId & HAS_AUTOINCREMENT_CREATION )
+ {
+ DECL_PROP1( AUTOINCREMENTCREATION, ::rtl::OUString, MAYBEVOID );
+ }
+ if ( nId & HAS_DEFAULTVALUE )
+ {
+ DECL_PROP0( DEFAULTVALUE, ::rtl::OUString );
+ }
+ if ( nId & HAS_DESCRIPTION )
+ {
+ DECL_PROP0( DESCRIPTION, ::rtl::OUString );
+ }
+ if ( nId & HAS_ROWVERSION )
+ {
+ DECL_PROP0_BOOL( ISROWVERSION );
+ }
+
+ OSL_ENSURE( nPos == nPropertyCount, "OTableColumnDescriptorWrapper::createArrayHelper: something went wrong!" );
+
+ if ( !m_bIsDescriptor )
+ {
+ for ( Property* prop = aTableDescProperties.getArray();
+ prop != aTableDescProperties.getArray() + aTableDescProperties.getLength();
+ ++prop
+ )
+ {
+ prop->Attributes |= PropertyAttribute::READONLY;
+ }
+ }
+
+ // finally also describe the properties which are maintained by our base class, in particular the OPropertyContainerHelper
+ Sequence< Property > aBaseProperties;
+ describeProperties( aBaseProperties );
+
+ Sequence< Property > aAllProperties( ::comphelper::concatSequences( aTableDescProperties, aBaseProperties ) );
+ return new ::cppu::OPropertyArrayHelper( aAllProperties, sal_False );
+}
+
+// cppu::OPropertySetHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OTableColumnDescriptorWrapper::getInfoHelper()
+{
+ return *static_cast< OIdPropertyArrayUsageHelper< OTableColumnDescriptorWrapper >* >(this)->getArrayHelper(m_nColTypeID);
+}
+
+//------------------------------------------------------------------------------
+void OTableColumnDescriptorWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ if ( m_bPureWrap )
+ {
+ rValue = m_xAggregate->getPropertyValue( impl_getPropertyNameFromHandle( nHandle ) );
+ }
+ else
+ {
+ OColumnWrapper::getFastPropertyValue( rValue, nHandle );
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OTableColumnDescriptorWrapper::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw (IllegalArgumentException)
+{
+ sal_Bool bModified(sal_False);
+ if ( m_bPureWrap )
+ {
+ // do not delegate to OColumnWrapper: It would, for the properties which were registered with registerProperty,
+ // ask the OPropertyContainer base class, which is not what we want here.
+ // TODO: the whole "m_bPureWrap"-thingie is strange. We should have a dedicated class doing this wrapping,
+ // not a class which normally serves other purposes, and only sometimes does a "pure wrap". It makes the
+ // code unnecessarily hard to maintain, and error prone.
+ rOldValue = m_xAggregate->getPropertyValue( impl_getPropertyNameFromHandle( nHandle ) );
+ if ( rOldValue != rValue )
+ {
+ rConvertedValue = rValue;
+ bModified = sal_True;
+ }
+ }
+ else
+ {
+ bModified = OColumnWrapper::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OTableColumnDescriptorWrapper::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const Any& rValue
+ )
+ throw (Exception)
+{
+ if ( m_bPureWrap )
+ {
+ m_xAggregate->setPropertyValue( impl_getPropertyNameFromHandle( nHandle ), rValue );
+ }
+ else
+ {
+ OColumnWrapper::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+ }
+}
+
+//============================================================
+//= OTableColumnWrapper
+//============================================================
+//--------------------------------------------------------------------------
+OTableColumnWrapper::OTableColumnWrapper( const Reference< XPropertySet >& rCol, const Reference< XPropertySet >& _xColDefintion,
+ const bool _bPureWrap )
+ :OTableColumnDescriptorWrapper( rCol, _bPureWrap, false )
+{
+ osl_incrementInterlockedCount( &m_refCount );
+ if ( _xColDefintion.is() )
+ {
+ try
+ {
+ ::comphelper::copyProperties( _xColDefintion, this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+//--------------------------------------------------------------------------
+OTableColumnWrapper::~OTableColumnWrapper()
+{
+}
+
+//--------------------------------------------------------------------------
+IMPLEMENT_GET_IMPLEMENTATION_ID( OTableColumnWrapper )
+
+//------------------------------------------------------------------------------
+rtl::OUString OTableColumnWrapper::getImplementationName( ) throw (RuntimeException)
+{
+ return rtl::OUString::createFromAscii( "com.sun.star.sdb.OTableColumnWrapper" );
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OTableColumnWrapper::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = SERVICE_SDBCX_COLUMN;
+ aSNS[1] = SERVICE_SDB_COLUMNSETTINGS;
+ return aSNS;
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OTableColumnWrapper::getInfoHelper()
+{
+ return *static_cast< OIdPropertyArrayUsageHelper< OTableColumnWrapper >* >(this)->getArrayHelper(m_nColTypeID);
+}
+
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OTableColumnWrapper::createArrayHelper( sal_Int32 nId ) const
+{
+ return OTableColumnDescriptorWrapper::createArrayHelper( nId );
+}
+
diff --git a/dbaccess/source/core/api/makefile.mk b/dbaccess/source/core/api/makefile.mk
new file mode 100644
index 000000000000..9a4dc9d8ec52
--- /dev/null
+++ b/dbaccess/source/core/api/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJINC=$(PRJ)$/source
+PRJNAME=dbaccess
+TARGET=api
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/dba.pmk
+
+# --- Files -------------------------------------
+SLOFILES= \
+ $(SLO)$/querydescriptor.obj \
+ $(SLO)$/FilteredContainer.obj \
+ $(SLO)$/TableDeco.obj \
+ $(SLO)$/RowSetCacheIterator.obj \
+ $(SLO)$/RowSet.obj \
+ $(SLO)$/column.obj \
+ $(SLO)$/RowSetBase.obj \
+ $(SLO)$/CRowSetDataColumn.obj \
+ $(SLO)$/CRowSetColumn.obj \
+ $(SLO)$/querycomposer.obj \
+ $(SLO)$/CIndexes.obj \
+ $(SLO)$/BookmarkSet.obj \
+ $(SLO)$/KeySet.obj \
+ $(SLO)$/StaticSet.obj \
+ $(SLO)$/CacheSet.obj \
+ $(SLO)$/RowSetCache.obj \
+ $(SLO)$/definitioncolumn.obj \
+ $(SLO)$/resultcolumn.obj \
+ $(SLO)$/datacolumn.obj \
+ $(SLO)$/resultset.obj \
+ $(SLO)$/statement.obj \
+ $(SLO)$/preparedstatement.obj \
+ $(SLO)$/callablestatement.obj \
+ $(SLO)$/query.obj \
+ $(SLO)$/querycontainer.obj \
+ $(SLO)$/table.obj \
+ $(SLO)$/viewcontainer.obj \
+ $(SLO)$/tablecontainer.obj \
+ $(SLO)$/SingleSelectQueryComposer.obj \
+ $(SLO)$/HelperCollections.obj \
+ $(SLO)$/datasettings.obj \
+ $(SLO)$/View.obj \
+ $(SLO)$/WrappedResultSet.obj \
+ $(SLO)$/OptimisticSet.obj \
+ $(SLO)$/PrivateRow.obj \
+ $(SLO)$/columnsettings.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/dbaccess/source/core/api/preparedstatement.cxx b/dbaccess/source/core/api/preparedstatement.cxx
new file mode 100644
index 000000000000..98c7c1c74b65
--- /dev/null
+++ b/dbaccess/source/core/api/preparedstatement.cxx
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "dbastrings.hrc"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+
+#include <comphelper/property.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <preparedstatement.hxx>
+#include <resultcolumn.hxx>
+#include <resultset.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace dbaccess;
+
+DBG_NAME(OPreparedStatement)
+
+//--------------------------------------------------------------------------
+OPreparedStatement::OPreparedStatement(const Reference< XConnection > & _xConn,
+ const Reference< XInterface > & _xStatement)
+ :OStatementBase(_xConn, _xStatement)
+{
+ DBG_CTOR(OPreparedStatement, NULL);
+ m_xAggregateAsParameters = Reference< XParameters >( m_xAggregateAsSet, UNO_QUERY_THROW );
+
+ Reference<XDatabaseMetaData> xMeta = _xConn->getMetaData();
+ m_pColumns = new OColumns(*this, m_aMutex, xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),::std::vector< ::rtl::OUString>(), NULL,NULL);
+}
+
+//--------------------------------------------------------------------------
+OPreparedStatement::~OPreparedStatement()
+{
+ m_pColumns->acquire();
+ m_pColumns->disposing();
+ delete m_pColumns;
+
+ DBG_DTOR(OPreparedStatement, NULL);
+}
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > OPreparedStatement::getTypes() throw (RuntimeException)
+{
+ OTypeCollection aTypes(::getCppuType( (const Reference< XServiceInfo > *)0 ),
+ ::getCppuType( (const Reference< XPreparedStatement > *)0 ),
+ ::getCppuType( (const Reference< XParameters > *)0 ),
+ ::getCppuType( (const Reference< XResultSetMetaDataSupplier > *)0 ),
+ ::getCppuType( (const Reference< XColumnsSupplier > *)0 ),
+ OStatementBase::getTypes() );
+
+ return aTypes.getTypes();
+}
+
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > OPreparedStatement::getImplementationId() throw (RuntimeException)
+{
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// com::sun::star::uno::XInterface
+//--------------------------------------------------------------------------
+Any OPreparedStatement::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ Any aIface = OStatementBase::queryInterface( rType );
+ if (!aIface.hasValue())
+ aIface = ::cppu::queryInterface(
+ rType,
+ static_cast< XServiceInfo * >( this ),
+ static_cast< XParameters * >( this ),
+ static_cast< XColumnsSupplier * >( this ),
+ static_cast< XResultSetMetaDataSupplier * >( this ),
+ static_cast< XPreparedBatchExecution * >( this ),
+ static_cast< XMultipleResults * >( this ),
+ static_cast< XPreparedStatement * >( this ));
+ return aIface;
+}
+
+//--------------------------------------------------------------------------
+void OPreparedStatement::acquire() throw ()
+{
+ OStatementBase::acquire();
+}
+
+//--------------------------------------------------------------------------
+void OPreparedStatement::release() throw ()
+{
+ OStatementBase::release();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OPreparedStatement::getImplementationName( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OPreparedStatement");
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OPreparedStatement::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OPreparedStatement::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS.getArray()[0] = SERVICE_SDBC_PREPAREDSTATEMENT;
+ aSNS.getArray()[1] = SERVICE_SDB_PREPAREDSTATMENT;
+ return aSNS;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OPreparedStatement::disposing()
+{
+ {
+ MutexGuard aGuard(m_aMutex);
+ m_pColumns->disposing();
+ m_xAggregateAsParameters = NULL;
+ }
+ OStatementBase::disposing();
+}
+
+// ::com::sun::star::sdbcx::XColumnsSupplier
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::container::XNameAccess > OPreparedStatement::getColumns(void) throw( RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // do we have to populate the columns
+ if (!m_pColumns->isInitialized())
+ {
+ try
+ {
+ Reference< XResultSetMetaDataSupplier > xSuppMeta( m_xAggregateAsSet, UNO_QUERY_THROW );
+ Reference< XResultSetMetaData > xMetaData( xSuppMeta->getMetaData(), UNO_SET_THROW );
+
+ Reference< XConnection > xConn( getConnection(), UNO_SET_THROW );
+ Reference< XDatabaseMetaData > xDBMeta( xConn->getMetaData(), UNO_SET_THROW );
+
+ for (sal_Int32 i = 0, nCount = xMetaData->getColumnCount(); i < nCount; ++i)
+ {
+ // retrieve the name of the column
+ rtl::OUString aName = xMetaData->getColumnName(i + 1);
+ OResultColumn* pColumn = new OResultColumn(xMetaData, i + 1, xDBMeta);
+ m_pColumns->append(aName, pColumn);
+ }
+ }
+ catch (const SQLException& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_pColumns->setInitialized();
+ }
+ return m_pColumns;
+}
+
+// XResultSetMetaDataSupplier
+//------------------------------------------------------------------------------
+Reference< XResultSetMetaData > OPreparedStatement::getMetaData(void) throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ return Reference< XResultSetMetaDataSupplier >( m_xAggregateAsSet, UNO_QUERY_THROW )->getMetaData();
+}
+
+// XPreparedStatement
+//------------------------------------------------------------------------------
+Reference< XResultSet > OPreparedStatement::executeQuery() throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ disposeResultSet();
+
+ Reference< XResultSet > xResultSet;
+ Reference< XResultSet > xDrvResultSet = Reference< XPreparedStatement >( m_xAggregateAsSet, UNO_QUERY_THROW )->executeQuery();
+ if (xDrvResultSet.is())
+ {
+ xResultSet = new OResultSet(xDrvResultSet, *this, m_pColumns->isCaseSensitive());
+
+ // keep the resultset weak
+ m_aResultSet = xResultSet;
+ }
+ return xResultSet;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 OPreparedStatement::executeUpdate() throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ disposeResultSet();
+
+ return Reference< XPreparedStatement >( m_xAggregateAsSet, UNO_QUERY_THROW )->executeUpdate();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OPreparedStatement::execute() throw( SQLException, RuntimeException )
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ disposeResultSet();
+
+ return Reference< XPreparedStatement >( m_xAggregateAsSet, UNO_QUERY_THROW )->execute();
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection > OPreparedStatement::getConnection(void) throw( SQLException, RuntimeException )
+{
+ return Reference< XConnection > (m_xParent, UNO_QUERY);
+}
+
+// XParameters
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setNull(parameterIndex, sqlType);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setObjectNull(parameterIndex, sqlType, typeName);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setBoolean(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setByte(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setShort(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setInt(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setLong(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setFloat(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setDouble(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setString(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setBytes(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setDate(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setTime(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setTimestamp(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setBinaryStream(parameterIndex, x, length);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setCharacterStream(parameterIndex, x, length);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setObject(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 scale ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setObjectWithInfo(parameterIndex, x, targetSqlType, scale);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setRef( sal_Int32 parameterIndex, const Reference< XRef >& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setRef(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setBlob(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setClob(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::setArray( sal_Int32 parameterIndex, const Reference< XArray >& x ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->setArray(parameterIndex, x);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OPreparedStatement::clearParameters( ) throw(SQLException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ m_xAggregateAsParameters->clearParameters();
+}
+
diff --git a/dbaccess/source/core/api/query.cxx b/dbaccess/source/core/api/query.cxx
new file mode 100644
index 000000000000..f4cc3cf34714
--- /dev/null
+++ b/dbaccess/source/core/api/query.cxx
@@ -0,0 +1,445 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _DBA_COREAPI_QUERY_HXX_
+#include "query.hxx"
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef DBTOOLS_WARNINGSCONTAINER_HXX
+#include <connectivity/warningscontainer.hxx>
+#endif
+#ifndef DBA_HELPERCOLLECTIONS_HXX
+#include "HelperCollections.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HXX_
+#include "core_resource.hxx"
+#endif
+#ifndef _DBA_CORE_RESOURCE_HRC_
+#include "core_resource.hrc"
+#endif
+
+#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
+#include <cppuhelper/queryinterface.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef TOOLS_DIAGNOSE_EX_H
+#include <tools/diagnose_ex.h>
+#endif
+#ifndef _COMPHELPER_PROPERTY_AGGREGATION_HXX_
+#include <comphelper/propagg.hxx>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+
+/** === begin UNO includes === **/
+#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
+#include <com/sun/star/sdbc/XConnection.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+/** === end UNO includes === **/
+
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef UNOTOOLS_INC_SHAREDUNOCOMPONENT_HXX
+#include <unotools/sharedunocomponent.hxx>
+#endif
+#ifndef _DBACORE_DEFINITIONCOLUMN_HXX_
+#include "definitioncolumn.hxx"
+#endif
+
+#include <functional>
+
+#ifndef DBACORE_SDBCORETOOLS_HXX
+#include "sdbcoretools.hxx"
+#endif
+#ifndef DBACCESS_CORE_API_QUERYCOMPOSER_HXX
+#include "querycomposer.hxx"
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef DBA_CONTAINERMEDIATOR_HXX
+#include "ContainerMediator.hxx"
+#endif
+
+using namespace dbaccess;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::comphelper;
+using namespace ::osl;
+using namespace ::cppu;
+using namespace ::utl;
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//==========================================================================
+//= OQuery
+//==========================================================================
+DBG_NAME(OQuery)
+//--------------------------------------------------------------------------
+OQuery::OQuery( const Reference< XPropertySet >& _rxCommandDefinition
+ ,const Reference< XConnection >& _rxConn
+ ,const Reference< XMultiServiceFactory >& _xORB)
+ :OContentHelper(_xORB,NULL,TContentPtr(new OContentHelper_Impl))
+ ,OQueryDescriptor_Base(m_aMutex,*this)
+ ,ODataSettings(OContentHelper::rBHelper,sal_True)
+ ,m_xCommandDefinition(_rxCommandDefinition)
+ ,m_xConnection(_rxConn)
+ ,m_pColumnMediator( NULL )
+ ,m_pWarnings( NULL )
+ ,m_bCaseSensitiv(sal_True)
+ ,m_eDoingCurrently(NONE)
+{
+ DBG_CTOR(OQuery, NULL);
+ registerProperties();
+ ODataSettings::registerPropertiesFor(this);
+
+ osl_incrementInterlockedCount(&m_refCount);
+ DBG_ASSERT(m_xCommandDefinition.is(), "OQuery::OQuery : invalid CommandDefinition object !");
+ if ( m_xCommandDefinition.is() )
+ {
+ try
+ {
+ ::comphelper::copyProperties(_rxCommandDefinition,this);
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(sal_False, "OQueryDescriptor_Base::OQueryDescriptor_Base: caught an exception!");
+ }
+
+ m_xCommandDefinition->addPropertyChangeListener(::rtl::OUString(), this);
+ // m_xCommandDefinition->addPropertyChangeListener(PROPERTY_NAME, this);
+ m_xCommandPropInfo = m_xCommandDefinition->getPropertySetInfo();
+ }
+ DBG_ASSERT(m_xConnection.is(), "OQuery::OQuery : invalid connection !");
+ osl_decrementInterlockedCount(&m_refCount);
+}
+
+//--------------------------------------------------------------------------
+OQuery::~OQuery()
+{
+ DBG_DTOR(OQuery, NULL);
+}
+// -----------------------------------------------------------------------------
+IMPLEMENT_IMPLEMENTATION_ID(OQuery);
+IMPLEMENT_GETTYPES3(OQuery,OQueryDescriptor_Base,ODataSettings,OContentHelper);
+IMPLEMENT_FORWARD_XINTERFACE3( OQuery,OContentHelper,OQueryDescriptor_Base,ODataSettings)
+//--------------------------------------------------------------------------
+void OQuery::rebuildColumns()
+{
+ OSL_PRECOND( getColumnCount() == 0, "OQuery::rebuildColumns: column container should be empty!" );
+ // the base class' definition of rebuildColumns promised that clearColumns is called before rebuildColumns
+
+ try
+ {
+ m_pColumnMediator = NULL;
+
+ Reference<XColumnsSupplier> xColSup(m_xCommandDefinition,UNO_QUERY);
+ Reference< XNameAccess > xColumnDefinitions;
+ if ( xColSup.is() )
+ {
+ xColumnDefinitions = xColSup->getColumns();
+ if ( xColumnDefinitions.is() )
+ m_pColumnMediator = new OContainerMediator( m_pColumns, xColumnDefinitions, m_xConnection, OContainerMediator::eColumns );
+ }
+
+ // fill the columns with columns from the statement
+ Reference< XMultiServiceFactory > xFactory( m_xConnection, UNO_QUERY_THROW );
+ SharedUNOComponent< XSingleSelectQueryComposer, DisposableComponent > xComposer(
+ Reference< XSingleSelectQueryComposer >( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW ) );
+
+ Reference< XNameAccess > xColumns;
+ Reference< XIndexAccess > xColumnsIndexed;
+ try
+ {
+ xComposer->setQuery( m_sCommand );
+ Reference< XColumnsSupplier > xCols( xComposer, UNO_QUERY_THROW );
+ xColumns.set( xCols->getColumns(), UNO_QUERY_THROW );
+ xColumnsIndexed.set( xColumns, UNO_QUERY_THROW );
+ }
+ catch( const SQLException& ) { }
+
+ SharedUNOComponent< XPreparedStatement, DisposableComponent > xPreparedStatement;
+ if ( !xColumns.is() || ( xColumnsIndexed->getCount() == 0 ) )
+ { // the QueryComposer could not parse it. Try a lean version.
+ xPreparedStatement.set( m_xConnection->prepareStatement( m_sCommand ), UNO_QUERY_THROW );
+ Reference< XResultSetMetaDataSupplier > xResMetaDataSup( xPreparedStatement, UNO_QUERY_THROW );
+ Reference< XResultSetMetaData > xResultSetMeta( xResMetaDataSup->getMetaData() );
+ if ( !xResultSetMeta.is() )
+ {
+ ::rtl::OUString sError( DBA_RES( RID_STR_STATEMENT_WITHOUT_RESULT_SET ) );
+ ::dbtools::throwSQLException( sError, SQL_GENERAL_ERROR, *this );
+ }
+
+ Reference< XDatabaseMetaData > xDBMeta( m_xConnection->getMetaData(), UNO_QUERY_THROW );
+ ::vos::ORef< OSQLColumns > aParseColumns(
+ ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, xDBMeta,xColumnDefinitions ) );
+ xColumns = OPrivateColumns::createWithIntrinsicNames(
+ aParseColumns, xDBMeta->storesMixedCaseQuotedIdentifiers(), *this, m_aMutex );
+ if ( !xColumns.is() )
+ throw RuntimeException();
+ }
+
+ Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
+ const ::rtl::OUString* pIter = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aNames.getLength();
+ for ( sal_Int32 i = 0;pIter != pEnd; ++pIter,++i)
+ {
+ Reference<XPropertySet> xSource(xColumns->getByName( *pIter ),UNO_QUERY);
+ ::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 );
+
+ implAppendColumn( *pIter, pColumn );
+ Reference< XPropertySet > xDest( *pColumn, UNO_QUERY_THROW );
+ if ( m_pColumnMediator.is() )
+ m_pColumnMediator->notifyElementCreated( *pIter, xDest );
+ }
+ }
+ catch( const SQLContext& e )
+ {
+ if ( m_pWarnings )
+ m_pWarnings->appendWarning( e );
+ }
+ catch( const SQLWarning& e )
+ {
+ if ( m_pWarnings )
+ m_pWarnings->appendWarning( e );
+ }
+ catch( const SQLException& e )
+ {
+ if ( m_pWarnings )
+ m_pWarnings->appendWarning( e );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+// XServiceInfo
+//--------------------------------------------------------------------------
+IMPLEMENT_SERVICE_INFO3(OQuery, "com.sun.star.sdb.dbaccess.OQuery", SERVICE_SDB_DATASETTINGS, SERVICE_SDB_QUERY, SERVICE_SDB_QUERYDEFINITION)
+
+// ::com::sun::star::beans::XPropertyChangeListener
+//--------------------------------------------------------------------------
+void SAL_CALL OQuery::propertyChange( const PropertyChangeEvent& _rSource ) throw(RuntimeException)
+{
+ sal_Int32 nOwnHandle = -1;
+ {
+ MutexGuard aGuard(m_aMutex);
+
+ DBG_ASSERT(_rSource.Source.get() == Reference< XInterface >(m_xCommandDefinition, UNO_QUERY).get(),
+ "OQuery::propertyChange : where did this call come from ?");
+
+ if (m_eDoingCurrently == SETTING_PROPERTIES)
+ // we're setting the property ourself, so we will do the neccessary notifications later
+ return;
+
+ // forward this to our own member holding a copy of the property value
+ if (getArrayHelper()->hasPropertyByName(_rSource.PropertyName))
+ {
+ Property aOwnProp = getArrayHelper()->getPropertyByName(_rSource.PropertyName);
+ nOwnHandle = aOwnProp.Handle;
+ ODataSettings::setFastPropertyValue_NoBroadcast(nOwnHandle, _rSource.NewValue);
+ // don't use our own setFastPropertyValue_NoBroadcast, this would forward it to the CommandSettings,
+ // again
+ // and don't use the "real" setPropertyValue, this is to expensive and not sure to succeed
+ }
+ else
+ {
+ DBG_ERROR("OQuery::propertyChange : my CommandDefinition has more properties than I do !");
+ }
+ }
+
+ fire(&nOwnHandle, &_rSource.NewValue, &_rSource.OldValue, 1, sal_False);
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OQuery::disposing( const EventObject& _rSource ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ (void)_rSource;
+ DBG_ASSERT(_rSource.Source.get() == Reference< XInterface >(m_xCommandDefinition, UNO_QUERY).get(),
+ "OQuery::disposing : where did this call come from ?");
+
+ m_xCommandDefinition->removePropertyChangeListener(::rtl::OUString(), this);
+ m_xCommandDefinition = NULL;
+}
+
+// XDataDescriptorFactory
+//--------------------------------------------------------------------------
+Reference< XPropertySet > SAL_CALL OQuery::createDataDescriptor( ) throw(RuntimeException)
+{
+ return new OQueryDescriptor(*this);
+}
+
+// pseudo-XComponent
+//--------------------------------------------------------------------------
+void SAL_CALL OQuery::disposing()
+{
+ MutexGuard aGuard(m_aMutex);
+ if (m_xCommandDefinition.is())
+ {
+ m_xCommandDefinition->removePropertyChangeListener(::rtl::OUString(), this);
+ m_xCommandDefinition = NULL;
+ }
+ disposeColumns();
+
+ m_pWarnings = NULL;
+}
+
+//--------------------------------------------------------------------------
+void OQuery::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
+{
+ ODataSettings::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
+ ::rtl::OUString sAggPropName;
+ sal_Int16 nAttr = 0;
+ if (getInfoHelper().fillPropertyMembersByHandle(&sAggPropName,&nAttr,_nHandle) &&
+ m_xCommandPropInfo.is() &&
+ m_xCommandPropInfo->hasPropertyByName(sAggPropName))
+ { // the base class holds the property values itself, but we have to forward this to our CommandDefinition
+
+ m_eDoingCurrently = SETTING_PROPERTIES;
+ OAutoActionReset(this);
+ m_xCommandDefinition->setPropertyValue(sAggPropName, _rValue);
+
+ if ( PROPERTY_ID_COMMAND == _nHandle )
+ // the columns are out of date if we are based on a new statement ....
+ // 90573 - 16.08.2001 - frank.schoenheit@sun.com
+ setColumnsOutOfDate();
+ }
+}
+
+//--------------------------------------------------------------------------
+Reference< XPropertySetInfo > SAL_CALL OQuery::getPropertySetInfo( ) throw(RuntimeException)
+{
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OQuery::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+//--------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OQuery::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ // our own props
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+// -----------------------------------------------------------------------------
+OColumn* OQuery::createColumn(const ::rtl::OUString& /*_rName*/) const
+{
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQuery::rename( const ::rtl::OUString& newName ) throw (SQLException, ElementExistException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ Reference<XRename> xRename(m_xCommandDefinition,UNO_QUERY);
+ OSL_ENSURE(xRename.is(),"No XRename interface!");
+ if(xRename.is())
+ xRename->rename(newName);
+}
+// -----------------------------------------------------------------------------
+void OQuery::registerProperties()
+{
+ // the properties which OCommandBase supplies (it has no own registration, as it's not derived from
+ // a OPropertyStateContainer)
+ registerProperty(PROPERTY_NAME, PROPERTY_ID_NAME, PropertyAttribute::BOUND|PropertyAttribute::CONSTRAINED,
+ &m_sElementName, ::getCppuType(&m_sElementName));
+
+ registerProperty(PROPERTY_COMMAND, PROPERTY_ID_COMMAND, PropertyAttribute::BOUND,
+ &m_sCommand, ::getCppuType(&m_sCommand));
+
+ registerProperty(PROPERTY_ESCAPE_PROCESSING, PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::BOUND,
+ &m_bEscapeProcessing, ::getBooleanCppuType());
+
+ registerProperty(PROPERTY_UPDATE_TABLENAME, PROPERTY_ID_UPDATE_TABLENAME, PropertyAttribute::BOUND,
+ &m_sUpdateTableName, ::getCppuType(&m_sUpdateTableName));
+
+ registerProperty(PROPERTY_UPDATE_SCHEMANAME, PROPERTY_ID_UPDATE_SCHEMANAME, PropertyAttribute::BOUND,
+ &m_sUpdateSchemaName, ::getCppuType(&m_sUpdateSchemaName));
+
+ registerProperty(PROPERTY_UPDATE_CATALOGNAME, PROPERTY_ID_UPDATE_CATALOGNAME, PropertyAttribute::BOUND,
+ &m_sUpdateCatalogName, ::getCppuType(&m_sUpdateCatalogName));
+
+ registerProperty(PROPERTY_LAYOUTINFORMATION, PROPERTY_ID_LAYOUTINFORMATION, PropertyAttribute::BOUND,
+ &m_aLayoutInformation, ::getCppuType(&m_aLayoutInformation));
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString OQuery::determineContentType() const
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseQuery" ) );
+}
+
+// -----------------------------------------------------------------------------
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
diff --git a/dbaccess/source/core/api/query.hxx b/dbaccess/source/core/api/query.hxx
new file mode 100644
index 000000000000..81e3a38c7862
--- /dev/null
+++ b/dbaccess/source/core/api/query.hxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 _DBA_COREAPI_QUERY_HXX_
+#define _DBA_COREAPI_QUERY_HXX_
+
+#ifndef _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
+#include "querydescriptor.hxx"
+#endif
+#ifndef _CPPUHELPER_IMPLBASE3_HXX_
+#include <cppuhelper/implbase3.hxx>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
+#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
+#include <com/sun/star/sdbc/XConnection.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
+#include <com/sun/star/sdbcx/XRename.hpp>
+#endif
+#ifndef DBA_CONTENTHELPER_HXX
+#include "ContentHelper.hxx"
+#endif
+
+#include <map>
+
+namespace dbtools
+{
+ class IWarningsContainer;
+}
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//==========================================================================
+//= OQuery - an object implementing the sdb.Query service
+//==========================================================================
+typedef ::cppu::ImplHelper3 < ::com::sun::star::sdbcx::XDataDescriptorFactory,
+ ::com::sun::star::beans::XPropertyChangeListener,
+ ::com::sun::star::sdbcx::XRename
+ > OQuery_Base;
+class OQuery;
+class OColumn;
+typedef ::comphelper::OPropertyArrayUsageHelper< OQuery > OQuery_ArrayHelperBase;
+
+
+class OQuery :public OContentHelper
+ ,public OQueryDescriptor_Base
+ ,public OQuery_Base
+ ,public OQuery_ArrayHelperBase
+ ,public ODataSettings
+{
+ friend struct TRelease;
+
+public:
+ typedef ::std::map< ::rtl::OUString,OColumn*,::comphelper::UStringMixLess> TNameColumnMap;
+
+protected:
+// TNameColumnMap m_aColumnMap; // contains all columnnames to columns
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xCommandDefinition;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > m_xConnection;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > m_xCommandPropInfo;
+ ::rtl::Reference< OContainerMediator > m_pColumnMediator;
+ ::dbtools::IWarningsContainer* m_pWarnings;
+ sal_Bool m_bCaseSensitiv : 1; // assume case sensitivity of the column names ?
+
+ // possible actions on our "aggregate"
+ enum AGGREGATE_ACTION { NONE, SETTING_PROPERTIES, FLUSHING };
+ AGGREGATE_ACTION m_eDoingCurrently;
+
+ // ------------------------------------------------------------------------
+ /** a class which automatically resets m_eDoingCurrently in it's destructor
+ */
+ class OAutoActionReset; // just for the following friend declaration
+ friend class OAutoActionReset;
+ class OAutoActionReset
+ {
+ OQuery* m_pActor;
+ public:
+ OAutoActionReset(OQuery* _pActor) : m_pActor(_pActor) { }
+ ~OAutoActionReset() { m_pActor->m_eDoingCurrently = NONE; }
+ };
+
+protected:
+ virtual ~OQuery();
+
+// OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+ ::cppu::IPropertyArrayHelper* getArrayHelper() { return OQuery_ArrayHelperBase::getArrayHelper(); }
+
+public:
+ OQuery(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxCommandDefinition,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConn,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
+ );
+
+// com::sun::star::lang::XTypeProvider
+ DECLARE_TYPEPROVIDER( );
+
+// ::com::sun::star::uno::XInterface
+ DECLARE_XINTERFACE( )
+
+// ::com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+// OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+// ::com::sun::star::lang::XServiceInfo
+ DECLARE_SERVICE_INFO();
+
+// ::com::sun::star::sdbcx::XDataDescriptorFactory
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::beans::XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException);
+
+// OPropertySetHelper
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::uno::Exception);
+
+public:
+ // the caller is responsible for the lifetime!
+ void setWarningsContainer( ::dbtools::IWarningsContainer* _pWarnings ) { m_pWarnings = _pWarnings; }
+ ::dbtools::IWarningsContainer* getWarningsContainer( ) const { return m_pWarnings; }
+
+ // XRename
+ virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ virtual void SAL_CALL disposing();
+
+ virtual OColumn* createColumn(const ::rtl::OUString& _rName) const;
+
+ virtual void rebuildColumns( );
+
+ // OContentHelper overridables
+ virtual ::rtl::OUString determineContentType() const;
+
+private:
+ void registerProperties();
+};
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // _DBA_COREAPI_QUERY_HXX_
+
+
diff --git a/dbaccess/source/core/api/querycomposer.cxx b/dbaccess/source/core/api/querycomposer.cxx
new file mode 100644
index 000000000000..ea0a3617e9ba
--- /dev/null
+++ b/dbaccess/source/core/api/querycomposer.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_COLUMNSEARCH_HPP_
+#include <com/sun/star/sdbc/ColumnSearch.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
+#include <com/sun/star/sdbc/DataType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_SERVICENOTREGISTEREDEXCEPTION_HPP_
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _COM_SUN_STAR_UNO_XAGGREGATION_HPP_
+#include <com/sun/star/uno/XAggregation.hpp>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/processfactory.hxx>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _UTL_CONFIGMGR_HXX_
+#include <unotools/configmgr.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _COM_SUN_STAR_I18N_XLOCALEDATA_HPP_
+#include <com/sun/star/i18n/XLocaleData.hpp>
+#endif
+#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
+#include <unotools/syslocale.hxx>
+#endif
+#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
+#ifndef DBA_HELPERCOLLECTIONS_HXX
+#include "HelperCollections.hxx"
+#endif
+#ifndef DBACCESS_SOURCE_CORE_INC_COMPOSERTOOLS_HXX
+#include "composertools.hxx"
+#endif
+#include <algorithm>
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+using namespace dbtools;
+using namespace comphelper;
+using namespace connectivity;
+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::i18n;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::utl;
+
+
+DBG_NAME(OQueryComposer)
+// -------------------------------------------------------------------------
+OQueryComposer::OQueryComposer(const Reference< XConnection>& _xConnection)
+ : OSubComponent(m_aMutex,_xConnection)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::OQueryComposer" );
+ DBG_CTOR(OQueryComposer,NULL);
+ OSL_ENSURE(_xConnection.is()," Connection cant be null!");
+
+ Reference<XMultiServiceFactory> xFac( _xConnection, UNO_QUERY_THROW );
+ m_xComposer.set( xFac->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
+ m_xComposerHelper.set( xFac->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
+}
+// -------------------------------------------------------------------------
+OQueryComposer::~OQueryComposer()
+{
+ DBG_DTOR(OQueryComposer,NULL);
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::disposing" );
+ ::comphelper::disposeComponent(m_xComposerHelper);
+ ::comphelper::disposeComponent(m_xComposer);
+}
+// -------------------------------------------------------------------------
+// ::com::sun::star::lang::XTypeProvider
+Sequence< Type > SAL_CALL OQueryComposer::getTypes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getTypes" );
+ return ::comphelper::concatSequences(OSubComponent::getTypes(),OQueryComposer_BASE::getTypes());
+}
+// -------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL OQueryComposer::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getImplementationId" );
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+// -------------------------------------------------------------------------
+// com::sun::star::lang::XUnoTunnel
+sal_Int64 SAL_CALL OQueryComposer::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getSomething" );
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL OQueryComposer::queryInterface( const Type & rType ) throw(RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::queryInterface" );
+ Any aRet = OSubComponent::queryInterface(rType);
+ if(!aRet.hasValue())
+ aRet = OQueryComposer_BASE::queryInterface(rType);
+ return aRet;
+}
+// -------------------------------------------------------------------------
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OQueryComposer::getImplementationName( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getImplementationName" );
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.dbaccess.OQueryComposer"));
+}
+//------------------------------------------------------------------------------
+sal_Bool OQueryComposer::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::supportsService" );
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OQueryComposer::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getSupportedServiceNames" );
+ Sequence< rtl::OUString > aSNS( 1 );
+ aSNS[0] = SERVICE_SDB_SQLQUERYCOMPOSER;
+ return aSNS;
+}
+// -------------------------------------------------------------------------
+// XSQLQueryComposer
+::rtl::OUString SAL_CALL OQueryComposer::getQuery( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getQuery" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ Reference<XPropertySet> xProp(m_xComposer,UNO_QUERY);
+ ::rtl::OUString sQuery;
+ if ( xProp.is() )
+ xProp->getPropertyValue(PROPERTY_ORIGINAL) >>= sQuery;
+ return sQuery;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::setQuery( const ::rtl::OUString& command ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::setQuery" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFilters.clear();
+ m_xComposer->setQuery(command);
+ m_sOrgFilter = m_xComposer->getFilter();
+ m_sOrgOrder = m_xComposer->getOrder();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OQueryComposer::getComposedQuery( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getComposedQuery" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ MutexGuard aGuard(m_aMutex);
+
+ return m_xComposer->getQuery();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OQueryComposer::getFilter( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getFilter" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ MutexGuard aGuard(m_aMutex);
+ FilterCreator aFilterCreator;
+ aFilterCreator = ::std::for_each(m_aFilters.begin(),m_aFilters.end(),aFilterCreator);
+ return aFilterCreator.getComposedAndClear();
+}
+// -------------------------------------------------------------------------
+Sequence< Sequence< PropertyValue > > SAL_CALL OQueryComposer::getStructuredFilter( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getStructuredFilter" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ MutexGuard aGuard(m_aMutex);
+ return m_xComposer->getStructuredFilter();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OQueryComposer::getOrder( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getOrder" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ OrderCreator aOrderCreator;
+ aOrderCreator = ::std::for_each(m_aOrders.begin(),m_aOrders.end(),aOrderCreator);
+ return aOrderCreator.getComposedAndClear();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::appendFilterByColumn" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_xComposerHelper->setQuery(getQuery());
+ m_xComposerHelper->setFilter(::rtl::OUString());
+ 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());
+ aFilterCreator.append(m_xComposerHelper->getFilter());
+
+ setFilter( aFilterCreator.getComposedAndClear() );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::appendOrderByColumn( const Reference< XPropertySet >& column, sal_Bool ascending ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::appendOrderByColumn" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_xComposerHelper->setQuery(getQuery());
+ m_xComposerHelper->setOrder(::rtl::OUString());
+ m_xComposerHelper->appendOrderByColumn(column,ascending);
+
+ OrderCreator aOrderCreator;
+ aOrderCreator.append(getOrder());
+ aOrderCreator.append(m_xComposerHelper->getOrder());
+
+ setOrder(aOrderCreator.getComposedAndClear());
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::setFilter( const ::rtl::OUString& filter ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::setFilter" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ FilterCreator aFilterCreator;
+ aFilterCreator.append(m_sOrgFilter);
+ aFilterCreator.append(filter);
+
+ m_aFilters.clear();
+ if ( filter.getLength() )
+ m_aFilters.push_back(filter);
+
+ m_xComposer->setFilter( aFilterCreator.getComposedAndClear() );
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::setOrder( const ::rtl::OUString& order ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::setOrder" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ OrderCreator aOrderCreator;
+ aOrderCreator.append(m_sOrgOrder);
+ aOrderCreator.append(order);
+
+ m_aOrders.clear();
+ if ( order.getLength() )
+ m_aOrders.push_back(order);
+
+ m_xComposer->setOrder(aOrderCreator.getComposedAndClear());
+}
+// -------------------------------------------------------------------------
+// XTablesSupplier
+Reference< XNameAccess > SAL_CALL OQueryComposer::getTables( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getTables" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return Reference<XTablesSupplier>(m_xComposer,UNO_QUERY)->getTables();
+}
+// -------------------------------------------------------------------------
+// XColumnsSupplier
+Reference< XNameAccess > SAL_CALL OQueryComposer::getColumns( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getColumns" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return Reference<XColumnsSupplier>(m_xComposer,UNO_QUERY)->getColumns();
+}
+// -------------------------------------------------------------------------
+Reference< XIndexAccess > SAL_CALL OQueryComposer::getParameters( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OQueryComposer::getParameters" );
+ ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return Reference<XParametersSupplier>(m_xComposer,UNO_QUERY)->getParameters();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::acquire() throw()
+{
+ OSubComponent::acquire();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OQueryComposer::release() throw()
+{
+ OSubComponent::release();
+}
+// -----------------------------------------------------------------------------
+
+
+
+
+
diff --git a/dbaccess/source/core/api/querycontainer.cxx b/dbaccess/source/core/api/querycontainer.cxx
new file mode 100644
index 000000000000..043912259aff
--- /dev/null
+++ b/dbaccess/source/core/api/querycontainer.cxx
@@ -0,0 +1,475 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _DBA_CORE_QUERYCONTAINER_HXX_
+#include "querycontainer.hxx"
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBA_COREAPI_QUERY_HXX_
+#include "query.hxx"
+#endif
+#ifndef DBACCESS_OBJECTNAMEAPPROVAL_HXX
+#include "objectnameapproval.hxx"
+#endif
+#ifndef DBA_CONTAINERLISTENER_HXX
+#include "ContainerListener.hxx"
+#endif
+#ifndef DBACCESS_VETO_HXX
+#include "veto.hxx"
+#endif
+
+/** === begin UNO includes === **/
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_
+#include <com/sun/star/container/XContainer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
+#include <com/sun/star/sdbc/XConnection.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINERAPPROVEBROADCASTER_HPP_
+#include <com/sun/star/container/XContainerApproveBroadcaster.hpp>
+#endif
+/** === end UNO includes === **/
+
+#ifndef _DBHELPER_DBEXCEPTION_HXX_
+#include <connectivity/dbexception.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _COMPHELPER_ENUMHELPER_HXX_
+#include <comphelper/enumhelper.hxx>
+#endif
+#ifndef _COMPHELPER_UNO3_HXX_
+#include <comphelper/uno3.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _COMPHELPER_EXTRACT_HXX_
+#include <comphelper/extract.hxx>
+#endif
+#ifndef _CPPUHELPER_EXC_HLP_HXX_
+#include <cppuhelper/exc_hlp.hxx>
+#endif
+
+using namespace dbtools;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//==========================================================================
+//= OQueryContainer
+//==========================================================================
+DBG_NAME(OQueryContainer)
+//------------------------------------------------------------------------------
+OQueryContainer::OQueryContainer(
+ const Reference< XNameContainer >& _rxCommandDefinitions
+ , const Reference< XConnection >& _rxConn
+ , const Reference< XMultiServiceFactory >& _rxORB,
+ ::dbtools::IWarningsContainer* _pWarnings)
+ :ODefinitionContainer(_rxORB,NULL,TContentPtr(new ODefinitionContainer_Impl))
+ ,m_pWarnings( _pWarnings )
+ ,m_xCommandDefinitions(_rxCommandDefinitions)
+ ,m_xConnection(_rxConn)
+{
+ DBG_CTOR(OQueryContainer, NULL);
+
+ increment(m_refCount);
+ {
+ m_pCommandsListener = new OContainerListener( *this, m_aMutex );
+ m_pCommandsListener->acquire();
+
+ Reference< XContainer > xContainer( m_xCommandDefinitions, UNO_QUERY_THROW );
+ xContainer->addContainerListener( m_pCommandsListener );
+
+ Reference< XContainerApproveBroadcaster > xContainerApprove( m_xCommandDefinitions, UNO_QUERY_THROW );
+ xContainerApprove->addContainerApproveListener( m_pCommandsListener );
+
+ // fill my structures
+ ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
+ Sequence< ::rtl::OUString > sDefinitionNames = m_xCommandDefinitions->getElementNames();
+ const ::rtl::OUString* pDefinitionName = sDefinitionNames.getConstArray();
+ const ::rtl::OUString* pEnd = pDefinitionName + sDefinitionNames.getLength();
+ for ( ; pDefinitionName != pEnd; ++pDefinitionName )
+ {
+ rDefinitions.insert( *pDefinitionName, TContentPtr() );
+ m_aDocuments.push_back(m_aDocumentMap.insert(Documents::value_type(*pDefinitionName,Documents::mapped_type())).first);
+ }
+ }
+ decrement(m_refCount);
+
+ setElementApproval( PContainerApprove( new ObjectNameApproval( _rxConn, ObjectNameApproval::TypeQuery ) ) );
+}
+
+//------------------------------------------------------------------------------
+OQueryContainer::~OQueryContainer()
+{
+ DBG_DTOR(OQueryContainer, NULL);
+ // dispose();
+ // maybe we're already disposed, but this should be uncritical
+}
+// -----------------------------------------------------------------------------
+IMPLEMENT_FORWARD_XINTERFACE2( OQueryContainer,ODefinitionContainer,OQueryContainer_Base)
+
+//------------------------------------------------------------------------------
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( OQueryContainer,ODefinitionContainer,OQueryContainer_Base)
+
+//------------------------------------------------------------------------------
+void OQueryContainer::disposing()
+{
+ ODefinitionContainer::disposing();
+ MutexGuard aGuard(m_aMutex);
+ if ( !m_xCommandDefinitions.is() )
+ // already disposed
+ return;
+
+ if ( m_pCommandsListener )
+ {
+ Reference< XContainer > xContainer( m_xCommandDefinitions, UNO_QUERY );
+ xContainer->removeContainerListener( m_pCommandsListener );
+ Reference< XContainerApproveBroadcaster > xContainerApprove( m_xCommandDefinitions, UNO_QUERY );
+ xContainerApprove->removeContainerApproveListener( m_pCommandsListener );
+
+ m_pCommandsListener->dispose();
+ m_pCommandsListener->release();
+ m_pCommandsListener = NULL;
+ }
+
+ m_xCommandDefinitions = NULL;
+ m_xConnection = NULL;
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+IMPLEMENT_SERVICE_INFO2(OQueryContainer, "com.sun.star.sdb.dbaccess.OQueryContainer", SERVICE_SDBCX_CONTAINER, SERVICE_SDB_QUERIES)
+
+// XDataDescriptorFactory
+//--------------------------------------------------------------------------
+Reference< XPropertySet > SAL_CALL OQueryContainer::createDataDescriptor( ) throw(RuntimeException)
+{
+ return new OQueryDescriptor();
+}
+
+// XAppend
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::appendByDescriptor( const Reference< XPropertySet >& _rxDesc ) throw(SQLException, ElementExistException, RuntimeException)
+{
+ ResettableMutexGuard aGuard(m_aMutex);
+ if ( !m_xCommandDefinitions.is() )
+ throw DisposedException( ::rtl::OUString(), *this );
+
+ // first clone this object's CommandDefinition part
+ Reference< XPropertySet > xCommandDefinitionPart( m_aContext.createComponent( (::rtl::OUString)SERVICE_SDB_QUERYDEFINITION ), UNO_QUERY_THROW );
+ ::comphelper::copyProperties( _rxDesc, xCommandDefinitionPart );
+ // TODO : the columns part of the descriptor has to be copied
+
+ // create a wrapper for the object (*before* inserting into our command definition container)
+ Reference< XContent > xNewObject( implCreateWrapper( Reference< XContent>( xCommandDefinitionPart, UNO_QUERY_THROW ) ) );
+
+ ::rtl::OUString sNewObjectName;
+ _rxDesc->getPropertyValue(PROPERTY_NAME) >>= sNewObjectName;
+
+ try
+ {
+ notifyByName( aGuard, sNewObjectName, xNewObject, NULL, E_INSERTED, ApproveListeners );
+ }
+ catch( const Exception& )
+ {
+ disposeComponent( xNewObject );
+ disposeComponent( xCommandDefinitionPart );
+ throw;
+ }
+
+ // insert the basic object into the definition container
+ {
+ m_eDoingCurrently = INSERTING;
+ OAutoActionReset aAutoReset(this);
+ m_xCommandDefinitions->insertByName(sNewObjectName, makeAny(xCommandDefinitionPart));
+ }
+
+ implAppend( sNewObjectName, xNewObject );
+ notifyByName( aGuard, sNewObjectName, xNewObject, NULL, E_INSERTED, ContainerListemers );
+}
+
+// XDrop
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::dropByName( const ::rtl::OUString& _rName ) throw(SQLException, NoSuchElementException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ if ( !checkExistence(_rName) )
+ throw NoSuchElementException(_rName,*this);
+
+ if ( !m_xCommandDefinitions.is() )
+ throw DisposedException( ::rtl::OUString(), *this );
+
+ // now simply forward the remove request to the CommandDefinition container, we're a listener for the removal
+ // and thus we do everything neccessary in ::elementRemoved
+ m_xCommandDefinitions->removeByName(_rName);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::dropByIndex( sal_Int32 _nIndex ) throw(SQLException, IndexOutOfBoundsException, RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ if ((_nIndex<0) || (_nIndex>getCount()))
+ throw IndexOutOfBoundsException();
+
+ if ( !m_xCommandDefinitions.is() )
+ throw DisposedException( ::rtl::OUString(), *this );
+
+ ::rtl::OUString sName;
+ Reference<XPropertySet> xProp(Reference<XIndexAccess>(m_xCommandDefinitions,UNO_QUERY)->getByIndex(_nIndex),UNO_QUERY);
+ if ( xProp.is() )
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
+
+ dropByName(sName);
+}
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::elementInserted( const ::com::sun::star::container::ContainerEvent& _rEvent ) throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XContent > xNewElement;
+ ::rtl::OUString sElementName;
+ _rEvent.Accessor >>= sElementName;
+ {
+ MutexGuard aGuard(m_aMutex);
+ if (INSERTING == m_eDoingCurrently)
+ // nothing to do, we're inserting via an "appendByDescriptor"
+ return;
+
+ DBG_ASSERT(sElementName.getLength(), "OQueryContainer::elementInserted : invalid name !");
+ DBG_ASSERT(m_aDocumentMap.find(sElementName) == m_aDocumentMap.end(), "OQueryContainer::elementInserted : oops .... we're inconsistent with our master container !");
+ if (!sElementName.getLength() || hasByName(sElementName))
+ return;
+
+ // insert an own new element
+ xNewElement = implCreateWrapper(sElementName);
+ }
+ insertByName(sElementName,makeAny(xNewElement));
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::elementRemoved( const ::com::sun::star::container::ContainerEvent& _rEvent ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::rtl::OUString sAccessor;
+ _rEvent.Accessor >>= sAccessor;
+ {
+ DBG_ASSERT(sAccessor.getLength(), "OQueryContainer::elementRemoved : invalid name !");
+ DBG_ASSERT(m_aDocumentMap.find(sAccessor) != m_aDocumentMap.end(), "OQueryContainer::elementRemoved : oops .... we're inconsistent with our master container !");
+ if ( !sAccessor.getLength() || !hasByName(sAccessor) )
+ return;
+ }
+ removeByName(sAccessor);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::elementReplaced( const ::com::sun::star::container::ContainerEvent& _rEvent ) throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XPropertySet > xReplacedElement;
+ Reference< XContent > xNewElement;
+ ::rtl::OUString sAccessor;
+ _rEvent.Accessor >>= sAccessor;
+
+ {
+ MutexGuard aGuard(m_aMutex);
+ DBG_ASSERT(sAccessor.getLength(), "OQueryContainer::elementReplaced : invalid name !");
+ DBG_ASSERT(m_aDocumentMap.find(sAccessor) != m_aDocumentMap.end(), "OQueryContainer::elementReplaced : oops .... we're inconsistent with our master container !");
+ if (!sAccessor.getLength() || !hasByName(sAccessor))
+ return;
+
+ xNewElement = implCreateWrapper(sAccessor);
+ }
+
+ replaceByName(sAccessor,makeAny(xNewElement));
+}
+
+//------------------------------------------------------------------------------
+Reference< XVeto > SAL_CALL OQueryContainer::approveInsertElement( const ContainerEvent& Event ) throw (WrappedTargetException, RuntimeException)
+{
+ ::rtl::OUString sName;
+ OSL_VERIFY( Event.Accessor >>= sName );
+ Reference< XContent > xElement( Event.Element, UNO_QUERY_THROW );
+
+ Reference< XVeto > xReturn;
+ try
+ {
+ getElementApproval()->approveElement( sName, xElement.get() );
+ }
+ catch( const Exception& )
+ {
+ xReturn = new Veto( ::rtl::OUString(), ::cppu::getCaughtException() );
+ }
+ return xReturn;
+}
+
+//------------------------------------------------------------------------------
+Reference< XVeto > SAL_CALL OQueryContainer::approveReplaceElement( const ContainerEvent& /*Event*/ ) throw (WrappedTargetException, RuntimeException)
+{
+ return NULL;
+}
+
+//------------------------------------------------------------------------------
+Reference< XVeto > SAL_CALL OQueryContainer::approveRemoveElement( const ContainerEvent& /*Event*/ ) throw (WrappedTargetException, RuntimeException)
+{
+ return NULL;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OQueryContainer::disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw(::com::sun::star::uno::RuntimeException)
+{
+ if (_rSource.Source.get() == Reference< XInterface >(m_xCommandDefinitions, UNO_QUERY).get())
+ { // our "master container" (with the command definitions) is beeing disposed
+ DBG_ERROR("OQueryContainer::disposing : nobody should dispose the CommandDefinition container before disposing my connection !");
+ dispose();
+ }
+ else
+ {
+ Reference< XContent > xSource(_rSource.Source, UNO_QUERY);
+ // it's one of our documents ....
+ Documents::iterator aIter = m_aDocumentMap.begin();
+ Documents::iterator aEnd = m_aDocumentMap.end();
+ for (;aIter != aEnd;++aIter )
+ {
+ if ( xSource == aIter->second.get() )
+ {
+ m_xCommandDefinitions->removeByName(aIter->first);
+ break;
+ }
+ }
+ ODefinitionContainer::disposing(_rSource);
+ }
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString OQueryContainer::determineContentType() const
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseQueryContainer" ) );
+}
+
+// -----------------------------------------------------------------------------
+Reference< XContent > OQueryContainer::implCreateWrapper(const ::rtl::OUString& _rName)
+{
+ Reference< XContent > xObject(m_xCommandDefinitions->getByName(_rName),UNO_QUERY);
+ return implCreateWrapper(xObject);
+}
+
+//--------------------------------------------------------------------------
+Reference< XContent > OQueryContainer::implCreateWrapper(const Reference< XContent >& _rxCommandDesc)
+{
+ Reference<XNameContainer> xContainer(_rxCommandDesc,UNO_QUERY);
+ Reference< XContent > xReturn;
+ if ( xContainer .is() )
+ {
+ xReturn = new OQueryContainer( xContainer, m_xConnection, m_aContext.getLegacyServiceFactory(), m_pWarnings );
+ }
+ else
+ {
+ OQuery* pNewObject = new OQuery( Reference< XPropertySet >( _rxCommandDesc, UNO_QUERY ), m_xConnection, m_aContext.getLegacyServiceFactory() );
+ xReturn = pNewObject;
+
+ pNewObject->setWarningsContainer( m_pWarnings );
+// pNewObject->getColumns();
+ // Why? This is expensive. If you comment this in 'cause you really need it, be sure to run the
+ // QueryInQuery test in dbaccess/qa/complex/dbaccess ...
+ }
+
+ return xReturn;
+}
+//--------------------------------------------------------------------------
+Reference< XContent > OQueryContainer::createObject( const ::rtl::OUString& _rName)
+{
+ return implCreateWrapper(_rName);
+}
+// -----------------------------------------------------------------------------
+sal_Bool OQueryContainer::checkExistence(const ::rtl::OUString& _rName)
+{
+ sal_Bool bRet = sal_False;
+ if ( !m_bInPropertyChange )
+ {
+ bRet = m_xCommandDefinitions->hasByName(_rName);
+ Documents::iterator aFind = m_aDocumentMap.find(_rName);
+ if ( !bRet && aFind != m_aDocumentMap.end() )
+ {
+ m_aDocuments.erase( ::std::find(m_aDocuments.begin(),m_aDocuments.end(),aFind));
+ m_aDocumentMap.erase(aFind);
+ }
+ else if ( bRet && aFind == m_aDocumentMap.end() )
+ {
+ implAppend(_rName,NULL);
+ }
+ }
+ return bRet;
+}
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OQueryContainer::hasElements( ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ return m_xCommandDefinitions->hasElements();
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SAL_CALL OQueryContainer::getCount( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+ return Reference<XIndexAccess>(m_xCommandDefinitions,UNO_QUERY)->getCount();
+}
+// -----------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL OQueryContainer::getElementNames( ) throw(RuntimeException)
+{
+ MutexGuard aGuard(m_aMutex);
+
+ return m_xCommandDefinitions->getElementNames();
+}
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
diff --git a/dbaccess/source/core/api/querydescriptor.cxx b/dbaccess/source/core/api/querydescriptor.cxx
new file mode 100644
index 000000000000..0fb61dbd1f64
--- /dev/null
+++ b/dbaccess/source/core/api/querydescriptor.cxx
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
+#include "querydescriptor.hxx"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _DBACORE_DEFINITIONCOLUMN_HXX_
+#include "definitioncolumn.hxx"
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::comphelper;
+using namespace ::osl;
+using namespace ::cppu;
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//==========================================================================
+//= OQueryDescriptor
+//==========================================================================
+DBG_NAME(OQueryDescriptor)
+//--------------------------------------------------------------------------
+OQueryDescriptor::OQueryDescriptor()
+ :OQueryDescriptor_Base(m_aMutex,*this)
+ ,ODataSettings(m_aBHelper,sal_True)
+{
+ DBG_CTOR(OQueryDescriptor,NULL);
+ registerProperties();
+ ODataSettings::registerPropertiesFor(this);
+}
+
+//--------------------------------------------------------------------------
+OQueryDescriptor::OQueryDescriptor(const OQueryDescriptor_Base& _rSource)
+ :OQueryDescriptor_Base(_rSource,*this)
+ ,ODataSettings(m_aBHelper,sal_True)
+{
+ DBG_CTOR(OQueryDescriptor,NULL);
+ registerProperties();
+ ODataSettings::registerPropertiesFor(this);
+}
+// -----------------------------------------------------------------------------
+OQueryDescriptor::~OQueryDescriptor()
+{
+ DBG_DTOR(OQueryDescriptor,NULL);
+}
+// -----------------------------------------------------------------------------
+IMPLEMENT_TYPEPROVIDER2(OQueryDescriptor,OQueryDescriptor_Base,ODataSettings);
+IMPLEMENT_FORWARD_XINTERFACE3( OQueryDescriptor,OWeakObject,OQueryDescriptor_Base,ODataSettings)
+//--------------------------------------------------------------------------
+void OQueryDescriptor::registerProperties()
+{
+ // the properties which OCommandBase supplies (it has no own registration, as it's not derived from
+ // a OPropertyStateContainer)
+ registerProperty(PROPERTY_NAME, PROPERTY_ID_NAME, PropertyAttribute::BOUND|PropertyAttribute::CONSTRAINED,
+ &m_sElementName, ::getCppuType(&m_sElementName));
+
+ registerProperty(PROPERTY_COMMAND, PROPERTY_ID_COMMAND, PropertyAttribute::BOUND,
+ &m_sCommand, ::getCppuType(&m_sCommand));
+
+ registerProperty(PROPERTY_ESCAPE_PROCESSING, PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::BOUND,
+ &m_bEscapeProcessing, ::getBooleanCppuType());
+
+ registerProperty(PROPERTY_UPDATE_TABLENAME, PROPERTY_ID_UPDATE_TABLENAME, PropertyAttribute::BOUND,
+ &m_sUpdateTableName, ::getCppuType(&m_sUpdateTableName));
+
+ registerProperty(PROPERTY_UPDATE_SCHEMANAME, PROPERTY_ID_UPDATE_SCHEMANAME, PropertyAttribute::BOUND,
+ &m_sUpdateSchemaName, ::getCppuType(&m_sUpdateSchemaName));
+
+ registerProperty(PROPERTY_UPDATE_CATALOGNAME, PROPERTY_ID_UPDATE_CATALOGNAME, PropertyAttribute::BOUND,
+ &m_sUpdateCatalogName, ::getCppuType(&m_sUpdateCatalogName));
+
+ registerProperty(PROPERTY_LAYOUTINFORMATION, PROPERTY_ID_LAYOUTINFORMATION, PropertyAttribute::BOUND,
+ &m_aLayoutInformation, ::getCppuType(&m_aLayoutInformation));
+}
+// -----------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+Reference< XPropertySetInfo > SAL_CALL OQueryDescriptor::getPropertySetInfo( ) throw(RuntimeException)
+{
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OQueryDescriptor::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+//--------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OQueryDescriptor::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+
+// -----------------------------------------------------------------------------
+DBG_NAME(OQueryDescriptor_Base);
+//--------------------------------------------------------------------------
+OQueryDescriptor_Base::OQueryDescriptor_Base(::osl::Mutex& _rMutex,::cppu::OWeakObject& _rMySelf)
+ :m_bColumnsOutOfDate(sal_True)
+ ,m_rMutex(_rMutex)
+{
+ DBG_CTOR(OQueryDescriptor_Base,NULL);
+ m_pColumns = new OColumns(_rMySelf, m_rMutex, sal_True,::std::vector< ::rtl::OUString>(), this,this);
+}
+//--------------------------------------------------------------------------
+OQueryDescriptor_Base::OQueryDescriptor_Base(const OQueryDescriptor_Base& _rSource,::cppu::OWeakObject& _rMySelf)
+ :m_bColumnsOutOfDate(sal_True)
+ ,m_rMutex(_rSource.m_rMutex)
+{
+ DBG_CTOR(OQueryDescriptor_Base,NULL);
+ m_pColumns = new OColumns(_rMySelf, m_rMutex, sal_True,::std::vector< ::rtl::OUString>(), this,this);
+
+ m_sCommand = _rSource.m_sCommand;
+ m_bEscapeProcessing = _rSource.m_bEscapeProcessing;
+ m_sUpdateTableName = _rSource.m_sUpdateTableName;
+ m_sUpdateSchemaName = _rSource.m_sUpdateSchemaName;
+ m_sUpdateCatalogName = _rSource.m_sUpdateCatalogName;
+ m_aLayoutInformation = _rSource.m_aLayoutInformation;
+}
+
+//--------------------------------------------------------------------------
+OQueryDescriptor_Base::~OQueryDescriptor_Base()
+{
+ m_pColumns->acquire();
+ m_pColumns->disposing();
+ delete m_pColumns;
+
+ DBG_DTOR(OQueryDescriptor_Base,NULL);
+}
+// -----------------------------------------------------------------------------
+sal_Int64 SAL_CALL OQueryDescriptor_Base::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException)
+{
+ if (_rIdentifier.getLength() != 16)
+ return 0;
+
+ if (0 == rtl_compareMemory(getImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 ) )
+ return reinterpret_cast<sal_Int64>(this);
+
+ return 0;
+}
+//--------------------------------------------------------------------------
+IMPLEMENT_IMPLEMENTATION_ID(OQueryDescriptor_Base)
+//--------------------------------------------------------------------------
+void OQueryDescriptor_Base::setColumnsOutOfDate( sal_Bool _bOutOfDate )
+{
+ m_bColumnsOutOfDate = _bOutOfDate;
+ if ( !m_bColumnsOutOfDate )
+ m_pColumns->setInitialized();
+}
+
+//--------------------------------------------------------------------------
+void OQueryDescriptor_Base::implAppendColumn( const ::rtl::OUString& _rName, OColumn* _pColumn )
+{
+ m_pColumns->append( _rName, _pColumn );
+}
+
+//--------------------------------------------------------------------------
+void OQueryDescriptor_Base::clearColumns( )
+{
+ m_pColumns->clearColumns();
+
+ setColumnsOutOfDate();
+}
+
+//--------------------------------------------------------------------------
+Reference< XNameAccess > SAL_CALL OQueryDescriptor_Base::getColumns( ) throw (RuntimeException)
+{
+ MutexGuard aGuard(m_rMutex);
+
+ if ( isColumnsOutOfDate() )
+ {
+ // clear the current columns
+ clearColumns();
+
+ // do this before rebuildColumns. This prevents recursion, e.g. in the case where we
+ // have queries with cyclic references:
+ // foo := SELECT * FROM bar
+ // bar := SELECT * FROM foo
+ setColumnsOutOfDate( sal_False );
+
+ // rebuild them
+ try
+ {
+ rebuildColumns();
+ }
+ catch ( const Exception& )
+ {
+ setColumnsOutOfDate( sal_True );
+ throw;
+ }
+ }
+
+ return m_pColumns;
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OQueryDescriptor_Base::getImplementationName( ) throw(RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.sdb.OQueryDescriptor");
+}
+
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OQueryDescriptor_Base::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
+{
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//--------------------------------------------------------------------------
+Sequence< ::rtl::OUString > SAL_CALL OQueryDescriptor_Base::getSupportedServiceNames( ) throw(RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSupported(2);
+ aSupported.getArray()[0] = SERVICE_SDB_DATASETTINGS;
+ aSupported.getArray()[1] = SERVICE_SDB_QUERYDESCRIPTOR;
+ return aSupported;
+}
+//--------------------------------------------------------------------------
+void OQueryDescriptor_Base::disposeColumns()
+{
+ m_pColumns->disposing();
+}
+
+// -----------------------------------------------------------------------------
+void OQueryDescriptor_Base::columnAppended( const Reference< XPropertySet >& /*_rxSourceDescriptor*/ )
+{
+ // not interested in
+}
+
+// -----------------------------------------------------------------------------
+void OQueryDescriptor_Base::columnDropped(const ::rtl::OUString& /*_sName*/)
+{
+ // not interested in
+}
+
+// -----------------------------------------------------------------------------
+Reference< XPropertySet > OQueryDescriptor_Base::createColumnDescriptor()
+{
+ OSL_ENSURE( false, "OQueryDescriptor_Base::createColumnDescriptor: called why?" );
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------
+void OQueryDescriptor_Base::rebuildColumns( )
+{
+}
+
+// -----------------------------------------------------------------------------
+// IRefreshableColumns
+void OQueryDescriptor_Base::refreshColumns()
+{
+ MutexGuard aGuard( m_rMutex );
+
+ clearColumns();
+ rebuildColumns();
+}
+
+//------------------------------------------------------------------------------
+OColumn* OQueryDescriptor_Base::createColumn( const ::rtl::OUString& /*_rName*/ ) const
+{
+ // creating a column/descriptor for a query/descriptor does not make sense at all
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+
diff --git a/dbaccess/source/core/api/querydescriptor.hxx b/dbaccess/source/core/api/querydescriptor.hxx
new file mode 100644
index 000000000000..2f27b4b9c628
--- /dev/null
+++ b/dbaccess/source/core/api/querydescriptor.hxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
+#define _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
+
+#ifndef _CPPUHELPER_IMPLBASE3_HXX_
+#include <cppuhelper/implbase3.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
+#include <comphelper/proparrhlp.hxx>
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include <osl/mutex.hxx>
+#endif
+
+#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#endif
+
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef _DBA_COREAPI_COLUMN_HXX_
+#include "column.hxx"
+#endif
+#ifndef _DBA_CORE_DATASETTINGS_HXX_
+#include "datasettings.hxx"
+#endif
+#ifndef _DBA_CORE_COMMANDBASE_HXX_
+#include "commandbase.hxx"
+#endif
+#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
+#include <comphelper/broadcasthelper.hxx>
+#endif
+#ifndef _COMPHELPER_UNO3_HXX_
+#include <comphelper/uno3.hxx>
+#endif
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+//==========================================================================
+//= OQueryDescriptor_Base - a query descriptor (as the name suggests :)
+//==========================================================================
+typedef ::cppu::ImplHelper3<
+ ::com::sun::star::sdbcx::XColumnsSupplier,
+ ::com::sun::star::lang::XUnoTunnel,
+ ::com::sun::star::lang::XServiceInfo > OQueryDescriptor_BASE;
+
+class OQueryDescriptor_Base
+ :public OQueryDescriptor_BASE
+ ,public OCommandBase
+ ,public IColumnFactory
+ ,public ::connectivity::sdbcx::IRefreshableColumns
+{
+private:
+ sal_Bool m_bColumnsOutOfDate : 1; // the columns have to be rebuild on the next getColumns ?
+ ::osl::Mutex& m_rMutex;
+
+protected:
+ OColumns* m_pColumns; // our column descriptions
+ ::rtl::OUString m_sElementName;
+ virtual ~OQueryDescriptor_Base();
+
+ void setColumnsOutOfDate( sal_Bool _bOutOfDate = sal_True );
+ sal_Bool isColumnsOutOfDate() const { return m_bColumnsOutOfDate; }
+
+ sal_Int32 getColumnCount() const { return m_pColumns ? m_pColumns->getCount() : 0; }
+ void clearColumns( );
+
+ void implAppendColumn( const ::rtl::OUString& _rName, OColumn* _pColumn );
+
+public:
+ OQueryDescriptor_Base(::osl::Mutex& _rMutex,::cppu::OWeakObject& _rMySelf);
+ /** constructs the object with a UNO QueryDescriptor. If you use this ctor, the resulting object
+ won't have any column informations (the column container will be empty)
+ */
+ OQueryDescriptor_Base(const OQueryDescriptor_Base& _rSource,::cppu::OWeakObject& _rMySelf);
+
+// ::com::sun::star::sdbcx::XColumnsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns( ) throw(::com::sun::star::uno::RuntimeException);
+
+// ::com::sun::star::lang::XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+ DECLARE_IMPLEMENTATION_ID( );
+
+// ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+protected:
+
+// IColumnFactory
+ virtual OColumn* createColumn(const ::rtl::OUString& _rName) const;
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createColumnDescriptor();
+ virtual void columnAppended( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxSourceDescriptor );
+ virtual void columnDropped(const ::rtl::OUString& _sName);
+
+ /** rebuild our columns set
+
+ clearColumns has already been called before, do <em>NOT</em> call it, again
+ */
+ virtual void rebuildColumns( );
+
+ virtual void disposeColumns();
+
+ // IRefreshableColumns overridables
+ virtual void refreshColumns();
+};
+
+class OQueryDescriptor : public comphelper::OMutexAndBroadcastHelper
+ ,public ::cppu::OWeakObject
+ ,public OQueryDescriptor_Base
+ ,public ::comphelper::OPropertyArrayUsageHelper< OQueryDescriptor_Base >
+ ,public ODataSettings
+{
+ OQueryDescriptor(const OQueryDescriptor&);
+ void operator =(const OQueryDescriptor&);
+ // helper
+ void registerProperties();
+protected:
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ virtual ~OQueryDescriptor();
+public:
+ OQueryDescriptor();
+ OQueryDescriptor(const OQueryDescriptor_Base& _rSource);
+
+ // com::sun::star::lang::XTypeProvider
+ DECLARE_TYPEPROVIDER( );
+
+// ::com::sun::star::uno::XInterface
+ DECLARE_XINTERFACE( )
+
+ // ::com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+};
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
+
+
diff --git a/dbaccess/source/core/api/resultcolumn.cxx b/dbaccess/source/core/api/resultcolumn.cxx
new file mode 100644
index 000000000000..02195693bba1
--- /dev/null
+++ b/dbaccess/source/core/api/resultcolumn.cxx
@@ -0,0 +1,357 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef _DBACORE_RESULTCOLUMN_HXX_
+#include "resultcolumn.hxx"
+#endif
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
+#include <com/sun/star/sdbc/DataType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef TOOLS_DIAGNOSE_EX_H
+#include <tools/diagnose_ex.h>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _CPPUHELPER_EXC_HLP_HXX_
+#include <cppuhelper/exc_hlp.hxx>
+#endif
+#ifndef _OSL_THREAD_H_
+#include <osl/thread.h>
+#endif
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+using namespace dbaccess;
+
+DBG_NAME(OResultColumn)
+//--------------------------------------------------------------------------
+OResultColumn::OResultColumn( const Reference < XResultSetMetaData >& _xMetaData, sal_Int32 _nPos,
+ const Reference< XDatabaseMetaData >& _rxDBMeta )
+ :OColumn( true )
+ ,m_xMetaData( _xMetaData )
+ ,m_xDBMetaData( _rxDBMeta )
+ ,m_nPos( _nPos )
+{
+ DBG_CTOR(OResultColumn,NULL);
+}
+// -----------------------------------------------------------------------------
+void OResultColumn::impl_determineIsRowVersion_nothrow()
+{
+ if ( m_aIsRowVersion.hasValue() )
+ return;
+ m_aIsRowVersion <<= (sal_Bool)(sal_False);
+
+ OSL_ENSURE( m_xDBMetaData.is(), "OResultColumn::impl_determineIsRowVersion_nothrow: no DBMetaData!" );
+ if ( !m_xDBMetaData.is() )
+ return;
+
+ try
+ {
+ ::rtl::OUString sCatalog, sSchema, sTable, sColumnName;
+ getPropertyValue( PROPERTY_CATALOGNAME ) >>= sCatalog;
+ getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema;
+ getPropertyValue( PROPERTY_TABLENAME ) >>= sTable;
+ getPropertyValue( PROPERTY_NAME ) >>= sColumnName;
+
+ try
+ {
+ Reference< XResultSet > xVersionColumns = m_xDBMetaData->getVersionColumns(
+ makeAny( sCatalog ), sSchema, sTable );
+ if ( xVersionColumns.is() ) // allowed to be NULL
+ {
+ Reference< XRow > xResultRow( xVersionColumns, UNO_QUERY_THROW );
+ while ( xVersionColumns->next() )
+ {
+ if ( xResultRow->getString( 2 ) == sColumnName )
+ {
+ m_aIsRowVersion <<= (sal_Bool)(sal_True);
+ break;
+ }
+ }
+ }
+ }
+ catch(const SQLException&)
+ {
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+// -----------------------------------------------------------------------------
+OResultColumn::~OResultColumn()
+{
+ DBG_DTOR(OResultColumn,NULL);
+}
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > OResultColumn::getImplementationId() throw (RuntimeException)
+{
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OResultColumn::getImplementationName( ) throw(RuntimeException)
+{
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OResultColumn");
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OResultColumn::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = SERVICE_SDBCX_COLUMN;
+ aSNS[1] = SERVICE_SDB_RESULTCOLUMN;
+ return aSNS;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OResultColumn::disposing()
+{
+ OColumn::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+ m_xMetaData = NULL;
+}
+
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OResultColumn::createArrayHelper( ) const
+{
+ BEGIN_PROPERTY_HELPER(21)
+ DECL_PROP1(CATALOGNAME, ::rtl::OUString, READONLY);
+ DECL_PROP1(DISPLAYSIZE, sal_Int32, READONLY);
+ DECL_PROP1_BOOL(ISAUTOINCREMENT, READONLY);
+ DECL_PROP1_BOOL(ISCASESENSITIVE, READONLY);
+ DECL_PROP1_BOOL(ISCURRENCY, READONLY);
+ DECL_PROP1_BOOL(ISDEFINITELYWRITABLE, READONLY);
+ DECL_PROP1(ISNULLABLE, sal_Int32, READONLY);
+ DECL_PROP1_BOOL(ISREADONLY, READONLY);
+ DECL_PROP1_BOOL(ISROWVERSION, READONLY);
+ DECL_PROP1_BOOL(ISSEARCHABLE, READONLY);
+ DECL_PROP1_BOOL(ISSIGNED, READONLY);
+ DECL_PROP1_BOOL(ISWRITABLE, READONLY);
+ DECL_PROP1(LABEL, ::rtl::OUString, READONLY);
+ DECL_PROP1(NAME, ::rtl::OUString, READONLY);
+ DECL_PROP1(PRECISION, sal_Int32, READONLY);
+ DECL_PROP1(SCALE, sal_Int32, READONLY);
+ DECL_PROP1(SCHEMANAME, ::rtl::OUString, READONLY);
+ DECL_PROP1(SERVICENAME, ::rtl::OUString, READONLY);
+ DECL_PROP1(TABLENAME, ::rtl::OUString, READONLY);
+ DECL_PROP1(TYPE, sal_Int32, READONLY);
+ DECL_PROP1(TYPENAME, ::rtl::OUString, READONLY);
+ END_PROPERTY_HELPER();
+}
+
+// cppu::OPropertySetHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OResultColumn::getInfoHelper()
+{
+ return *static_cast< ::comphelper::OPropertyArrayUsageHelper< OResultColumn >* >(this)->getArrayHelper();
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ template< typename TYPE >
+ void obtain( Any& _out_rValue, ::boost::optional< TYPE > _rCache, const sal_Int32 _nPos, const Reference < XResultSetMetaData >& _rxResultMeta, TYPE (SAL_CALL XResultSetMetaData::*Getter)( sal_Int32 ) )
+ {
+ if ( !_rCache )
+ _rCache.reset( (_rxResultMeta.get()->*Getter)( _nPos ) );
+ _out_rValue <<= *_rCache;
+ }
+}
+
+//------------------------------------------------------------------------------
+void OResultColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ try
+ {
+ if ( OColumn::isRegisteredProperty( nHandle ) )
+ {
+ OColumn::getFastPropertyValue( rValue, nHandle );
+ }
+ else
+ {
+ switch (nHandle)
+ {
+ case PROPERTY_ID_ISROWVERSION:
+ const_cast< OResultColumn* >( this )->impl_determineIsRowVersion_nothrow();
+ rValue = m_aIsRowVersion;
+ break;
+ case PROPERTY_ID_TABLENAME:
+ rValue <<= m_xMetaData->getTableName(m_nPos);
+ break;
+ case PROPERTY_ID_SCHEMANAME:
+ rValue <<= m_xMetaData->getSchemaName(m_nPos);
+ break;
+ case PROPERTY_ID_CATALOGNAME:
+ rValue <<= m_xMetaData->getCatalogName(m_nPos);
+ break;
+ case PROPERTY_ID_ISSIGNED:
+ obtain( rValue, m_isSigned, m_nPos, m_xMetaData, &XResultSetMetaData::isSigned );
+ break;
+ case PROPERTY_ID_ISCURRENCY:
+ obtain( rValue, m_isCurrency, m_nPos, m_xMetaData, &XResultSetMetaData::isCurrency );
+ break;
+ case PROPERTY_ID_ISSEARCHABLE:
+ obtain( rValue, m_bSearchable, m_nPos, m_xMetaData, &XResultSetMetaData::isSearchable );
+ break;
+ case PROPERTY_ID_ISCASESENSITIVE:
+ obtain( rValue, m_isCaseSensitive, m_nPos, m_xMetaData, &XResultSetMetaData::isCaseSensitive );
+ break;
+ case PROPERTY_ID_ISREADONLY:
+ obtain( rValue, m_isReadOnly, m_nPos, m_xMetaData, &XResultSetMetaData::isReadOnly );
+ break;
+ case PROPERTY_ID_ISWRITABLE:
+ obtain( rValue, m_isWritable, m_nPos, m_xMetaData, &XResultSetMetaData::isWritable );
+ break;
+ case PROPERTY_ID_ISDEFINITELYWRITABLE:
+ obtain( rValue, m_isDefinitelyWritable, m_nPos, m_xMetaData, &XResultSetMetaData::isDefinitelyWritable );
+ break;
+ case PROPERTY_ID_ISAUTOINCREMENT:
+ obtain( rValue, m_isAutoIncrement, m_nPos, m_xMetaData, &XResultSetMetaData::isAutoIncrement );
+ break;
+ case PROPERTY_ID_SERVICENAME:
+ rValue <<= m_xMetaData->getColumnServiceName(m_nPos);
+ break;
+ case PROPERTY_ID_LABEL:
+ obtain( rValue, m_sColumnLabel, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnLabel );
+ break;
+ case PROPERTY_ID_DISPLAYSIZE:
+ obtain( rValue, m_nColumnDisplaySize, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnDisplaySize );
+ break;
+ case PROPERTY_ID_TYPE:
+ obtain( rValue, m_nColumnType, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnType );
+ break;
+ case PROPERTY_ID_PRECISION:
+ obtain( rValue, m_nPrecision, m_nPos, m_xMetaData, &XResultSetMetaData::getPrecision );
+ break;
+ case PROPERTY_ID_SCALE:
+ obtain( rValue, m_nScale, m_nPos, m_xMetaData, &XResultSetMetaData::getScale );
+ break;
+ case PROPERTY_ID_ISNULLABLE:
+ obtain( rValue, m_isNullable, m_nPos, m_xMetaData, &XResultSetMetaData::isNullable );
+ break;
+ case PROPERTY_ID_TYPENAME:
+ rValue <<= m_xMetaData->getColumnTypeName(m_nPos);
+ break;
+ default:
+ OSL_ENSURE( false, "OResultColumn::getFastPropertyValue: unknown property handle!" );
+ break;
+ }
+ }
+ }
+ catch (SQLException& )
+ {
+ // default handling if we caught an exception
+ switch (nHandle)
+ {
+ case PROPERTY_ID_LABEL:
+ case PROPERTY_ID_TYPENAME:
+ case PROPERTY_ID_SERVICENAME:
+ case PROPERTY_ID_TABLENAME:
+ case PROPERTY_ID_SCHEMANAME:
+ case PROPERTY_ID_CATALOGNAME:
+ // empty string'S
+ rValue <<= rtl::OUString();
+ break;
+ case PROPERTY_ID_ISROWVERSION:
+ case PROPERTY_ID_ISAUTOINCREMENT:
+ case PROPERTY_ID_ISWRITABLE:
+ case PROPERTY_ID_ISDEFINITELYWRITABLE:
+ case PROPERTY_ID_ISCASESENSITIVE:
+ case PROPERTY_ID_ISSEARCHABLE:
+ case PROPERTY_ID_ISCURRENCY:
+ case PROPERTY_ID_ISSIGNED:
+ {
+ sal_Bool bVal = sal_False;
+ rValue.setValue(&bVal, getBooleanCppuType());
+ } break;
+ case PROPERTY_ID_ISREADONLY:
+ {
+ sal_Bool bVal = sal_True;
+ rValue.setValue(&bVal, getBooleanCppuType());
+ } break;
+ case PROPERTY_ID_SCALE:
+ case PROPERTY_ID_PRECISION:
+ case PROPERTY_ID_DISPLAYSIZE:
+ rValue <<= sal_Int32(0);
+ break;
+ case PROPERTY_ID_TYPE:
+ rValue <<= sal_Int32(DataType::SQLNULL);
+ break;
+ case PROPERTY_ID_ISNULLABLE:
+ rValue <<= ColumnValue::NULLABLE_UNKNOWN;
+ break;
+ }
+ }
+}
+
diff --git a/dbaccess/source/core/api/resultcolumn.hxx b/dbaccess/source/core/api/resultcolumn.hxx
new file mode 100644
index 000000000000..7e1842241cf6
--- /dev/null
+++ b/dbaccess/source/core/api/resultcolumn.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 _DBACORE_RESULTCOLUMN_HXX_
+#define _DBACORE_RESULTCOLUMN_HXX_
+
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HDL_
+#include <com/sun/star/sdbc/XResultSetMetaData.hdl>
+#endif
+#ifndef _DBA_COREAPI_COLUMN_HXX_
+#include <column.hxx>
+#endif
+#include <boost/optional.hpp>
+namespace dbaccess
+{
+ //************************************************************
+ // OResultColumn
+ //************************************************************
+ class OResultColumn : public OColumn,
+ public ::comphelper::OPropertyArrayUsageHelper < OResultColumn >
+ {
+ protected:
+ ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData > m_xMetaData;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xDBMetaData;
+ sal_Int32 m_nPos;
+ ::com::sun::star::uno::Any m_aIsRowVersion;
+ mutable ::boost::optional< sal_Bool > m_isSigned;
+ mutable ::boost::optional< sal_Bool > m_isCurrency;
+ mutable ::boost::optional< sal_Bool > m_bSearchable;
+ mutable ::boost::optional< sal_Bool > m_isCaseSensitive;
+ mutable ::boost::optional< sal_Bool > m_isReadOnly;
+ mutable ::boost::optional< sal_Bool > m_isWritable;
+ mutable ::boost::optional< sal_Bool > m_isDefinitelyWritable;
+ mutable ::boost::optional< sal_Bool > m_isAutoIncrement;
+ mutable ::boost::optional< sal_Int32 > m_isNullable;
+ mutable ::boost::optional< ::rtl::OUString > m_sColumnLabel;
+ mutable ::boost::optional< sal_Int32 > m_nColumnDisplaySize;
+ mutable ::boost::optional< sal_Int32 > m_nColumnType;
+ mutable ::boost::optional< sal_Int32 > m_nPrecision;
+ mutable ::boost::optional< sal_Int32 > m_nScale;
+
+ virtual ~OResultColumn();
+ public:
+ OResultColumn(
+ const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData >& _xMetaData,
+ sal_Int32 _nPos,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMeta );
+
+ // com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // cppu::OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+ virtual void SAL_CALL getFastPropertyValue(
+ ::com::sun::star::uno::Any& rValue,
+ sal_Int32 nHandle
+ ) const;
+
+ private:
+ void impl_determineIsRowVersion_nothrow();
+
+ protected:
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+ };
+}
+#endif // _DBACORE_RESULTCOLUMN_HXX_
+
diff --git a/dbaccess/source/core/api/resultset.cxx b/dbaccess/source/core/api/resultset.cxx
new file mode 100644
index 000000000000..0f1be7553ad6
--- /dev/null
+++ b/dbaccess/source/core/api/resultset.cxx
@@ -0,0 +1,1208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef _DBA_COREAPI_RESULTSET_HXX_
+#include <resultset.hxx>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _DBASHARED_APITOOLS_HXX_
+#include "apitools.hxx"
+#endif
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_RESULTSETTYPE_HPP_
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+#ifndef TOOLS_DIAGNOSE_EX_H
+#include <tools/diagnose_ex.h>
+#endif
+#ifndef _DBA_COREAPI_DATACOLUMN_HXX_
+#include <datacolumn.hxx>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#endif
+#ifndef _DBHELPER_DBEXCEPTION_HXX_
+#include <connectivity/dbexception.hxx>
+#endif
+#ifndef _CONNECTIVITY_DBTOOLS_HXX_
+#include <connectivity/dbtools.hxx>
+#endif
+#ifndef _CPPUHELPER_EXC_HLP_HXX_
+#include <cppuhelper/exc_hlp.hxx>
+#endif
+#ifndef _OSL_THREAD_H_
+#include <osl/thread.h>
+#endif
+#include <rtl/logfile.hxx>
+
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+//using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace dbaccess;
+using namespace dbtools;
+
+DBG_NAME(OResultSet)
+
+//--------------------------------------------------------------------------
+OResultSet::OResultSet(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& _xResultSet,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xStatement,
+ sal_Bool _bCaseSensitive)
+ :OResultSetBase(m_aMutex)
+ ,OPropertySetHelper(OResultSetBase::rBHelper)
+ ,m_xDelegatorResultSet(_xResultSet)
+ ,m_aWarnings( Reference< XWarningsSupplier >( _xResultSet, UNO_QUERY ) )
+ ,m_bIsBookmarkable(sal_False)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::OResultSet" );
+ DBG_CTOR(OResultSet, NULL);
+
+ m_pColumns = new OColumns(*this, m_aMutex, _bCaseSensitive, ::std::vector< ::rtl::OUString>(), NULL,NULL);
+
+ try
+ {
+ m_aStatement = _xStatement;
+ m_xDelegatorResultSetUpdate = m_xDelegatorResultSetUpdate.query( m_xDelegatorResultSet );
+ m_xDelegatorRow = m_xDelegatorRow.query( m_xDelegatorResultSet );
+ m_xDelegatorRowUpdate = m_xDelegatorRowUpdate.query( m_xDelegatorResultSet );
+
+ Reference< XPropertySet > xSet(m_xDelegatorResultSet, UNO_QUERY);
+ xSet->getPropertyValue(PROPERTY_RESULTSETTYPE) >>= m_nResultSetType;
+ xSet->getPropertyValue(PROPERTY_RESULTSETCONCURRENCY) >>= m_nResultSetConcurrency;
+
+ // test for Bookmarks
+ if (ResultSetType::FORWARD_ONLY != m_nResultSetType)
+ {
+ Reference <XPropertySetInfo > xInfo(xSet->getPropertySetInfo());
+ if (xInfo->hasPropertyByName(PROPERTY_ISBOOKMARKABLE))
+ {
+ m_bIsBookmarkable = ::comphelper::getBOOL(xSet->getPropertyValue(PROPERTY_ISBOOKMARKABLE));
+ OSL_ENSURE( !m_bIsBookmarkable || Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY).is(),
+ "OResultSet::OResultSet: aggregate is inconsistent in it's bookmarkable attribute!" );
+ m_bIsBookmarkable = m_bIsBookmarkable && Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY).is();
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ }
+}
+
+//--------------------------------------------------------------------------
+OResultSet::~OResultSet()
+{
+ m_pColumns->acquire();
+ m_pColumns->disposing();
+ delete m_pColumns;
+
+ DBG_DTOR(OResultSet, NULL);
+}
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > OResultSet::getTypes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getTypes" );
+ OTypeCollection aTypes(::getCppuType( (const Reference< XPropertySet > *)0 ),
+ OResultSetBase::getTypes());
+
+ return aTypes.getTypes();
+}
+
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > OResultSet::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getImplementationId" );
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// com::sun::star::uno::XInterface
+//--------------------------------------------------------------------------
+Any OResultSet::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::queryInterface" );
+ Any aIface = OResultSetBase::queryInterface( rType );
+ if (!aIface.hasValue())
+ aIface = ::cppu::queryInterface(
+ rType,
+ static_cast< XPropertySet * >( this ));
+
+ return aIface;
+}
+
+//--------------------------------------------------------------------------
+void OResultSet::acquire() throw ()
+{
+ OResultSetBase::acquire();
+}
+
+//--------------------------------------------------------------------------
+void OResultSet::release() throw ()
+{
+ OResultSetBase::release();
+}
+
+
+// OResultSetBase
+//------------------------------------------------------------------------------
+void OResultSet::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::disposing" );
+ OPropertySetHelper::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+
+ // free the columns
+ m_pColumns->disposing();
+
+ // close the pending result set
+ Reference< XCloseable > (m_xDelegatorResultSet, UNO_QUERY)->close();
+
+ m_xDelegatorResultSet = NULL;
+ m_xDelegatorRow = NULL;
+ m_xDelegatorRowUpdate = NULL;
+
+ m_aStatement = Reference< XInterface >();
+}
+
+// XCloseable
+//------------------------------------------------------------------------------
+void OResultSet::close(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::close" );
+ {
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+ }
+ dispose();
+}
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OResultSet::getImplementationName( ) throw(RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getImplementationName" );
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OResultSet");
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::supportsService" );
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OResultSet::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getSupportedServiceNames" );
+ Sequence< ::rtl::OUString > aSNS( 2 );
+ aSNS[0] = SERVICE_SDBC_RESULTSET;
+ aSNS[1] = SERVICE_SDB_RESULTSET;
+ return aSNS;
+}
+
+// com::sun::star::beans::XPropertySet
+//------------------------------------------------------------------------------
+Reference< XPropertySetInfo > OResultSet::getPropertySetInfo() throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getPropertySetInfo" );
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::createArrayHelper" );
+ BEGIN_PROPERTY_HELPER(6)
+ DECL_PROP1(CURSORNAME, ::rtl::OUString, READONLY);
+ DECL_PROP0(FETCHDIRECTION, sal_Int32);
+ DECL_PROP0(FETCHSIZE, sal_Int32);
+ DECL_PROP1_BOOL(ISBOOKMARKABLE, READONLY);
+ DECL_PROP1(RESULTSETCONCURRENCY, sal_Int32, READONLY);
+ DECL_PROP1(RESULTSETTYPE, sal_Int32, READONLY);
+ END_PROPERTY_HELPER();
+}
+
+// cppu::OPropertySetHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OResultSet::getInfoHelper()
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getInfoHelper" );
+ return *getArrayHelper();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::convertFastPropertyValue(Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::convertFastPropertyValue" );
+ // be lazy ...
+ rConvertedValue = rValue;
+ getFastPropertyValue( rOldValue, nHandle );
+ return sal_True;
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::setFastPropertyValue_NoBroadcast" );
+ // set it for the driver result set
+ Reference< XPropertySet > xSet(m_xDelegatorResultSet, UNO_QUERY);
+ switch (nHandle)
+ {
+ case PROPERTY_ID_FETCHDIRECTION:
+ xSet->setPropertyValue(PROPERTY_FETCHDIRECTION, rValue);
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ xSet->setPropertyValue(PROPERTY_FETCHSIZE, rValue);
+ break;
+ default:
+ DBG_ERROR("unknown Property");
+ }
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getFastPropertyValue" );
+ switch (nHandle)
+ {
+ case PROPERTY_ID_ISBOOKMARKABLE:
+ {
+ sal_Bool bVal = m_bIsBookmarkable;
+ rValue.setValue(&bVal, getBooleanCppuType());
+ } break;
+ default:
+ {
+ // get the property name
+ ::rtl::OUString aPropName;
+ sal_Int16 nAttributes;
+ const_cast<OResultSet*>(this)->getInfoHelper().
+ fillPropertyMembersByHandle(&aPropName, &nAttributes, nHandle);
+ OSL_ENSURE(aPropName.getLength(), "property not found?");
+
+ // now read the value
+ rValue = Reference< XPropertySet >(m_xDelegatorResultSet, UNO_QUERY)->getPropertyValue(aPropName);
+ }
+ }
+}
+
+// XWarningsSupplier
+//------------------------------------------------------------------------------
+Any OResultSet::getWarnings(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getWarnings" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+ return m_aWarnings.getWarnings();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::clearWarnings(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::clearWarnings" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+ m_aWarnings.clearWarnings();
+}
+
+// ::com::sun::star::sdbc::XResultSetMetaDataSupplier
+//------------------------------------------------------------------------------
+Reference< XResultSetMetaData > OResultSet::getMetaData(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getMetaData" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return Reference< XResultSetMetaDataSupplier >(m_xDelegatorResultSet, UNO_QUERY)->getMetaData();
+}
+
+// ::com::sun::star::sdbc::XColumnLocate
+//------------------------------------------------------------------------------
+sal_Int32 OResultSet::findColumn(const rtl::OUString& columnName) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::findColumn" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return Reference< XColumnLocate >(m_xDelegatorResultSet, UNO_QUERY)->findColumn(columnName);
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ static Reference< XDatabaseMetaData > lcl_getDBMetaDataFromStatement_nothrow( const Reference< XInterface >& _rxStatement )
+ {
+ Reference< XDatabaseMetaData > xDBMetaData;
+ try
+ {
+ Reference< XStatement > xStatement( _rxStatement, UNO_QUERY );
+ Reference< XPreparedStatement > xPreparedStatement( _rxStatement, UNO_QUERY );
+ Reference< XConnection > xConn;
+ if ( xStatement.is() )
+ xConn = xStatement->getConnection();
+ else if ( xPreparedStatement.is() )
+ xConn = xPreparedStatement->getConnection();
+ if ( xConn.is() )
+ xDBMetaData = xConn->getMetaData();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return xDBMetaData;
+ }
+}
+// ::com::sun::star::sdbcx::XColumnsSupplier
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::container::XNameAccess > OResultSet::getColumns(void) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getColumns" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ // do we have to populate the columns
+ if (!m_pColumns->isInitialized())
+ {
+ // get the metadata
+ Reference< XResultSetMetaData > xMetaData = Reference< XResultSetMetaDataSupplier >(m_xDelegatorResultSet, UNO_QUERY)->getMetaData();
+
+ sal_Int32 nColCount = 0;
+ // do we have columns
+ try
+ {
+ Reference< XDatabaseMetaData > xDBMetaData( lcl_getDBMetaDataFromStatement_nothrow( getStatement() ) );
+ nColCount = xMetaData->getColumnCount();
+
+ for ( sal_Int32 i = 0; i < nColCount; ++i)
+ {
+ // retrieve the name of the column
+ rtl::OUString sName = xMetaData->getColumnName(i + 1);
+ ODataColumn* pColumn = new ODataColumn(xMetaData, m_xDelegatorRow, m_xDelegatorRowUpdate, i + 1, xDBMetaData);
+
+ // don't silently assume that the name is unique - result set implementations
+ // are allowed to return duplicate names, but we are required to have
+ // unique column names
+ if ( m_pColumns->hasByName( sName ) )
+ sName = ::dbtools::createUniqueName( m_pColumns, sName );
+
+ m_pColumns->append( sName, pColumn );
+ }
+ }
+ catch ( const SQLException& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ m_pColumns->setInitialized();
+
+ #if OSL_DEBUG_LEVEL > 0
+ // some sanity checks. Especially in case we auto-adjusted the column names above,
+ // this might be reasonable
+ try
+ {
+ const Reference< XNameAccess > xColNames( static_cast< XNameAccess* >( m_pColumns ), UNO_SET_THROW );
+ const Sequence< ::rtl::OUString > aNames( xColNames->getElementNames() );
+ OSL_POSTCOND( aNames.getLength() == nColCount,
+ "OResultSet::getColumns: invalid column count!" );
+ for ( const ::rtl::OUString* pName = aNames.getConstArray();
+ pName != aNames.getConstArray() + aNames.getLength();
+ ++pName
+ )
+ {
+ Reference< XPropertySet > xColProps( xColNames->getByName( *pName ), UNO_QUERY_THROW );
+ ::rtl::OUString sName;
+ OSL_VERIFY( xColProps->getPropertyValue( PROPERTY_NAME ) >>= sName );
+ OSL_POSTCOND( sName == *pName, "OResultSet::getColumns: invalid column name!" );
+ }
+
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ #endif
+ }
+ return m_pColumns;
+}
+
+// ::com::sun::star::sdbc::XRow
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::wasNull(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::wasNull" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->wasNull();
+}
+//------------------------------------------------------------------------------
+rtl::OUString OResultSet::getString(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getString" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getString(columnIndex);
+}
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::getBoolean(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getBoolean" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getBoolean(columnIndex);
+}
+//------------------------------------------------------------------------------
+sal_Int8 OResultSet::getByte(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getByte" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getByte(columnIndex);
+}
+//------------------------------------------------------------------------------
+sal_Int16 OResultSet::getShort(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getShort" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getShort(columnIndex);
+}
+//------------------------------------------------------------------------------
+sal_Int32 OResultSet::getInt(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getInt" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getInt(columnIndex);
+}
+//------------------------------------------------------------------------------
+sal_Int64 OResultSet::getLong(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getLong" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getLong(columnIndex);
+}
+//------------------------------------------------------------------------------
+float OResultSet::getFloat(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getFloat" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getFloat(columnIndex);
+}
+//------------------------------------------------------------------------------
+double OResultSet::getDouble(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getDouble" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getDouble(columnIndex);
+}
+//------------------------------------------------------------------------------
+Sequence< sal_Int8 > OResultSet::getBytes(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getBytes" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getBytes(columnIndex);
+}
+//------------------------------------------------------------------------------
+::com::sun::star::util::Date OResultSet::getDate(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getDate" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getDate(columnIndex);
+}
+//------------------------------------------------------------------------------
+::com::sun::star::util::Time OResultSet::getTime(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getTime" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getTime(columnIndex);
+}
+//------------------------------------------------------------------------------
+::com::sun::star::util::DateTime OResultSet::getTimestamp(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getTimestamp" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getTimestamp(columnIndex);
+}
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > OResultSet::getBinaryStream(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getBinaryStream" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getBinaryStream(columnIndex);
+}
+//------------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > OResultSet::getCharacterStream(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getCharacterStream" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getCharacterStream(columnIndex);
+}
+//------------------------------------------------------------------------------
+Any OResultSet::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", "OResultSet::getObject" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getObject(columnIndex, typeMap);
+}
+//------------------------------------------------------------------------------
+Reference< XRef > OResultSet::getRef(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getRef" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getRef(columnIndex);
+}
+//------------------------------------------------------------------------------
+Reference< XBlob > OResultSet::getBlob(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getBlob" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getBlob(columnIndex);
+}
+//------------------------------------------------------------------------------
+Reference< XClob > OResultSet::getClob(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getClob" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getClob(columnIndex);
+}
+//------------------------------------------------------------------------------
+Reference< XArray > OResultSet::getArray(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getArray" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorRow->getArray(columnIndex);
+}
+
+// ::com::sun::star::sdbc::XRowUpdate
+//------------------------------------------------------------------------------
+void OResultSet::updateNull(sal_Int32 columnIndex) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateNull" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateNull(columnIndex);
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::updateBoolean(sal_Int32 columnIndex, sal_Bool x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateBoolean" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateBoolean(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateByte(sal_Int32 columnIndex, sal_Int8 x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateByte" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateByte(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateShort(sal_Int32 columnIndex, sal_Int16 x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateShort" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateShort(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateInt(sal_Int32 columnIndex, sal_Int32 x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateInt" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateInt(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateLong(sal_Int32 columnIndex, sal_Int64 x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateLong" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateLong(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateFloat(sal_Int32 columnIndex, float x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateFloat" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateFloat(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateDouble(sal_Int32 columnIndex, double x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateDouble" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateDouble(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateString(sal_Int32 columnIndex, const rtl::OUString& x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateString" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateString(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateBytes(sal_Int32 columnIndex, const Sequence< sal_Int8 >& x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateBytes" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateBytes(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateDate(sal_Int32 columnIndex, const ::com::sun::star::util::Date& x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateDate" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateDate(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateTime(sal_Int32 columnIndex, const ::com::sun::star::util::Time& x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateTime" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateTime(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateTimestamp(sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateTimestamp" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateTimestamp(columnIndex, x);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateBinaryStream(sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream > & x, sal_Int32 length) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateBinaryStream" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateBinaryStream(columnIndex, x, length);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateCharacterStream(sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream > & x, sal_Int32 length) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateCharacterStream" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateCharacterStream(columnIndex, x, length);
+}
+//------------------------------------------------------------------------------
+void OResultSet::updateNumericObject(sal_Int32 columnIndex, const Any& x, sal_Int32 scale) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateNumericObject" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateNumericObject(columnIndex, x, scale);
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::updateObject(sal_Int32 columnIndex, const Any& x) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateObject" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorRowUpdate->updateObject(columnIndex, x);
+}
+
+// ::com::sun::star::sdbc::XResultSet
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::next(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::next" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->next();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::isBeforeFirst(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::isBeforeFirst" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->isBeforeFirst();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::isAfterLast(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::isAfterLast" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->isAfterLast();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::isFirst(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::isFirst" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->isFirst();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::isLast(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::isLast" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->isLast();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::beforeFirst(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::beforeFirst" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ m_xDelegatorResultSet->beforeFirst();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::afterLast(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::afterLast" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ m_xDelegatorResultSet->afterLast();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::first(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::first" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->first();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::last(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::last" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->last();
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 OResultSet::getRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->getRow();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::absolute(sal_Int32 row) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::absolute" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->absolute(row);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::relative(sal_Int32 rows) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::relative" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->relative(rows);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::previous(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::previous" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->previous();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::refreshRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::refreshRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ m_xDelegatorResultSet->refreshRow();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::rowUpdated(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::rowUpdated" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->rowUpdated();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::rowInserted(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::rowInserted" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->rowInserted();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::rowDeleted(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::rowDeleted" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_xDelegatorResultSet->rowDeleted();
+}
+
+//------------------------------------------------------------------------------
+Reference< XInterface > OResultSet::getStatement(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getStatement" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ return m_aStatement;
+}
+
+// ::com::sun::star::sdbcx::XRowLocate
+//------------------------------------------------------------------------------
+Any OResultSet::getBookmark(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::getBookmark" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkBookmarkable();
+
+ return Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY)->getBookmark();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::moveToBookmark(const Any& bookmark) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::moveToBookmark" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkBookmarkable();
+
+ return Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY)->moveToBookmark(bookmark);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::moveRelativeToBookmark(const Any& bookmark, sal_Int32 rows) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::moveRelativeToBookmark" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkBookmarkable();
+
+ return Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY)->moveRelativeToBookmark(bookmark, rows);
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 OResultSet::compareBookmarks(const Any& _first, const Any& _second) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::compareBookmarks" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkBookmarkable();
+
+ return Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY)->compareBookmarks(_first, _second);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OResultSet::hasOrderedBookmarks(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::hasOrderedBookmarks" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkBookmarkable();
+
+ return Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY)->hasOrderedBookmarks();
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 OResultSet::hashBookmark(const Any& bookmark) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::hashBookmark" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkBookmarkable();
+
+ return Reference< XRowLocate >(m_xDelegatorResultSet, UNO_QUERY)->hashBookmark(bookmark);
+}
+
+// ::com::sun::star::sdbc::XResultSetUpdate
+//------------------------------------------------------------------------------
+void OResultSet::insertRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::insertRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorResultSetUpdate->insertRow();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::updateRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::updateRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorResultSetUpdate->updateRow();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::deleteRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::deleteRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorResultSetUpdate->deleteRow();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::cancelRowUpdates(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::cancelRowUpdates" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorResultSetUpdate->cancelRowUpdates();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::moveToInsertRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::moveToInsertRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorResultSetUpdate->moveToInsertRow();
+}
+
+//------------------------------------------------------------------------------
+void OResultSet::moveToCurrentRow(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::moveToCurrentRow" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OResultSetBase::rBHelper.bDisposed);
+
+ checkReadOnly();
+
+ m_xDelegatorResultSetUpdate->moveToCurrentRow();
+}
+
+// -----------------------------------------------------------------------------
+void OResultSet::checkReadOnly() const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::checkReadOnly" );
+ if ( ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
+ || !m_xDelegatorResultSetUpdate.is()
+ )
+ throwSQLException( "The result set is read-only.", SQL_GENERAL_ERROR, *const_cast< OResultSet* >( this ) );
+}
+
+// -----------------------------------------------------------------------------
+void OResultSet::checkBookmarkable() const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OResultSet::checkBookmarkable" );
+ if ( !m_bIsBookmarkable )
+ throwSQLException( "The result set does not have bookmark support.", SQL_GENERAL_ERROR, *const_cast< OResultSet* >( this ) );
+}
+// -----------------------------------------------------------------------------
+
diff --git a/dbaccess/source/core/api/resultset.hxx b/dbaccess/source/core/api/resultset.hxx
new file mode 100644
index 000000000000..cc765919c313
--- /dev/null
+++ b/dbaccess/source/core/api/resultset.hxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 _DBA_COREAPI_RESULTSET_HXX_
+#define _DBA_COREAPI_RESULTSET_HXX_
+
+#ifndef _DBA_COREAPI_COLUMN_HXX_
+#include "column.hxx"
+#endif
+#ifndef DBTOOLS_WARNINGSCONTAINER_HXX
+#include <connectivity/warningscontainer.hxx>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XSTATEMENT_HPP_
+#include <com/sun/star/sdbc/XStatement.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCLOSEABLE_HPP_
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP_
+#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
+#include <com/sun/star/sdbc/XRow.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_
+#include <com/sun/star/sdbc/XColumnLocate.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
+#include <com/sun/star/sdbcx/XRowLocate.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_RESULTSETCONCURRENCY_HPP_
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#endif
+
+#ifndef _CPPUHELPER_PROPSHLP_HXX
+#include <cppuhelper/propshlp.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
+#include <comphelper/proparrhlp.hxx>
+#endif
+#ifndef _OSL_DIAGNOSE_H_
+#include <osl/diagnose.h>
+#endif
+#ifndef _CPPUHELPER_COMPBASE11_HXX_
+#include <cppuhelper/compbase11.hxx>
+#endif
+#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
+#include <comphelper/broadcasthelper.hxx>
+#endif
+
+namespace dbaccess
+{
+ typedef ::cppu::WeakComponentImplHelper11< ::com::sun::star::sdbc::XWarningsSupplier,
+ ::com::sun::star::sdbc::XResultSet,
+ ::com::sun::star::sdbc::XResultSetMetaDataSupplier,
+ ::com::sun::star::sdbc::XRow,
+ ::com::sun::star::sdbc::XCloseable,
+ ::com::sun::star::sdbc::XColumnLocate,
+ ::com::sun::star::sdbcx::XRowLocate,
+ ::com::sun::star::sdbcx::XColumnsSupplier,
+ ::com::sun::star::sdbc::XResultSetUpdate,
+ ::com::sun::star::sdbc::XRowUpdate,
+ ::com::sun::star::lang::XServiceInfo > OResultSetBase;
+
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> ONoWeakStatement;
+
+ //************************************************************
+ // OResultSet
+ //************************************************************
+ class OResultSet : public comphelper::OBaseMutex,
+ public OResultSetBase,
+ public ::cppu::OPropertySetHelper,
+ public ::comphelper::OPropertyArrayUsageHelper < OResultSet >
+ {
+ protected:
+ ONoWeakStatement m_aStatement;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > m_xDelegatorResultSet;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetUpdate > m_xDelegatorResultSetUpdate;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > m_xDelegatorRow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowUpdate > m_xDelegatorRowUpdate;
+
+ ::dbtools::WarningsContainer m_aWarnings;
+ OColumns* m_pColumns;
+ sal_Int32 m_nResultSetType;
+ sal_Int32 m_nResultSetConcurrency;
+ sal_Bool m_bIsBookmarkable : 1;
+
+ public:
+ OResultSet(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& _xResultSet,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xStatement,
+ sal_Bool _bCaseSensitive);
+ virtual ~OResultSet();
+
+ // ::com::sun::star::lang::XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::uno::XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // ::com::sun::star::lang::XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::cppu::OComponentHelper
+ virtual void SAL_CALL disposing(void);
+
+ // ::com::sun::star::sdbc::XCloseable
+ virtual void SAL_CALL close( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // com::sun::star::beans::XPropertySet
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ ::com::sun::star::uno::Any & rConvertedValue,
+ ::com::sun::star::uno::Any & rOldValue,
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue )
+ throw (::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const ::com::sun::star::uno::Any& rValue
+ )
+ throw (::com::sun::star::uno::Exception);
+ virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
+
+ // ::com::sun::star::sdbc::XWarningsSupplier
+ virtual ::com::sun::star::uno::Any SAL_CALL getWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clearWarnings( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XResultSetMetaDataSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbc::XColumnLocate
+ virtual sal_Int32 SAL_CALL findColumn( const ::rtl::OUString& columnName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ // ::com::sun::star::sdbcx::XColumnsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ::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);
+
+ // ::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);
+ 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);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getStatement( ) 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::sdbc::XResultSetUpdate
+ virtual void SAL_CALL insertRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateRow( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deleteRow( ) 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);
+
+ // ::com::sun::star::sdbc::XRowUpdate
+ virtual void SAL_CALL updateNull( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateFloat( sal_Int32 columnIndex, float x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateDouble( sal_Int32 columnIndex, double x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBytes( sal_Int32 columnIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL updateNumericObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x, sal_Int32 scale ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
+
+ protected:
+ void checkReadOnly() const;
+ void checkBookmarkable() const;
+
+ private:
+ using ::cppu::OPropertySetHelper::getFastPropertyValue;
+ };
+}
+#endif // _DBA_COREAPI_RESULTSET_HXX_
+
diff --git a/dbaccess/source/core/api/statement.cxx b/dbaccess/source/core/api/statement.cxx
new file mode 100644
index 000000000000..05ef557f2582
--- /dev/null
+++ b/dbaccess/source/core/api/statement.cxx
@@ -0,0 +1,696 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#ifndef _DBA_COREAPI_STATEMENT_HXX_
+#include <statement.hxx>
+#endif
+#ifndef _DBA_COREAPI_RESULTSET_HXX_
+#include <resultset.hxx>
+#endif
+#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
+#include "dbastrings.hrc"
+#endif
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#endif
+#ifndef _COMPHELPER_SEQUENCE_HXX_
+#include <comphelper/sequence.hxx>
+#endif
+#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
+#include <cppuhelper/typeprovider.hxx>
+#endif
+#ifndef _COMPHELPER_PROPERTY_HXX_
+#include <comphelper/property.hxx>
+#endif
+#ifndef _COMPHELPER_TYPES_HXX_
+#include <comphelper/types.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+#ifndef TOOLS_DIAGNOSE_EX_H
+#include <tools/diagnose_ex.h>
+#endif
+#ifndef _DBHELPER_DBEXCEPTION_HXX_
+#include <connectivity/dbexception.hxx>
+#endif
+#include <rtl/logfile.hxx>
+
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace dbaccess;
+using namespace dbtools;
+
+DBG_NAME(OStatementBase)
+
+//--------------------------------------------------------------------------
+OStatementBase::OStatementBase(const Reference< XConnection > & _xConn,
+ const Reference< XInterface > & _xStatement)
+ :OSubComponent(m_aMutex, _xConn)
+ ,OPropertySetHelper(OComponentHelper::rBHelper)
+ ,m_bUseBookmarks( sal_False )
+ ,m_bEscapeProcessing( sal_True )
+
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::OStatementBase" );
+ DBG_CTOR(OStatementBase, NULL);
+ OSL_ENSURE(_xStatement.is() ,"Statement is NULL!");
+ m_xAggregateAsSet.set(_xStatement,UNO_QUERY);
+ m_xAggregateAsCancellable = Reference< ::com::sun::star::util::XCancellable > (m_xAggregateAsSet, UNO_QUERY);
+}
+
+//--------------------------------------------------------------------------
+OStatementBase::~OStatementBase()
+{
+ DBG_DTOR(OStatementBase, NULL);
+}
+
+// com::sun::star::lang::XTypeProvider
+//--------------------------------------------------------------------------
+Sequence< Type > OStatementBase::getTypes() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getTypes" );
+ OTypeCollection aTypes(::getCppuType( (const Reference< XPropertySet > *)0 ),
+ ::getCppuType( (const Reference< XWarningsSupplier > *)0 ),
+ ::getCppuType( (const Reference< XCloseable > *)0 ),
+ ::getCppuType( (const Reference< XMultipleResults > *)0 ),
+ ::getCppuType( (const Reference< ::com::sun::star::util::XCancellable > *)0 ),
+ OSubComponent::getTypes() );
+ Reference< XGeneratedResultSet > xGRes(m_xAggregateAsSet, UNO_QUERY);
+ if ( xGRes.is() )
+ aTypes = OTypeCollection(::getCppuType( (const Reference< XGeneratedResultSet > *)0 ),aTypes.getTypes());
+ Reference< XPreparedBatchExecution > xPreparedBatchExecution(m_xAggregateAsSet, UNO_QUERY);
+ if ( xPreparedBatchExecution.is() )
+ aTypes = OTypeCollection(::getCppuType( (const Reference< XPreparedBatchExecution > *)0 ),aTypes.getTypes());
+
+ return aTypes.getTypes();
+}
+
+// com::sun::star::uno::XInterface
+//--------------------------------------------------------------------------
+Any OStatementBase::queryInterface( const Type & rType ) throw (RuntimeException)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::queryInterface" );
+ Any aIface = OSubComponent::queryInterface( rType );
+ if (!aIface.hasValue())
+ {
+ aIface = ::cppu::queryInterface(
+ rType,
+ static_cast< XPropertySet * >( this ),
+ static_cast< XWarningsSupplier * >( this ),
+ static_cast< XCloseable * >( this ),
+ static_cast< XMultipleResults * >( this ),
+ static_cast< ::com::sun::star::util::XCancellable * >( this ));
+ if ( !aIface.hasValue() )
+ {
+ Reference< XGeneratedResultSet > xGRes(m_xAggregateAsSet, UNO_QUERY);
+ if ( ::getCppuType( (const Reference< XGeneratedResultSet > *)0 ) == rType && xGRes.is() )
+ aIface = ::cppu::queryInterface(rType,static_cast< XGeneratedResultSet * >( this ));
+ } // if ( !aIface.hasValue() )
+ if ( !aIface.hasValue() )
+ {
+ Reference< XPreparedBatchExecution > xGRes(m_xAggregateAsSet, UNO_QUERY);
+ if ( ::getCppuType( (const Reference< XPreparedBatchExecution > *)0 ) == rType && xGRes.is() )
+ aIface = ::cppu::queryInterface(rType,static_cast< XPreparedBatchExecution * >( this ));
+ }
+ }
+ return aIface;
+}
+
+//--------------------------------------------------------------------------
+void OStatementBase::acquire() throw ()
+{
+ OSubComponent::acquire();
+}
+
+//--------------------------------------------------------------------------
+void OStatementBase::release() throw ()
+{
+ OSubComponent::release();
+}
+
+//------------------------------------------------------------------------------
+void OStatementBase::disposeResultSet()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::disposeResultSet" );
+ // free the cursor if alive
+ Reference< XComponent > xComp(m_aResultSet.get(), UNO_QUERY);
+ if (xComp.is())
+ xComp->dispose();
+ m_aResultSet = NULL;
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void OStatementBase::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::disposing" );
+ OPropertySetHelper::disposing();
+
+ MutexGuard aGuard(m_aMutex);
+
+ // free pending results
+ disposeResultSet();
+
+ // free the original statement
+ {
+ MutexGuard aCancelGuard(m_aCancelMutex);
+ m_xAggregateAsCancellable = NULL;
+ }
+
+ if ( m_xAggregateAsSet.is() )
+ {
+ try
+ {
+ Reference< XCloseable > (m_xAggregateAsSet, UNO_QUERY)->close();
+ }
+ catch(RuntimeException& )
+ {// don't care for anymore
+ }
+ }
+ m_xAggregateAsSet = NULL;
+
+ // free the parent at last
+ OSubComponent::disposing();
+}
+
+// XCloseable
+//------------------------------------------------------------------------------
+void OStatementBase::close(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::close" );
+ {
+ MutexGuard aGuard( m_aMutex );
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ }
+ dispose();
+}
+
+// OPropertySetHelper
+//------------------------------------------------------------------------------
+Reference< XPropertySetInfo > OStatementBase::getPropertySetInfo() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getPropertySetInfo" );
+ return createPropertySetInfo( getInfoHelper() ) ;
+}
+
+// comphelper::OPropertyArrayUsageHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* OStatementBase::createArrayHelper( ) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::createArrayHelper" );
+ BEGIN_PROPERTY_HELPER(10)
+ DECL_PROP0(CURSORNAME, ::rtl::OUString);
+ DECL_PROP0_BOOL(ESCAPE_PROCESSING);
+ DECL_PROP0(FETCHDIRECTION, sal_Int32);
+ DECL_PROP0(FETCHSIZE, sal_Int32);
+ DECL_PROP0(MAXFIELDSIZE, sal_Int32);
+ DECL_PROP0(MAXROWS, sal_Int32);
+ DECL_PROP0(QUERYTIMEOUT, sal_Int32);
+ DECL_PROP0(RESULTSETCONCURRENCY, sal_Int32);
+ DECL_PROP0(RESULTSETTYPE, sal_Int32);
+ DECL_PROP0_BOOL(USEBOOKMARKS);
+ END_PROPERTY_HELPER();
+}
+
+// cppu::OPropertySetHelper
+//------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& OStatementBase::getInfoHelper()
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getInfoHelper" );
+ return *getArrayHelper();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OStatementBase::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::convertFastPropertyValue" );
+ sal_Bool bModified(sal_False);
+ switch (nHandle)
+ {
+ case PROPERTY_ID_USEBOOKMARKS:
+ bModified = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, m_bUseBookmarks );
+ break;
+
+ case PROPERTY_ID_ESCAPE_PROCESSING:
+ bModified = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, m_bEscapeProcessing );
+ break;
+
+ default:
+ if ( m_xAggregateAsSet.is() )
+ {
+ // get the property name
+ ::rtl::OUString sPropName;
+ getInfoHelper().fillPropertyMembersByHandle( &sPropName, NULL, nHandle );
+
+ // now set the value
+ Any aCurrentValue = m_xAggregateAsSet->getPropertyValue( sPropName );
+ if ( aCurrentValue != rValue )
+ {
+ rOldValue = aCurrentValue;
+ rConvertedValue = rValue;
+ bModified = sal_True;
+ }
+ }
+ break;
+ }
+ return bModified;
+}
+
+//------------------------------------------------------------------------------
+void OStatementBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::setFastPropertyValue_NoBroadcast" );
+ switch ( nHandle )
+ {
+ case PROPERTY_ID_USEBOOKMARKS:
+ {
+ m_bUseBookmarks = ::comphelper::getBOOL( rValue );
+ if ( m_xAggregateAsSet.is() && m_xAggregateAsSet->getPropertySetInfo()->hasPropertyByName( PROPERTY_USEBOOKMARKS ) )
+ m_xAggregateAsSet->setPropertyValue( PROPERTY_USEBOOKMARKS, rValue );
+ }
+ break;
+
+ case PROPERTY_ID_ESCAPE_PROCESSING:
+ m_bEscapeProcessing = ::comphelper::getBOOL( rValue );
+ if ( m_xAggregateAsSet.is() )
+ m_xAggregateAsSet->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, rValue );
+ break;
+
+ default:
+ if ( m_xAggregateAsSet.is() )
+ {
+ ::rtl::OUString sPropName;
+ getInfoHelper().fillPropertyMembersByHandle( &sPropName, NULL, nHandle );
+ m_xAggregateAsSet->setPropertyValue( sPropName, rValue );
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+void OStatementBase::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+{
+ //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getFastPropertyValue" );
+ switch (nHandle)
+ {
+ case PROPERTY_ID_USEBOOKMARKS:
+ rValue <<= m_bUseBookmarks;
+ break;
+
+ case PROPERTY_ID_ESCAPE_PROCESSING:
+ // don't rely on our aggregate - if it implements this wrong, and always returns
+ // TRUE here, then we would loop in impl_doEscapeProcessing_nothrow
+ rValue <<= m_bEscapeProcessing;
+ break;
+
+ default:
+ if ( m_xAggregateAsSet.is() )
+ {
+ ::rtl::OUString sPropName;
+ const_cast< OStatementBase* >( this )->getInfoHelper().fillPropertyMembersByHandle( &sPropName, NULL, nHandle );
+ rValue = m_xAggregateAsSet->getPropertyValue( sPropName );
+ }
+ break;
+ }
+}
+
+// XWarningsSupplier
+//------------------------------------------------------------------------------
+Any OStatementBase::getWarnings(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getWarnings" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ return Reference< XWarningsSupplier >(m_xAggregateAsSet, UNO_QUERY)->getWarnings();
+}
+
+//------------------------------------------------------------------------------
+void OStatementBase::clearWarnings(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::clearWarnings" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ Reference< XWarningsSupplier >(m_xAggregateAsSet, UNO_QUERY)->clearWarnings();
+}
+
+// ::com::sun::star::util::XCancellable
+//------------------------------------------------------------------------------
+void OStatementBase::cancel(void) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::cancel" );
+ // no blocking as cancel is typically called from a different thread
+ ClearableMutexGuard aCancelGuard(m_aCancelMutex);
+ if (m_xAggregateAsCancellable.is())
+ m_xAggregateAsCancellable->cancel();
+ // else do nothing
+}
+
+// XMultipleResults
+//------------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL OStatementBase::getResultSet( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getResultSet" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsMultipleResultSets())
+ throwFunctionSequenceException(*this);
+
+ return Reference< XMultipleResults >(m_xAggregateAsSet, UNO_QUERY)->getResultSet();
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OStatementBase::getUpdateCount( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getUpdateCount" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsMultipleResultSets())
+ throwFunctionSequenceException(*this);
+
+ return Reference< XMultipleResults >(m_xAggregateAsSet, UNO_QUERY)->getUpdateCount();
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL OStatementBase::getMoreResults( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getMoreResults" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsMultipleResultSets())
+ throwFunctionSequenceException(*this);
+ throwFunctionSequenceException(*this);
+
+ // free the previous results
+ disposeResultSet();
+
+ return Reference< XMultipleResults >(m_xAggregateAsSet, UNO_QUERY)->getMoreResults();
+}
+
+// XPreparedBatchExecution
+//------------------------------------------------------------------------------
+void SAL_CALL OStatementBase::addBatch( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::addBatch" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsBatchUpdates())
+ throwFunctionSequenceException(*this);
+
+ Reference< XPreparedBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->addBatch();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OStatementBase::clearBatch( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::clearBatch" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsBatchUpdates())
+ throwFunctionSequenceException(*this);
+
+ Reference< XPreparedBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->clearBatch();
+}
+
+//------------------------------------------------------------------------------
+Sequence< sal_Int32 > SAL_CALL OStatementBase::executeBatch( ) throw(SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::executeBatch" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsBatchUpdates())
+ throwFunctionSequenceException(*this);
+
+ // free the previous results
+ disposeResultSet();
+
+ return Reference< XPreparedBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->executeBatch();
+}
+// -----------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL OStatementBase::getGeneratedValues( ) throw (SQLException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getGeneratedValues" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ Reference< XGeneratedResultSet > xGRes(m_xAggregateAsSet, UNO_QUERY);
+
+ if ( xGRes.is() )
+ return xGRes->getGeneratedValues( );
+ return Reference< XResultSet >();
+}
+
+//************************************************************
+// OStatement
+//************************************************************
+//------------------------------------------------------------------------------
+OStatement::OStatement( const Reference< XConnection >& _xConn, const Reference< XInterface > & _xStatement )
+ :OStatementBase( _xConn, _xStatement )
+ ,m_bAttemptedComposerCreation( false )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::OStatement" );
+ m_xAggregateStatement.set( _xStatement, UNO_QUERY_THROW );
+}
+
+//------------------------------------------------------------------------------
+IMPLEMENT_FORWARD_XINTERFACE2( OStatement, OStatementBase, OStatement_IFACE );
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( OStatement, OStatementBase, OStatement_IFACE );
+
+// XServiceInfo
+//------------------------------------------------------------------------------
+rtl::OUString OStatement::getImplementationName( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::getImplementationName" );
+ return rtl::OUString::createFromAscii("com.sun.star.sdb.OStatement");
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OStatement::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::supportsService" );
+ return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > OStatement::getSupportedServiceNames( ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::getSupportedServiceNames" );
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[0] = SERVICE_SDBC_STATEMENT;
+ return aSNS;
+}
+
+// XStatement
+//------------------------------------------------------------------------------
+Reference< XResultSet > OStatement::executeQuery( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::executeQuery" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ disposeResultSet();
+ Reference< XResultSet > xResultSet;
+
+ ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
+
+ Reference< XResultSet > xInnerResultSet = m_xAggregateStatement->executeQuery( sSQL );
+ Reference< XConnection > xConnection( m_xParent, UNO_QUERY_THROW );
+
+ if ( xInnerResultSet.is() )
+ {
+ Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
+ sal_Bool bCaseSensitive = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
+ xResultSet = new OResultSet( xInnerResultSet, *this, bCaseSensitive );
+
+ // keep the resultset weak
+ m_aResultSet = xResultSet;
+ }
+
+ return xResultSet;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 OStatement::executeUpdate( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::executeUpdate" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ disposeResultSet();
+
+ ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
+ return m_xAggregateStatement->executeUpdate( sSQL );
+}
+
+//------------------------------------------------------------------------------
+sal_Bool OStatement::execute( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ disposeResultSet();
+
+ ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
+ return m_xAggregateStatement->execute( sSQL );
+}
+//------------------------------------------------------------------------------
+void OStatement::addBatch( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsBatchUpdates())
+ throwFunctionSequenceException(*this);
+
+ ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
+ Reference< XBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->addBatch( sSQL );
+}
+//------------------------------------------------------------------------------
+void OStatement::clearBatch( ) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsBatchUpdates())
+ throwFunctionSequenceException(*this);
+
+ Reference< XBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->clearBatch();
+}
+//------------------------------------------------------------------------------
+Sequence< sal_Int32 > OStatement::executeBatch( ) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
+ MutexGuard aGuard(m_aMutex);
+ ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
+ // first check the meta data
+ Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
+ if (!xMeta.is() && !xMeta->supportsBatchUpdates())
+ throwFunctionSequenceException(*this);
+ return Reference< XBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->executeBatch( );
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection > OStatement::getConnection(void) throw( SQLException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::getConnection" );
+ return Reference< XConnection >( m_xParent, UNO_QUERY );
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL OStatement::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::disposing" );
+ OStatementBase::disposing();
+ m_xComposer.clear();
+ m_xAggregateStatement.clear();
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString OStatement::impl_doEscapeProcessing_nothrow( const ::rtl::OUString& _rSQL ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::impl_doEscapeProcessing_nothrow" );
+ if ( !m_bEscapeProcessing )
+ return _rSQL;
+ try
+ {
+ if ( !impl_ensureComposer_nothrow() )
+ return _rSQL;
+
+ bool bParseable = false;
+ try { m_xComposer->setQuery( _rSQL ); bParseable = true; }
+ catch( const SQLException& ) { }
+
+ if ( !bParseable )
+ // if we cannot parse it, silently accept this. The driver is probably able to cope with it then
+ return _rSQL;
+
+ ::rtl::OUString sLowLevelSQL = m_xComposer->getQueryWithSubstitution();
+ return sLowLevelSQL;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return _rSQL;
+}
+
+// -----------------------------------------------------------------------------
+bool OStatement::impl_ensureComposer_nothrow() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::impl_ensureComposer_nothrow" );
+ if ( m_bAttemptedComposerCreation )
+ return m_xComposer.is();
+
+ const_cast< OStatement* >( this )->m_bAttemptedComposerCreation = true;
+ try
+ {
+ Reference< XMultiServiceFactory > xFactory( m_xParent, UNO_QUERY_THROW );
+ const_cast< OStatement* >( this )->m_xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return m_xComposer.is();
+}
diff --git a/dbaccess/source/core/api/table.cxx b/dbaccess/source/core/api/table.cxx
new file mode 100644
index 000000000000..e33098f74f4c
--- /dev/null
+++ b/dbaccess/source/core/api/table.cxx
@@ -0,0 +1,417 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "table.hxx"
+#include <definitioncolumn.hxx>
+#include "dbastrings.hrc"
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include "CIndexes.hxx"
+
+#include <tools/debug.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/container.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+//#include <comphelper/extract.hxx>
+#include <com/sun/star/util/XRefreshListener.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+
+#include <connectivity/TKeys.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbexception.hxx>
+
+#include "sdbcoretools.hxx"
+#include "ContainerMediator.hxx"
+#include <rtl/logfile.hxx>
+
+using namespace dbaccess;
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+typedef ::std::map <sal_Int32, OTableColumn*, std::less <sal_Int32> > OColMap;
+
+//==========================================================================
+//= ODBTable
+//==========================================================================
+DBG_NAME(ODBTable)
+//--------------------------------------------------------------------------
+ODBTable::ODBTable(connectivity::sdbcx::OCollection* _pTables
+ ,const Reference< XConnection >& _rxConn
+ ,const ::rtl::OUString& _rCatalog
+ ,const ::rtl::OUString& _rSchema
+ ,const ::rtl::OUString& _rName
+ ,const ::rtl::OUString& _rType
+ ,const ::rtl::OUString& _rDesc
+ ,const Reference< XNameAccess >& _xColumnDefinitions) throw(SQLException)
+ :OTable_Base(_pTables,_rxConn,_rxConn->getMetaData().is() && _rxConn->getMetaData()->supportsMixedCaseQuotedIdentifiers(), _rName, _rType, _rDesc, _rSchema, _rCatalog )
+ ,m_xColumnDefinitions(_xColumnDefinitions)
+ ,m_nPrivileges(0)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::ODBTable" );
+ DBG_CTOR(ODBTable, NULL);
+ DBG_ASSERT(getMetaData().is(), "ODBTable::ODBTable : invalid conn !");
+ DBG_ASSERT(_rName.getLength(), "ODBTable::ODBTable : name !");
+ // TODO : think about collecting the privileges here, as we can't ensure that in getFastPropertyValue, where
+ // we do this at the moment, the statement needed can be supplied by the connection (for example the SQL-Server
+ // ODBC driver does not allow more than one statement per connection, and in getFastPropertyValue it's more
+ // likely that it's already used up than it's here.)
+}
+// -----------------------------------------------------------------------------
+ODBTable::ODBTable(connectivity::sdbcx::OCollection* _pTables
+ ,const Reference< XConnection >& _rxConn)
+ throw(SQLException)
+ :OTable_Base(_pTables,_rxConn, _rxConn->getMetaData().is() && _rxConn->getMetaData()->supportsMixedCaseQuotedIdentifiers())
+ ,m_nPrivileges(-1)
+{
+ DBG_CTOR(ODBTable, NULL);
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::ODBTable" );
+}
+// -------------------------------------------------------------------------
+ODBTable::~ODBTable()
+{
+ DBG_DTOR(ODBTable, NULL);
+}
+// -----------------------------------------------------------------------------
+IMPLEMENT_FORWARD_REFCOUNT(ODBTable,OTable_Base)
+
+//--------------------------------------------------------------------------
+OColumn* ODBTable::createColumn(const ::rtl::OUString& _rName) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::createColumn" );
+ OColumn* pReturn = NULL;
+
+ Reference<XPropertySet> xProp;
+ if ( m_xDriverColumns.is() && m_xDriverColumns->hasByName(_rName) )
+ {
+ xProp.set(m_xDriverColumns->getByName(_rName),UNO_QUERY);
+ }
+ else
+ {
+ OColumns* pColumns = static_cast<OColumns*>(m_pColumns);
+ xProp.set(pColumns->createBaseObject(_rName),UNO_QUERY);
+ }
+
+ Reference<XPropertySet> xColumnDefintion;
+ if ( m_xColumnDefinitions.is() && m_xColumnDefinitions->hasByName(_rName) )
+ xColumnDefintion.set(m_xColumnDefinitions->getByName(_rName),UNO_QUERY);
+ pReturn = new OTableColumnWrapper( xProp, xColumnDefintion, false );
+
+ return pReturn;
+}
+// -----------------------------------------------------------------------------
+void ODBTable::columnAppended( const Reference< XPropertySet >& /*_rxSourceDescriptor*/ )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::columnAppended" );
+ // not interested in
+}
+// -----------------------------------------------------------------------------
+void ODBTable::columnDropped(const ::rtl::OUString& _sName)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::columnDropped" );
+ Reference<XDrop> xDrop(m_xColumnDefinitions,UNO_QUERY);
+ if ( xDrop.is() && m_xColumnDefinitions->hasByName(_sName) )
+ {
+ xDrop->dropByName(_sName);
+ }
+}
+//--------------------------------------------------------------------------
+Sequence< sal_Int8 > ODBTable::getImplementationId() throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::getImplementationId" );
+ static OImplementationId * pId = 0;
+ if (! pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+// OComponentHelper
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTable::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::disposing" );
+ OPropertySetHelper::disposing();
+ OTable_Base::disposing();
+ m_xColumnDefinitions = NULL;
+ m_xDriverColumns = NULL;
+ m_pColumnMediator = NULL;
+}
+
+//------------------------------------------------------------------------------
+void ODBTable::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::getFastPropertyValue" );
+ if ((PROPERTY_ID_PRIVILEGES == _nHandle) && (-1 == m_nPrivileges))
+ { // somebody is asking for the privileges an we do not know them, yet
+ const_cast<ODBTable*>(this)->m_nPrivileges = ::dbtools::getTablePrivileges(getMetaData(),m_CatalogName,m_SchemaName, m_Name);
+ }
+
+ OTable_Base::getFastPropertyValue(_rValue, _nHandle);
+}
+// -------------------------------------------------------------------------
+void ODBTable::construct()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::construct" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // we don't collect the privileges here, this is potentially expensive. Instead we determine them on request.
+ // (see getFastPropertyValue)
+ m_nPrivileges = -1;
+
+ OTable_Base::construct();
+
+ registerProperty(PROPERTY_FILTER, PROPERTY_ID_FILTER, PropertyAttribute::BOUND,
+ &m_sFilter, ::getCppuType(&m_sFilter));
+
+ registerProperty(PROPERTY_ORDER, PROPERTY_ID_ORDER, PropertyAttribute::BOUND,
+ &m_sOrder, ::getCppuType(&m_sOrder));
+
+ registerProperty(PROPERTY_APPLYFILTER, PROPERTY_ID_APPLYFILTER, PropertyAttribute::BOUND,
+ &m_bApplyFilter, ::getBooleanCppuType());
+
+ registerProperty(PROPERTY_FONT, PROPERTY_ID_FONT, PropertyAttribute::BOUND,
+ &m_aFont, ::getCppuType(&m_aFont));
+
+ registerMayBeVoidProperty(PROPERTY_ROW_HEIGHT, PROPERTY_ID_ROW_HEIGHT, PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
+ &m_aRowHeight, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerMayBeVoidProperty(PROPERTY_TEXTCOLOR, PROPERTY_ID_TEXTCOLOR, PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
+ &m_aTextColor, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, PropertyAttribute::BOUND | PropertyAttribute::READONLY,
+ &m_nPrivileges, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerMayBeVoidProperty(PROPERTY_TEXTLINECOLOR, PROPERTY_ID_TEXTLINECOLOR, PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
+ &m_aTextLineColor, ::getCppuType(static_cast<sal_Int32*>(NULL)));
+
+ registerProperty(PROPERTY_TEXTEMPHASIS, PROPERTY_ID_TEXTEMPHASIS, PropertyAttribute::BOUND,
+ &m_nFontEmphasis, ::getCppuType(&m_nFontEmphasis));
+
+ registerProperty(PROPERTY_TEXTRELIEF, PROPERTY_ID_TEXTRELIEF, PropertyAttribute::BOUND,
+ &m_nFontRelief, ::getCppuType(&m_nFontRelief));
+
+ registerProperty(PROPERTY_FONTNAME, PROPERTY_ID_FONTNAME, PropertyAttribute::BOUND,&m_aFont.Name, ::getCppuType(&m_aFont.Name));
+ registerProperty(PROPERTY_FONTHEIGHT, PROPERTY_ID_FONTHEIGHT, PropertyAttribute::BOUND,&m_aFont.Height, ::getCppuType(&m_aFont.Height));
+ registerProperty(PROPERTY_FONTWIDTH, PROPERTY_ID_FONTWIDTH, PropertyAttribute::BOUND,&m_aFont.Width, ::getCppuType(&m_aFont.Width));
+ registerProperty(PROPERTY_FONTSTYLENAME, PROPERTY_ID_FONTSTYLENAME, PropertyAttribute::BOUND,&m_aFont.StyleName, ::getCppuType(&m_aFont.StyleName));
+ registerProperty(PROPERTY_FONTFAMILY, PROPERTY_ID_FONTFAMILY, PropertyAttribute::BOUND,&m_aFont.Family, ::getCppuType(&m_aFont.Family));
+ registerProperty(PROPERTY_FONTCHARSET, PROPERTY_ID_FONTCHARSET, PropertyAttribute::BOUND,&m_aFont.CharSet, ::getCppuType(&m_aFont.CharSet));
+ registerProperty(PROPERTY_FONTPITCH, PROPERTY_ID_FONTPITCH, PropertyAttribute::BOUND,&m_aFont.Pitch, ::getCppuType(&m_aFont.Pitch));
+ registerProperty(PROPERTY_FONTCHARWIDTH, PROPERTY_ID_FONTCHARWIDTH, PropertyAttribute::BOUND,&m_aFont.CharacterWidth, ::getCppuType(&m_aFont.CharacterWidth));
+ registerProperty(PROPERTY_FONTWEIGHT, PROPERTY_ID_FONTWEIGHT, PropertyAttribute::BOUND,&m_aFont.Weight, ::getCppuType(&m_aFont.Weight));
+ registerProperty(PROPERTY_FONTSLANT, PROPERTY_ID_FONTSLANT, PropertyAttribute::BOUND,&m_aFont.Slant, ::getCppuType(&m_aFont.Slant));
+ registerProperty(PROPERTY_FONTUNDERLINE, PROPERTY_ID_FONTUNDERLINE, PropertyAttribute::BOUND,&m_aFont.Underline, ::getCppuType(&m_aFont.Underline));
+ registerProperty(PROPERTY_FONTSTRIKEOUT, PROPERTY_ID_FONTSTRIKEOUT, PropertyAttribute::BOUND,&m_aFont.Strikeout, ::getCppuType(&m_aFont.Strikeout));
+ registerProperty(PROPERTY_FONTORIENTATION, PROPERTY_ID_FONTORIENTATION, PropertyAttribute::BOUND,&m_aFont.Orientation, ::getCppuType(&m_aFont.Orientation));
+ registerProperty(PROPERTY_FONTKERNING, PROPERTY_ID_FONTKERNING, PropertyAttribute::BOUND,&m_aFont.Kerning, ::getCppuType(&m_aFont.Kerning));
+ registerProperty(PROPERTY_FONTWORDLINEMODE, PROPERTY_ID_FONTWORDLINEMODE,PropertyAttribute::BOUND,&m_aFont.WordLineMode, ::getCppuType(&m_aFont.WordLineMode));
+ registerProperty(PROPERTY_FONTTYPE, PROPERTY_ID_FONTTYPE, PropertyAttribute::BOUND,&m_aFont.Type, ::getCppuType(&m_aFont.Type));
+
+ refreshColumns();
+}
+// -----------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* ODBTable::createArrayHelper( sal_Int32 _nId) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::createArrayHelper" );
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ if(!_nId)
+ {
+ Property* pIter = aProps.getArray();
+ Property* pEnd = pIter + aProps.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if (0 == pIter->Name.compareToAscii(PROPERTY_CATALOGNAME))
+ pIter->Attributes = PropertyAttribute::READONLY;
+ else if (0 == pIter->Name.compareToAscii(PROPERTY_SCHEMANAME))
+ pIter->Attributes = PropertyAttribute::READONLY;
+ else if (0 == pIter->Name.compareToAscii(PROPERTY_DESCRIPTION))
+ pIter->Attributes = PropertyAttribute::READONLY;
+ else if (0 == pIter->Name.compareToAscii(PROPERTY_NAME))
+ pIter->Attributes = PropertyAttribute::READONLY;
+ }
+ }
+
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+// -----------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper & SAL_CALL ODBTable::getInfoHelper()
+{
+ return *ODBTable_PROP::getArrayHelper(isNew() ? 1 : 0);
+}
+// -------------------------------------------------------------------------
+// XServiceInfo
+IMPLEMENT_SERVICE_INFO1(ODBTable, "com.sun.star.sdb.dbaccess.ODBTable", SERVICE_SDBCX_TABLE)
+// -------------------------------------------------------------------------
+Any SAL_CALL ODBTable::queryInterface( const Type & rType ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::getInfoHelper" );
+ if(rType == getCppuType( (Reference<XRename>*)0) && !getRenameService().is() )
+ return Any();
+ if(rType == getCppuType( (Reference<XAlterTable>*)0) && !getAlterService().is() )
+ return Any();
+ return OTable_Base::queryInterface( rType);
+}
+// -------------------------------------------------------------------------
+Sequence< Type > SAL_CALL ODBTable::getTypes( ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::getTypes" );
+ Type aRenameType = getCppuType( (Reference<XRename>*)0);
+ Type aAlterType = getCppuType( (Reference<XAlterTable>*)0);
+
+ Sequence< Type > aTypes(OTable_Base::getTypes());
+ ::std::vector<Type> aOwnTypes;
+ aOwnTypes.reserve(aTypes.getLength());
+
+ const Type* pIter = aTypes.getConstArray();
+ const Type* pEnd = pIter + aTypes.getLength();
+ for(;pIter != pEnd ;++pIter)
+ {
+ if( (*pIter != aRenameType || getRenameService().is()) && (*pIter != aAlterType || getAlterService().is()))
+ aOwnTypes.push_back(*pIter);
+ }
+
+ Type* pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
+ return Sequence< Type >(pTypes, aOwnTypes.size());
+}
+// XRename,
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTable::rename( const ::rtl::OUString& _rNewName ) throw(SQLException, ElementExistException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::rename" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ checkDisposed(connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed);
+ if ( !getRenameService().is() )
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NO_TABLE_RENAME),*this,SQLSTATE_GENERAL,1000,Any() );
+
+ Reference<XPropertySet> xTable(this);
+ getRenameService()->rename(xTable,_rNewName);
+ ::connectivity::OTable_TYPEDEF::rename(_rNewName);
+}
+
+// XAlterTable,
+//------------------------------------------------------------------------------
+void SAL_CALL ODBTable::alterColumnByName( const ::rtl::OUString& _rName, const Reference< XPropertySet >& _rxDescriptor ) throw(SQLException, NoSuchElementException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::alterColumnByName" );
+ ::osl::MutexGuard aGuard(m_aMutex);
+ checkDisposed(connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed);
+ if ( !getAlterService().is() )
+ throw SQLException(DBACORE_RESSTRING(RID_STR_NO_TABLE_RENAME),*this,SQLSTATE_GENERAL,1000,Any() );
+
+ if ( !m_pColumns->hasByName(_rName) )
+ throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,Any() );
+
+ Reference<XPropertySet> xTable(this);
+ getAlterService()->alterColumnByName(xTable,_rName,_rxDescriptor);
+ m_pColumns->refresh();
+}
+// -----------------------------------------------------------------------------
+sal_Int64 SAL_CALL ODBTable::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::getSomething" );
+ sal_Int64 nRet(0);
+ if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ nRet = reinterpret_cast<sal_Int64>(this);
+ else
+ nRet = OTable_Base::getSomething(rId);
+
+ return nRet;
+}
+// -----------------------------------------------------------------------------
+Sequence< sal_Int8 > ODBTable::getUnoTunnelImplementationId()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::getUnoTunnelImplementationId" );
+ static ::cppu::OImplementationId * pId = 0;
+ if (! pId)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! pId)
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+}
+// -----------------------------------------------------------------------------
+Reference< XPropertySet > ODBTable::createColumnDescriptor()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::createColumnDescriptor" );
+ return new OTableColumnDescriptor( true );
+}
+// -----------------------------------------------------------------------------
+sdbcx::OCollection* ODBTable::createColumns(const TStringVector& _rNames)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::createColumns" );
+ Reference<XDatabaseMetaData> xMeta = getMetaData();
+ OColumns* pCol = new OColumns(*this, m_aMutex, NULL, isCaseSensitive(), _rNames, this,this,
+ getAlterService().is() || (xMeta.is() && xMeta->supportsAlterTableWithAddColumn()),
+ getAlterService().is() || (xMeta.is() && xMeta->supportsAlterTableWithDropColumn()));
+ static_cast<OColumnsHelper*>(pCol)->setParent(this);
+ pCol->setParent(*this);
+ m_pColumnMediator = new OContainerMediator( pCol, m_xColumnDefinitions, getConnection(), OContainerMediator::eColumns );
+ pCol->setMediator( m_pColumnMediator.get() );
+ return pCol;
+}
+// -----------------------------------------------------------------------------
+sdbcx::OCollection* ODBTable::createKeys(const TStringVector& _rNames)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::createKeys" );
+ return new connectivity::OKeysHelper(this,m_aMutex,_rNames);
+}
+// -----------------------------------------------------------------------------
+sdbcx::OCollection* ODBTable::createIndexes(const TStringVector& _rNames)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTable::createIndexes" );
+ return new OIndexes(this,m_aMutex,_rNames,NULL);
+}
+// -----------------------------------------------------------------------------
diff --git a/dbaccess/source/core/api/tablecontainer.cxx b/dbaccess/source/core/api/tablecontainer.cxx
new file mode 100644
index 000000000000..76d6ac063441
--- /dev/null
+++ b/dbaccess/source/core/api/tablecontainer.cxx
@@ -0,0 +1,516 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "tablecontainer.hxx"
+#include "dbastrings.hrc"
+#include "table.hxx"
+#include <comphelper/property.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/debug.hxx>
+#include <comphelper/enumhelper.hxx>
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <comphelper/extract.hxx>
+#include <connectivity/dbexception.hxx>
+#include "TableDeco.hxx"
+#include "sdbcoretools.hxx"
+#include "ContainerMediator.hxx"
+#include "definitioncolumn.hxx"
+#include "objectnameapproval.hxx"
+#include <tools/string.hxx>
+#include <rtl/logfile.hxx>
+#ifndef TOOLS_DIAGNOSE_EX_H
+#include <tools/diagnose_ex.h>
+#endif
+#ifndef TOOLS_DIAGNOSE_EX_H
+#include <tools/diagnose_ex.h>
+#endif
+
+using namespace dbaccess;
+using namespace dbtools;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+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::util;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+using namespace ::connectivity::sdbcx;
+
+namespace
+{
+ sal_Bool lcl_isPropertySetDefaulted(const Sequence< ::rtl::OUString>& _aNames,const Reference<XPropertySet>& _xProp)
+ {
+ Reference<XPropertyState> xState(_xProp,UNO_QUERY);
+ if ( xState.is() )
+ {
+ const ::rtl::OUString* pIter = _aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + _aNames.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ try
+ {
+ PropertyState aState = xState->getPropertyState(*pIter);
+ if ( aState != PropertyState_DEFAULT_VALUE )
+ break;
+ }
+ catch(Exception)
+ {
+ OSL_ENSURE( 0, "lcl_isPropertySetDefaulted: Exception caught!" );
+ }
+ }
+ return ( pIter == pEnd );
+ }
+ return sal_False;
+ }
+}
+//==========================================================================
+//= OTableContainer
+//==========================================================================
+DBG_NAME(OTableContainer)
+//------------------------------------------------------------------------------
+OTableContainer::OTableContainer(::cppu::OWeakObject& _rParent,
+ ::osl::Mutex& _rMutex,
+ const Reference< XConnection >& _xCon,
+ sal_Bool _bCase,
+ const Reference< XNameContainer >& _xTableDefinitions,
+ IRefreshListener* _pRefreshListener,
+ ::dbtools::IWarningsContainer* _pWarningsContainer
+ ,oslInterlockedCount& _nInAppend)
+ :OFilteredContainer(_rParent,_rMutex,_xCon,_bCase,_pRefreshListener,_pWarningsContainer,_nInAppend)
+ ,m_xTableDefinitions(_xTableDefinitions)
+ ,m_pTableMediator( NULL )
+ ,m_bInDrop(sal_False)
+{
+ DBG_CTOR(OTableContainer, NULL);
+}
+
+//------------------------------------------------------------------------------
+OTableContainer::~OTableContainer()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::OTableContainer" );
+ // dispose();
+ DBG_DTOR(OTableContainer, NULL);
+}
+
+// -----------------------------------------------------------------------------
+void OTableContainer::removeMasterContainerListener()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::removeMasterContainerListener" );
+ try
+ {
+ Reference<XContainer> xCont( m_xMasterContainer, UNO_QUERY_THROW );
+ xCont->removeContainerListener( this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString OTableContainer::getTableTypeRestriction() const
+{
+ // no restriction at all (other than the ones provided externally)
+ return ::rtl::OUString();
+}
+
+// -----------------------------------------------------------------------------
+// XServiceInfo
+//------------------------------------------------------------------------------
+IMPLEMENT_SERVICE_INFO2(OTableContainer, "com.sun.star.sdb.dbaccess.OTableContainer", SERVICE_SDBCX_CONTAINER, SERVICE_SDBCX_TABLES)
+
+// -----------------------------------------------------------------------------
+namespace
+{
+void lcl_createDefintionObject(const ::rtl::OUString& _rName
+ ,const Reference< XNameContainer >& _xTableDefinitions
+ ,Reference<XPropertySet>& _xTableDefinition
+ ,Reference<XNameAccess>& _xColumnDefinitions
+ ,sal_Bool _bModified)
+{
+ if ( _xTableDefinitions.is() )
+ {
+ if ( _xTableDefinitions->hasByName(_rName) )
+ _xTableDefinition.set(_xTableDefinitions->getByName(_rName),UNO_QUERY);
+ else
+ {
+ Sequence< Any > aArguments(1);
+ PropertyValue aValue;
+ // set as folder
+ aValue.Name = PROPERTY_NAME;
+ aValue.Value <<= _rName;
+ aArguments[0] <<= aValue;
+ _xTableDefinition.set(::comphelper::getProcessServiceFactory()->createInstanceWithArguments(SERVICE_SDB_TABLEDEFINITION,aArguments),UNO_QUERY);
+ _xTableDefinitions->insertByName(_rName,makeAny(_xTableDefinition));
+ ::dbaccess::notifyDataSourceModified(_xTableDefinitions,_bModified);
+ }
+ Reference<XColumnsSupplier> xColumnsSupplier(_xTableDefinition,UNO_QUERY);
+ if ( xColumnsSupplier.is() )
+ _xColumnDefinitions = xColumnsSupplier->getColumns();
+ }
+}
+// -------------------------------------------------------------------------
+}
+// -------------------------------------------------------------------------
+connectivity::sdbcx::ObjectType OTableContainer::createObject(const ::rtl::OUString& _rName)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::createObject" );
+ Reference<XColumnsSupplier > xSup;
+ if(m_xMasterContainer.is() && m_xMasterContainer->hasByName(_rName))
+ xSup.set(m_xMasterContainer->getByName(_rName),UNO_QUERY);
+
+ connectivity::sdbcx::ObjectType xRet;
+ if ( m_xMetaData.is() )
+ {
+ Reference<XPropertySet> xTableDefinition;
+ Reference<XNameAccess> xColumnDefinitions;
+ lcl_createDefintionObject(_rName,m_xTableDefinitions,xTableDefinition,xColumnDefinitions,sal_False);
+
+ if ( xSup.is() )
+ {
+ ODBTableDecorator* pTable = new ODBTableDecorator( m_xConnection, xSup, ::dbtools::getNumberFormats( m_xConnection ) ,xColumnDefinitions);
+ xRet = pTable;
+ pTable->construct();
+ }
+ else
+ {
+ ::rtl::OUString sCatalog,sSchema,sTable;
+ ::dbtools::qualifiedNameComponents(m_xMetaData,
+ _rName,
+ sCatalog,
+ sSchema,
+ sTable,
+ ::dbtools::eInDataManipulation);
+ Any aCatalog;
+ if(sCatalog.getLength())
+ aCatalog <<= sCatalog;
+ ::rtl::OUString sType,sDescription;
+ Sequence< ::rtl::OUString> aTypeFilter;
+ getAllTableTypeFilter( aTypeFilter );
+
+ Reference< XResultSet > xRes = m_xMetaData.is() ? m_xMetaData->getTables(aCatalog,sSchema,sTable,aTypeFilter) : Reference< XResultSet >();
+ if(xRes.is() && xRes->next())
+ {
+ Reference< XRow > xRow(xRes,UNO_QUERY);
+ if(xRow.is())
+ {
+ sType = xRow->getString(4);
+ sDescription = xRow->getString(5);
+ }
+ }
+ ::comphelper::disposeComponent(xRes);
+ ODBTable* pTable = new ODBTable(this
+ ,m_xConnection
+ ,sCatalog
+ ,sSchema
+ ,sTable
+ ,sType
+ ,sDescription
+ ,xColumnDefinitions);
+ xRet = pTable;
+ pTable->construct();
+ }
+ Reference<XPropertySet> xDest(xRet,UNO_QUERY);
+ if ( xTableDefinition.is() )
+ ::comphelper::copyProperties(xTableDefinition,xDest);
+
+ if ( !m_pTableMediator.is() )
+ m_pTableMediator = new OContainerMediator(
+ this, m_xTableDefinitions.get(), m_xConnection, OContainerMediator::eTables );
+ if ( m_pTableMediator.is() )
+ m_pTableMediator->notifyElementCreated(_rName,xDest);
+ }
+
+ return xRet;
+}
+// -----------------------------------------------------------------------------
+Reference< XPropertySet > OTableContainer::createDescriptor()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::createDescriptor" );
+ Reference< XPropertySet > xRet;
+
+ // frist we have to look if the master tables does support this
+ // and if then create a table object as well with the master tables
+ Reference<XColumnsSupplier > xMasterColumnsSup;
+ Reference<XDataDescriptorFactory> xDataFactory(m_xMasterContainer,UNO_QUERY);
+ if ( xDataFactory.is() && m_xMetaData.is() )
+ {
+ xMasterColumnsSup = Reference< XColumnsSupplier >( xDataFactory->createDataDescriptor(), UNO_QUERY );
+ ODBTableDecorator* pTable = new ODBTableDecorator( m_xConnection, xMasterColumnsSup, ::dbtools::getNumberFormats( m_xConnection ) ,NULL);
+ xRet = pTable;
+ pTable->construct();
+ }
+ else
+ {
+ ODBTable* pTable = new ODBTable(this, m_xConnection);
+ xRet = pTable;
+ pTable->construct();
+ }
+ return xRet;
+}
+// -----------------------------------------------------------------------------
+// XAppend
+ObjectType OTableContainer::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::appendObject" );
+ // append the new table with a create stmt
+ ::rtl::OUString aName = getString(descriptor->getPropertyValue(PROPERTY_NAME));
+ if(m_xMasterContainer.is() && m_xMasterContainer->hasByName(aName))
+ {
+ String sMessage(DBACORE_RESSTRING(RID_STR_TABLE_IS_FILTERED));
+ sMessage.SearchAndReplaceAscii("$name$", aName);
+ throw SQLException(sMessage,static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)),SQLSTATE_GENERAL,1000,Any());
+ }
+
+ Reference< XConnection > xConnection( m_xConnection.get(), UNO_QUERY );
+ PContainerApprove pApprove( new ObjectNameApproval( xConnection, ObjectNameApproval::TypeTable ) );
+ pApprove->approveElement( aName, descriptor );
+
+ try
+ {
+ EnsureReset aReset(m_nInAppend);
+ Reference<XAppend> xAppend(m_xMasterContainer,UNO_QUERY);
+ if(xAppend.is())
+ {
+ xAppend->appendByDescriptor(descriptor);
+ }
+ else
+ {
+ ::rtl::OUString aSql = ::dbtools::createSqlCreateTableStatement(descriptor,m_xConnection);
+
+ Reference<XConnection> xCon = m_xConnection;
+ OSL_ENSURE(xCon.is(),"Connection is null!");
+ if ( xCon.is() )
+ {
+ Reference< XStatement > xStmt = xCon->createStatement( );
+ if ( xStmt.is() )
+ xStmt->execute(aSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ throw;
+ }
+
+ Reference<XPropertySet> xTableDefinition;
+ Reference<XNameAccess> xColumnDefinitions;
+ lcl_createDefintionObject(getNameForObject(descriptor),m_xTableDefinitions,xTableDefinition,xColumnDefinitions,sal_False);
+ Reference<XColumnsSupplier> xSup(descriptor,UNO_QUERY);
+ Reference<XDataDescriptorFactory> xFac(xColumnDefinitions,UNO_QUERY);
+ Reference<XAppend> xAppend(xColumnDefinitions,UNO_QUERY);
+ sal_Bool bModified = sal_False;
+ if ( xSup.is() && xColumnDefinitions.is() && xFac.is() && xAppend.is() )
+ {
+ Reference<XNameAccess> xNames = xSup->getColumns();
+ if ( xNames.is() )
+ {
+ Reference<XPropertySet> xProp = xFac->createDataDescriptor();
+ Sequence< ::rtl::OUString> aSeq = xNames->getElementNames();
+ const ::rtl::OUString* pIter = aSeq.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( !xColumnDefinitions->hasByName(*pIter) )
+ {
+ Reference<XPropertySet> xColumn(xNames->getByName(*pIter),UNO_QUERY);
+ if ( !OColumnSettings::hasDefaultSettings( xColumn ) )
+ {
+ ::comphelper::copyProperties( xColumn, xProp );
+ xAppend->appendByDescriptor( xProp );
+ bModified = sal_True;
+ }
+ }
+ }
+ }
+ }
+ const static ::rtl::OUString s_pTableProps[] = { ::rtl::OUString(PROPERTY_FILTER), ::rtl::OUString(PROPERTY_ORDER)
+ , ::rtl::OUString(PROPERTY_APPLYFILTER), ::rtl::OUString(PROPERTY_FONT)
+ , ::rtl::OUString(PROPERTY_ROW_HEIGHT), ::rtl::OUString(PROPERTY_TEXTCOLOR)
+ , ::rtl::OUString(PROPERTY_TEXTLINECOLOR), ::rtl::OUString(PROPERTY_TEXTEMPHASIS)
+ , ::rtl::OUString(PROPERTY_TEXTRELIEF) };
+ Sequence< ::rtl::OUString> aNames(s_pTableProps,sizeof(s_pTableProps)/sizeof(s_pTableProps[0]));
+ if ( bModified || !lcl_isPropertySetDefaulted(aNames,xTableDefinition) )
+ ::dbaccess::notifyDataSourceModified(m_xTableDefinitions,sal_True);
+
+ return createObject( _rForName );
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OTableContainer::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::dropObject" );
+ m_bInDrop = sal_True;
+ try
+ {
+ Reference< XDrop > xDrop(m_xMasterContainer,UNO_QUERY);
+ if(xDrop.is())
+ xDrop->dropByName(_sElementName);
+ else
+ {
+ ::rtl::OUString sCatalog,sSchema,sTable,sComposedName;
+
+ sal_Bool bIsView = sal_False;
+ Reference<XPropertySet> xTable(getObject(_nPos),UNO_QUERY);
+ if ( xTable.is() && m_xMetaData.is() )
+ {
+ if( m_xMetaData.is() && m_xMetaData->supportsCatalogsInTableDefinitions() )
+ xTable->getPropertyValue(PROPERTY_CATALOGNAME) >>= sCatalog;
+ if( m_xMetaData.is() && m_xMetaData->supportsSchemasInTableDefinitions() )
+ xTable->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema;
+ xTable->getPropertyValue(PROPERTY_NAME) >>= sTable;
+
+ sComposedName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions );
+
+ ::rtl::OUString sType;
+ xTable->getPropertyValue(PROPERTY_TYPE) >>= sType;
+ bIsView = sType.equalsIgnoreAsciiCase(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")));
+ }
+
+ if(!sComposedName.getLength())
+ ::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
+
+ ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP ");
+
+ // #104282# OJ
+ if ( bIsView ) // here we have a view
+ aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW "));
+ else
+ aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TABLE "));
+ aSql += sComposedName;
+ Reference<XConnection> xCon = m_xConnection;
+ OSL_ENSURE(xCon.is(),"Connection is null!");
+ if ( xCon.is() )
+ {
+ Reference< XStatement > xStmt = xCon->createStatement( );
+ if(xStmt.is())
+ xStmt->execute(aSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+
+ if ( m_xTableDefinitions.is() && m_xTableDefinitions->hasByName(_sElementName) )
+ {
+ m_xTableDefinitions->removeByName(_sElementName);
+ }
+ }
+ catch(Exception&)
+ {
+ m_bInDrop = sal_False;
+ throw;
+ }
+ m_bInDrop = sal_False;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableContainer::elementInserted( const ContainerEvent& Event ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::elementInserted" );
+ ::osl::MutexGuard aGuard(m_rMutex);
+ ::rtl::OUString sName;
+ Event.Accessor >>= sName;
+ if ( !m_nInAppend && !hasByName(sName) )
+ {
+ if(!m_xMasterContainer.is() || m_xMasterContainer->hasByName(sName))
+ {
+ ObjectType xName = createObject(sName);
+ insertElement(sName,xName);
+ // and notify our listeners
+ ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(sName), makeAny(xName), Any());
+ m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableContainer::elementRemoved( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::elementRemoved" );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableContainer::elementReplaced( const ContainerEvent& Event ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::elementReplaced" );
+ // create a new config entry
+ {
+ ::rtl::OUString sOldComposedName,sNewComposedName;
+ Event.ReplacedElement >>= sOldComposedName;
+ Event.Accessor >>= sNewComposedName;
+
+ renameObject(sOldComposedName,sNewComposedName);
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableContainer::disposing()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::disposing" );
+ OFilteredContainer::disposing();
+ // say our listeners goobye
+ m_xTableDefinitions = NULL;
+ m_pTableMediator = NULL;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "api", "Ocke.Janssen@sun.com", "OTableContainer::disposing" );
+}
+
+// -----------------------------------------------------------------------------
+void OTableContainer::addMasterContainerListener()
+{
+ try
+ {
+ Reference< XContainer > xCont( m_xMasterContainer, UNO_QUERY_THROW );
+ xCont->addContainerListener( this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
diff --git a/dbaccess/source/core/api/viewcontainer.cxx b/dbaccess/source/core/api/viewcontainer.cxx
new file mode 100644
index 000000000000..0fc2542bfa4a
--- /dev/null
+++ b/dbaccess/source/core/api/viewcontainer.cxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "viewcontainer.hxx"
+#include "dbastrings.hrc"
+#include "core_resource.hxx"
+#include "core_resource.hrc"
+#include "View.hxx"
+
+#include <tools/debug.hxx>
+#include <tools/wldcrd.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <comphelper/extract.hxx>
+#include <connectivity/dbexception.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+
+using namespace dbaccess;
+using namespace dbtools;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+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::util;
+using namespace ::com::sun::star::container;
+using namespace ::osl;
+using namespace ::comphelper;
+using namespace ::cppu;
+using namespace ::connectivity::sdbcx;
+
+//==========================================================================
+//= OViewContainer
+//==========================================================================
+DBG_NAME(OViewContainer)
+//------------------------------------------------------------------------------
+OViewContainer::OViewContainer(::cppu::OWeakObject& _rParent
+ ,::osl::Mutex& _rMutex
+ ,const Reference< XConnection >& _xCon
+ ,sal_Bool _bCase
+ ,IRefreshListener* _pRefreshListener
+ ,::dbtools::IWarningsContainer* _pWarningsContainer
+ ,oslInterlockedCount& _nInAppend)
+ :OFilteredContainer(_rParent,_rMutex,_xCon,_bCase,_pRefreshListener,_pWarningsContainer,_nInAppend)
+ ,m_bInElementRemoved(false)
+{
+ DBG_CTOR(OViewContainer, NULL);
+}
+
+//------------------------------------------------------------------------------
+OViewContainer::~OViewContainer()
+{
+ // dispose();
+ DBG_DTOR(OViewContainer, NULL);
+}
+//------------------------------------------------------------------------------
+// XServiceInfo
+//------------------------------------------------------------------------------
+IMPLEMENT_SERVICE_INFO2(OViewContainer, "com.sun.star.sdb.dbaccess.OViewContainer", SERVICE_SDBCX_CONTAINER, SERVICE_SDBCX_TABLES)
+// -----------------------------------------------------------------------------
+ObjectType OViewContainer::createObject(const ::rtl::OUString& _rName)
+{
+ ObjectType xProp;
+ if ( m_xMasterContainer.is() && m_xMasterContainer->hasByName(_rName) )
+ xProp.set(m_xMasterContainer->getByName(_rName),UNO_QUERY);
+
+ if ( !xProp.is() )
+ {
+ ::rtl::OUString sCatalog,sSchema,sTable;
+ ::dbtools::qualifiedNameComponents(m_xMetaData,
+ _rName,
+ sCatalog,
+ sSchema,
+ sTable,
+ ::dbtools::eInDataManipulation);
+ return new View(m_xConnection,
+ isCaseSensitive(),
+ sCatalog,
+ sSchema,
+ sTable
+ );
+ }
+
+ return xProp;
+}
+// -----------------------------------------------------------------------------
+Reference< XPropertySet > OViewContainer::createDescriptor()
+{
+ Reference< XPropertySet > xRet;
+ // frist we have to look if the master tables does support this
+ // and if then create a table object as well with the master tables
+ Reference<XColumnsSupplier > xMasterColumnsSup;
+ Reference<XDataDescriptorFactory> xDataFactory(m_xMasterContainer,UNO_QUERY);
+ if(xDataFactory.is())
+ xRet = xDataFactory->createDataDescriptor();
+ else
+ xRet = new ::connectivity::sdbcx::OView(isCaseSensitive(),m_xMetaData);
+
+ return xRet;
+}
+// -----------------------------------------------------------------------------
+// XAppend
+ObjectType OViewContainer::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ // append the new table with a create stmt
+ ::rtl::OUString aName = getString(descriptor->getPropertyValue(PROPERTY_NAME));
+
+ Reference<XAppend> xAppend(m_xMasterContainer,UNO_QUERY);
+ Reference< XPropertySet > xProp = descriptor;
+ if(xAppend.is())
+ {
+ EnsureReset aReset(m_nInAppend);
+
+ xAppend->appendByDescriptor(descriptor);
+ if(m_xMasterContainer->hasByName(aName))
+ xProp.set(m_xMasterContainer->getByName(aName),UNO_QUERY);
+ }
+ else
+ {
+ ::rtl::OUString sComposedName = ::dbtools::composeTableName( m_xMetaData, descriptor, ::dbtools::eInTableDefinitions, false, false, true );
+ if(!sComposedName.getLength())
+ ::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
+
+ ::rtl::OUString sCommand;
+ descriptor->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
+
+ ::rtl::OUStringBuffer aSQL;
+ aSQL.appendAscii( "CREATE VIEW " );
+ aSQL.append ( sComposedName );
+ aSQL.appendAscii( " AS " );
+ aSQL.append ( sCommand );
+
+ Reference<XConnection> xCon = m_xConnection;
+ OSL_ENSURE(xCon.is(),"Connection is null!");
+ if ( xCon.is() )
+ {
+ ::utl::SharedUNOComponent< XStatement > xStmt( xCon->createStatement() );
+ if ( xStmt.is() )
+ xStmt->execute( aSQL.makeStringAndClear() );
+ }
+ }
+
+ return createObject( _rForName );
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OViewContainer::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
+{
+ if ( !m_bInElementRemoved )
+ {
+ Reference< XDrop > xDrop(m_xMasterContainer,UNO_QUERY);
+ if(xDrop.is())
+ xDrop->dropByName(_sElementName);
+ else
+ {
+ ::rtl::OUString sCatalog,sSchema,sTable,sComposedName;
+
+ Reference<XPropertySet> xTable(getObject(_nPos),UNO_QUERY);
+ if ( xTable.is() )
+ {
+ xTable->getPropertyValue(PROPERTY_CATALOGNAME) >>= sCatalog;
+ xTable->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema;
+ xTable->getPropertyValue(PROPERTY_NAME) >>= sTable;
+
+ sComposedName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions );
+ }
+
+ if(!sComposedName.getLength())
+ ::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
+
+ ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP VIEW ");
+ aSql += sComposedName;
+ Reference<XConnection> xCon = m_xConnection;
+ OSL_ENSURE(xCon.is(),"Connection is null!");
+ if ( xCon.is() )
+ {
+ Reference< XStatement > xStmt = xCon->createStatement( );
+ if(xStmt.is())
+ xStmt->execute(aSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OViewContainer::elementInserted( const ContainerEvent& Event ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_rMutex);
+ ::rtl::OUString sName;
+ if ( ( Event.Accessor >>= sName )
+ && ( !m_nInAppend )
+ && ( !hasByName( sName ) )
+ )
+ {
+ Reference<XPropertySet> xProp(Event.Element,UNO_QUERY);
+ ::rtl::OUString sType;
+ xProp->getPropertyValue(PROPERTY_TYPE) >>= sType;
+ if ( sType == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")) )
+ insertElement(sName,createObject(sName));
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OViewContainer::elementRemoved( const ContainerEvent& Event ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_rMutex);
+ ::rtl::OUString sName;
+ if ( (Event.Accessor >>= sName) && hasByName(sName) )
+ {
+ m_bInElementRemoved = true;
+ try
+ {
+ dropByName(sName);
+ }
+ catch(Exception&)
+ {
+ m_bInElementRemoved = sal_False;
+ throw;
+ }
+ m_bInElementRemoved = false;
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OViewContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (RuntimeException)
+{
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OViewContainer::elementReplaced( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
+{
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OViewContainer::getTableTypeRestriction() const
+{
+ // no restriction at all (other than the ones provided externally)
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VIEW" ) );
+}