summaryrefslogtreecommitdiff
path: root/connectivity/source/commontools
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/commontools')
-rw-r--r--connectivity/source/commontools/AutoRetrievingBase.cxx71
-rw-r--r--connectivity/source/commontools/BlobHelper.cxx69
-rw-r--r--connectivity/source/commontools/CommonTools.cxx369
-rw-r--r--connectivity/source/commontools/ConnectionWrapper.cxx267
-rw-r--r--connectivity/source/commontools/DateConversion.cxx520
-rwxr-xr-xconnectivity/source/commontools/DriversConfig.cxx262
-rw-r--r--connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx913
-rw-r--r--connectivity/source/commontools/FDatabaseMetaDataResultSetMetaData.cxx692
-rw-r--r--connectivity/source/commontools/FValue.cxx2333
-rw-r--r--connectivity/source/commontools/ParamterSubstitution.cxx132
-rw-r--r--connectivity/source/commontools/RowFunctionParser.cxx499
-rw-r--r--connectivity/source/commontools/TColumnsHelper.cxx225
-rw-r--r--connectivity/source/commontools/TConnection.cxx106
-rw-r--r--connectivity/source/commontools/TDatabaseMetaDataBase.cxx333
-rw-r--r--connectivity/source/commontools/TIndex.cxx110
-rw-r--r--connectivity/source/commontools/TIndexColumns.cxx127
-rw-r--r--connectivity/source/commontools/TIndexes.cxx262
-rw-r--r--connectivity/source/commontools/TKey.cxx119
-rw-r--r--connectivity/source/commontools/TKeyColumns.cxx145
-rw-r--r--connectivity/source/commontools/TKeys.cxx320
-rw-r--r--connectivity/source/commontools/TPrivilegesResultSet.cxx155
-rw-r--r--connectivity/source/commontools/TSkipDeletedSet.cxx278
-rw-r--r--connectivity/source/commontools/TSortIndex.cxx178
-rw-r--r--connectivity/source/commontools/TTableHelper.cxx630
-rw-r--r--connectivity/source/commontools/conncleanup.cxx247
-rw-r--r--connectivity/source/commontools/dbcharset.cxx232
-rw-r--r--connectivity/source/commontools/dbconversion.cxx490
-rw-r--r--connectivity/source/commontools/dbexception.cxx564
-rw-r--r--connectivity/source/commontools/dbmetadata.cxx448
-rw-r--r--connectivity/source/commontools/dbtools.cxx2173
-rw-r--r--connectivity/source/commontools/dbtools2.cxx974
-rw-r--r--connectivity/source/commontools/filtermanager.cxx198
-rw-r--r--connectivity/source/commontools/formattedcolumnvalue.cxx345
-rw-r--r--connectivity/source/commontools/makefile.mk103
-rw-r--r--connectivity/source/commontools/parameters.cxx1120
-rw-r--r--connectivity/source/commontools/paramwrapper.cxx364
-rw-r--r--connectivity/source/commontools/predicateinput.cxx391
-rw-r--r--connectivity/source/commontools/propertyids.cxx198
-rw-r--r--connectivity/source/commontools/sqlerror.cxx363
-rw-r--r--connectivity/source/commontools/statementcomposer.cxx315
-rw-r--r--connectivity/source/commontools/warningscontainer.cxx123
41 files changed, 17763 insertions, 0 deletions
diff --git a/connectivity/source/commontools/AutoRetrievingBase.cxx b/connectivity/source/commontools/AutoRetrievingBase.cxx
new file mode 100644
index 000000000000..5f84bc5f0e93
--- /dev/null
+++ b/connectivity/source/commontools/AutoRetrievingBase.cxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "AutoRetrievingBase.hxx"
+
+namespace connectivity
+{
+ ::rtl::OUString OAutoRetrievingBase::getTransformedGeneratedStatement(const ::rtl::OUString& _sInsertStatement) const
+ {
+ ::rtl::OUString sStmt = _sInsertStatement;
+ OSL_ENSURE( m_bAutoRetrievingEnabled,"Illegal call here. isAutoRetrievingEnabled is false!");
+ sStmt = sStmt.toAsciiUpperCase();
+ ::rtl::OUString sStatement;
+ if ( sStmt.compareToAscii("INSERT",6) == 0 )
+ {
+ sStatement = m_sGeneratedValueStatement;
+ static const ::rtl::OUString sColumn(RTL_CONSTASCII_USTRINGPARAM("$column"));
+ static const ::rtl::OUString sTable(RTL_CONSTASCII_USTRINGPARAM("$table"));
+ sal_Int32 nIndex = 0;
+ nIndex = sStatement.indexOf(sColumn,nIndex);
+ if ( -1 != nIndex )
+ { // we need a column
+ }
+ nIndex = 0;
+ nIndex = sStatement.indexOf(sTable,nIndex);
+ if ( -1 != nIndex )
+ { // we need a table name
+ sal_Int32 nIntoIndex = sStmt.indexOf(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("INTO ")));
+ sStmt = sStmt.copy(nIntoIndex+5);
+ do
+ {
+ if ( sStmt.indexOf(' ') == 0 )
+ sStmt = sStmt.copy(1);
+ }
+ while (sStmt.indexOf(' ') == 0 );
+
+ nIntoIndex = 0;
+ ::rtl::OUString sTableName = sStmt.getToken(0,' ',nIntoIndex);
+ sStatement = sStatement.replaceAt(nIndex,sTable.getLength(),sTableName);
+ }
+ }
+ return sStatement;
+ }
+}
+
diff --git a/connectivity/source/commontools/BlobHelper.cxx b/connectivity/source/commontools/BlobHelper.cxx
new file mode 100644
index 000000000000..1b7ad15ca394
--- /dev/null
+++ b/connectivity/source/commontools/BlobHelper.cxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/BlobHelper.hxx"
+#include <comphelper/seqstream.hxx>
+#include "connectivity/dbexception.hxx"
+
+using namespace connectivity;
+using namespace dbtools;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+BlobHelper::BlobHelper(const ::com::sun::star::uno::Sequence< sal_Int8 >& _val) : m_aValue(_val)
+{
+}
+// -----------------------------------------------------------------------------
+::sal_Int64 SAL_CALL BlobHelper::length( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ return m_aValue.getLength();
+}
+// -----------------------------------------------------------------------------
+::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL BlobHelper::getBytes( ::sal_Int64 pos, ::sal_Int32 _length ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ if ( sal_Int32(pos + _length) > m_aValue.getLength() )
+ throw ::com::sun::star::sdbc::SQLException();
+ return ::com::sun::star::uno::Sequence< ::sal_Int8 >(m_aValue.getConstArray() + sal_Int32(pos),_length);
+}
+// -----------------------------------------------------------------------------
+::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL BlobHelper::getBinaryStream( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ return new ::comphelper::SequenceInputStream(m_aValue);
+}
+// -----------------------------------------------------------------------------
+::sal_Int64 SAL_CALL BlobHelper::position( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& /*pattern*/, ::sal_Int64 /*start*/ ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ ::dbtools::throwFeatureNotImplementedException( "XBlob::position", *this );
+ return 0;
+}
+// -----------------------------------------------------------------------------
+::sal_Int64 SAL_CALL BlobHelper::positionOfBlob( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob >& /*pattern*/, ::sal_Int64 /*start*/ ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ ::dbtools::throwFeatureNotImplementedException( "XBlob::positionOfBlob", *this );
+ return 0;
+}
diff --git a/connectivity/source/commontools/CommonTools.cxx b/connectivity/source/commontools/CommonTools.cxx
new file mode 100644
index 000000000000..b9d3e8bec1b5
--- /dev/null
+++ b/connectivity/source/commontools/CommonTools.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include <stdio.h>
+#include "connectivity/CommonTools.hxx"
+#include "connectivity/dbtools.hxx"
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <comphelper/extract.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include "TConnection.hxx"
+#include <comphelper/types.hxx>
+#include <com/sun/star/java/XJavaVM.hpp>
+#include <rtl/process.h>
+
+using namespace ::comphelper;
+inline sal_Unicode rtl_ascii_toUpperCase( sal_Unicode ch )
+{
+ return ch >= 0x0061 && ch <= 0x007a ? ch + 0x20 : ch;
+}
+
+namespace connectivity
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace dbtools;
+ namespace starjava = com::sun::star::java;
+ //------------------------------------------------------------------------------
+ const sal_Unicode CHAR_PLACE = '_';
+ const sal_Unicode CHAR_WILD = '%';
+ // -------------------------------------------------------------------------
+ sal_Bool match(const sal_Unicode* pWild, const sal_Unicode* pStr, const sal_Unicode cEscape)
+ {
+ int pos=0;
+ int flag=0;
+
+ while ( *pWild || flag )
+ {
+ switch (*pWild)
+ {
+ case CHAR_PLACE:
+ if ( *pStr == 0 )
+ return sal_False;
+ break;
+ default:
+ if (*pWild && (*pWild == cEscape) && ((*(pWild+1)== CHAR_PLACE) || (*(pWild+1) == CHAR_WILD)) )
+ pWild++;
+ if ( rtl_ascii_toUpperCase(*pWild) != rtl_ascii_toUpperCase(*pStr) )
+ if ( !pos )
+ return sal_False;
+ else
+ pWild += pos;
+ else
+ break; // ACHTUNG laeuft unter bestimmten
+ // Umstaenden in den nachsten case rein!!
+ case CHAR_WILD:
+ while ( *pWild == CHAR_WILD )
+ pWild++;
+ if ( *pWild == 0 )
+ return sal_True;
+ flag = 1;
+ pos = 0;
+ if ( *pStr == 0 )
+ return ( *pWild == 0 );
+ while ( *pStr && *pStr != *pWild )
+ {
+ if ( *pWild == CHAR_PLACE ) {
+ pWild++;
+ while ( *pWild == CHAR_WILD )
+ pWild++;
+ }
+ pStr++;
+ if ( *pStr == 0 )
+ return ( *pWild == 0 );
+ }
+ break;
+ }
+ if ( *pWild != 0 )
+ pWild++;
+ if ( *pStr != 0 )
+ pStr++;
+ else
+ flag = 0;
+ if ( flag )
+ pos--;
+ }
+ return ( *pStr == 0 ) && ( *pWild == 0 );
+ }
+ //------------------------------------------------------------------
+ rtl::OUString toDateString(const ::com::sun::star::util::Date& rDate)
+ {
+ sal_Char s[11];
+ snprintf(s,
+ sizeof(s),
+ "%04d-%02d-%02d",
+ (int)rDate.Year,
+ (int)rDate.Month,
+ (int)rDate.Day);
+ s[10] = 0;
+ return rtl::OUString::createFromAscii(s);
+ }
+
+ //------------------------------------------------------------------
+ rtl::OUString toTimeString(const ::com::sun::star::util::Time& rTime)
+ {
+ sal_Char s[9];
+ snprintf(s,
+ sizeof(s),
+ "%02d:%02d:%02d",
+ (int)rTime.Hours,
+ (int)rTime.Minutes,
+ (int)rTime.Seconds);
+ s[8] = 0;
+ return rtl::OUString::createFromAscii(s);
+ }
+
+ //------------------------------------------------------------------
+ rtl::OUString toDateTimeString(const ::com::sun::star::util::DateTime& rDateTime)
+ {
+ sal_Char s[21];
+ snprintf(s,
+ sizeof(s),
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (int)rDateTime.Year,
+ (int)rDateTime.Month,
+ (int)rDateTime.Day,
+ (int)rDateTime.Hours,
+ (int)rDateTime.Minutes,
+ (int)rDateTime.Seconds);
+ s[20] = 0;
+ return rtl::OUString::createFromAscii(s);
+ }
+
+
+ //--------------------------------------------------------------------------------------------------
+ rtl::OUString toString(const Any& rValue)
+ {
+ rtl::OUString aRes;
+ TypeClass aDestinationClass = rValue.getValueType().getTypeClass();
+
+ switch (aDestinationClass)
+ {
+ case TypeClass_CHAR:
+ aRes = ::rtl::OUString::valueOf(*(sal_Unicode*)rValue.getValue());
+ break;
+ case TypeClass_FLOAT:
+ aRes = ::rtl::OUString::valueOf(*(float*)rValue.getValue());
+ break;
+ case TypeClass_DOUBLE:
+ aRes = ::rtl::OUString::valueOf(*(double*)rValue.getValue());
+ break;
+ case TypeClass_BOOLEAN:
+ aRes = ::rtl::OUString::valueOf((sal_Int32)*(sal_Bool*)rValue.getValue());
+ break;
+ case TypeClass_BYTE:
+ case TypeClass_SHORT:
+ case TypeClass_LONG:
+ aRes = ::rtl::OUString::valueOf(*(sal_Int32*)rValue.getValue());
+ break;
+ case TypeClass_HYPER:
+ {
+ sal_Int64 nValue = 0;
+ OSL_VERIFY( rValue >>= nValue );
+ aRes = ::rtl::OUString::valueOf(nValue);
+ }
+ case TypeClass_STRING:
+ rValue >>= aRes;
+ break;
+ case TypeClass_STRUCT:
+ if (rValue.getValueType() == ::getCppuType((const ::com::sun::star::util::Date*)0))
+ {
+ ::com::sun::star::util::Date aDate;
+ rValue >>= aDate;
+ aRes = toDateString(aDate);
+ }
+ else if (rValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0))
+ {
+ ::com::sun::star::util::DateTime aDT;
+ rValue >>= aDT;
+ aRes = toDateTimeString(aDT);
+ }
+ else if (rValue.getValueType() == ::getCppuType((const ::com::sun::star::util::Time*)0))
+ {
+ ::com::sun::star::util::Time aTime;
+ rValue >>= aTime;
+ aRes = toTimeString(aTime);
+ }
+
+ break;
+ default:
+ ;
+ }
+ return aRes;
+ }
+
+ // -----------------------------------------------------------------------------
+ ::rtl::Reference< jvmaccess::VirtualMachine > getJavaVM(const Reference<XMultiServiceFactory >& _rxFactory)
+ {
+ ::rtl::Reference< jvmaccess::VirtualMachine > aRet;
+ OSL_ENSURE(_rxFactory.is(),"No XMultiServiceFactory a.v.!");
+ if(!_rxFactory.is())
+ return aRet;
+
+ try
+ {
+ Reference< starjava::XJavaVM > xVM(_rxFactory->createInstance(
+ rtl::OUString::createFromAscii("com.sun.star.java.JavaVirtualMachine")), UNO_QUERY);
+
+ OSL_ENSURE(_rxFactory.is(),"InitJava: I have no factory!");
+ if (!xVM.is() || !_rxFactory.is())
+ throw Exception(); // -2;
+
+ Sequence<sal_Int8> processID(16);
+ rtl_getGlobalProcessId( (sal_uInt8*) processID.getArray() );
+ processID.realloc(17);
+ processID[16] = 0;
+
+ Any uaJVM = xVM->getJavaVM( processID );
+
+ if (!uaJVM.hasValue())
+ throw Exception(); // -5
+ else
+ {
+ sal_Int32 nValue = 0;
+ jvmaccess::VirtualMachine* pJVM = NULL;
+ if ( uaJVM >>= nValue )
+ pJVM = reinterpret_cast< jvmaccess::VirtualMachine* > (nValue);
+ else
+ {
+ sal_Int64 nTemp = 0;
+ uaJVM >>= nTemp;
+ pJVM = reinterpret_cast< jvmaccess::VirtualMachine* > (nTemp);
+ }
+ aRet = pJVM;
+ }
+ }
+ catch (Exception&)
+ {
+ }
+
+ return aRet;
+ }
+ //------------------------------------------------------------------------------
+ sal_Bool existsJavaClassByName( const ::rtl::Reference< jvmaccess::VirtualMachine >& _pJVM,const ::rtl::OUString& _sClassName )
+ {
+ sal_Bool bRet = sal_False;
+#ifdef SOLAR_JAVA
+ if ( _pJVM.is() )
+ {
+ jvmaccess::VirtualMachine::AttachGuard aGuard(_pJVM);
+ JNIEnv* pEnv = aGuard.getEnvironment();
+ if( pEnv )
+ {
+ ::rtl::OString sClassName = ::rtl::OUStringToOString(_sClassName, RTL_TEXTENCODING_ASCII_US);
+ sClassName = sClassName.replace('.','/');
+ jobject out = pEnv->FindClass(sClassName);
+ bRet = out != NULL;
+ pEnv->DeleteLocalRef( out );
+ }
+ }
+#endif
+ return bRet;
+ }
+
+}
+
+#include <ctype.h> //isdigit
+namespace dbtools
+{
+//------------------------------------------------------------------
+sal_Bool isCharOk(sal_Unicode c,const ::rtl::OUString& _rSpecials)
+{
+
+ return ( ((c >= 97) && (c <= 122)) || ((c >= 65) && (c <= 90)) || ((c >= 48) && (c <= 57)) ||
+ c == '_' || _rSpecials.indexOf(c) != -1);
+}
+
+//------------------------------------------------------------------------------
+sal_Bool isValidSQLName(const ::rtl::OUString& rName,const ::rtl::OUString& _rSpecials)
+{
+ // Ueberpruefung auf korrekte Namensgebung im SQL Sinne
+ // Dieses ist wichtig fuer Tabellennamen beispielsweise
+ const sal_Unicode* pStr = rName.getStr();
+ if (*pStr > 127 || isdigit(*pStr))
+ return sal_False;
+
+ for (; *pStr; ++pStr )
+ if(!isCharOk(*pStr,_rSpecials))
+ return sal_False;
+
+ if ( rName.getLength()
+ && ( (rName.toChar() == '_')
+ || ( (rName.toChar() >= '0')
+ && (rName.toChar() <= '9')
+ )
+ )
+ )
+ return sal_False;
+ // the SQL-Standard requires the first character to be an alphabetic character, which
+ // isn't easy to decide in UniCode ...
+ // So we just prohibit the characters which already lead to problems ....
+ // 11.04.00 - 74902 - FS
+
+ return sal_True;
+}
+//------------------------------------------------------------------
+// Erzeugt einen neuen Namen falls noetig
+::rtl::OUString convertName2SQLName(const ::rtl::OUString& rName,const ::rtl::OUString& _rSpecials)
+{
+ if(isValidSQLName(rName,_rSpecials))
+ return rName;
+ ::rtl::OUString aNewName(rName);
+ const sal_Unicode* pStr = rName.getStr();
+ sal_Int32 nLength = rName.getLength();
+ sal_Bool bValid(*pStr < 128 && !isdigit(*pStr));
+ for (sal_Int32 i=0; bValid && i < nLength; ++pStr,++i )
+ if(!isCharOk(*pStr,_rSpecials))
+ {
+ aNewName = aNewName.replace(*pStr,'_');
+ pStr = aNewName.getStr() + i;
+ }
+
+ if ( !bValid )
+ aNewName = ::rtl::OUString();
+
+ return aNewName;
+}
+//------------------------------------------------------------------------------
+::rtl::OUString quoteName(const ::rtl::OUString& _rQuote, const ::rtl::OUString& _rName)
+{
+ ::rtl::OUString sName = _rName;
+ if(_rQuote.getLength() && _rQuote.toChar() != ' ')
+ sName = _rQuote + _rName + _rQuote;
+ return sName;
+}
+
+
+}
diff --git a/connectivity/source/commontools/ConnectionWrapper.cxx b/connectivity/source/commontools/ConnectionWrapper.cxx
new file mode 100644
index 000000000000..61d3b06cb25d
--- /dev/null
+++ b/connectivity/source/commontools/ConnectionWrapper.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#ifndef _CONNECTIVITY_CONNECTIONWRAPPER_HXX_
+#include "connectivity/ConnectionWrapper.hxx"
+#endif
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <comphelper/uno3.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <com/sun/star/reflection/XProxyFactory.hpp>
+#include <rtl/digest.h>
+#include <algorithm>
+
+#include <algorithm>
+
+using namespace connectivity;
+//------------------------------------------------------------------------------
+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::reflection;
+// --------------------------------------------------------------------------------
+OConnectionWrapper::OConnectionWrapper()
+{
+
+}
+// -----------------------------------------------------------------------------
+void OConnectionWrapper::setDelegation(Reference< XAggregation >& _rxProxyConnection,oslInterlockedCount& _rRefCount)
+{
+ OSL_ENSURE(_rxProxyConnection.is(),"OConnectionWrapper: Connection must be valid!");
+ osl_incrementInterlockedCount( &_rRefCount );
+ if (_rxProxyConnection.is())
+ {
+ // transfer the (one and only) real ref to the aggregate to our member
+ m_xProxyConnection = _rxProxyConnection;
+ _rxProxyConnection = NULL;
+ ::comphelper::query_aggregation(m_xProxyConnection,m_xConnection);
+ m_xTypeProvider.set(m_xConnection,UNO_QUERY);
+ m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
+ m_xServiceInfo.set(m_xConnection,UNO_QUERY);
+
+ // set ourself as delegator
+ Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
+ m_xProxyConnection->setDelegator( xIf );
+
+ }
+ osl_decrementInterlockedCount( &_rRefCount );
+}
+// -----------------------------------------------------------------------------
+void OConnectionWrapper::setDelegation(const Reference< XConnection >& _xConnection
+ ,const Reference< XMultiServiceFactory>& _xORB
+ ,oslInterlockedCount& _rRefCount)
+{
+ OSL_ENSURE(_xConnection.is(),"OConnectionWrapper: Connection must be valid!");
+ osl_incrementInterlockedCount( &_rRefCount );
+
+ m_xConnection = _xConnection;
+ m_xTypeProvider.set(m_xConnection,UNO_QUERY);
+ m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
+ m_xServiceInfo.set(m_xConnection,UNO_QUERY);
+
+ Reference< XProxyFactory > xProxyFactory(_xORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY);
+ Reference< XAggregation > xConProxy = xProxyFactory->createProxy(_xConnection);
+ if (xConProxy.is())
+ {
+ // transfer the (one and only) real ref to the aggregate to our member
+ m_xProxyConnection = xConProxy;
+
+ // set ourself as delegator
+ Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
+ m_xProxyConnection->setDelegator( xIf );
+
+ }
+ osl_decrementInterlockedCount( &_rRefCount );
+}
+// -----------------------------------------------------------------------------
+void OConnectionWrapper::disposing()
+{
+m_xConnection.clear();
+}
+//-----------------------------------------------------------------------------
+OConnectionWrapper::~OConnectionWrapper()
+{
+ if (m_xProxyConnection.is())
+ m_xProxyConnection->setDelegator(NULL);
+}
+
+// XServiceInfo
+// --------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OConnectionWrapper::getImplementationName( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.drivers.OConnectionWrapper" ) );
+}
+
+// --------------------------------------------------------------------------------
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OConnectionWrapper::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException)
+{
+ // first collect the services which are supported by our aggregate
+ Sequence< ::rtl::OUString > aSupported;
+ if ( m_xServiceInfo.is() )
+ aSupported = m_xServiceInfo->getSupportedServiceNames();
+
+ // append our own service, if necessary
+ ::rtl::OUString sConnectionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Connection" ) );
+ if ( 0 == ::comphelper::findValue( aSupported, sConnectionService, sal_True ).getLength() )
+ {
+ sal_Int32 nLen = aSupported.getLength();
+ aSupported.realloc( nLen + 1 );
+ aSupported[ nLen ] = sConnectionService;
+ }
+
+ // outta here
+ return aSupported;
+}
+
+// --------------------------------------------------------------------------------
+sal_Bool SAL_CALL OConnectionWrapper::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ return ::comphelper::findValue( getSupportedServiceNames(), _rServiceName, sal_True ).getLength() != 0;
+}
+
+// --------------------------------------------------------------------------------
+Any SAL_CALL OConnectionWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
+{
+ Any aReturn = OConnection_BASE::queryInterface(_rType);
+ return aReturn.hasValue() ? aReturn : (m_xProxyConnection.is() ? m_xProxyConnection->queryAggregation(_rType) : aReturn);
+}
+// --------------------------------------------------------------------------------
+Sequence< Type > SAL_CALL OConnectionWrapper::getTypes( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ OConnection_BASE::getTypes(),
+ m_xTypeProvider->getTypes()
+ );
+}
+// -----------------------------------------------------------------------------
+// com::sun::star::lang::XUnoTunnel
+sal_Int64 SAL_CALL OConnectionWrapper::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 );
+
+ if(m_xUnoTunnel.is())
+ return m_xUnoTunnel->getSomething(rId);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+Sequence< sal_Int8 > OConnectionWrapper::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();
+}
+// -----------------------------------------------------------------------------
+namespace
+{
+ class TPropertyValueLessFunctor : public ::std::binary_function< ::com::sun::star::beans::PropertyValue,::com::sun::star::beans::PropertyValue,bool>
+ {
+ public:
+ TPropertyValueLessFunctor()
+ {}
+ bool operator() (const ::com::sun::star::beans::PropertyValue& lhs, const ::com::sun::star::beans::PropertyValue& rhs) const
+ {
+ return !!(lhs.Name.equalsIgnoreAsciiCase( rhs.Name ));
+ }
+ };
+
+}
+
+// -----------------------------------------------------------------------------
+// creates a unique id out of the url and sequence of properties
+void OConnectionWrapper::createUniqueId( const ::rtl::OUString& _rURL
+ ,Sequence< PropertyValue >& _rInfo
+ ,sal_uInt8* _pBuffer
+ ,const ::rtl::OUString& _rUserName
+ ,const ::rtl::OUString& _rPassword)
+{
+ // first we create the digest we want to have
+ rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ rtlDigestError aError = rtl_digest_update(aDigest,_rURL.getStr(),_rURL.getLength()*sizeof(sal_Unicode));
+ if ( _rUserName.getLength() )
+ aError = rtl_digest_update(aDigest,_rUserName.getStr(),_rUserName.getLength()*sizeof(sal_Unicode));
+ if ( _rPassword.getLength() )
+ aError = rtl_digest_update(aDigest,_rPassword.getStr(),_rPassword.getLength()*sizeof(sal_Unicode));
+ // now we need to sort the properties
+ PropertyValue* pBegin = _rInfo.getArray();
+ PropertyValue* pEnd = pBegin + _rInfo.getLength();
+ ::std::sort(pBegin,pEnd,TPropertyValueLessFunctor());
+
+ pBegin = _rInfo.getArray();
+ pEnd = pBegin + _rInfo.getLength();
+ for (; pBegin != pEnd; ++pBegin)
+ {
+ // we only include strings an integer values
+ ::rtl::OUString sValue;
+ if ( pBegin->Value >>= sValue )
+ ;
+ else
+ {
+ sal_Int32 nValue = 0;
+ if ( pBegin->Value >>= nValue )
+ sValue = ::rtl::OUString::valueOf(nValue);
+ else
+ {
+ Sequence< ::rtl::OUString> aSeq;
+ if ( pBegin->Value >>= aSeq )
+ {
+ const ::rtl::OUString* pSBegin = aSeq.getConstArray();
+ const ::rtl::OUString* pSEnd = pSBegin + aSeq.getLength();
+ for(;pSBegin != pSEnd;++pSBegin)
+ aError = rtl_digest_update(aDigest,pSBegin->getStr(),pSBegin->getLength()*sizeof(sal_Unicode));
+ }
+ }
+ }
+ if ( sValue.getLength() > 0 )
+ {
+ // we don't have to convert this into UTF8 because we don't store on a file system
+ aError = rtl_digest_update(aDigest,sValue.getStr(),sValue.getLength()*sizeof(sal_Unicode));
+ }
+ }
+
+ aError = rtl_digest_get(aDigest,_pBuffer,RTL_DIGEST_LENGTH_SHA1);
+ // we have to destroy the digest
+ rtl_digest_destroy(aDigest);
+}
+// -----------------------------------------------------------------------------
+
+
diff --git a/connectivity/source/commontools/DateConversion.cxx b/connectivity/source/commontools/DateConversion.cxx
new file mode 100644
index 000000000000..9f5be37f208f
--- /dev/null
+++ b/connectivity/source/commontools/DateConversion.cxx
@@ -0,0 +1,520 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+
+#include "connectivity/dbconversion.hxx"
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/sdb/XColumnUpdate.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <comphelper/extract.hxx>
+#include "TConnection.hxx"
+#include "diagnose_ex.h"
+#include <comphelper/numbers.hxx>
+#include <rtl/ustrbuf.hxx>
+
+
+using namespace ::connectivity;
+using namespace ::comphelper;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::dbtools;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+// -----------------------------------------------------------------------------
+::rtl::OUString DBTypeConversion::toSQLString(sal_Int32 eType, const Any& _rVal, sal_Bool bQuote,
+ const Reference< XTypeConverter >& _rxTypeConverter)
+{
+ ::rtl::OUStringBuffer aRet;
+ if (_rVal.hasValue())
+ {
+ try
+ {
+ switch (eType)
+ {
+ case DataType::INTEGER:
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_BOOLEAN)
+ {
+ if (::cppu::any2bool(_rVal))
+ aRet.appendAscii("1");
+ else
+ aRet.appendAscii("0");
+ }
+ else
+ {
+ ::rtl::OUString sTemp;
+ _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= sTemp;
+ aRet.append(sTemp);
+ }
+ break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ if (bQuote)
+ aRet.appendAscii("'");
+ {
+ ::rtl::OUString aTemp;
+ _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= aTemp;
+ sal_Int32 nIndex = (sal_Int32)-1;
+ const ::rtl::OUString sQuot(RTL_CONSTASCII_USTRINGPARAM("\'"));
+ const ::rtl::OUString sQuotToReplace(RTL_CONSTASCII_USTRINGPARAM("\'\'"));
+ do
+ {
+ nIndex += 2;
+ nIndex = aTemp.indexOf(sQuot,nIndex);
+ if(nIndex != -1)
+ aTemp = aTemp.replaceAt(nIndex,sQuot.getLength(),sQuotToReplace);
+ } while (nIndex != -1);
+
+ aRet.append(aTemp);
+ }
+ if (bQuote)
+ aRet.appendAscii("'");
+ break;
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::BIGINT:
+ default:
+ {
+ ::rtl::OUString sTemp;
+ _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= sTemp;
+ aRet.append(sTemp);
+ }
+ break;
+ case DataType::TIMESTAMP:
+ {
+ DateTime aDateTime;
+ bool bOk = false;
+ if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_DOUBLE)
+ {
+ double nValue = 0.0;
+ _rVal >>= nValue;
+ aDateTime = DBTypeConversion::toDateTime(nValue);
+ bOk = true;
+ }
+ else if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_STRING)
+ {
+ ::rtl::OUString sValue;
+ _rVal >>= sValue;
+ aDateTime = DBTypeConversion::toDateTime(sValue);
+ bOk = true;
+ }
+ else
+ bOk = _rVal >>= aDateTime;
+
+ OSL_VERIFY_RES( bOk, "DBTypeConversion::toSQLString: _rVal is not datetime!");
+ // check if this is really a timestamp or only a date
+ if ( bOk )
+ {
+ if (bQuote)
+ aRet.appendAscii("{TS '");
+ aRet.append(DBTypeConversion::toDateTimeString(aDateTime));
+ if (bQuote)
+ aRet.appendAscii("'}");
+ break;
+ }
+ break;
+ }
+ case DataType::DATE:
+ {
+ Date aDate;
+ bool bOk = false;
+ if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_DOUBLE)
+ {
+ double nValue = 0.0;
+ _rVal >>= nValue;
+ aDate = DBTypeConversion::toDate(nValue);
+ bOk = true;
+ }
+ else if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_STRING)
+ {
+ ::rtl::OUString sValue;
+ _rVal >>= sValue;
+ aDate = DBTypeConversion::toDate(sValue);
+ bOk = true;
+ }
+ else
+ bOk = _rVal >>= aDate;
+ OSL_VERIFY_RES( bOk, "DBTypeConversion::toSQLString: _rVal is not date!");
+ if (bQuote)
+ aRet.appendAscii("{D '");
+ aRet.append(DBTypeConversion::toDateString(aDate));
+ if (bQuote)
+ aRet.appendAscii("'}");
+ } break;
+ case DataType::TIME:
+ {
+ Time aTime;
+ bool bOk = false;
+ if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_DOUBLE)
+ {
+ double nValue = 0.0;
+ _rVal >>= nValue;
+ aTime = DBTypeConversion::toTime(nValue);
+ bOk = true;
+ }
+ else if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_STRING)
+ {
+ ::rtl::OUString sValue;
+ _rVal >>= sValue;
+ aTime = DBTypeConversion::toTime(sValue);
+ bOk = true;
+ }
+ else
+ bOk = _rVal >>= aTime;
+ OSL_VERIFY_RES( bOk,"DBTypeConversion::toSQLString: _rVal is not time!");
+ if (bQuote)
+ aRet.appendAscii("{T '");
+ aRet.append(DBTypeConversion::toTimeString(aTime));
+ if (bQuote)
+ aRet.appendAscii("'}");
+ } break;
+ }
+ }
+ catch ( const Exception& )
+ {
+ OSL_ENSURE(0,"TypeConversion Error");
+ }
+ }
+ else
+ aRet.appendAscii(" NULL ");
+ return aRet.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+Date DBTypeConversion::getNULLDate(const Reference< XNumberFormatsSupplier > &xSupplier)
+{
+ OSL_ENSURE(xSupplier.is(), "getNULLDate : the formatter doesn't implement a supplier !");
+ if (xSupplier.is())
+ {
+ try
+ {
+ // get the null date
+ Date aDate;
+ xSupplier->getNumberFormatSettings()->getPropertyValue(::rtl::OUString::createFromAscii("NullDate")) >>= aDate;
+ return aDate;
+ }
+ catch ( const Exception& )
+ {
+ }
+ }
+
+ return getStandardDate();
+}
+// -----------------------------------------------------------------------------
+void DBTypeConversion::setValue(const Reference<XColumnUpdate>& xVariant,
+ const Reference<XNumberFormatter>& xFormatter,
+ const Date& rNullDate,
+ const ::rtl::OUString& rString,
+ sal_Int32 nKey,
+ sal_Int16 nFieldType,
+ sal_Int16 nKeyType) throw(::com::sun::star::lang::IllegalArgumentException)
+{
+ double fValue = 0;
+ if (rString.getLength())
+ {
+ // Muss der String formatiert werden?
+ sal_Int16 nTypeClass = nKeyType & ~NumberFormat::DEFINED;
+ sal_Bool bTextFormat = nTypeClass == NumberFormat::TEXT;
+ sal_Int32 nKeyToUse = bTextFormat ? 0 : nKey;
+ sal_Int16 nRealUsedTypeClass = nTypeClass;
+ // bei einem Text-Format muessen wir dem Formatter etwas mehr Freiheiten einraeumen, sonst
+ // wirft convertStringToNumber eine NotNumericException
+ try
+ {
+ fValue = xFormatter->convertStringToNumber(nKeyToUse, rString);
+ sal_Int32 nRealUsedKey = xFormatter->detectNumberFormat(0, rString);
+ if (nRealUsedKey != nKeyToUse)
+ nRealUsedTypeClass = getNumberFormatType(xFormatter, nRealUsedKey) & ~NumberFormat::DEFINED;
+
+ // und noch eine Sonderbehandlung, diesmal fuer Prozent-Formate
+ if ((NumberFormat::NUMBER == nRealUsedTypeClass) && (NumberFormat::PERCENT == nTypeClass))
+ { // die Formatierung soll eigentlich als Prozent erfolgen, aber der String stellt nur eine
+ // einfache Nummer dar -> anpassen
+ ::rtl::OUString sExpanded(rString);
+ static ::rtl::OUString s_sPercentSymbol = ::rtl::OUString::createFromAscii("%");
+ // need a method to add a sal_Unicode to a string, 'til then we use a static string
+ sExpanded += s_sPercentSymbol;
+ fValue = xFormatter->convertStringToNumber(nKeyToUse, sExpanded);
+ }
+
+ switch (nRealUsedTypeClass)
+ {
+ case NumberFormat::DATE:
+ case NumberFormat::DATETIME:
+ case NumberFormat::TIME:
+ DBTypeConversion::setValue(xVariant,rNullDate,fValue,nRealUsedTypeClass);
+ // xVariant->updateDouble(toStandardDbDate(rNullDate, fValue));
+ break;
+ case NumberFormat::CURRENCY:
+ case NumberFormat::NUMBER:
+ case NumberFormat::SCIENTIFIC:
+ case NumberFormat::FRACTION:
+ case NumberFormat::PERCENT:
+ xVariant->updateDouble(fValue);
+ break;
+ default:
+ xVariant->updateString(rString);
+ }
+ }
+ catch(const Exception& )
+ {
+ xVariant->updateString(rString);
+ }
+ }
+ else
+ {
+ switch (nFieldType)
+ {
+ case ::com::sun::star::sdbc::DataType::CHAR:
+ case ::com::sun::star::sdbc::DataType::VARCHAR:
+ case ::com::sun::star::sdbc::DataType::LONGVARCHAR:
+ xVariant->updateString(rString);
+ break;
+ default:
+ xVariant->updateNull();
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void DBTypeConversion::setValue(const Reference<XColumnUpdate>& xVariant,
+ const Date& rNullDate,
+ const double& rValue,
+ sal_Int16 nKeyType) throw(::com::sun::star::lang::IllegalArgumentException)
+{
+ switch (nKeyType & ~NumberFormat::DEFINED)
+ {
+ case NumberFormat::DATE:
+ xVariant->updateDate(toDate( rValue, rNullDate));
+ break;
+ case NumberFormat::DATETIME:
+ xVariant->updateTimestamp(toDateTime(rValue,rNullDate));
+ break;
+ case NumberFormat::TIME:
+ xVariant->updateTime(toTime(rValue));
+ break;
+ default:
+ {
+ double nValue = rValue;
+// Reference<XPropertySet> xProp(xVariant,UNO_QUERY);
+// if ( xProp.is()
+// && xProp->getPropertySetInfo()->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISSIGNED))
+// && !::comphelper::getBOOL(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISSIGNED))) )
+// {
+// switch (::comphelper::getINT32(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))))
+// {
+// case DataType::TINYINT:
+// nValue = static_cast<sal_uInt8>(rValue);
+// break;
+// case DataType::SMALLINT:
+// nValue = static_cast<sal_uInt16>(rValue);
+// break;
+// case DataType::INTEGER:
+// nValue = static_cast<sal_uInt32>(rValue);
+// break;
+// case DataType::BIGINT:
+// nValue = static_cast<sal_uInt64>(rValue);
+// break;
+// }
+// }
+ xVariant->updateDouble(nValue);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+double DBTypeConversion::getValue(const Reference<XColumn>& xVariant,
+ const Date& rNullDate,
+ sal_Int16 nKeyType)
+{
+ try
+ {
+ switch (nKeyType & ~NumberFormat::DEFINED)
+ {
+ case NumberFormat::DATE:
+ return toDouble( xVariant->getDate(), rNullDate);
+ case NumberFormat::DATETIME:
+ return toDouble(xVariant->getTimestamp(),rNullDate);
+ case NumberFormat::TIME:
+ return toDouble(xVariant->getTime());
+ default:
+ {
+ Reference<XPropertySet> xProp(xVariant,UNO_QUERY);
+ if ( xProp.is()
+ && xProp->getPropertySetInfo()->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISSIGNED))
+ && !::comphelper::getBOOL(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISSIGNED))) )
+ {
+ switch (::comphelper::getINT32(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))))
+ {
+ case DataType::TINYINT:
+ return static_cast<double>(static_cast<sal_uInt8>(xVariant->getByte()));
+ case DataType::SMALLINT:
+ return static_cast<double>(static_cast<sal_uInt16>(xVariant->getShort()));
+ case DataType::INTEGER:
+ return static_cast<double>(static_cast<sal_uInt32>(xVariant->getInt()));
+ case DataType::BIGINT:
+ return static_cast<double>(static_cast<sal_uInt64>(xVariant->getLong()));
+ }
+ }
+
+ return xVariant->getDouble();
+ }
+ }
+ }
+ catch(const Exception& )
+ {
+ return 0.0;
+ }
+}
+//------------------------------------------------------------------------------
+::rtl::OUString DBTypeConversion::getValue(const Reference< XPropertySet>& _xColumn,
+ const Reference<XNumberFormatter>& _xFormatter,
+ const ::com::sun::star::lang::Locale& _rLocale,
+ const Date& _rNullDate)
+{
+ OSL_ENSURE(_xColumn.is() && _xFormatter.is(), "DBTypeConversion::getValue: invalid arg !");
+ if (!_xColumn.is() || !_xFormatter.is())
+ return ::rtl::OUString();
+
+ sal_Int32 nKey(0);
+ try
+ {
+ _xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) >>= nKey;
+ }
+ catch (const Exception& )
+ {
+ OSL_ENSURE(false, "DBTypeConversion::getValue: caught an exception while asking for the format key!");
+ }
+
+ if (!nKey)
+ {
+ Reference<XNumberFormats> xFormats( _xFormatter->getNumberFormatsSupplier()->getNumberFormats() );
+ Reference<XNumberFormatTypes> xTypeList(_xFormatter->getNumberFormatsSupplier()->getNumberFormats(), UNO_QUERY);
+
+ nKey = ::dbtools::getDefaultNumberFormat(_xColumn,
+ Reference< XNumberFormatTypes > (xFormats, UNO_QUERY),
+ _rLocale);
+
+ }
+
+ sal_Int16 nKeyType = getNumberFormatType(_xFormatter, nKey) & ~NumberFormat::DEFINED;
+
+ return DBTypeConversion::getValue(Reference< XColumn > (_xColumn, UNO_QUERY), _xFormatter, _rNullDate, nKey, nKeyType);
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString DBTypeConversion::getValue(const Reference<XColumn>& xVariant,
+ const Reference<XNumberFormatter>& xFormatter,
+ const Date& rNullDate,
+ sal_Int32 nKey,
+ sal_Int16 nKeyType)
+{
+ ::rtl::OUString aString;
+ if (xVariant.is())
+ {
+ try
+ {
+ switch (nKeyType & ~NumberFormat::DEFINED)
+ {
+ case NumberFormat::DATE:
+ case NumberFormat::DATETIME:
+ {
+ // get a value which represents the given date, relative to the given null date
+ double fValue = getValue(xVariant, rNullDate, nKeyType);
+ if ( !xVariant->wasNull() )
+ {
+ // get the null date of the formatter
+ Date aFormatterNullDate( rNullDate );
+ try
+ {
+ Reference< XPropertySet > xFormatterSettings;
+ Reference< XNumberFormatsSupplier > xSupplier( xFormatter->getNumberFormatsSupplier( ) );
+ if ( xSupplier.is() )
+ xFormatterSettings = xSupplier->getNumberFormatSettings();
+ if ( xFormatterSettings.is() )
+ xFormatterSettings->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NullDate" ) ) ) >>= aFormatterNullDate;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "DBTypeConversion::getValue: caught an exception while retrieving the formatter's NullDate!" );
+ }
+ // get a value which represents the given date, relative to the null date of the formatter
+ fValue -= toDays( rNullDate, aFormatterNullDate );
+ // format this value
+ aString = xFormatter->convertNumberToString( nKey, fValue );
+ }
+ }
+ break;
+ case NumberFormat::TIME:
+ case NumberFormat::NUMBER:
+ case NumberFormat::SCIENTIFIC:
+ case NumberFormat::FRACTION:
+ case NumberFormat::PERCENT:
+ {
+ double fValue = xVariant->getDouble();
+ if (!xVariant->wasNull())
+ aString = xFormatter->convertNumberToString(nKey, fValue);
+ } break;
+ case NumberFormat::CURRENCY:
+ {
+ double fValue = xVariant->getDouble();
+ if (!xVariant->wasNull())
+ aString = xFormatter->getInputString(nKey, fValue);
+ } break;
+ case NumberFormat::TEXT:
+ aString = xFormatter->formatString(nKey, xVariant->getString());
+ break;
+ default:
+ aString = xVariant->getString();
+ }
+ }
+ catch(const Exception& )
+ {
+ aString = xVariant->getString();
+ }
+ }
+ return aString;
+}
+//------------------------------------------------------------------
diff --git a/connectivity/source/commontools/DriversConfig.cxx b/connectivity/source/commontools/DriversConfig.cxx
new file mode 100755
index 000000000000..48c2736cd05a
--- /dev/null
+++ b/connectivity/source/commontools/DriversConfig.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "connectivity/DriversConfig.hxx"
+#include <tools/wldcrd.hxx>
+
+using namespace connectivity;
+using namespace utl;
+using namespace ::com::sun::star;
+
+namespace
+{
+ void lcl_convert(const uno::Sequence< ::rtl::OUString >& _aSource,uno::Any& _rDest)
+ {
+ uno::Sequence<uno::Any> aRet(_aSource.getLength());
+ uno::Any* pAny = aRet.getArray();
+ const ::rtl::OUString* pIter = _aSource.getConstArray();
+ const ::rtl::OUString* pEnd = pIter + _aSource.getLength();
+ for (;pIter != pEnd ; ++pIter,++pAny)
+ {
+ *pAny <<= *pIter;
+ }
+ _rDest <<= aRet;
+ }
+ void lcl_fillValues(const ::utl::OConfigurationNode& _aURLPatternNode,const ::rtl::OUString& _sNode,::comphelper::NamedValueCollection& _rValues)
+ {
+ const ::utl::OConfigurationNode aPropertiesNode = _aURLPatternNode.openNode(_sNode);
+ if ( aPropertiesNode.isValid() )
+ {
+ uno::Sequence< ::rtl::OUString > aStringSeq;
+ static const ::rtl::OUString s_sValue(RTL_CONSTASCII_USTRINGPARAM("/Value"));
+ const uno::Sequence< ::rtl::OUString > aProperties = aPropertiesNode.getNodeNames();
+ const ::rtl::OUString* pPropertiesIter = aProperties.getConstArray();
+ const ::rtl::OUString* pPropertiesEnd = pPropertiesIter + aProperties.getLength();
+ for (;pPropertiesIter != pPropertiesEnd ; ++pPropertiesIter)
+ {
+ uno::Any aValue = aPropertiesNode.getNodeValue(*pPropertiesIter + s_sValue);
+ if ( aValue >>= aStringSeq )
+ {
+ lcl_convert(aStringSeq,aValue);
+ }
+ _rValues.put(*pPropertiesIter,aValue);
+ } // for (;pPropertiesIter != pPropertiesEnd ; ++pPropertiesIter,++pNamedIter)
+ } // if ( aPropertiesNode.isValid() )
+ }
+ void lcl_readURLPatternNode(const ::utl::OConfigurationTreeRoot& _aInstalled,const ::rtl::OUString& _sEntry,TInstalledDriver& _rInstalledDriver)
+ {
+ const ::utl::OConfigurationNode aURLPatternNode = _aInstalled.openNode(_sEntry);
+ if ( aURLPatternNode.isValid() )
+ {
+ static const ::rtl::OUString s_sParentURLPattern(RTL_CONSTASCII_USTRINGPARAM("ParentURLPattern"));
+ static const ::rtl::OUString s_sDriver(RTL_CONSTASCII_USTRINGPARAM("Driver"));
+ static const ::rtl::OUString s_sDriverTypeDisplayName(RTL_CONSTASCII_USTRINGPARAM("DriverTypeDisplayName"));
+ static const ::rtl::OUString s_sProperties(RTL_CONSTASCII_USTRINGPARAM("Properties"));
+ static const ::rtl::OUString s_sFeatures(RTL_CONSTASCII_USTRINGPARAM("Features"));
+ static const ::rtl::OUString s_sMetaData(RTL_CONSTASCII_USTRINGPARAM("MetaData"));
+ ::rtl::OUString sParentURLPattern;
+ aURLPatternNode.getNodeValue(s_sParentURLPattern) >>= sParentURLPattern;
+ if ( sParentURLPattern.getLength() )
+ lcl_readURLPatternNode(_aInstalled,sParentURLPattern,_rInstalledDriver);
+
+ ::rtl::OUString sDriverFactory;
+ aURLPatternNode.getNodeValue(s_sDriver) >>= sDriverFactory;
+ if ( sDriverFactory.getLength() )
+ _rInstalledDriver.sDriverFactory = sDriverFactory;
+
+ ::rtl::OUString sDriverTypeDisplayName;
+ aURLPatternNode.getNodeValue(s_sDriverTypeDisplayName) >>= sDriverTypeDisplayName;
+ OSL_ENSURE(sDriverTypeDisplayName.getLength(),"No valid DriverTypeDisplayName property!");
+ if ( sDriverTypeDisplayName.getLength() )
+ _rInstalledDriver.sDriverTypeDisplayName = sDriverTypeDisplayName;
+
+ lcl_fillValues(aURLPatternNode,s_sProperties,_rInstalledDriver.aProperties);
+ lcl_fillValues(aURLPatternNode,s_sFeatures,_rInstalledDriver.aFeatures);
+ lcl_fillValues(aURLPatternNode,s_sMetaData,_rInstalledDriver.aMetaData);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+DriversConfigImpl::DriversConfigImpl()
+{
+}
+// -----------------------------------------------------------------------------
+void DriversConfigImpl::Load(const uno::Reference< lang::XMultiServiceFactory >& _rxORB) const
+{
+ if ( m_aDrivers.empty() )
+ {
+ if ( !m_aInstalled.isValid() )
+ {
+ static const ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess.Drivers/Installed")); ///Installed
+ m_aInstalled = ::utl::OConfigurationTreeRoot::createWithServiceFactory(_rxORB, s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
+ }
+
+ if ( m_aInstalled.isValid() )
+ {
+ const uno::Sequence< ::rtl::OUString > aURLPatterns = m_aInstalled.getNodeNames();
+ const ::rtl::OUString* pPatternIter = aURLPatterns.getConstArray();
+ const ::rtl::OUString* pPatternEnd = pPatternIter + aURLPatterns.getLength();
+ for (;pPatternIter != pPatternEnd ; ++pPatternIter)
+ {
+ TInstalledDriver aInstalledDriver;
+ lcl_readURLPatternNode(m_aInstalled,*pPatternIter,aInstalledDriver);
+ if ( aInstalledDriver.sDriverFactory.getLength() )
+ m_aDrivers.insert(TInstalledDrivers::value_type(*pPatternIter,aInstalledDriver));
+ }
+ } // if ( m_aInstalled.isValid() )
+ }
+}
+// -----------------------------------------------------------------------------
+DriversConfig::DriversConfig(const uno::Reference< lang::XMultiServiceFactory >& _rxORB)
+:m_xORB(_rxORB)
+{
+}
+
+// -----------------------------------------------------------------------------
+DriversConfig::~DriversConfig()
+{
+}
+
+// -----------------------------------------------------------------------------
+DriversConfig::DriversConfig( const DriversConfig& _rhs )
+{
+ *this = _rhs;
+}
+
+// -----------------------------------------------------------------------------
+DriversConfig& DriversConfig::operator=( const DriversConfig& _rhs )
+{
+ if ( this != &_rhs )
+ {
+ m_aNode = _rhs.m_aNode;
+ }
+ return *this;
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString DriversConfig::getDriverFactoryName(const ::rtl::OUString& _sURL) const
+{
+ const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
+ ::rtl::OUString sRet;
+ ::rtl::OUString sOldPattern;
+ TInstalledDrivers::const_iterator aIter = rDrivers.begin();
+ TInstalledDrivers::const_iterator aEnd = rDrivers.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ WildCard aWildCard(aIter->first);
+ if ( sOldPattern.getLength() < aIter->first.getLength() && aWildCard.Matches(_sURL) )
+ {
+ sRet = aIter->second.sDriverFactory;
+ sOldPattern = aIter->first;
+ }
+ }
+
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString DriversConfig::getDriverTypeDisplayName(const ::rtl::OUString& _sURL) const
+{
+ const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
+ ::rtl::OUString sRet;
+ ::rtl::OUString sOldPattern;
+ TInstalledDrivers::const_iterator aIter = rDrivers.begin();
+ TInstalledDrivers::const_iterator aEnd = rDrivers.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ WildCard aWildCard(aIter->first);
+ if ( sOldPattern.getLength() < aIter->first.getLength() && aWildCard.Matches(_sURL) )
+ {
+ sRet = aIter->second.sDriverTypeDisplayName;
+ sOldPattern = aIter->first;
+ }
+ }
+
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+const ::comphelper::NamedValueCollection& DriversConfig::getProperties(const ::rtl::OUString& _sURL) const
+{
+ return impl_get(_sURL,1);
+}
+// -----------------------------------------------------------------------------
+const ::comphelper::NamedValueCollection& DriversConfig::getFeatures(const ::rtl::OUString& _sURL) const
+{
+ return impl_get(_sURL,0);
+}
+// -----------------------------------------------------------------------------
+const ::comphelper::NamedValueCollection& DriversConfig::getMetaData(const ::rtl::OUString& _sURL) const
+{
+ return impl_get(_sURL,2);
+}
+// -----------------------------------------------------------------------------
+const ::comphelper::NamedValueCollection& DriversConfig::impl_get(const ::rtl::OUString& _sURL,sal_Int32 _nProps) const
+{
+ const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
+ const ::comphelper::NamedValueCollection* pRet = NULL;
+ ::rtl::OUString sOldPattern;
+ TInstalledDrivers::const_iterator aIter = rDrivers.begin();
+ TInstalledDrivers::const_iterator aEnd = rDrivers.end();
+ for(;aIter != aEnd;++aIter)
+ {
+ WildCard aWildCard(aIter->first);
+ if ( sOldPattern.getLength() < aIter->first.getLength() && aWildCard.Matches(_sURL) )
+ {
+ switch(_nProps)
+ {
+ case 0:
+ pRet = &aIter->second.aFeatures;
+ break;
+ case 1:
+ pRet = &aIter->second.aProperties;
+ break;
+ case 2:
+ pRet = &aIter->second.aMetaData;
+ break;
+ }
+ sOldPattern = aIter->first;
+ }
+ } // for(;aIter != aEnd;++aIter)
+ if ( pRet == NULL )
+ {
+ static const ::comphelper::NamedValueCollection s_sEmpty;
+ pRet = &s_sEmpty;
+ }
+ return *pRet;
+}
+// -----------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > DriversConfig::getURLs() const
+{
+ const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB);
+ uno::Sequence< ::rtl::OUString > aRet(rDrivers.size());
+ ::rtl::OUString* pIter = aRet.getArray();
+ TInstalledDrivers::const_iterator aIter = rDrivers.begin();
+ TInstalledDrivers::const_iterator aEnd = rDrivers.end();
+ for(;aIter != aEnd;++aIter,++pIter)
+ {
+ *pIter = aIter->first;
+ }
+ return aRet;
+}
diff --git a/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx b/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx
new file mode 100644
index 000000000000..52e76f834ab5
--- /dev/null
+++ b/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx
@@ -0,0 +1,913 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include "ParameterSubstitution.hxx"
+#include "FDatabaseMetaDataResultSet.hxx"
+#include "FDatabaseMetaDataResultSetMetaData.hxx"
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ColumnSearch.hpp>
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include <com/sun/star/sdbc/ProcedureResult.hpp>
+#include <com/sun/star/sdbc/IndexType.hpp>
+#include <comphelper/property.hxx>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+#include <com/sun/star/sdbc/FetchDirection.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include "connectivity/dbexception.hxx"
+#include "TConnection.hxx"
+
+using namespace connectivity;
+using namespace dbtools;
+using namespace cppu;
+//------------------------------------------------------------------------------
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+// -------------------------------------------------------------------------
+ODatabaseMetaDataResultSet::ODatabaseMetaDataResultSet()
+ :ODatabaseMetaDataResultSet_BASE(m_aMutex)
+ ,::comphelper::OPropertyContainer(ODatabaseMetaDataResultSet_BASE::rBHelper)
+ ,m_aStatement(NULL)
+ ,m_xMetaData(NULL)
+ ,m_bBOF(sal_True)
+ ,m_bEOF(sal_True)
+{
+ construct();
+}
+
+// -------------------------------------------------------------------------
+ODatabaseMetaDataResultSet::ODatabaseMetaDataResultSet( MetaDataResultSetType _eType )
+ :ODatabaseMetaDataResultSet_BASE(m_aMutex)
+ ,::comphelper::OPropertyContainer(ODatabaseMetaDataResultSet_BASE::rBHelper)
+ ,m_aStatement(NULL)
+ ,m_xMetaData(NULL)
+ ,m_bBOF(sal_True)
+ ,m_bEOF(sal_True)
+{
+ construct();
+
+ setType(_eType);
+}
+
+// -------------------------------------------------------------------------
+ODatabaseMetaDataResultSet::~ODatabaseMetaDataResultSet()
+{
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::construct()
+{
+ registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE), PROPERTY_ID_FETCHSIZE, 0,&m_nFetchSize, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
+ registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE), PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::READONLY,&m_nResultSetType, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
+ registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION), PROPERTY_ID_FETCHDIRECTION, 0, &m_nFetchDirection, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
+ registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY), PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::READONLY,&m_nResultSetConcurrency, ::getCppuType(reinterpret_cast<sal_Int32*>(NULL)));
+}
+// -----------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setType(MetaDataResultSetType _eType)
+{
+ switch( _eType )
+ {
+ case eCatalogs: setCatalogsMap(); break;
+ case eSchemas: setSchemasMap(); break;
+ case eColumnPrivileges: setColumnPrivilegesMap(); break;
+ case eColumns: setColumnsMap(); break;
+ case eTables: setTablesMap(); break;
+ case eTableTypes: setTableTypes(); break;
+ case eProcedureColumns: setProcedureColumnsMap(); break;
+ case eProcedures: setProceduresMap(); break;
+ case eExportedKeys: setExportedKeysMap(); break;
+ case eImportedKeys: setImportedKeysMap(); break;
+ case ePrimaryKeys: setPrimaryKeysMap(); break;
+ case eIndexInfo: setIndexInfoMap(); break;
+ case eTablePrivileges: setTablePrivilegesMap(); break;
+ case eCrossReference: setCrossReferenceMap(); break;
+ case eTypeInfo: setTypeInfoMap(); break;
+ case eBestRowIdentifier: setBestRowIdentifierMap(); break;
+ case eVersionColumns: setVersionColumnsMap(); break;
+ default:
+ OSL_ENSURE(0,"Wrong type!");
+ }
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::disposing(void)
+{
+ OPropertySetHelper::disposing();
+
+ ::osl::MutexGuard aGuard(m_aMutex);
+ m_aStatement = NULL;
+m_xMetaData.clear();
+ m_aRowsIter = m_aRows.end();
+ m_aRows.clear();
+ m_aRowsIter = m_aRows.end();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::acquire() throw()
+{
+ ODatabaseMetaDataResultSet_BASE::acquire();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::release() throw()
+{
+ ODatabaseMetaDataResultSet_BASE::release();
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL ODatabaseMetaDataResultSet::queryInterface( const Type & rType ) throw(RuntimeException)
+{
+ Any aRet = OPropertySetHelper::queryInterface(rType);
+ return aRet.hasValue() ? aRet : ODatabaseMetaDataResultSet_BASE::queryInterface(rType);
+}
+// -------------------------------------------------------------------------
+Sequence< Type > SAL_CALL ODatabaseMetaDataResultSet::getTypes( ) throw(RuntimeException)
+{
+ ::cppu::OTypeCollection aTypes( ::getCppuType( (const Reference< ::com::sun::star::beans::XMultiPropertySet > *)0 ),
+ ::getCppuType( (const Reference< ::com::sun::star::beans::XFastPropertySet > *)0 ),
+ ::getCppuType( (const Reference< ::com::sun::star::beans::XPropertySet > *)0 ));
+
+ return ::comphelper::concatSequences(aTypes.getTypes(),ODatabaseMetaDataResultSet_BASE::getTypes());
+}
+// -----------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setRows(const ORows& _rRows)
+{
+ m_aRows = _rRows;
+ m_bBOF = sal_True;
+ m_bEOF = m_aRows.empty();
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+
+ Reference< XResultSetMetaData > xMeta = getMetaData();
+ sal_Int32 nLen = xMeta->getColumnCount();
+ sal_Int32 i = 1;
+ for(;i<=nLen;++i)
+ if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
+ columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i))
+ )
+ break;
+ return i;
+}
+// -----------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::checkIndex(sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException)
+{
+ if(columnIndex >= (sal_Int32)(*m_aRowsIter).size() || columnIndex < 1)
+ ::dbtools::throwInvalidIndexException(*this);
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return NULL;
+}
+// -------------------------------------------------------------------------
+Reference< ::com::sun::star::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return NULL;
+}
+
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+sal_Int8 SAL_CALL ODatabaseMetaDataResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+Sequence< sal_Int8 > SAL_CALL ODatabaseMetaDataResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+::com::sun::star::util::Date SAL_CALL ODatabaseMetaDataResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+double SAL_CALL ODatabaseMetaDataResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+float SAL_CALL ODatabaseMetaDataResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+
+// -------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getRow( ) throw(SQLException, RuntimeException)
+{
+ return 0;
+}
+// -------------------------------------------------------------------------
+
+sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+Reference< XResultSetMetaData > SAL_CALL ODatabaseMetaDataResultSet::getMetaData( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+
+ if(!m_xMetaData.is())
+ m_xMetaData = new ODatabaseMetaDataResultSetMetaData();
+
+ return m_xMetaData;
+}
+// -------------------------------------------------------------------------
+Reference< XArray > SAL_CALL ODatabaseMetaDataResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return NULL;
+}
+
+// -------------------------------------------------------------------------
+
+Reference< XClob > SAL_CALL ODatabaseMetaDataResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return NULL;
+}
+// -------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL ODatabaseMetaDataResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return NULL;
+}
+// -------------------------------------------------------------------------
+
+Reference< XRef > SAL_CALL ODatabaseMetaDataResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
+{
+ return NULL;
+}
+// -------------------------------------------------------------------------
+
+Any SAL_CALL ODatabaseMetaDataResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex).makeAny();
+}
+// -------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+
+// -------------------------------------------------------------------------
+
+
+::com::sun::star::util::Time SAL_CALL ODatabaseMetaDataResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+
+::com::sun::star::util::DateTime SAL_CALL ODatabaseMetaDataResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
+{
+ return getValue(columnIndex);
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isAfterLast( ) throw(SQLException, RuntimeException)
+{
+ return m_bEOF;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isFirst( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isLast( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::beforeFirst( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::afterLast( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+}
+// -------------------------------------------------------------------------
+
+void SAL_CALL ODatabaseMetaDataResultSet::close( ) throw(SQLException, RuntimeException)
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+ }
+ dispose();
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::first( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::last( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::absolute( sal_Int32 /*row*/ ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::relative( sal_Int32 /*row*/ ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::previous( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL ODatabaseMetaDataResultSet::getStatement( ) throw(SQLException, RuntimeException)
+{
+ return m_aStatement.get();
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowDeleted( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowInserted( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowUpdated( ) throw(SQLException, RuntimeException)
+{
+ ::dbtools::throwFunctionSequenceException(*this);
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isBeforeFirst( ) throw(SQLException, RuntimeException)
+{
+ return m_bBOF;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::next( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+ if ( m_bBOF )
+ {
+ m_aRowsIter = m_aRows.begin();
+ m_bBOF = sal_False;
+ }
+ else
+ {
+ if ( m_bEOF )
+ throwFunctionSequenceException( *this );
+ else
+ if ( m_aRowsIter != m_aRows.end() )
+ ++m_aRowsIter;
+ }
+
+ bool bSuccess = m_aRowsIter != m_aRows.end();
+ if ( !bSuccess )
+ {
+ m_bEOF = sal_True;
+ m_bBOF = m_aRows.empty();
+ }
+ return bSuccess;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSet::wasNull( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+
+ if(m_aRowsIter == m_aRows.end() || !(*m_aRowsIter)[m_nColPos].isValid())
+ return sal_True;
+
+ return (*m_aRowsIter)[m_nColPos]->getValue().isNull();
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::refreshRow( ) throw(SQLException, RuntimeException)
+{
+}
+// -------------------------------------------------------------------------
+
+void SAL_CALL ODatabaseMetaDataResultSet::cancel( ) throw(RuntimeException)
+{
+}
+// -------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::clearWarnings( ) throw(SQLException, RuntimeException)
+{
+}
+// -------------------------------------------------------------------------
+Any SAL_CALL ODatabaseMetaDataResultSet::getWarnings( ) throw(SQLException, RuntimeException)
+{
+ return Any();
+}
+// -------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper* ODatabaseMetaDataResultSet::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+// -------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper & ODatabaseMetaDataResultSet::getInfoHelper()
+{
+ return *const_cast<ODatabaseMetaDataResultSet*>(this)->getArrayHelper();
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setProceduresMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setProceduresMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setCatalogsMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setCatalogsMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setSchemasMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setSchemasMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setColumnPrivilegesMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setColumnPrivilegesMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setColumnsMap()
+{
+
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setColumnsMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setTablesMap()
+{
+
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setTablesMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setProcedureColumnsMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setProcedureColumnsMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setPrimaryKeysMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setPrimaryKeysMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setIndexInfoMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setIndexInfoMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setTablePrivilegesMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setTablePrivilegesMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setCrossReferenceMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setCrossReferenceMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setVersionColumnsMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setVersionColumnsMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setBestRowIdentifierMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setBestRowIdentifierMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setTypeInfoMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setTypeInfoMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setTableTypes()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setTableTypes();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setExportedKeysMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setExportedKeysMap();
+ m_xMetaData = pMetaData;
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSet::setImportedKeysMap()
+{
+ ODatabaseMetaDataResultSetMetaData* pMetaData = new ODatabaseMetaDataResultSetMetaData();
+ pMetaData->setImportedKeysMap();
+ m_xMetaData = pMetaData;
+}
+// -----------------------------------------------------------------------------
+Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL ODatabaseMetaDataResultSet::getPropertySetInfo( ) throw(RuntimeException)
+{
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecorator& ORowSetValueDecorator::operator=(const ORowSetValue& _aValue)
+{
+ m_aValue = _aValue;
+ return *this;
+}
+// -----------------------------------------------------------------------------
+const ORowSetValue& ODatabaseMetaDataResultSet::getValue(sal_Int32 columnIndex)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+ if ( isBeforeFirst() || isAfterLast() )
+ ::dbtools::throwFunctionSequenceException( *this );
+
+ checkIndex(columnIndex );
+ m_nColPos = columnIndex;
+
+ if(m_aRowsIter != m_aRows.end() && (*m_aRowsIter)[columnIndex].isValid())
+ return *(*m_aRowsIter)[columnIndex];
+ return m_aEmptyValue;
+}
+// -----------------------------------------------------------------------------
+/// return an empty ORowSetValueDecorator
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getEmptyValue()
+{
+ static ORowSetValueDecoratorRef aEmptyValueRef = new ORowSetValueDecorator();
+ return aEmptyValueRef;
+}
+// -----------------------------------------------------------------------------
+/// return an ORowSetValueDecorator with 0 as value
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::get0Value()
+{
+ static ORowSetValueDecoratorRef a0ValueRef = new ORowSetValueDecorator((sal_Int32)0);
+ return a0ValueRef;
+}
+// -----------------------------------------------------------------------------
+/// return an ORowSetValueDecorator with 1 as value
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::get1Value()
+{
+ static ORowSetValueDecoratorRef a1ValueRef = new ORowSetValueDecorator((sal_Int32)1);
+ return a1ValueRef;
+}
+// -----------------------------------------------------------------------------
+/// return an ORowSetValueDecorator with ColumnSearch::BASIC as value
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getBasicValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(ColumnSearch::BASIC);
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getSelectValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("SELECT"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getInsertValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("INSERT"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getDeleteValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DELETE"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getUpdateValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("UPDATE"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getCreateValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("CREATE"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getReadValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("READ"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getAlterValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("ALTER"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getDropValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DROP"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+ORowSetValueDecoratorRef ODatabaseMetaDataResultSet::getQuoteValue()
+{
+ static ORowSetValueDecoratorRef aValueRef = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("'"));
+ return aValueRef;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataResultSet::initialize( const Sequence< Any >& _aArguments ) throw (Exception, RuntimeException)
+{
+ if ( _aArguments.getLength() == 2 )
+ {
+ sal_Int32 nResultSetType = 0;
+ if ( _aArguments[0] >>= nResultSetType)
+ {
+ setType(static_cast<MetaDataResultSetType>(nResultSetType));
+ Sequence< Sequence<Any> > aRows;
+ if ( _aArguments[1] >>= aRows )
+ {
+ ORows aRowsToSet;
+ const Sequence<Any>* pRowsIter = aRows.getConstArray();
+ const Sequence<Any>* pRowsEnd = pRowsIter + aRows.getLength();
+ for (; pRowsIter != pRowsEnd;++pRowsIter)
+ {
+ ORow aRowToSet;
+ const Any* pRowIter = pRowsIter->getConstArray();
+ const Any* pRowEnd = pRowIter + pRowsIter->getLength();
+ for (; pRowIter != pRowEnd;++pRowIter)
+ {
+ ORowSetValueDecoratorRef aValue;
+ switch( pRowIter->getValueTypeClass() )
+ {
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool bValue = sal_False;
+ *pRowIter >>= bValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(bValue));
+ }
+ break;
+ case TypeClass_BYTE:
+ {
+ sal_Int8 nValue(0);
+ *pRowIter >>= nValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(nValue));
+ }
+ break;
+ case TypeClass_SHORT:
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_Int16 nValue(0);
+ *pRowIter >>= nValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(nValue));
+ }
+ break;
+ case TypeClass_LONG:
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_Int32 nValue(0);
+ *pRowIter >>= nValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(nValue));
+ }
+ break;
+ case TypeClass_HYPER:
+ case TypeClass_UNSIGNED_HYPER:
+ {
+ sal_Int64 nValue(0);
+ *pRowIter >>= nValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(nValue));
+ }
+ break;
+ case TypeClass_FLOAT:
+ {
+ float nValue(0.0);
+ *pRowIter >>= nValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(nValue));
+ }
+ break;
+ case TypeClass_DOUBLE:
+ {
+ double nValue(0.0);
+ *pRowIter >>= nValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(nValue));
+ }
+ break;
+ case TypeClass_STRING:
+ {
+ ::rtl::OUString sValue;
+ *pRowIter >>= sValue;
+ aValue = new ORowSetValueDecorator(ORowSetValue(sValue));
+ }
+ break;
+ default:
+ break;
+ }
+ aRowToSet.push_back(aValue);
+ }
+ aRowsToSet.push_back(aRowToSet);
+ } // for (; pRowsIter != pRowsEnd;++pRowsIter
+ setRows(aRowsToSet);
+ }
+ }
+ }
+}
+// XServiceInfo
+ // --------------------------------------------------------------------------------
+ //------------------------------------------------------------------------------
+ rtl::OUString ODatabaseMetaDataResultSet::getImplementationName_Static( ) throw(RuntimeException)
+ {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.helper.DatabaseMetaDataResultSet"));
+ }
+ //------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > ODatabaseMetaDataResultSet::getSupportedServiceNames_Static( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ResultSet");
+ return aSNS;
+ }
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ODatabaseMetaDataResultSet::getImplementationName( ) throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+
+ //------------------------------------------------------------------
+ sal_Bool SAL_CALL ODatabaseMetaDataResultSet::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
+ const ::rtl::OUString* pSupported = aSupported.getConstArray();
+ const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
+ for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
+ ;
+
+ return pSupported != pEnd;
+ }
+ //------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL ODatabaseMetaDataResultSet::getSupportedServiceNames( ) throw(RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+ // -------------------------------------------------------------------------
+ namespace connectivity
+ {
+ Reference< XInterface > SAL_CALL ODatabaseMetaDataResultSet_CreateInstance(const Reference< XComponentContext >& ) throw( Exception )
+ {
+ return *(new ODatabaseMetaDataResultSet());
+ }
+ }
+
+// -----------------------------------------------------------------------------
+namespace
+{
+ cppu::ImplementationEntry entries[] = {
+ { &ODatabaseMetaDataResultSet_CreateInstance, &ODatabaseMetaDataResultSet::getImplementationName_Static, &ODatabaseMetaDataResultSet::getSupportedServiceNames_Static,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { &ParameterSubstitution::create, &ParameterSubstitution::getImplementationName_Static, &ParameterSubstitution::getSupportedServiceNames_Static,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+ };
+}
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::registry::XRegistryKey;
+using ::com::sun::star::registry::InvalidRegistryException;
+using ::com::sun::star::registry::InvalidValueException;
+using ::com::sun::star::lang::XMultiServiceFactory;
+
+//==========================================================================
+//= registration
+//==========================================================================
+extern "C"
+{
+
+//---------------------------------------------------------------------------------------
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(const sal_Char** _ppEnvTypeName, uno_Environment** /*_ppEnv*/)
+{
+ *_ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//---------------------------------------------------------------------------------------
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(void* serviceManager, com::sun::star::registry::XRegistryKey* registryKey)
+{
+ return cppu::component_writeInfoHelper(serviceManager, registryKey, entries);
+}
+//---------------------------------------------------------------------------------------
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(const sal_Char* implName, ::com::sun::star::lang::XMultiServiceFactory* serviceManager, void* registryKey)
+{
+ return cppu::component_getFactoryHelper(implName, serviceManager, registryKey, entries);
+}
+
+} // extern "C"
diff --git a/connectivity/source/commontools/FDatabaseMetaDataResultSetMetaData.cxx b/connectivity/source/commontools/FDatabaseMetaDataResultSetMetaData.cxx
new file mode 100644
index 000000000000..97e7201a53ff
--- /dev/null
+++ b/connectivity/source/commontools/FDatabaseMetaDataResultSetMetaData.cxx
@@ -0,0 +1,692 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "FDatabaseMetaDataResultSetMetaData.hxx"
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ProcedureResult.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+
+using namespace connectivity;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+// -------------------------------------------------------------------------
+ODatabaseMetaDataResultSetMetaData::~ODatabaseMetaDataResultSetMetaData()
+{
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getColumnDisplaySize();
+
+ return 0;
+}
+// -------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnType( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getColumnType();
+ return 1;
+}
+// -------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnCount( ) throw(SQLException, RuntimeException)
+{
+ return m_mColumns.size();
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isCaseSensitive( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.isCaseSensitive();
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getSchemaName( sal_Int32 /*column*/ ) throw(SQLException, RuntimeException)
+{
+ return ::rtl::OUString();
+}
+// -------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnName( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getColumnName();
+ return ::rtl::OUString();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getTableName( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getTableName();
+ return ::rtl::OUString();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getCatalogName( sal_Int32 /*column*/ ) throw(SQLException, RuntimeException)
+{
+ return ::rtl::OUString();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnTypeName( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getColumnTypeName();
+ return ::rtl::OUString();
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnLabel( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getColumnLabel();
+ return getColumnName(column);
+}
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataResultSetMetaData::getColumnServiceName( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getColumnServiceName();
+ return ::rtl::OUString();
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isCurrency( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.isCurrency();
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isAutoIncrement( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.isAutoIncrement();
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isSigned( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.isSigned();
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getPrecision( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getPrecision();
+ return 0;
+}
+// -------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::getScale( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.getScale();
+
+ return 0;
+}
+// -------------------------------------------------------------------------
+
+sal_Int32 SAL_CALL ODatabaseMetaDataResultSetMetaData::isNullable( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.isNullable();
+
+ return sal_False;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isSearchable( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+ if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+ return (*m_mColumnsIter).second.isSearchable();
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isReadOnly( sal_Int32 /*column*/ ) throw(SQLException, RuntimeException)
+{
+// if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+// return (*m_mColumnsIter).second.isReadOnly();
+
+ return sal_True;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isDefinitelyWritable( sal_Int32 /*column*/ ) throw(SQLException, RuntimeException)
+{
+// if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+// return (*m_mColumnsIter).second.isDefinitelyWritable();
+
+ return sal_False;
+;
+}
+// -------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataResultSetMetaData::isWritable( sal_Int32 column ) throw(SQLException, RuntimeException)
+{
+// if(m_mColumns.size() && (m_mColumnsIter = m_mColumns.find(column)) != m_mColumns.end())
+// return (*m_mColumnsIter).second.isWritable();
+ return isDefinitelyWritable(column);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setColumnPrivilegesMap()
+{
+ setColumnMap();
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("GRANTOR"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::VARCHAR);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("GRANTEE"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PRIVILEGE"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::VARCHAR);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("IS_GRANTABLE"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::VARCHAR);
+}
+// -----------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setTableNameMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_CAT"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::VARCHAR);
+ m_mColumns[2] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_SCHEM"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::VARCHAR);
+ m_mColumns[3] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_NAME"),
+ ColumnValue::NO_NULLS,
+ 3,3,0,
+ DataType::VARCHAR);
+}
+// -----------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setColumnMap()
+{
+ setTableNameMap();
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_NAME"),
+ ColumnValue::NO_NULLS,
+ 3,3,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setColumnsMap()
+{
+ setColumnMap();
+
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DATA_TYPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TYPE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_SIZE"),
+ ColumnValue::NO_NULLS,
+ 3,3,0,
+ DataType::INTEGER);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("BUFFER_LENGTH"),
+ ColumnValue::NULLABLE,
+ 3,3,0,
+ DataType::INTEGER);
+ m_mColumns[9] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DECIMAL_DIGITS"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[10] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("NUM_PREC_RADIX"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[11] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("NULLABLE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[12] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("REMARKS"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[13] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_DEF"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[14] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SQL_DATA_TYPE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[15] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SQL_DATETIME_SUB"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[16] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("CHAR_OCTET_LENGTH"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[17] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("ORDINAL_POSITION"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[18] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("IS_NULLABLE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setTablesMap()
+{
+ setTableNameMap();
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_TYPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("REMARKS"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setProcedureNameMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PROCEDURE_CAT"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[2] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PROCEDURE_SCHEM"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[3] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PROCEDURE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setProcedureColumnsMap()
+{
+ setProcedureNameMap();
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_TYPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DATA_TYPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TYPE_NAME"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PRECISION"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[9] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("LENGTH"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[10] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SCALE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[11] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("RADIX"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[12] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("NULLABLE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[13] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("REMARKS"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setPrimaryKeysMap()
+{
+ setColumnMap();
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("KEY_SEQ"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PK_NAME"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setIndexInfoMap()
+{
+ setTableNameMap();
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("NON_UNIQUE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::BIT);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("INDEX_QUALIFIER"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("INDEX_NAME"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TYPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("ORDINAL_POSITION"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[9] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[10] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("ASC_OR_DESC"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[11] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("CARDINALITY"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[12] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PAGES"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[13] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FILTER_CONDITION"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setTablePrivilegesMap()
+{
+ setTableNameMap();
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("GRANTOR"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("GRANTEE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PRIVILEGE"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("IS_GRANTABLE"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setCrossReferenceMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PKTABLE_CAT"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[2] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PKTABLE_SCHEM"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[3] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PKTABLE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PKCOLUMN_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FKTABLE_CAT"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FKTABLE_SCHEM"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FKTABLE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FKCOLUMN_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+
+ m_mColumns[9] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("KEY_SEQ"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[10] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("UPDATE_RULE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[11] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DELETE_RULE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[12] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FK_NAME"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[13] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PK_NAME"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[14] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DEFERRABILITY"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setTypeInfoMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TYPE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[2] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DATA_TYPE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[3] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PRECISION"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("LITERAL_PREFIX"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("LITERAL_SUFFIX"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("CREATE_PARAMS"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("NULLABLE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("CASE_SENSITIVE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::BIT);
+ m_mColumns[9] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SEARCHABLE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[10] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("UNSIGNED_ATTRIBUTE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::BIT);
+ m_mColumns[11] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("FIXED_PREC_SCALE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::BIT);
+ m_mColumns[12] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("AUTO_INCREMENT"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::BIT);
+ m_mColumns[13] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("LOCAL_TYPE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[14] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("MINIMUM_SCALE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[15] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("MAXIMUM_SCALE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[16] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SQL_DATA_TYPE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[17] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SQL_DATETIME_SUB"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+ m_mColumns[18] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("NUM_PREC_RADIX"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setProceduresMap()
+{
+ setProcedureNameMap();
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("RESERVED1"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("RESERVED2"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("RESERVED3"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("REMARKS"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PROCEDURE_TYPE"),
+ ColumnValue::NO_NULLS,
+ 1,1,0,
+ DataType::INTEGER);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setTableTypes()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_TYPE"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setCatalogsMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_CAT"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setSchemasMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TABLE_SCHEM"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::VARCHAR);
+}
+// -------------------------------------------------------------------------
+void ODatabaseMetaDataResultSetMetaData::setVersionColumnsMap()
+{
+ m_mColumns[1] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("SCOPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[2] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[3] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DATA_TYPE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[4] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("TYPE_NAME"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::VARCHAR);
+ m_mColumns[5] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("COLUMN_SIZE"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[6] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("BUFFER_LENGTH"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[7] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("DECIMAL_DIGITS"),
+ ColumnValue::NULLABLE,
+ 0,0,0,
+ DataType::INTEGER);
+ m_mColumns[8] = OColumn(::rtl::OUString(),::rtl::OUString::createFromAscii("PSEUDO_COLUMN"),
+ ColumnValue::NO_NULLS,
+ 0,0,0,
+ DataType::INTEGER);
+}
+
+
diff --git a/connectivity/source/commontools/FValue.cxx b/connectivity/source/commontools/FValue.cxx
new file mode 100644
index 000000000000..aca181916b47
--- /dev/null
+++ b/connectivity/source/commontools/FValue.cxx
@@ -0,0 +1,2333 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include <stdio.h>
+#include "connectivity/FValue.hxx"
+#include "connectivity/CommonTools.hxx"
+#include <connectivity/dbconversion.hxx>
+#include <cppuhelper/extract.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace ::dbtools;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::io;
+
+namespace connectivity
+{
+
+namespace {
+ static sal_Bool isStorageCompatible(sal_Int32 _eType1, sal_Int32 _eType2)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::isStorageCompatible" );
+ sal_Bool bIsCompatible = sal_True;
+
+ if (_eType1 != _eType2)
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLogger, "ORowSetValue::isStorageCompatible _eType1 != _eType2" );
+ switch (_eType1)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ bIsCompatible = (DataType::CHAR == _eType2)
+ || (DataType::VARCHAR == _eType2)
+ || (DataType::DECIMAL == _eType2)
+ || (DataType::NUMERIC == _eType2)
+ || (DataType::LONGVARCHAR == _eType2);
+ break;
+
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ bIsCompatible = (DataType::DOUBLE == _eType2)
+ || (DataType::REAL == _eType2);
+ break;
+
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ bIsCompatible = (DataType::BINARY == _eType2)
+ || (DataType::VARBINARY == _eType2)
+ || (DataType::LONGVARBINARY == _eType2);
+ break;
+
+ case DataType::INTEGER:
+ bIsCompatible = (DataType::SMALLINT == _eType2)
+ || (DataType::TINYINT == _eType2)
+ || (DataType::BIT == _eType2)
+ || (DataType::BOOLEAN == _eType2);
+ break;
+ case DataType::SMALLINT:
+ bIsCompatible = (DataType::TINYINT == _eType2)
+ || (DataType::BIT == _eType2)
+ || (DataType::BOOLEAN == _eType2);
+ break;
+ case DataType::TINYINT:
+ bIsCompatible = (DataType::BIT == _eType2)
+ || (DataType::BOOLEAN == _eType2);
+ break;
+
+ case DataType::BLOB:
+ case DataType::CLOB:
+ case DataType::OBJECT:
+ bIsCompatible = (DataType::BLOB == _eType2)
+ || (DataType::CLOB == _eType2)
+ || (DataType::OBJECT == _eType2);
+ break;
+
+ default:
+ bIsCompatible = sal_False;
+ }
+ }
+ return bIsCompatible;
+ }
+}
+
+// -----------------------------------------------------------------------------
+#ifdef DBG_UTIL
+
+#include <vector>
+#include <rtl/string.h>
+
+namespace tracing
+{
+ struct AllocationType
+ {
+ const sal_Char* pName;
+ sal_Int32 nAllocatedUnits;
+
+ AllocationType( ) : pName( NULL ), nAllocatedUnits( 0 ) { }
+ };
+
+ // =============================================================================
+ class AllocationTracer
+ {
+ public:
+ typedef ::std::vector< AllocationType > AllocationState;
+ static AllocationState s_aAllocated;
+ static ::osl::Mutex s_aMutex;
+
+ public:
+ static void registerUnit( const sal_Char* _pName );
+ static void revokeUnit( const sal_Char* _pName );
+
+ private:
+ static AllocationState::iterator getLocation( const sal_Char* _pName );
+ };
+
+ // =============================================================================
+ AllocationTracer::AllocationState::iterator AllocationTracer::getLocation( const sal_Char* _pName )
+ {
+ AllocationState::iterator aLookFor = s_aAllocated.begin();
+ for ( ;
+ aLookFor != s_aAllocated.end();
+ ++aLookFor
+ )
+ {
+ if ( 0 == rtl_str_compare( aLookFor->pName, _pName ) )
+ // found
+ return aLookFor;
+ }
+ // not found
+ s_aAllocated.push_back( AllocationType() );
+ aLookFor = s_aAllocated.end(); --aLookFor;
+ aLookFor->pName = _pName; // note that this assumes that _pName is a constant string ....
+ return aLookFor;
+ }
+
+ // =============================================================================
+ AllocationTracer::AllocationState AllocationTracer::s_aAllocated;
+ ::osl::Mutex AllocationTracer::s_aMutex;
+
+ // =============================================================================
+ void AllocationTracer::registerUnit( const sal_Char* _pName )
+ {
+ ::osl::MutexGuard aGuard( s_aMutex );
+
+ AllocationState::iterator aPos = getLocation( _pName );
+ ++aPos->nAllocatedUnits;
+ }
+
+ // =============================================================================
+ void AllocationTracer::revokeUnit( const sal_Char* _pName )
+ {
+ ::osl::MutexGuard aGuard( s_aMutex );
+
+ AllocationState::iterator aPos = getLocation( _pName );
+ --aPos->nAllocatedUnits;
+ }
+
+#define TRACE_ALLOC( type ) tracing::AllocationTracer::registerUnit( #type );
+#define TRACE_FREE( type ) tracing::AllocationTracer::revokeUnit( #type );
+}
+#else
+#define TRACE_ALLOC( type )
+#define TRACE_FREE( type )
+#endif
+
+// -----------------------------------------------------------------------------
+void ORowSetValue::setTypeKind(sal_Int32 _eType)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::setTypeKind" );
+ if ( !m_bNull && !isStorageCompatible(_eType, m_eTypeKind) )
+ {
+ switch(_eType)
+ {
+ case DataType::VARCHAR:
+ case DataType::CHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ (*this) = getString();
+ break;
+ case DataType::BIGINT:
+ (*this) = getLong();
+ break;
+
+ case DataType::FLOAT:
+ (*this) = getFloat();
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ (*this) = getDouble();
+ break;
+ case DataType::TINYINT:
+ (*this) = getInt8();
+ break;
+ case DataType::SMALLINT:
+ (*this) = getInt16();
+ break;
+ case DataType::INTEGER:
+ (*this) = getInt32();
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ (*this) = getBool();
+ break;
+ case DataType::DATE:
+ (*this) = getDate();
+ break;
+ case DataType::TIME:
+ (*this) = getTime();
+ break;
+ case DataType::TIMESTAMP:
+ (*this) = getDateTime();
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ (*this) = getSequence();
+ break;
+ case DataType::BLOB:
+ case DataType::CLOB:
+ case DataType::OBJECT:
+ case DataType::OTHER:
+ (*this) = getAny();
+ break;
+ default:
+ (*this) = getAny();
+ OSL_ENSURE(0,"ORowSetValue:operator==(): UNSPUPPORTED TYPE!");
+ }
+ }
+
+ m_eTypeKind = _eType;
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetValue::free()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::free" );
+ if(!m_bNull)
+ {
+ switch(m_eTypeKind)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ OSL_ENSURE(m_aValue.m_pString,"String pointer is null!");
+ rtl_uString_release(m_aValue.m_pString);
+ m_aValue.m_pString = NULL;
+ break;
+ case DataType::INTEGER:
+ if ( !m_bSigned )
+ {
+ delete (sal_Int64*)m_aValue.m_pValue;
+ TRACE_FREE( sal_Int64 )
+ m_aValue.m_pValue = NULL;
+ }
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ {
+ delete (sal_Int64*)m_aValue.m_pValue;
+ TRACE_FREE( sal_Int64 )
+ m_aValue.m_pValue = NULL;
+ }
+ else
+ {
+ OSL_ENSURE(m_aValue.m_pString,"String pointer is null!");
+ rtl_uString_release(m_aValue.m_pString);
+ m_aValue.m_pString = NULL;
+ }
+ break;
+ case DataType::FLOAT:
+ delete (float*)m_aValue.m_pValue;
+ TRACE_FREE( float )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ delete (double*)m_aValue.m_pValue;
+ TRACE_FREE( double )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::DATE:
+ delete (::com::sun::star::util::Date*)m_aValue.m_pValue;
+ TRACE_FREE( Date )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::TIME:
+ delete (::com::sun::star::util::Time*)m_aValue.m_pValue;
+ TRACE_FREE( Time )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::TIMESTAMP:
+ delete (::com::sun::star::util::DateTime*)m_aValue.m_pValue;
+ TRACE_FREE( DateTime )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ delete (Sequence<sal_Int8>*)m_aValue.m_pValue;
+ TRACE_FREE( Sequence_sal_Int8 )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::BLOB:
+ case DataType::CLOB:
+ case DataType::OBJECT:
+ delete (Any*)m_aValue.m_pValue;
+ TRACE_FREE( Any )
+ m_aValue.m_pValue = NULL;
+ break;
+ case DataType::BIT:
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::BOOLEAN:
+ break;
+ default:
+ if ( m_aValue.m_pValue )
+ {
+ delete (Any*)m_aValue.m_pValue;
+ TRACE_FREE( Any )
+ m_aValue.m_pValue = NULL;
+ }
+ break;
+
+ }
+ m_bNull = sal_True;
+ }
+}
+// -----------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const ORowSetValue& _rRH)
+{
+ if(&_rRH == this)
+ return *this;
+
+ if ( m_eTypeKind != _rRH.m_eTypeKind || (_rRH.m_bNull && !m_bNull) || m_bSigned != _rRH.m_bSigned)
+ free();
+
+ m_bBound = _rRH.m_bBound;
+ m_eTypeKind = _rRH.m_eTypeKind;
+ m_bSigned = _rRH.m_bSigned;
+
+ if(m_bNull && !_rRH.m_bNull)
+ {
+ switch(_rRH.m_eTypeKind)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ rtl_uString_acquire(_rRH.m_aValue.m_pString);
+ m_aValue.m_pString = _rRH.m_aValue.m_pString;
+ break;
+ case DataType::BIGINT:
+ if ( _rRH.m_bSigned )
+ {
+ m_aValue.m_pValue = new sal_Int64(*(sal_Int64*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( sal_Int64 )
+ }
+ else
+ {
+ rtl_uString_acquire(_rRH.m_aValue.m_pString);
+ m_aValue.m_pString = _rRH.m_aValue.m_pString;
+ }
+ break;
+ case DataType::FLOAT:
+ m_aValue.m_pValue = new float(*(float*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( float )
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ m_aValue.m_pValue = new double(*(double*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( double )
+ break;
+ case DataType::DATE:
+ m_aValue.m_pValue = new Date(*(Date*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( Date )
+ break;
+ case DataType::TIME:
+ m_aValue.m_pValue = new Time(*(Time*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( Time )
+ break;
+ case DataType::TIMESTAMP:
+ m_aValue.m_pValue = new DateTime(*(DateTime*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( DateTime )
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ m_aValue.m_pValue = new Sequence<sal_Int8>(*(Sequence<sal_Int8>*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( Sequence_sal_Int8 )
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ m_aValue.m_bBool = _rRH.m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( _rRH.m_bSigned )
+ m_aValue.m_nInt8 = _rRH.m_aValue.m_nInt8;
+ else
+ m_aValue.m_nInt16 = _rRH.m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( _rRH.m_bSigned )
+ m_aValue.m_nInt16 = _rRH.m_aValue.m_nInt16;
+ else
+ m_aValue.m_nInt32 = _rRH.m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( _rRH.m_bSigned )
+ m_aValue.m_nInt32 = _rRH.m_aValue.m_nInt32;
+ else
+ {
+ m_aValue.m_pValue = new sal_Int64(*(sal_Int64*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( sal_Int64 )
+ }
+ break;
+ default:
+ m_aValue.m_pValue = new Any(*(Any*)_rRH.m_aValue.m_pValue);
+ TRACE_ALLOC( Any )
+ }
+ }
+ else if(!_rRH.m_bNull)
+ {
+ switch(_rRH.m_eTypeKind)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ (*this) = ::rtl::OUString(_rRH.m_aValue.m_pString);
+ break;
+ case DataType::BIGINT:
+ if ( _rRH.m_bSigned )
+ (*this) = *(sal_Int64*)_rRH.m_aValue.m_pValue;
+ else
+ (*this) = ::rtl::OUString(_rRH.m_aValue.m_pString);
+ break;
+ case DataType::FLOAT:
+ (*this) = *(float*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ (*this) = *(double*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::DATE:
+ (*this) = *(Date*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::TIME:
+ (*this) = *(Time*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::TIMESTAMP:
+ (*this) = *(DateTime*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ (*this) = *(Sequence<sal_Int8>*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ m_aValue.m_bBool = _rRH.m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( _rRH.m_bSigned )
+ m_aValue.m_nInt8 = _rRH.m_aValue.m_nInt8;
+ else
+ m_aValue.m_nInt16 = _rRH.m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( _rRH.m_bSigned )
+ m_aValue.m_nInt16 = _rRH.m_aValue.m_nInt16;
+ else
+ m_aValue.m_nInt32 = _rRH.m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( _rRH.m_bSigned )
+ m_aValue.m_nInt32 = _rRH.m_aValue.m_nInt32;
+ else
+ *static_cast<sal_Int64*>(m_aValue.m_pValue) = *(sal_Int64*)_rRH.m_aValue.m_pValue;
+ break;
+ default:
+ (*(Any*)m_aValue.m_pValue) = (*(Any*)_rRH.m_aValue.m_pValue);
+ }
+ }
+
+ m_bNull = _rRH.m_bNull;
+ // OJ: BUGID: 96277
+ m_eTypeKind = _rRH.m_eTypeKind;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const Date& _rRH)
+{
+ if(m_eTypeKind != DataType::DATE)
+ free();
+
+ if(m_bNull)
+ {
+ m_aValue.m_pValue = new Date(_rRH);
+ TRACE_ALLOC( Date )
+ m_eTypeKind = DataType::DATE;
+ m_bNull = sal_False;
+ }
+ else
+ *(Date*)m_aValue.m_pValue = _rRH;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const Time& _rRH)
+{
+ if(m_eTypeKind != DataType::TIME)
+ free();
+
+ if(m_bNull)
+ {
+ m_aValue.m_pValue = new Time(_rRH);
+ TRACE_ALLOC( Time )
+ m_eTypeKind = DataType::TIME;
+ m_bNull = sal_False;
+ }
+ else
+ *(Time*)m_aValue.m_pValue = _rRH;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const DateTime& _rRH)
+{
+ if(m_eTypeKind != DataType::TIMESTAMP)
+ free();
+ if(m_bNull)
+ {
+ m_aValue.m_pValue = new DateTime(_rRH);
+ TRACE_ALLOC( DateTime )
+ m_eTypeKind = DataType::TIMESTAMP;
+ m_bNull = sal_False;
+ }
+ else
+ *(DateTime*)m_aValue.m_pValue = _rRH;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const ::rtl::OUString& _rRH)
+{
+ if(m_eTypeKind != DataType::VARCHAR || m_aValue.m_pString != _rRH.pData)
+ {
+ free();
+ m_bNull = sal_False;
+
+ m_aValue.m_pString = _rRH.pData;
+ rtl_uString_acquire(m_aValue.m_pString);
+ m_eTypeKind = DataType::VARCHAR;
+ }
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const double& _rRH)
+{
+ if( !isStorageCompatible(m_eTypeKind,DataType::DOUBLE) )
+ free();
+
+ if(m_bNull)
+ {
+ m_aValue.m_pValue = new double(_rRH);
+ TRACE_ALLOC( double )
+ m_eTypeKind = DataType::DOUBLE;
+ m_bNull = sal_False;
+ }
+ else
+ *(double*)m_aValue.m_pValue = _rRH;
+
+ return *this;
+}
+// -----------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const float& _rRH)
+{
+ if(m_eTypeKind != DataType::FLOAT)
+ free();
+
+ if(m_bNull)
+ {
+ m_aValue.m_pValue = new float(_rRH);
+ TRACE_ALLOC( float )
+ m_eTypeKind = DataType::FLOAT;
+ m_bNull = sal_False;
+ }
+ else
+ *(float*)m_aValue.m_pValue = _rRH;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const sal_Int8& _rRH)
+{
+ if(m_eTypeKind != DataType::TINYINT )
+ free();
+
+ m_aValue.m_nInt8 = _rRH;
+ m_eTypeKind = DataType::TINYINT;
+ m_bNull = sal_False;
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const sal_Int16& _rRH)
+{
+ if(m_eTypeKind != DataType::SMALLINT )
+ free();
+
+ m_aValue.m_nInt16 = _rRH;
+ m_eTypeKind = DataType::SMALLINT;
+ m_bNull = sal_False;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const sal_Int32& _rRH)
+{
+ if(m_eTypeKind != DataType::INTEGER )
+ free();
+
+ if ( m_bSigned )
+ m_aValue.m_nInt32 = _rRH;
+ else
+ {
+ if ( m_bNull )
+ {
+ m_aValue.m_pValue = new sal_Int64(_rRH);
+ TRACE_ALLOC( sal_Int64 )
+ }
+ else
+ *static_cast<sal_Int64*>(m_aValue.m_pValue) = static_cast<sal_Int64>(_rRH);
+ }
+
+ m_eTypeKind = DataType::INTEGER;
+ m_bNull = sal_False;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+ORowSetValue& ORowSetValue::operator=(const sal_Bool _rRH)
+{
+ if(m_eTypeKind != DataType::BIT && DataType::BOOLEAN != m_eTypeKind )
+ free();
+
+ m_aValue.m_bBool = _rRH;
+ m_eTypeKind = DataType::BIT;
+ m_bNull = sal_False;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const sal_Int64& _rRH)
+{
+ if ( DataType::BIGINT != m_eTypeKind || !m_bSigned )
+ free();
+
+ if ( m_bSigned )
+ {
+ if(m_bNull)
+ {
+ m_aValue.m_pValue = new sal_Int64(_rRH);
+ TRACE_ALLOC( sal_Int64 )
+ }
+ else
+ *static_cast<sal_Int64*>(m_aValue.m_pValue) = _rRH;
+ }
+ else
+ {
+ ::rtl::OUString aVal = ::rtl::OUString::valueOf(_rRH);
+ m_aValue.m_pString = aVal.pData;
+ rtl_uString_acquire(m_aValue.m_pString);
+ }
+
+ m_eTypeKind = DataType::BIGINT;
+ m_bNull = sal_False;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const Sequence<sal_Int8>& _rRH)
+{
+ if (!isStorageCompatible(DataType::LONGVARBINARY,m_eTypeKind))
+ free();
+
+ if (m_bNull)
+ {
+ m_aValue.m_pValue = new Sequence<sal_Int8>(_rRH);
+ TRACE_ALLOC( Sequence_sal_Int8 )
+ }
+ else
+ *static_cast< Sequence< sal_Int8 >* >(m_aValue.m_pValue) = _rRH;
+
+ m_eTypeKind = DataType::LONGVARBINARY;
+ m_bNull = sal_False;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+ORowSetValue& ORowSetValue::operator=(const Any& _rAny)
+{
+ if (!isStorageCompatible(DataType::OBJECT,m_eTypeKind))
+ free();
+
+ if ( m_bNull )
+ {
+ m_aValue.m_pValue = new Any(_rAny);
+ TRACE_ALLOC( Any )
+ }
+ else
+ *static_cast<Any*>(m_aValue.m_pValue) = _rAny;
+
+ m_eTypeKind = DataType::OBJECT;
+ m_bNull = sal_False;
+
+ return *this;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool operator==(const Date& _rLH,const Date& _rRH)
+{
+ return _rLH.Day == _rRH.Day && _rLH.Month == _rRH.Month && _rLH.Year == _rRH.Year;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool operator==(const Time& _rLH,const Time& _rRH)
+{
+ return _rLH.Minutes == _rRH.Minutes && _rLH.Hours == _rRH.Hours && _rLH.Seconds == _rRH.Seconds && _rLH.HundredthSeconds == _rRH.HundredthSeconds;
+}
+// -------------------------------------------------------------------------
+
+sal_Bool operator==(const DateTime& _rLH,const DateTime& _rRH)
+{
+ return _rLH.Day == _rRH.Day && _rLH.Month == _rRH.Month && _rLH.Year == _rRH.Year &&
+ _rLH.Minutes == _rRH.Minutes && _rLH.Hours == _rRH.Hours && _rLH.Seconds == _rRH.Seconds && _rLH.HundredthSeconds == _rRH.HundredthSeconds;
+}
+// -------------------------------------------------------------------------
+
+bool ORowSetValue::operator==(const ORowSetValue& _rRH) const
+{
+ if(m_eTypeKind != _rRH.m_eTypeKind)
+ return false;
+ if ( m_bSigned != _rRH.m_bSigned )
+ return false;
+ if(m_bNull != _rRH.isNull())
+ return false;
+ if(m_bNull && _rRH.isNull())
+ return true;
+
+ bool bRet = false;
+ OSL_ENSURE(!m_bNull,"SHould not be null!");
+ switch(m_eTypeKind)
+ {
+ case DataType::VARCHAR:
+ case DataType::CHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ {
+ ::rtl::OUString aVal1(m_aValue.m_pString);
+ ::rtl::OUString aVal2(_rRH.m_aValue.m_pString);
+ bRet = aVal1 == aVal2;
+ break;
+ }
+
+ case DataType::FLOAT:
+ bRet = *(float*)m_aValue.m_pValue == *(float*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ bRet = *(double*)m_aValue.m_pValue == *(double*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::TINYINT:
+ bRet = m_bSigned ? ( m_aValue.m_nInt8 == _rRH.m_aValue.m_nInt8 ) : (m_aValue.m_nInt16 == _rRH.m_aValue.m_nInt16);
+ break;
+ case DataType::SMALLINT:
+ bRet = m_bSigned ? ( m_aValue.m_nInt16 == _rRH.m_aValue.m_nInt16 ) : (m_aValue.m_nInt32 == _rRH.m_aValue.m_nInt32);
+ break;
+ case DataType::INTEGER:
+ bRet = m_bSigned ? ( m_aValue.m_nInt32 == _rRH.m_aValue.m_nInt32 ) : (*(sal_Int64*)m_aValue.m_pValue == *(sal_Int64*)_rRH.m_aValue.m_pValue);
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ bRet = *(sal_Int64*)m_aValue.m_pValue == *(sal_Int64*)_rRH.m_aValue.m_pValue;
+ else
+ {
+ ::rtl::OUString aVal1(m_aValue.m_pString);
+ ::rtl::OUString aVal2(_rRH.m_aValue.m_pString);
+ bRet = aVal1 == aVal2;
+ }
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ bRet = m_aValue.m_bBool == _rRH.m_aValue.m_bBool;
+ break;
+ case DataType::DATE:
+ bRet = *(Date*)m_aValue.m_pValue == *(Date*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::TIME:
+ bRet = *(Time*)m_aValue.m_pValue == *(Time*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::TIMESTAMP:
+ bRet = *(DateTime*)m_aValue.m_pValue == *(DateTime*)_rRH.m_aValue.m_pValue;
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ bRet = false;
+ break;
+ case DataType::BLOB:
+ case DataType::CLOB:
+ case DataType::OBJECT:
+ case DataType::OTHER:
+ bRet = false;
+ break;
+ default:
+ bRet = false;
+ OSL_ENSURE(0,"ORowSetValue::operator==(): UNSPUPPORTED TYPE!");
+ break;
+ }
+ return bRet;
+}
+// -------------------------------------------------------------------------
+Any ORowSetValue::makeAny() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::makeAny" );
+ Any rValue;
+ if(isBound() && !isNull())
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ OSL_ENSURE(m_aValue.m_pString,"Value is null!");
+ rValue <<= (::rtl::OUString)m_aValue.m_pString;
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ {
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(sal_Int64*)m_aValue.m_pValue;
+ }
+ else
+ {
+ OSL_ENSURE(m_aValue.m_pString,"Value is null!");
+ rValue <<= (::rtl::OUString)m_aValue.m_pString;
+ }
+ break;
+ case DataType::FLOAT:
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(float*)m_aValue.m_pValue;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(double*)m_aValue.m_pValue;
+ break;
+ case DataType::DATE:
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(Date*)m_aValue.m_pValue;
+ break;
+ case DataType::TIME:
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(Time*)m_aValue.m_pValue;
+ break;
+ case DataType::TIMESTAMP:
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(DateTime*)m_aValue.m_pValue;
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(Sequence<sal_Int8>*)m_aValue.m_pValue;
+ break;
+ case DataType::BLOB:
+ case DataType::CLOB:
+ case DataType::OBJECT:
+ case DataType::OTHER:
+ rValue = getAny();
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ rValue.setValue( &m_aValue.m_bBool, ::getCppuBooleanType() );
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ rValue <<= m_aValue.m_nInt8;
+ else
+ rValue <<= m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ rValue <<= m_aValue.m_nInt16;
+ else
+ rValue <<= m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ rValue <<= m_aValue.m_nInt32;
+ else
+ {
+ OSL_ENSURE(m_aValue.m_pValue,"Value is null!");
+ rValue <<= *(sal_Int64*)m_aValue.m_pValue;
+ }
+ break;
+ default:
+ OSL_ENSURE(0,"ORowSetValue::makeAny(): UNSPUPPORTED TYPE!");
+ rValue = getAny();
+ break;
+ }
+ }
+ return rValue;
+}
+// -------------------------------------------------------------------------
+::rtl::OUString ORowSetValue::getString( ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getString" );
+ ::rtl::OUString aRet;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ aRet = m_aValue.m_pString;
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ aRet = ::rtl::OUString::valueOf((sal_Int64)*this);
+ else
+ aRet = m_aValue.m_pString;
+ break;
+ case DataType::FLOAT:
+ aRet = ::rtl::OUString::valueOf((float)*this);
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ aRet = ::rtl::OUString::valueOf((double)*this);
+ break;
+ case DataType::DATE:
+ aRet = connectivity::toDateString(*this);
+ break;
+ case DataType::TIME:
+ aRet = connectivity::toTimeString(*this);
+ break;
+ case DataType::TIMESTAMP:
+ aRet = connectivity::toDateTimeString(*this);
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ {
+ ::rtl::OUStringBuffer sVal = ::rtl::OUString::createFromAscii("0x");
+ Sequence<sal_Int8> aSeq(getSequence());
+ const sal_Int8* pBegin = aSeq.getConstArray();
+ const sal_Int8* pEnd = pBegin + aSeq.getLength();
+ for(;pBegin != pEnd;++pBegin)
+ sVal.append((sal_Int32)*pBegin,16);
+ aRet = sVal.makeStringAndClear();
+ }
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ aRet = ::rtl::OUString::valueOf((sal_Int32)(sal_Bool)*this);
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ aRet = ::rtl::OUString::valueOf((sal_Int32)(sal_Int8)*this);
+ else
+ aRet = ::rtl::OUString::valueOf((sal_Int32)(sal_Int16)*this);
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ aRet = ::rtl::OUString::valueOf((sal_Int32)(sal_Int16)*this);
+ else
+ aRet = ::rtl::OUString::valueOf((sal_Int32)*this);
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ aRet = ::rtl::OUString::valueOf((sal_Int32)*this);
+ else
+ aRet = ::rtl::OUString::valueOf((sal_Int64)*this);
+ break;
+ case DataType::CLOB:
+ {
+ Any aValue( getAny() );
+ Reference< XClob > xClob;
+ if ( aValue >>= xClob )
+ {
+ if ( xClob.is() )
+ {
+ aRet = xClob->getSubString(1,(sal_Int32)xClob->length() );
+ }
+ }
+ }
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= aRet;
+ break;
+ }
+ }
+ }
+ return aRet;
+}
+// -------------------------------------------------------------------------
+sal_Bool ORowSetValue::getBool() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getBool" );
+ sal_Bool bRet = sal_False;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ {
+ const ::rtl::OUString sValue(m_aValue.m_pString);
+ const static ::rtl::OUString s_sTrue(RTL_CONSTASCII_USTRINGPARAM("true"));
+ const static ::rtl::OUString s_sFalse(RTL_CONSTASCII_USTRINGPARAM("false"));
+ if ( sValue.equalsIgnoreAsciiCase(s_sTrue) )
+ {
+ bRet = sal_True;
+ break;
+ }
+ else if ( sValue.equalsIgnoreAsciiCase(s_sFalse) )
+ {
+ bRet = sal_False;
+ break;
+ }
+ }
+ // run through
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+
+ bRet = ::rtl::OUString(m_aValue.m_pString).toInt32() != 0;
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ bRet = *(sal_Int64*)m_aValue.m_pValue != 0;
+ else
+ bRet = ::rtl::OUString(m_aValue.m_pString).toInt64() != 0;
+ break;
+ case DataType::FLOAT:
+ bRet = *(float*)m_aValue.m_pValue != 0.0;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ bRet = *(double*)m_aValue.m_pValue != 0.0;
+ break;
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ OSL_ASSERT(!"getBool() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ bRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ bRet = m_bSigned ? (m_aValue.m_nInt8 != 0) : (m_aValue.m_nInt16 != 0);
+ break;
+ case DataType::SMALLINT:
+ bRet = m_bSigned ? (m_aValue.m_nInt16 != 0) : (m_aValue.m_nInt32 != 0);
+ break;
+ case DataType::INTEGER:
+ bRet = m_bSigned ? (m_aValue.m_nInt32 != 0) : (*static_cast<sal_Int64*>(m_aValue.m_pValue) != sal_Int64(0));
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= bRet;
+ break;
+ }
+ }
+ }
+ return bRet;
+}
+// -------------------------------------------------------------------------
+sal_Int8 ORowSetValue::getInt8() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getInt8" );
+
+
+ sal_Int8 nRet = 0;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ nRet = sal_Int8(::rtl::OUString(m_aValue.m_pString).toInt32());
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ nRet = sal_Int8(*(sal_Int64*)m_aValue.m_pValue);
+ else
+ nRet = sal_Int8(::rtl::OUString(m_aValue.m_pString).toInt32());
+ break;
+ case DataType::FLOAT:
+ nRet = sal_Int8(*(float*)m_aValue.m_pValue);
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ nRet = sal_Int8(*(double*)m_aValue.m_pValue);
+ break;
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"getInt8() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt8;
+ else
+ nRet = static_cast<sal_Int8>(m_aValue.m_nInt16);
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ nRet = static_cast<sal_Int8>(m_aValue.m_nInt16);
+ else
+ nRet = static_cast<sal_Int8>(m_aValue.m_nInt32);
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ nRet = static_cast<sal_Int8>(m_aValue.m_nInt32);
+ else
+ nRet = static_cast<sal_Int8>(*static_cast<sal_Int64*>(m_aValue.m_pValue));
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= nRet;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+// -------------------------------------------------------------------------
+sal_Int16 ORowSetValue::getInt16() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getInt16" );
+
+
+ sal_Int16 nRet = 0;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ nRet = sal_Int16(::rtl::OUString(m_aValue.m_pString).toInt32());
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ nRet = sal_Int16(*(sal_Int64*)m_aValue.m_pValue);
+ else
+ nRet = sal_Int16(::rtl::OUString(m_aValue.m_pString).toInt32());
+ break;
+ case DataType::FLOAT:
+ nRet = sal_Int16(*(float*)m_aValue.m_pValue);
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ nRet = sal_Int16(*(double*)m_aValue.m_pValue);
+ break;
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"getInt16() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt8;
+ else
+ nRet = m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt16;
+ else
+ nRet = static_cast<sal_Int16>(m_aValue.m_nInt32);
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ nRet = static_cast<sal_Int16>(m_aValue.m_nInt32);
+ else
+ nRet = static_cast<sal_Int16>(*static_cast<sal_Int64*>(m_aValue.m_pValue));
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= nRet;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+// -------------------------------------------------------------------------
+sal_Int32 ORowSetValue::getInt32() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getInt32" );
+ sal_Int32 nRet = 0;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ nRet = ::rtl::OUString(m_aValue.m_pString).toInt32();
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ nRet = sal_Int32(*(sal_Int64*)m_aValue.m_pValue);
+ else
+ nRet = ::rtl::OUString(m_aValue.m_pString).toInt32();
+ break;
+ case DataType::FLOAT:
+ nRet = sal_Int32(*(float*)m_aValue.m_pValue);
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ nRet = sal_Int32(*(double*)m_aValue.m_pValue);
+ break;
+ case DataType::DATE:
+ nRet = dbtools::DBTypeConversion::toDays(*(::com::sun::star::util::Date*)m_aValue.m_pValue);
+ break;
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"getInt32() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt8;
+ else
+ nRet = m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt16;
+ else
+ nRet = m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt32;
+ else
+ nRet = static_cast<sal_Int32>(*static_cast<sal_Int64*>(m_aValue.m_pValue));
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= nRet;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+// -------------------------------------------------------------------------
+sal_Int64 ORowSetValue::getLong() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getLong" );
+ sal_Int64 nRet = 0;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ nRet = ::rtl::OUString(m_aValue.m_pString).toInt64();
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ nRet = *(sal_Int64*)m_aValue.m_pValue;
+ else
+ nRet = ::rtl::OUString(m_aValue.m_pString).toInt64();
+ break;
+ case DataType::FLOAT:
+ nRet = sal_Int64(*(float*)m_aValue.m_pValue);
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ nRet = sal_Int64(*(double*)m_aValue.m_pValue);
+ break;
+ case DataType::DATE:
+ nRet = dbtools::DBTypeConversion::toDays(*(::com::sun::star::util::Date*)m_aValue.m_pValue);
+ break;
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"getInt32() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt8;
+ else
+ nRet = m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt16;
+ else
+ nRet = m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt32;
+ else
+ nRet = *(sal_Int64*)m_aValue.m_pValue;
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= nRet;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+// -------------------------------------------------------------------------
+float ORowSetValue::getFloat() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getFloat" );
+ float nRet = 0;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ nRet = ::rtl::OUString(m_aValue.m_pString).toFloat();
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ nRet = float(*(sal_Int64*)m_aValue.m_pValue);
+ else
+ nRet = ::rtl::OUString(m_aValue.m_pString).toFloat();
+ break;
+ case DataType::FLOAT:
+ nRet = *(float*)m_aValue.m_pValue;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ nRet = (float)*(double*)m_aValue.m_pValue;
+ break;
+ case DataType::DATE:
+ nRet = (float)dbtools::DBTypeConversion::toDouble(*(::com::sun::star::util::Date*)m_aValue.m_pValue);
+ break;
+ case DataType::TIME:
+ nRet = (float)dbtools::DBTypeConversion::toDouble(*(::com::sun::star::util::Time*)m_aValue.m_pValue);
+ break;
+ case DataType::TIMESTAMP:
+ nRet = (float)dbtools::DBTypeConversion::toDouble(*(::com::sun::star::util::DateTime*)m_aValue.m_pValue);
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"getDouble() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt8;
+ else
+ nRet = m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt16;
+ else
+ nRet = (float)m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ nRet = (float)m_aValue.m_nInt32;
+ else
+ nRet = float(*(sal_Int64*)m_aValue.m_pValue);
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= nRet;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+// -------------------------------------------------------------------------
+double ORowSetValue::getDouble() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getDouble" );
+
+
+ double nRet = 0;
+ if(!m_bNull)
+ {
+ switch(getTypeKind())
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ nRet = ::rtl::OUString(m_aValue.m_pString).toDouble();
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ nRet = double(*(sal_Int64*)m_aValue.m_pValue);
+ else
+ nRet = ::rtl::OUString(m_aValue.m_pString).toDouble();
+ break;
+ case DataType::FLOAT:
+ nRet = *(float*)m_aValue.m_pValue;
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ nRet = *(double*)m_aValue.m_pValue;
+ break;
+ case DataType::DATE:
+ nRet = dbtools::DBTypeConversion::toDouble(*(::com::sun::star::util::Date*)m_aValue.m_pValue);
+ break;
+ case DataType::TIME:
+ nRet = dbtools::DBTypeConversion::toDouble(*(::com::sun::star::util::Time*)m_aValue.m_pValue);
+ break;
+ case DataType::TIMESTAMP:
+ nRet = dbtools::DBTypeConversion::toDouble(*(::com::sun::star::util::DateTime*)m_aValue.m_pValue);
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"getDouble() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nRet = m_aValue.m_bBool;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt8;
+ else
+ nRet = m_aValue.m_nInt16;
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt16;
+ else
+ nRet = m_aValue.m_nInt32;
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ nRet = m_aValue.m_nInt32;
+ else
+ nRet = double(*(sal_Int64*)m_aValue.m_pValue);
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= nRet;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+// -------------------------------------------------------------------------
+void ORowSetValue::setFromDouble(const double& _rVal,sal_Int32 _nDatatype)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::setFromDouble" );
+ free();
+
+ m_bNull = sal_False;
+ switch(_nDatatype)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ {
+ ::rtl::OUString aVal = ::rtl::OUString::valueOf(_rVal);
+ m_aValue.m_pString = aVal.pData;
+ rtl_uString_acquire(m_aValue.m_pString);
+ }
+ break;
+ case DataType::BIGINT:
+ if ( m_bSigned )
+ {
+ m_aValue.m_pValue = new sal_Int64((sal_Int64)_rVal);
+ TRACE_ALLOC( sal_Int64 )
+ }
+ else
+ {
+ ::rtl::OUString aVal = ::rtl::OUString::valueOf(_rVal);
+ m_aValue.m_pString = aVal.pData;
+ rtl_uString_acquire(m_aValue.m_pString);
+ }
+ break;
+ case DataType::FLOAT:
+ m_aValue.m_pValue = new float((float)_rVal);
+ TRACE_ALLOC( float )
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ m_aValue.m_pValue = new double(_rVal);
+ TRACE_ALLOC( double )
+ break;
+ case DataType::DATE:
+ m_aValue.m_pValue = new Date(dbtools::DBTypeConversion::toDate(_rVal));
+ TRACE_ALLOC( Date )
+ break;
+ case DataType::TIME:
+ m_aValue.m_pValue = new Time(dbtools::DBTypeConversion::toTime(_rVal));
+ TRACE_ALLOC( Time )
+ break;
+ case DataType::TIMESTAMP:
+ m_aValue.m_pValue = new DateTime(dbtools::DBTypeConversion::toDateTime(_rVal));
+ TRACE_ALLOC( DateTime )
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ case DataType::CLOB:
+ OSL_ASSERT(!"setFromDouble() for this type is not allowed!");
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ m_aValue.m_bBool = _rVal != 0.0;
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ m_aValue.m_nInt8 = sal_Int8(_rVal);
+ else
+ m_aValue.m_nInt16 = sal_Int16(_rVal);
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ m_aValue.m_nInt16 = sal_Int16(_rVal);
+ else
+ m_aValue.m_nInt32 = sal_Int32(_rVal);
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ m_aValue.m_nInt32 = sal_Int32(_rVal);
+ else
+ {
+ m_aValue.m_pValue = new sal_Int64((sal_Int64)_rVal);
+ TRACE_ALLOC( sal_Int64 )
+ }
+ break;
+ default:
+ {
+ m_aValue.m_pValue = new Any(_rVal);
+ break;
+ }
+ }
+ m_eTypeKind = _nDatatype;
+}
+// -----------------------------------------------------------------------------
+Sequence<sal_Int8> ORowSetValue::getSequence() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getSequence" );
+ Sequence<sal_Int8> aSeq;
+ if (!m_bNull)
+ {
+ switch(m_eTypeKind)
+ {
+ case DataType::OBJECT:
+ case DataType::CLOB:
+ case DataType::BLOB:
+ {
+ Reference<XInputStream> xStream;
+ const Any aValue = makeAny();
+ if(aValue.hasValue())
+ {
+ Reference<XBlob> xBlob(aValue,UNO_QUERY);
+ if ( xBlob.is() )
+ xStream = xBlob->getBinaryStream();
+ else
+ {
+ Reference<XClob> xClob(aValue,UNO_QUERY);
+ if ( xClob.is() )
+ xStream = xClob->getCharacterStream();
+ }
+ if(xStream.is())
+ {
+ const sal_uInt32 nBytesToRead = 65535;
+ sal_uInt32 nRead;
+
+ do
+ {
+ ::com::sun::star::uno::Sequence< sal_Int8 > aReadSeq;
+
+ nRead = xStream->readSomeBytes( aReadSeq, nBytesToRead );
+
+ if( nRead )
+ {
+ const sal_uInt32 nOldLength = aSeq.getLength();
+ aSeq.realloc( nOldLength + nRead );
+ rtl_copyMemory( aSeq.getArray() + nOldLength, aReadSeq.getConstArray(), aReadSeq.getLength() );
+ }
+ }
+ while( nBytesToRead == nRead );
+ xStream->closeInput();
+ }
+ }
+ }
+ break;
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ {
+ ::rtl::OUString sVal(m_aValue.m_pString);
+ aSeq = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(sVal.getStr()),sizeof(sal_Unicode)*sVal.getLength());
+ }
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ aSeq = *static_cast< Sequence<sal_Int8>*>(m_aValue.m_pValue);
+ break;
+ default:
+ {
+ Any aValue = getAny();
+ aValue >>= aSeq;
+ break;
+ }
+ }
+ }
+ return aSeq;
+
+}
+// -----------------------------------------------------------------------------
+::com::sun::star::util::Date ORowSetValue::getDate() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getDate" );
+ ::com::sun::star::util::Date aValue;
+ if(!m_bNull)
+ {
+ switch(m_eTypeKind)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ aValue = DBTypeConversion::toDate(getString());
+ break;
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ aValue = DBTypeConversion::toDate((double)*this);
+ break;
+ case DataType::FLOAT:
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ aValue = DBTypeConversion::toDate((double)*this);
+ break;
+
+ case DataType::DATE:
+ aValue = *static_cast< ::com::sun::star::util::Date*>(m_aValue.m_pValue);
+ break;
+ case DataType::TIMESTAMP:
+ {
+ ::com::sun::star::util::DateTime* pDateTime = static_cast< ::com::sun::star::util::DateTime*>(m_aValue.m_pValue);
+ aValue.Day = pDateTime->Day;
+ aValue.Month = pDateTime->Month;
+ aValue.Year = pDateTime->Year;
+ }
+ break;
+ default:
+ {
+ Any aAnyValue = getAny();
+ aAnyValue >>= aValue;
+ break;
+ }
+ }
+ }
+ return aValue;
+}
+// -----------------------------------------------------------------------------
+::com::sun::star::util::Time ORowSetValue::getTime() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getTime" );
+ ::com::sun::star::util::Time aValue;
+ if(!m_bNull)
+ {
+ switch(m_eTypeKind)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ aValue = DBTypeConversion::toTime(getString());
+ break;
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ aValue = DBTypeConversion::toTime((double)*this);
+ break;
+ case DataType::FLOAT:
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ aValue = DBTypeConversion::toTime((double)*this);
+ break;
+ case DataType::TIMESTAMP:
+ {
+ ::com::sun::star::util::DateTime* pDateTime = static_cast< ::com::sun::star::util::DateTime*>(m_aValue.m_pValue);
+ aValue.HundredthSeconds = pDateTime->HundredthSeconds;
+ aValue.Seconds = pDateTime->Seconds;
+ aValue.Minutes = pDateTime->Minutes;
+ aValue.Hours = pDateTime->Hours;
+ }
+ break;
+ case DataType::TIME:
+ aValue = *static_cast< ::com::sun::star::util::Time*>(m_aValue.m_pValue);
+ break;
+ default:
+ {
+ Any aAnyValue = getAny();
+ aAnyValue >>= aValue;
+ break;
+ }
+ }
+ }
+ return aValue;
+}
+// -----------------------------------------------------------------------------
+::com::sun::star::util::DateTime ORowSetValue::getDateTime() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::getDateTime" );
+ ::com::sun::star::util::DateTime aValue;
+ if(!m_bNull)
+ {
+ switch(m_eTypeKind)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ aValue = DBTypeConversion::toDateTime(getString());
+ break;
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ aValue = DBTypeConversion::toDateTime((double)*this);
+ break;
+ case DataType::FLOAT:
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ aValue = DBTypeConversion::toDateTime((double)*this);
+ break;
+ case DataType::DATE:
+ {
+ ::com::sun::star::util::Date* pDate = static_cast< ::com::sun::star::util::Date*>(m_aValue.m_pValue);
+ aValue.Day = pDate->Day;
+ aValue.Month = pDate->Month;
+ aValue.Year = pDate->Year;
+ }
+ break;
+ case DataType::TIME:
+ {
+ ::com::sun::star::util::Time* pTime = static_cast< ::com::sun::star::util::Time*>(m_aValue.m_pValue);
+ aValue.HundredthSeconds = pTime->HundredthSeconds;
+ aValue.Seconds = pTime->Seconds;
+ aValue.Minutes = pTime->Minutes;
+ aValue.Hours = pTime->Hours;
+ }
+ break;
+ case DataType::TIMESTAMP:
+ aValue = *static_cast< ::com::sun::star::util::DateTime*>(m_aValue.m_pValue);
+ break;
+ default:
+ {
+ Any aAnyValue = getAny();
+ aAnyValue >>= aValue;
+ break;
+ }
+ }
+ }
+ return aValue;
+}
+// -----------------------------------------------------------------------------
+void ORowSetValue::setSigned(sal_Bool _bMod)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::setSigned" );
+ if ( m_bSigned != _bMod )
+ {
+ m_bSigned = _bMod;
+ if ( !m_bNull )
+ {
+ sal_Int32 nType = m_eTypeKind;
+ switch(m_eTypeKind)
+ {
+ case DataType::BIGINT:
+ if ( m_bSigned ) // now we are signed, so we were unsigned and need to call getString()
+ {
+ m_bSigned = !m_bSigned;
+ const ::rtl::OUString sValue = getString();
+ free();
+ m_bSigned = !m_bSigned;
+ (*this) = sValue;
+ }
+ else
+ {
+ m_bSigned = !m_bSigned;
+ const sal_Int64 nValue = getLong();
+ free();
+ m_bSigned = !m_bSigned;
+ (*this) = nValue;
+ }
+ break;
+ case DataType::TINYINT:
+ if ( m_bSigned )
+ (*this) = getInt8();
+ else
+ {
+ m_bSigned = !m_bSigned;
+ (*this) = getInt16();
+ m_bSigned = !m_bSigned;
+ }
+ break;
+ case DataType::SMALLINT:
+ if ( m_bSigned )
+ (*this) = getInt16();
+ else
+ {
+ m_bSigned = !m_bSigned;
+ (*this) = getInt32();
+ m_bSigned = !m_bSigned;
+ }
+ break;
+ case DataType::INTEGER:
+ if ( m_bSigned )
+ (*this) = getInt32();
+ else
+ {
+ m_bSigned = !m_bSigned;
+ (*this) = getLong();
+ m_bSigned = !m_bSigned;
+ }
+ break;
+ }
+ m_eTypeKind = nType;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+namespace detail
+{
+ class SAL_NO_VTABLE IValueSource
+ {
+ public:
+ virtual ::rtl::OUString getString() const = 0;
+ virtual sal_Bool getBoolean() const = 0;
+ virtual sal_Int8 getByte() const = 0;
+ virtual sal_Int16 getShort() const = 0;
+ virtual sal_Int32 getInt() const = 0;
+ virtual sal_Int64 getLong() const = 0;
+ virtual float getFloat() const = 0;
+ virtual double getDouble() const = 0;
+ virtual Date getDate() const = 0;
+ virtual Time getTime() const = 0;
+ virtual DateTime getTimestamp() const = 0;
+ virtual Sequence< sal_Int8 > getBytes() const = 0;
+ virtual Reference< XInputStream > getBinaryStream() const = 0;
+ virtual Reference< XInputStream > getCharacterStream() const = 0;
+ virtual Reference< XBlob > getBlob() const = 0;
+ virtual Reference< XClob > getClob() const = 0;
+ virtual Any getObject() const = 0;
+ virtual sal_Bool wasNull() const = 0;
+
+ virtual ~IValueSource() { }
+ };
+
+ class RowValue : public IValueSource
+ {
+ public:
+ RowValue( const Reference< XRow >& _xRow, const sal_Int32 _nPos )
+ :m_xRow( _xRow )
+ ,m_nPos( _nPos )
+ {
+ }
+
+ // IValueSource
+ virtual ::rtl::OUString getString() const { return m_xRow->getString( m_nPos ); };
+ virtual sal_Bool getBoolean() const { return m_xRow->getBoolean( m_nPos ); };
+ virtual sal_Int8 getByte() const { return m_xRow->getByte( m_nPos ); };
+ virtual sal_Int16 getShort() const { return m_xRow->getShort( m_nPos ); }
+ virtual sal_Int32 getInt() const { return m_xRow->getInt( m_nPos ); }
+ virtual sal_Int64 getLong() const { return m_xRow->getLong( m_nPos ); }
+ virtual float getFloat() const { return m_xRow->getFloat( m_nPos ); };
+ virtual double getDouble() const { return m_xRow->getDouble( m_nPos ); };
+ virtual Date getDate() const { return m_xRow->getDate( m_nPos ); };
+ virtual Time getTime() const { return m_xRow->getTime( m_nPos ); };
+ virtual DateTime getTimestamp() const { return m_xRow->getTimestamp( m_nPos ); };
+ virtual Sequence< sal_Int8 > getBytes() const { return m_xRow->getBytes( m_nPos ); };
+ virtual Reference< XInputStream > getBinaryStream() const { return m_xRow->getBinaryStream( m_nPos ); };
+ virtual Reference< XInputStream > getCharacterStream() const { return m_xRow->getCharacterStream( m_nPos ); };
+ virtual Reference< XBlob > getBlob() const { return m_xRow->getBlob( m_nPos ); };
+ virtual Reference< XClob > getClob() const { return m_xRow->getClob( m_nPos ); };
+ virtual Any getObject() const { return m_xRow->getObject( m_nPos ,NULL); };
+ virtual sal_Bool wasNull() const { return m_xRow->wasNull( ); };
+
+ private:
+ const Reference< XRow > m_xRow;
+ const sal_Int32 m_nPos;
+ };
+
+ class ColumnValue : public IValueSource
+ {
+ public:
+ ColumnValue( const Reference< XColumn >& _rxColumn )
+ :m_xColumn( _rxColumn )
+ {
+ }
+
+ // IValueSource
+ virtual ::rtl::OUString getString() const { return m_xColumn->getString(); };
+ virtual sal_Bool getBoolean() const { return m_xColumn->getBoolean(); };
+ virtual sal_Int8 getByte() const { return m_xColumn->getByte(); };
+ virtual sal_Int16 getShort() const { return m_xColumn->getShort(); }
+ virtual sal_Int32 getInt() const { return m_xColumn->getInt(); }
+ virtual sal_Int64 getLong() const { return m_xColumn->getLong(); }
+ virtual float getFloat() const { return m_xColumn->getFloat(); };
+ virtual double getDouble() const { return m_xColumn->getDouble(); };
+ virtual Date getDate() const { return m_xColumn->getDate(); };
+ virtual Time getTime() const { return m_xColumn->getTime(); };
+ virtual DateTime getTimestamp() const { return m_xColumn->getTimestamp(); };
+ virtual Sequence< sal_Int8 > getBytes() const { return m_xColumn->getBytes(); };
+ virtual Reference< XInputStream > getBinaryStream() const { return m_xColumn->getBinaryStream(); };
+ virtual Reference< XInputStream > getCharacterStream() const { return m_xColumn->getCharacterStream(); };
+ virtual Reference< XBlob > getBlob() const { return m_xColumn->getBlob(); };
+ virtual Reference< XClob > getClob() const { return m_xColumn->getClob(); };
+ virtual Any getObject() const { return m_xColumn->getObject( NULL ); };
+ virtual sal_Bool wasNull() const { return m_xColumn->wasNull( ); };
+
+ private:
+ const Reference< XColumn > m_xColumn;
+ };
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetValue::fill( const sal_Int32 _nType, const Reference< XColumn >& _rxColumn )
+{
+ detail::ColumnValue aColumnValue( _rxColumn );
+ impl_fill( _nType, sal_True, aColumnValue );
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetValue::fill( sal_Int32 _nPos, sal_Int32 _nType, sal_Bool _bNullable, const Reference< XRow>& _xRow )
+{
+ detail::RowValue aRowValue( _xRow, _nPos );
+ impl_fill( _nType, _bNullable, aRowValue );
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetValue::fill(sal_Int32 _nPos,
+ sal_Int32 _nType,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow>& _xRow)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill (1)" );
+ fill(_nPos,_nType,sal_True,_xRow);
+}
+
+// -----------------------------------------------------------------------------
+void ORowSetValue::impl_fill( const sal_Int32 _nType, sal_Bool _bNullable, const detail::IValueSource& _rValueSource )
+
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill (2)" );
+ sal_Bool bReadData = sal_True;
+ switch(_nType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ case DataType::LONGVARCHAR:
+ (*this) = _rValueSource.getString();
+ break;
+ case DataType::BIGINT:
+ if ( isSigned() )
+ (*this) = _rValueSource.getLong();
+ else
+ (*this) = _rValueSource.getString();
+ break;
+ case DataType::FLOAT:
+ (*this) = _rValueSource.getFloat();
+ break;
+ case DataType::DOUBLE:
+ case DataType::REAL:
+ (*this) = _rValueSource.getDouble();
+ break;
+ case DataType::DATE:
+ (*this) = _rValueSource.getDate();
+ break;
+ case DataType::TIME:
+ (*this) = _rValueSource.getTime();
+ break;
+ case DataType::TIMESTAMP:
+ (*this) = _rValueSource.getTimestamp();
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ (*this) = _rValueSource.getBytes();
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ (*this) = _rValueSource.getBoolean();
+ break;
+ case DataType::TINYINT:
+ if ( isSigned() )
+ (*this) = _rValueSource.getByte();
+ else
+ (*this) = _rValueSource.getShort();
+ break;
+ case DataType::SMALLINT:
+ if ( isSigned() )
+ (*this) = _rValueSource.getShort();
+ else
+ (*this) = _rValueSource.getInt();
+ break;
+ case DataType::INTEGER:
+ if ( isSigned() )
+ (*this) = _rValueSource.getInt();
+ else
+ (*this) = _rValueSource.getLong();
+ break;
+ case DataType::CLOB:
+ (*this) = ::com::sun::star::uno::makeAny(_rValueSource.getClob());
+ setTypeKind(DataType::CLOB);
+ break;
+ case DataType::BLOB:
+ (*this) = ::com::sun::star::uno::makeAny(_rValueSource.getBlob());
+ setTypeKind(DataType::BLOB);
+ break;
+ case DataType::OTHER:
+ (*this) = _rValueSource.getObject();
+ setTypeKind(DataType::OTHER);
+ break;
+ default:
+ OSL_ENSURE( false, "ORowSetValue::fill: unsupported type!" );
+ (*this) = _rValueSource.getObject();
+ break;
+ }
+ if ( bReadData && _bNullable && _rValueSource.wasNull() )
+ setNull();
+ setTypeKind(_nType);
+}
+// -----------------------------------------------------------------------------
+void ORowSetValue::fill(const Any& _rValue)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill (3)" );
+ switch (_rValue.getValueType().getTypeClass())
+ {
+ case TypeClass_VOID:
+ setNull();
+ break;
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool bValue( sal_False );
+ _rValue >>= bValue;
+ (*this) = bValue;
+ break;
+ }
+ case TypeClass_CHAR:
+ {
+ sal_Unicode aDummy(0);
+ _rValue >>= aDummy;
+ (*this) = ::rtl::OUString(aDummy);
+ break;
+ }
+ case TypeClass_STRING:
+ {
+ ::rtl::OUString sDummy;
+ _rValue >>= sDummy;
+ (*this) = sDummy;
+ break;
+ }
+ case TypeClass_FLOAT:
+ {
+ float aDummy(0.0);
+ _rValue >>= aDummy;
+ (*this) = aDummy;
+ break;
+ }
+ case TypeClass_DOUBLE:
+ {
+ double aDummy(0.0);
+ _rValue >>= aDummy;
+ (*this) = aDummy;
+ break;
+ }
+ case TypeClass_BYTE:
+ {
+ sal_Int8 aDummy(0);
+ _rValue >>= aDummy;
+ (*this) = aDummy;
+ break;
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 aDummy(0);
+ _rValue >>= aDummy;
+ (*this) = aDummy;
+ break;
+ }
+ case TypeClass_LONG:
+ {
+ sal_Int32 aDummy(0);
+ _rValue >>= aDummy;
+ (*this) = aDummy;
+ break;
+ }
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_uInt16 nValue(0);
+ _rValue >>= nValue;
+ (*this) = static_cast<sal_Int32>(nValue);
+ setSigned(sal_False);
+ break;
+ }
+ case TypeClass_HYPER:
+ {
+ sal_Int64 nValue(0);
+ _rValue >>= nValue;
+ (*this) = nValue;
+ break;
+ }
+ case TypeClass_UNSIGNED_HYPER:
+ {
+ sal_uInt64 nValue(0);
+ _rValue >>= nValue;
+ (*this) = static_cast<sal_Int64>(nValue);
+ setSigned(sal_False);
+ break;
+ }
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 nValue(0);
+ _rValue >>= nValue;
+ (*this) = static_cast<sal_Int64>(nValue);
+ setSigned(sal_False);
+ break;
+ }
+ case TypeClass_ENUM:
+ {
+ sal_Int32 enumValue( 0 );
+ ::cppu::enum2int( enumValue, _rValue );
+ (*this) = enumValue;
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ Sequence<sal_Int8> aDummy;
+ if ( _rValue >>= aDummy )
+ (*this) = aDummy;
+ else
+ OSL_ENSURE( false, "ORowSetValue::fill: unsupported sequence type!" );
+ break;
+ }
+
+ case TypeClass_STRUCT:
+ {
+ ::com::sun::star::util::Date aDate;
+ ::com::sun::star::util::Time aTime;
+ ::com::sun::star::util::DateTime aDateTime;
+ if ( _rValue >>= aDate )
+ {
+ (*this) = aDate;
+ }
+ else if ( _rValue >>= aTime )
+ {
+ (*this) = aTime;
+ }
+ else if ( _rValue >>= aDateTime )
+ {
+ (*this) = aDateTime;
+ }
+ else
+ OSL_ENSURE( false, "ORowSetValue::fill: unsupported structure!" );
+
+ break;
+ }
+ case TypeClass_INTERFACE:
+ {
+ Reference< XClob > xClob;
+ if ( _rValue >>= xClob )
+ {
+ (*this) = _rValue;
+ setTypeKind(DataType::CLOB);
+ }
+ else
+ {
+ Reference< XBlob > xBlob;
+ if ( _rValue >>= xBlob )
+ {
+ (*this) = _rValue;
+ setTypeKind(DataType::BLOB);
+ }
+ else
+ {
+ (*this) = _rValue;
+ }
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(0,"Unknown type");
+ break;
+ }
+}
+
+} // namespace connectivity
diff --git a/connectivity/source/commontools/ParamterSubstitution.cxx b/connectivity/source/commontools/ParamterSubstitution.cxx
new file mode 100644
index 000000000000..df76724aa008
--- /dev/null
+++ b/connectivity/source/commontools/ParamterSubstitution.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+#include "precompiled_connectivity.hxx"
+#include "ParameterSubstitution.hxx"
+#include "connectivity/sqlparse.hxx"
+#include <comphelper/sequenceashashmap.hxx>
+
+namespace connectivity
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star;
+
+ ParameterSubstitution::ParameterSubstitution(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext ) : m_xContext(_rxContext)
+ {
+ }
+ void SAL_CALL ParameterSubstitution::initialize( const uno::Sequence< uno::Any >& _aArguments ) throw (uno::Exception, uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ comphelper::SequenceAsHashMap aArgs(_aArguments);
+ uno::Reference< sdbc::XConnection > xConnection;
+ xConnection = aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ActiveConnection")),xConnection);
+ m_xConnection = xConnection;
+ }
+ //------------------------------------------------------------------------------
+ rtl::OUString ParameterSubstitution::getImplementationName_Static( ) throw(RuntimeException)
+ {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.helper.ParameterSubstitution"));
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ParameterSubstitution::getImplementationName( ) throw(RuntimeException)
+ {
+ return getImplementationName_Static();
+ }
+ //------------------------------------------------------------------
+ sal_Bool SAL_CALL ParameterSubstitution::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
+ const ::rtl::OUString* pSupported = aSupported.getConstArray();
+ const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
+ for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
+ ;
+
+ return pSupported != pEnd;
+ }
+ //------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL ParameterSubstitution::getSupportedServiceNames( ) throw(RuntimeException)
+ {
+ return getSupportedServiceNames_Static();
+ }
+ //------------------------------------------------------------------
+ Sequence< ::rtl::OUString > ParameterSubstitution::getSupportedServiceNames_Static( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.ParameterSubstitution");
+ return aSNS;
+ }
+
+ //------------------------------------------------------------------
+ Reference< XInterface > ParameterSubstitution::create(const Reference< XComponentContext >& _xContext)
+ {
+ return *(new ParameterSubstitution(_xContext));
+ }
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ParameterSubstitution::substituteVariables( const ::rtl::OUString& _sText, ::sal_Bool /*bSubstRequired*/ ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+ {
+ ::rtl::OUString sRet = _sText;
+ uno::Reference< sdbc::XConnection > xConnection = m_xConnection;
+ if ( xConnection.is() )
+ {
+ try
+ {
+ uno::Reference< XMultiServiceFactory> xFac(m_xContext->getServiceManager(),uno::UNO_QUERY_THROW);
+ OSQLParser aParser( xFac );
+ ::rtl::OUString sErrorMessage;
+ ::rtl::OUString sNewSql;
+ OSQLParseNode* pNode = aParser.parseTree(sErrorMessage,_sText);
+ if(pNode)
+ { // special handling for parameters
+ OSQLParseNode::substituteParameterNames(pNode);
+ pNode->parseNodeToStr( sNewSql, xConnection );
+ delete pNode;
+ sRet = sNewSql;
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ }
+ return sRet;
+ }
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ParameterSubstitution::reSubstituteVariables( const ::rtl::OUString& _sText ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ return _sText;
+ }
+ //------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ParameterSubstitution::getSubstituteVariableValue( const ::rtl::OUString& /*variable*/ ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+ {
+ throw container::NoSuchElementException();
+ }
+ //------------------------------------------------------------------
+
+
+// ==================================
+} // connectivity
+// ==================================
diff --git a/connectivity/source/commontools/RowFunctionParser.cxx b/connectivity/source/commontools/RowFunctionParser.cxx
new file mode 100644
index 000000000000..3804ddfb259f
--- /dev/null
+++ b/connectivity/source/commontools/RowFunctionParser.cxx
@@ -0,0 +1,499 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+// Makes parser a static resource,
+// we're synchronized externally.
+// But watch out, the parser might have
+// state not visible to this code!
+#define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
+#if defined(VERBOSE) && defined(DBG_UTIL)
+#include <typeinfo>
+#define BOOST_SPIRIT_DEBUG
+#endif
+#include <boost/spirit/include/classic_core.hpp>
+#include "RowFunctionParser.hxx"
+#include <rtl/ustring.hxx>
+#include <tools/fract.hxx>
+
+
+
+#if (OSL_DEBUG_LEVEL > 0)
+#include <iostream>
+#endif
+#include <functional>
+#include <algorithm>
+#include <stack>
+
+namespace connectivity
+{
+using namespace com::sun::star;
+
+namespace
+{
+//////////////////////
+//////////////////////
+// EXPRESSION NODES
+//////////////////////
+//////////////////////
+class ConstantValueExpression : public ExpressionNode
+{
+ ORowSetValueDecoratorRef maValue;
+
+public:
+
+ ConstantValueExpression( ORowSetValueDecoratorRef rValue ) :
+ maValue( rValue )
+ {
+ }
+ virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const
+ {
+ return maValue;
+ }
+ virtual void fill(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const
+ {
+ }
+ virtual ExpressionFunct getType() const
+ {
+ return FUNC_CONST;
+ }
+ virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ )
+ {
+ ODatabaseMetaDataResultSet::ORow aRet;
+ return aRet;
+ }
+};
+
+
+/** ExpressionNode implementation for unary
+ function over two ExpressionNodes
+ */
+class BinaryFunctionExpression : public ExpressionNode
+{
+ const ExpressionFunct meFunct;
+ ExpressionNodeSharedPtr mpFirstArg;
+ ExpressionNodeSharedPtr mpSecondArg;
+
+public:
+
+ BinaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rFirstArg, const ExpressionNodeSharedPtr& rSecondArg ) :
+ meFunct( eFunct ),
+ mpFirstArg( rFirstArg ),
+ mpSecondArg( rSecondArg )
+ {
+ }
+ virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& _aRow ) const
+ {
+ ORowSetValueDecoratorRef aRet;
+ switch(meFunct)
+ {
+ case ENUM_FUNC_EQUATION:
+ aRet = new ORowSetValueDecorator(sal_Bool(mpFirstArg->evaluate(_aRow )->getValue() == mpSecondArg->evaluate(_aRow )->getValue()) );
+ break;
+ case ENUM_FUNC_AND:
+ aRet = new ORowSetValueDecorator( sal_Bool(mpFirstArg->evaluate(_aRow )->getValue().getBool() && mpSecondArg->evaluate(_aRow )->getValue().getBool()) );
+ break;
+ case ENUM_FUNC_OR:
+ aRet = new ORowSetValueDecorator( sal_Bool(mpFirstArg->evaluate(_aRow )->getValue().getBool() || mpSecondArg->evaluate(_aRow )->getValue().getBool()) );
+ break;
+ default:
+ break;
+ }
+ return aRet;
+ }
+ virtual void fill(const ODatabaseMetaDataResultSet::ORow& _aRow ) const
+ {
+ switch(meFunct)
+ {
+ case ENUM_FUNC_EQUATION:
+ (*mpFirstArg->evaluate(_aRow )) = mpSecondArg->evaluate(_aRow )->getValue();
+ break;
+ default:
+ break;
+ }
+ }
+ virtual ExpressionFunct getType() const
+ {
+ return meFunct;
+ }
+ virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /*pOptionalArg*/, sal_uInt32 /*nFlags*/ )
+ {
+ ODatabaseMetaDataResultSet::ORow aRet;
+ return aRet;
+ }
+};
+
+
+////////////////////////
+////////////////////////
+// FUNCTION PARSER
+////////////////////////
+////////////////////////
+
+typedef const sal_Char* StringIteratorT;
+
+struct ParserContext
+{
+ typedef ::std::stack< ExpressionNodeSharedPtr > OperandStack;
+
+ // stores a stack of not-yet-evaluated operands. This is used
+ // by the operators (i.e. '+', '*', 'sin' etc.) to pop their
+ // arguments from. If all arguments to an operator are constant,
+ // the operator pushes a precalculated result on the stack, and
+ // a composite ExpressionNode otherwise.
+ OperandStack maOperandStack;
+};
+
+typedef ::boost::shared_ptr< ParserContext > ParserContextSharedPtr;
+
+/** Generate apriori constant value
+ */
+
+class ConstantFunctor
+{
+ ParserContextSharedPtr mpContext;
+
+public:
+
+ ConstantFunctor( const ParserContextSharedPtr& rContext ) :
+ mpContext( rContext )
+ {
+ }
+ void operator()( StringIteratorT rFirst,StringIteratorT rSecond) const
+ {
+ rtl::OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
+ mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( new ORowSetValueDecorator( sVal ) ) ) );
+ }
+};
+
+/** Generate parse-dependent-but-then-constant value
+ */
+class IntConstantFunctor
+{
+ ParserContextSharedPtr mpContext;
+
+public:
+ IntConstantFunctor( const ParserContextSharedPtr& rContext ) :
+ mpContext( rContext )
+ {
+ }
+ void operator()( sal_Int32 n ) const
+ {
+ mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( new ORowSetValueDecorator( n ) ) ) );
+ }
+ void operator()( StringIteratorT rFirst,StringIteratorT rSecond) const
+ {
+ rtl::OUString sVal( rFirst, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
+ (void)sVal;
+ }
+};
+
+/** Implements a binary function over two ExpressionNodes
+
+ @tpl Generator
+ Generator functor, to generate an ExpressionNode of
+ appropriate type
+
+ */
+class BinaryFunctionFunctor
+{
+ const ExpressionFunct meFunct;
+ ParserContextSharedPtr mpContext;
+
+public:
+
+ BinaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) :
+ meFunct( eFunct ),
+ mpContext( rContext )
+ {
+ }
+
+ void operator()( StringIteratorT, StringIteratorT ) const
+ {
+ ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
+
+ if( rNodeStack.size() < 2 )
+ throw ParseError( "Not enough arguments for binary operator" );
+
+ // retrieve arguments
+ ExpressionNodeSharedPtr pSecondArg( rNodeStack.top() );
+ rNodeStack.pop();
+ ExpressionNodeSharedPtr pFirstArg( rNodeStack.top() );
+ rNodeStack.pop();
+
+ // create combined ExpressionNode
+ ExpressionNodeSharedPtr pNode = ExpressionNodeSharedPtr( new BinaryFunctionExpression( meFunct, pFirstArg, pSecondArg ) );
+ // check for constness
+ rNodeStack.push( pNode );
+ }
+};
+/** ExpressionNode implementation for unary
+ function over one ExpressionNode
+ */
+class UnaryFunctionExpression : public ExpressionNode
+{
+ const ExpressionFunct meFunct;
+ ExpressionNodeSharedPtr mpArg;
+
+public:
+ UnaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rArg ) :
+ meFunct( eFunct ),
+ mpArg( rArg )
+ {
+ }
+ virtual ORowSetValueDecoratorRef evaluate(const ODatabaseMetaDataResultSet::ORow& _aRow ) const
+ {
+ return _aRow[mpArg->evaluate(_aRow )->getValue().getInt32()];
+ }
+ virtual void fill(const ODatabaseMetaDataResultSet::ORow& /*_aRow*/ ) const
+ {
+ }
+ virtual ExpressionFunct getType() const
+ {
+ return meFunct;
+ }
+ virtual ODatabaseMetaDataResultSet::ORow fillNode( std::vector< RowEquation >& /*rEquations*/, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ )
+ {
+ ODatabaseMetaDataResultSet::ORow aRet;
+ return aRet;
+ }
+};
+
+class UnaryFunctionFunctor
+{
+ const ExpressionFunct meFunct;
+ ParserContextSharedPtr mpContext;
+
+public :
+
+ UnaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) :
+ meFunct( eFunct ),
+ mpContext( rContext )
+ {
+ }
+ void operator()( StringIteratorT, StringIteratorT ) const
+ {
+
+ ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
+
+ if( rNodeStack.size() < 1 )
+ throw ParseError( "Not enough arguments for unary operator" );
+
+ // retrieve arguments
+ ExpressionNodeSharedPtr pArg( rNodeStack.top() );
+ rNodeStack.pop();
+
+ rNodeStack.push( ExpressionNodeSharedPtr( new UnaryFunctionExpression( meFunct, pArg ) ) );
+ }
+};
+
+/* This class implements the following grammar (more or
+ less literally written down below, only slightly
+ obfuscated by the parser actions):
+
+ basic_expression =
+ number |
+ '(' additive_expression ')'
+
+ unary_expression =
+ basic_expression
+
+ multiplicative_expression =
+ unary_expression ( ( '*' unary_expression )* |
+ ( '/' unary_expression )* )
+
+ additive_expression =
+ multiplicative_expression ( ( '+' multiplicative_expression )* |
+ ( '-' multiplicative_expression )* )
+
+ */
+class ExpressionGrammar : public ::boost::spirit::grammar< ExpressionGrammar >
+{
+public:
+ /** Create an arithmetic expression grammar
+
+ @param rParserContext
+ Contains context info for the parser
+ */
+ ExpressionGrammar( const ParserContextSharedPtr& rParserContext ) :
+ mpParserContext( rParserContext )
+ {
+ }
+
+ template< typename ScannerT > class definition
+ {
+ public:
+ // grammar definition
+ definition( const ExpressionGrammar& self )
+ {
+ using ::boost::spirit::str_p;
+ using ::boost::spirit::space_p;
+ using ::boost::spirit::range_p;
+ using ::boost::spirit::lexeme_d;
+ using ::boost::spirit::real_parser;
+ using ::boost::spirit::chseq_p;
+ using ::boost::spirit::ch_p;
+ using ::boost::spirit::int_p;
+ using ::boost::spirit::as_lower_d;
+ using ::boost::spirit::strlit;
+ using ::boost::spirit::inhibit_case;
+
+
+ typedef inhibit_case<strlit<> > token_t;
+ token_t COLUMN = as_lower_d[ "column" ];
+ token_t OR_ = as_lower_d[ "or" ];
+ token_t AND_ = as_lower_d[ "and" ];
+
+ integer =
+ int_p
+ [IntConstantFunctor(self.getContext())];
+
+ argument =
+ integer
+ | lexeme_d[ +( range_p('a','z') | range_p('A','Z') | range_p('0','9') ) ]
+ [ ConstantFunctor(self.getContext()) ]
+ ;
+
+ unaryFunction =
+ (COLUMN >> '(' >> integer >> ')' )
+ [ UnaryFunctionFunctor( UNARY_FUNC_COLUMN, self.getContext()) ]
+ ;
+
+ assignment =
+ unaryFunction >> ch_p('=') >> argument
+ [ BinaryFunctionFunctor( ENUM_FUNC_EQUATION, self.getContext()) ]
+ ;
+
+ andExpression =
+ assignment
+ | ( '(' >> orExpression >> ')' )
+ | ( assignment >> AND_ >> assignment ) [ BinaryFunctionFunctor( ENUM_FUNC_AND, self.getContext()) ]
+ ;
+
+ orExpression =
+ andExpression
+ | ( orExpression >> OR_ >> andExpression ) [ BinaryFunctionFunctor( ENUM_FUNC_OR, self.getContext()) ]
+ ;
+
+ basicExpression =
+ orExpression
+ ;
+
+ BOOST_SPIRIT_DEBUG_RULE(basicExpression);
+ BOOST_SPIRIT_DEBUG_RULE(unaryFunction);
+ BOOST_SPIRIT_DEBUG_RULE(assignment);
+ BOOST_SPIRIT_DEBUG_RULE(argument);
+ BOOST_SPIRIT_DEBUG_RULE(integer);
+ BOOST_SPIRIT_DEBUG_RULE(orExpression);
+ BOOST_SPIRIT_DEBUG_RULE(andExpression);
+ }
+
+ const ::boost::spirit::rule< ScannerT >& start() const
+ {
+ return basicExpression;
+ }
+
+ private:
+ // the constituents of the Spirit arithmetic expression grammar.
+ // For the sake of readability, without 'ma' prefix.
+ ::boost::spirit::rule< ScannerT > basicExpression;
+ ::boost::spirit::rule< ScannerT > unaryFunction;
+ ::boost::spirit::rule< ScannerT > assignment;
+ ::boost::spirit::rule< ScannerT > integer,argument;
+ ::boost::spirit::rule< ScannerT > orExpression,andExpression;
+ };
+
+ const ParserContextSharedPtr& getContext() const
+ {
+ return mpParserContext;
+ }
+
+private:
+ ParserContextSharedPtr mpParserContext; // might get modified during parsing
+};
+
+#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
+const ParserContextSharedPtr& getParserContext()
+{
+ static ParserContextSharedPtr lcl_parserContext( new ParserContext() );
+
+ // clear node stack (since we reuse the static object, that's
+ // the whole point here)
+ while( !lcl_parserContext->maOperandStack.empty() )
+ lcl_parserContext->maOperandStack.pop();
+
+ return lcl_parserContext;
+}
+#endif
+}
+
+ExpressionNodeSharedPtr FunctionParser::parseFunction( const ::rtl::OUString& _sFunction)
+{
+ // TODO(Q1): Check if a combination of the RTL_UNICODETOTEXT_FLAGS_*
+ // gives better conversion robustness here (we might want to map space
+ // etc. to ASCII space here)
+ const ::rtl::OString& rAsciiFunction(
+ rtl::OUStringToOString( _sFunction, RTL_TEXTENCODING_ASCII_US ) );
+
+ StringIteratorT aStart( rAsciiFunction.getStr() );
+ StringIteratorT aEnd( rAsciiFunction.getStr()+rAsciiFunction.getLength() );
+
+ ParserContextSharedPtr pContext;
+
+#ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
+ // static parser context, because the actual
+ // Spirit parser is also a static object
+ pContext = getParserContext();
+#else
+ pContext.reset( new ParserContext() );
+#endif
+
+ ExpressionGrammar aExpressionGrammer( pContext );
+
+ const ::boost::spirit::parse_info<StringIteratorT> aParseInfo(
+ ::boost::spirit::parse( aStart,
+ aEnd,
+ aExpressionGrammer,
+ ::boost::spirit::space_p ) );
+
+ OSL_DEBUG_ONLY(::std::cout.flush()); // needed to keep stdout and cout in sync
+
+ // input fully congested by the parser?
+ if( !aParseInfo.full )
+ throw ParseError( "RowFunctionParser::parseFunction(): string not fully parseable" );
+
+ // parser's state stack now must contain exactly _one_ ExpressionNode,
+ // which represents our formula.
+ if( pContext->maOperandStack.size() != 1 )
+ throw ParseError( "RowFunctionParser::parseFunction(): incomplete or empty expression" );
+
+ return pContext->maOperandStack.top();
+}
+}
+
diff --git a/connectivity/source/commontools/TColumnsHelper.cxx b/connectivity/source/commontools/TColumnsHelper.cxx
new file mode 100644
index 000000000000..325fcfbd0f42
--- /dev/null
+++ b/connectivity/source/commontools/TColumnsHelper.cxx
@@ -0,0 +1,225 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TColumnsHelper.hxx"
+#include "connectivity/sdbcx/VColumn.hxx"
+#include "connectivity/sdbcx/VColumn.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#include <comphelper/types.hxx>
+#include "connectivity/dbtools.hxx"
+#include "TConnection.hxx"
+#include "connectivity/TTableHelper.hxx"
+#include <comphelper/property.hxx>
+
+using namespace ::comphelper;
+
+
+using namespace connectivity::sdbcx;
+using namespace connectivity;
+using namespace dbtools;
+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;
+typedef connectivity::sdbcx::OCollection OCollection_TYPE;
+
+namespace connectivity
+{
+ class OColumnsHelperImpl
+ {
+ public:
+ OColumnsHelperImpl(sal_Bool _bCase)
+ : m_aColumnInfo(_bCase)
+ {
+ }
+ ColumnInformationMap m_aColumnInfo;
+ };
+}
+
+OColumnsHelper::OColumnsHelper( ::cppu::OWeakObject& _rParent
+ ,sal_Bool _bCase
+ ,::osl::Mutex& _rMutex
+ ,const TStringVector &_rVector
+ ,sal_Bool _bUseHardRef
+ ) : OCollection(_rParent,_bCase,_rMutex,_rVector,sal_False,_bUseHardRef)
+ ,m_pImpl(NULL)
+ ,m_pTable(NULL)
+{
+}
+// -----------------------------------------------------------------------------
+OColumnsHelper::~OColumnsHelper()
+{
+ delete m_pImpl;
+ m_pImpl = NULL;
+}
+// -----------------------------------------------------------------------------
+
+sdbcx::ObjectType OColumnsHelper::createObject(const ::rtl::OUString& _rName)
+{
+ OSL_ENSURE(m_pTable,"NO Table set. Error!");
+ Reference<XConnection> xConnection = m_pTable->getConnection();
+
+ if ( !m_pImpl )
+ m_pImpl = new OColumnsHelperImpl(isCaseSensitive());
+
+ sal_Bool bQueryInfo = sal_True;
+ sal_Bool bAutoIncrement = sal_False;
+ sal_Bool bIsCurrency = sal_False;
+ sal_Int32 nDataType = DataType::OTHER;
+
+ ColumnInformationMap::iterator aFind = m_pImpl->m_aColumnInfo.find(_rName);
+ if ( aFind == m_pImpl->m_aColumnInfo.end() ) // we have to fill it
+ {
+ ::rtl::OUString sComposedName = ::dbtools::composeTableNameForSelect( xConnection, m_pTable );
+ collectColumnInformation(xConnection,sComposedName,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")) ,m_pImpl->m_aColumnInfo);
+ aFind = m_pImpl->m_aColumnInfo.find(_rName);
+ }
+ if ( aFind != m_pImpl->m_aColumnInfo.end() )
+ {
+ bQueryInfo = sal_False;
+ bAutoIncrement = aFind->second.first.first;
+ bIsCurrency = aFind->second.first.second;
+ nDataType = aFind->second.second;
+ } // if ( aFind != m_pImpl->m_aColumnInfo.end() )
+
+ sdbcx::ObjectType xRet;
+ const ColumnDesc* pColDesc = m_pTable->getColumnDescription(_rName);
+ if ( pColDesc )
+ {
+ Reference<XPropertySet> xPr = m_pTable;
+ const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(xPr);
+ sal_Int32 nField11 = pColDesc->nField11;
+ if ( nField11 != ColumnValue::NO_NULLS && xPrimaryKeyColumns.is() && xPrimaryKeyColumns->hasByName(_rName) )
+ {
+ nField11 = ColumnValue::NO_NULLS;
+ } // if ( xKeys.is() )
+ connectivity::sdbcx::OColumn* pRet = new connectivity::sdbcx::OColumn(_rName,
+ pColDesc->aField6,
+ pColDesc->sField13,
+ pColDesc->sField12,
+ nField11,
+ pColDesc->nField7,
+ pColDesc->nField9,
+ pColDesc->nField5,
+ bAutoIncrement,
+ sal_False,
+ bIsCurrency,
+ isCaseSensitive());
+
+ xRet = pRet;
+ }
+ else
+ {
+
+ xRet.set(::dbtools::createSDBCXColumn( m_pTable,
+ xConnection,
+ _rName,
+ isCaseSensitive(),
+ bQueryInfo,
+ bAutoIncrement,
+ bIsCurrency,
+ nDataType),UNO_QUERY);
+ }
+ return xRet;
+}
+
+// -------------------------------------------------------------------------
+void OColumnsHelper::impl_refresh() throw(RuntimeException)
+{
+ if ( m_pTable )
+ {
+ m_pImpl->m_aColumnInfo.clear();
+ m_pTable->refreshColumns();
+ }
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OColumnsHelper::createDescriptor()
+{
+ return new OColumn(sal_True);
+}
+// -----------------------------------------------------------------------------
+// XAppend
+sdbcx::ObjectType OColumnsHelper::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ ::osl::MutexGuard aGuard(m_rMutex);
+ OSL_ENSURE(m_pTable,"OColumnsHelper::appendByDescriptor: Table is null!");
+ if ( !m_pTable || m_pTable->isNew() )
+ return cloneDescriptor( descriptor );
+
+ Reference<XDatabaseMetaData> xMetaData = m_pTable->getConnection()->getMetaData();
+ ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("ALTER TABLE ");
+ ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString( );
+
+ aSql += ::dbtools::composeTableName( xMetaData, m_pTable, ::dbtools::eInTableDefinitions, false, false, true );
+ aSql += ::rtl::OUString::createFromAscii(" ADD ");
+ aSql += ::dbtools::createStandardColumnPart(descriptor,m_pTable->getConnection(),NULL,m_pTable->getTypeCreatePattern());
+
+ Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
+ if ( xStmt.is() )
+ {
+ xStmt->execute(aSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ return createObject( _rForName );
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OColumnsHelper::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString _sElementName)
+{
+ OSL_ENSURE(m_pTable,"OColumnsHelper::dropByName: Table is null!");
+ if ( m_pTable && !m_pTable->isNew() )
+ {
+ ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("ALTER TABLE ");
+ Reference<XDatabaseMetaData> xMetaData = m_pTable->getConnection()->getMetaData();
+ ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString( );
+
+ aSql += ::dbtools::composeTableName( xMetaData, m_pTable, ::dbtools::eInTableDefinitions, false, false, true );
+ aSql += ::rtl::OUString::createFromAscii(" DROP ");
+ aSql += ::dbtools::quoteName( aQuote,_sElementName);
+
+ Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
+ if ( xStmt.is() )
+ {
+ xStmt->execute(aSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+
+
diff --git a/connectivity/source/commontools/TConnection.cxx b/connectivity/source/commontools/TConnection.cxx
new file mode 100644
index 000000000000..7f471d739186
--- /dev/null
+++ b/connectivity/source/commontools/TConnection.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "TConnection.hxx"
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/officeresourcebundle.hxx>
+#include <connectivity/dbexception.hxx>
+
+using namespace connectivity;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::beans;
+using namespace ::osl;
+
+//------------------------------------------------------------------------------
+OMetaConnection::OMetaConnection()
+ : OMetaConnection_BASE(m_aMutex)
+ , m_nTextEncoding(RTL_TEXTENCODING_MS_1252)
+{
+}
+//------------------------------------------------------------------------------
+void OMetaConnection::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ m_xMetaData = WeakReference< XDatabaseMetaData>();
+ for (OWeakRefArray::iterator i = m_aStatements.begin(); m_aStatements.end() != i; ++i)
+ {
+ try
+ {
+ Reference< XInterface > xStatement( i->get() );
+ ::comphelper::disposeComponent( xStatement );
+ }
+ catch (DisposedException)
+ {
+ }
+ }
+ m_aStatements.clear();
+}
+//XUnoTunnel
+sal_Int64 SAL_CALL OMetaConnection::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException)
+{
+ return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
+ ? reinterpret_cast< sal_Int64 >( this )
+ : (sal_Int64)0;
+}
+// -----------------------------------------------------------------------------
+Sequence< sal_Int8 > OMetaConnection::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();
+}
+// -----------------------------------------------------------------------------
+::dbtools::OPropertyMap& OMetaConnection::getPropMap()
+{
+ static ::dbtools::OPropertyMap s_aPropertyNameMap;
+ return s_aPropertyNameMap;
+}
+// -----------------------------------------------------------------------------
+void OMetaConnection::throwGenericSQLException( sal_uInt16 _nErrorResourceId,const Reference< XInterface>& _xContext )
+{
+ ::rtl::OUString sErrorMessage;
+ if ( _nErrorResourceId )
+ sErrorMessage = m_aResources.getResourceString( _nErrorResourceId );
+ Reference< XInterface> xContext = _xContext;
+ if ( !xContext.is() )
+ xContext = *this;
+ ::dbtools::throwGenericSQLException( sErrorMessage, xContext);
+}
+
diff --git a/connectivity/source/commontools/TDatabaseMetaDataBase.cxx b/connectivity/source/commontools/TDatabaseMetaDataBase.cxx
new file mode 100644
index 000000000000..c0b2520b6cfb
--- /dev/null
+++ b/connectivity/source/commontools/TDatabaseMetaDataBase.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "TDatabaseMetaDataBase.hxx"
+#include "RowFunctionParser.hxx"
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/evtlistenerhlp.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include "resource/sharedresources.hxx"
+#include "resource/common_res.hrc"
+#include <connectivity/dbexception.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace comphelper;
+using namespace connectivity;
+
+
+ODatabaseMetaDataBase::ODatabaseMetaDataBase(const Reference< XConnection >& _rxConnection,const Sequence< PropertyValue >& _rInfo)
+ : m_aConnectionInfo(_rInfo)
+ ,m_isCatalogAtStart(false,sal_False)
+ ,m_sCatalogSeparator(false,::rtl::OUString())
+ ,m_sIdentifierQuoteString(false,::rtl::OUString())
+ ,m_supportsCatalogsInTableDefinitions(false,sal_False)
+ ,m_supportsSchemasInTableDefinitions(false,sal_False)
+ ,m_supportsCatalogsInDataManipulation(false,sal_False)
+ ,m_supportsSchemasInDataManipulation(false,sal_False)
+ ,m_supportsMixedCaseQuotedIdentifiers(false,sal_False)
+ ,m_supportsAlterTableWithAddColumn(false,sal_False)
+ ,m_supportsAlterTableWithDropColumn(false,sal_False)
+ ,m_MaxStatements(false,0)
+ ,m_MaxTablesInSelect(false,0)
+ ,m_storesMixedCaseQuotedIdentifiers(false,sal_False)
+ , m_xConnection(_rxConnection)
+{
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ m_xListenerHelper = new OEventListenerHelper(this);
+ Reference<XComponent> xCom(m_xConnection,UNO_QUERY);
+ if(xCom.is())
+ xCom->addEventListener(m_xListenerHelper);
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+// -------------------------------------------------------------------------
+ODatabaseMetaDataBase::~ODatabaseMetaDataBase()
+{
+}
+
+// -----------------------------------------------------------------------------
+Sequence< PropertyValue > SAL_CALL ODatabaseMetaDataBase::getConnectionInfo( ) throw (RuntimeException)
+{
+ return m_aConnectionInfo;
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseMetaDataBase::disposing( const EventObject& /*Source*/ ) throw(RuntimeException)
+{
+ // cut off all references to the connection
+m_xConnection.clear();
+m_xListenerHelper.clear();
+}
+// -----------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getTypeInfo( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_aTypeInfoRows.empty() )
+ {
+ Reference< XResultSet > xRet = impl_getTypeInfo_throw();
+ Reference< XRow > xRow(xRet,UNO_QUERY);
+ ::comphelper::SequenceAsHashMap aMap(m_aConnectionInfo);
+ Sequence< Any > aTypeInfoSettings;
+ aTypeInfoSettings = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeInfoSettings")),aTypeInfoSettings);
+
+ if ( xRow.is() )
+ {
+ static sal_Int32 pTypes[] = {
+ DataType::VARCHAR
+ ,DataType::INTEGER
+ ,DataType::INTEGER
+ ,DataType::VARCHAR
+ ,DataType::VARCHAR
+ ,DataType::VARCHAR
+ ,DataType::INTEGER
+ ,DataType::BOOLEAN
+ ,DataType::INTEGER
+ ,DataType::BOOLEAN
+ ,DataType::BOOLEAN
+ ,DataType::BOOLEAN
+ ,DataType::VARCHAR
+ ,DataType::INTEGER
+ ,DataType::INTEGER
+ ,DataType::INTEGER
+ ,DataType::INTEGER
+ ,DataType::INTEGER
+ };
+ ::std::vector<ExpressionNodeSharedPtr> aConditions;
+ if ( aTypeInfoSettings.getLength() > 1 && ((aTypeInfoSettings.getLength() % 2) == 0) )
+ {
+ const Any* pIter = aTypeInfoSettings.getConstArray();
+ const Any* pEnd = pIter + aTypeInfoSettings.getLength();
+ try
+ {
+ for(;pIter != pEnd;++pIter)
+ aConditions.push_back(FunctionParser::parseFunction(::comphelper::getString(*pIter)));
+ }
+ catch(ParseError&)
+ {
+ ::connectivity::SharedResources aResources;
+ const ::rtl::OUString sError( aResources.getResourceString(STR_FORMULA_WRONG));
+ ::dbtools::throwGenericSQLException(sError,*this);
+ }
+ }
+
+ ::connectivity::ODatabaseMetaDataResultSet::ORows aTypeInfoRows;
+ while( xRet->next() )
+ {
+ ::connectivity::ODatabaseMetaDataResultSet::ORow aRow;
+ aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
+ sal_Int32* pType = pTypes;
+ for (sal_Int32 i = 1; i <= sal_Int32(sizeof(pTypes)/sizeof(pTypes[0])); ++i,++pType)
+ {
+ ORowSetValue aValue;
+ aValue.fill(i,*pType,xRow);
+ aRow.push_back(new ORowSetValueDecorator(aValue));
+ }
+
+ ::std::vector<ExpressionNodeSharedPtr>::iterator aIter = aConditions.begin();
+ ::std::vector<ExpressionNodeSharedPtr>::iterator aEnd = aConditions.end();
+ for (; aIter != aEnd; ++aIter)
+ {
+ if ( (*aIter)->evaluate(aRow)->getValue().getBool() )
+ {
+ ++aIter;
+ (*aIter)->fill(aRow);
+ }
+ else
+ ++aIter;
+ }
+ aTypeInfoRows.push_back(aRow);
+ }
+ m_aTypeInfoRows = aTypeInfoRows;
+ }
+ }
+ ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTypeInfo);
+ Reference< XResultSet > xRet = pResult;
+ pResult->setRows(m_aTypeInfoRows);
+ return xRet;
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getExportedKeys(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eExportedKeys );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getImportedKeys(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eImportedKeys );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getPrimaryKeys(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::ePrimaryKeys );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getIndexInfo(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/,
+ sal_Bool /*unique*/, sal_Bool /*approximate*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eIndexInfo );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getBestRowIdentifier(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/, sal_Int32 /*scope*/,
+ sal_Bool /*nullable*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eBestRowIdentifier );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getCrossReference(
+ const Any& /*primaryCatalog*/, const ::rtl::OUString& /*primarySchema*/,
+ const ::rtl::OUString& /*primaryTable*/, const Any& /*foreignCatalog*/,
+ const ::rtl::OUString& /*foreignSchema*/, const ::rtl::OUString& /*foreignTable*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eCrossReference );
+}
+// -------------------------------------------------------------------------
+Reference< XConnection > SAL_CALL ODatabaseMetaDataBase::getConnection( ) throw(SQLException, RuntimeException)
+{
+ return m_xConnection;
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getProcedureColumns(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/,
+ const ::rtl::OUString& /*procedureNamePattern*/, const ::rtl::OUString& /*columnNamePattern*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eProcedureColumns );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getProcedures(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/,
+ const ::rtl::OUString& /*procedureNamePattern*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eProcedures );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getVersionColumns(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eVersionColumns );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getSchemas( ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eSchemas );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getColumnPrivileges(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/,
+ const ::rtl::OUString& /*columnNamePattern*/ ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eColumnPrivileges );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getTablePrivileges(
+ const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eTablePrivileges );
+}
+// -------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getCatalogs( ) throw(SQLException, RuntimeException)
+{
+ return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eCatalogs );
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataBase::getIdentifierQuoteString( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_sIdentifierQuoteString,::std::mem_fun_t< ::rtl::OUString ,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getIdentifierQuoteString_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::isCatalogAtStart( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_isCatalogAtStart,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_isCatalogAtStart_throw));
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ODatabaseMetaDataBase::getCatalogSeparator( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_sCatalogSeparator,::std::mem_fun_t< ::rtl::OUString,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getCatalogSeparator_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsCatalogsInTableDefinitions( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsCatalogsInTableDefinitions,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsCatalogsInTableDefinitions_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsSchemasInTableDefinitions( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsSchemasInTableDefinitions,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsSchemasInTableDefinitions_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsCatalogsInDataManipulation( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsCatalogsInDataManipulation,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsCatalogsInDataManipulation_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsSchemasInDataManipulation( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsSchemasInDataManipulation,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsSchemasInDataManipulation_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsMixedCaseQuotedIdentifiers( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsMixedCaseQuotedIdentifiers,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsMixedCaseQuotedIdentifiers_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsAlterTableWithAddColumn( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsAlterTableWithAddColumn,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsAlterTableWithAddColumn_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsAlterTableWithDropColumn( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_supportsAlterTableWithDropColumn,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsAlterTableWithDropColumn_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseMetaDataBase::getMaxStatements( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_MaxStatements,::std::mem_fun_t< sal_Int32,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getMaxStatements_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Int32 SAL_CALL ODatabaseMetaDataBase::getMaxTablesInSelect( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_MaxTablesInSelect,::std::mem_fun_t< sal_Int32,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getMaxTablesInSelect_throw));
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL ODatabaseMetaDataBase::storesMixedCaseQuotedIdentifiers( ) throw(SQLException, RuntimeException)
+{
+ return callImplMethod(m_storesMixedCaseQuotedIdentifiers,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_storesMixedCaseQuotedIdentifiers_throw));
+}
+// -----------------------------------------------------------------------------
diff --git a/connectivity/source/commontools/TIndex.cxx b/connectivity/source/commontools/TIndex.cxx
new file mode 100644
index 000000000000..0987ba124777
--- /dev/null
+++ b/connectivity/source/commontools/TIndex.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TIndex.hxx"
+#include "connectivity/TIndexColumns.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include "connectivity/TTableHelper.hxx"
+#include "TConnection.hxx"
+
+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;
+// -------------------------------------------------------------------------
+OIndexHelper::OIndexHelper( OTableHelper* _pTable) : connectivity::sdbcx::OIndex(sal_True)
+ , m_pTable(_pTable)
+{
+ construct();
+ ::std::vector< ::rtl::OUString> aVector;
+ m_pColumns = new OIndexColumns(this,m_aMutex,aVector);
+}
+// -------------------------------------------------------------------------
+OIndexHelper::OIndexHelper( OTableHelper* _pTable,
+ const ::rtl::OUString& _Name,
+ const ::rtl::OUString& _Catalog,
+ sal_Bool _isUnique,
+ sal_Bool _isPrimaryKeyIndex,
+ sal_Bool _isClustered
+ ) : connectivity::sdbcx::OIndex(_Name,
+ _Catalog,
+ _isUnique,
+ _isPrimaryKeyIndex,
+ _isClustered,sal_True)
+ ,m_pTable(_pTable)
+{
+ construct();
+ refreshColumns();
+}
+// -------------------------------------------------------------------------
+
+void OIndexHelper::refreshColumns()
+{
+ if ( !m_pTable )
+ return;
+
+ ::std::vector< ::rtl::OUString> aVector;
+ if ( !isNew() )
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ ::rtl::OUString aSchema,aTable;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+
+ Reference< XResultSet > xResult = m_pTable->getMetaData()->getIndexInfo(
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),
+ aSchema,aTable,sal_False,sal_False);
+
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ ::rtl::OUString aColName;
+ while( xResult->next() )
+ {
+ if ( xRow->getString(6) == m_Name )
+ {
+ aColName = xRow->getString(9);
+ if ( !xRow->wasNull() )
+ aVector.push_back(aColName);
+ }
+ }
+ }
+ }
+ if(m_pColumns)
+ m_pColumns->reFill(aVector);
+ else
+ m_pColumns = new OIndexColumns(this,m_aMutex,aVector);
+}
+// -----------------------------------------------------------------------------
+
diff --git a/connectivity/source/commontools/TIndexColumns.cxx b/connectivity/source/commontools/TIndexColumns.cxx
new file mode 100644
index 000000000000..3c9ac59112f6
--- /dev/null
+++ b/connectivity/source/commontools/TIndexColumns.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TIndexColumns.hxx"
+#include "connectivity/sdbcx/VIndexColumn.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <comphelper/property.hxx>
+#include "connectivity/TIndex.hxx"
+#include "connectivity/TTableHelper.hxx"
+#include "TConnection.hxx"
+
+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;
+// -------------------------------------------------------------------------
+OIndexColumns::OIndexColumns( OIndexHelper* _pIndex,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector)
+ : connectivity::sdbcx::OCollection(*_pIndex,sal_True,_rMutex,_rVector)
+ ,m_pIndex(_pIndex)
+{
+}
+// -------------------------------------------------------------------------
+sdbcx::ObjectType OIndexColumns::createObject(const ::rtl::OUString& _rName)
+{
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ ::rtl::OUString aSchema,aTable;
+ m_pIndex->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ m_pIndex->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+
+ Reference< XResultSet > xResult = m_pIndex->getTable()->getConnection()->getMetaData()->getIndexInfo(
+ m_pIndex->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),
+ aSchema,aTable,sal_False,sal_False);
+
+ sal_Bool bAsc = sal_True;
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ ::rtl::OUString aD(::rtl::OUString::createFromAscii("D"));
+ while( xResult->next() )
+ {
+ if(xRow->getString(9) == _rName)
+ bAsc = xRow->getString(10) != aD;
+ }
+ }
+
+ xResult = m_pIndex->getTable()->getConnection()->getMetaData()->getColumns(
+ m_pIndex->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),
+ aSchema,aTable,_rName);
+
+ sdbcx::ObjectType xRet;
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ while( xResult->next() )
+ {
+ if ( xRow->getString(4) == _rName )
+ {
+ sal_Int32 nDataType = xRow->getInt(5);
+ ::rtl::OUString aTypeName(xRow->getString(6));
+ sal_Int32 nSize = xRow->getInt(7);
+ sal_Int32 nDec = xRow->getInt(9);
+ sal_Int32 nNull = xRow->getInt(11);
+ ::rtl::OUString aColumnDef(xRow->getString(13));
+
+ OIndexColumn* pRet = new OIndexColumn(bAsc,
+ _rName,
+ aTypeName,
+ aColumnDef,
+ nNull,
+ nSize,
+ nDec,
+ nDataType,
+ sal_False,sal_False,sal_False,sal_True);
+ xRet = pRet;
+ break;
+ }
+ }
+ }
+
+ return xRet;
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OIndexColumns::createDescriptor()
+{
+ return new OIndexColumn(sal_True);
+}
+// -------------------------------------------------------------------------
+void OIndexColumns::impl_refresh() throw(RuntimeException)
+{
+ m_pIndex->refreshColumns();
+}
+// -----------------------------------------------------------------------------
diff --git a/connectivity/source/commontools/TIndexes.cxx b/connectivity/source/commontools/TIndexes.cxx
new file mode 100644
index 000000000000..1f77d51929d0
--- /dev/null
+++ b/connectivity/source/commontools/TIndexes.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TIndexes.hxx"
+#include "connectivity/TIndex.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/IndexType.hpp>
+#include <connectivity/dbtools.hxx>
+#include "connectivity/TTableHelper.hxx"
+#include "TConnection.hxx"
+#include <comphelper/extract.hxx>
+#include <rtl/ustrbuf.hxx>
+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 cppu;
+
+typedef connectivity::sdbcx::OCollection OCollection_TYPE;
+// -----------------------------------------------------------------------------
+OIndexesHelper::OIndexesHelper(OTableHelper* _pTable,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector
+ )
+ : OCollection(*_pTable,sal_True,_rMutex,_rVector)
+ ,m_pTable(_pTable)
+{
+}
+// -----------------------------------------------------------------------------
+
+sdbcx::ObjectType OIndexesHelper::createObject(const ::rtl::OUString& _rName)
+{
+ Reference< XConnection> xConnection = m_pTable->getConnection();
+ if ( !xConnection.is() )
+ return NULL;
+
+ sdbcx::ObjectType xRet;
+ ::rtl::OUString aName,aQualifier;
+ sal_Int32 nLen = _rName.indexOf('.');
+ if ( nLen != -1 )
+ {
+ aQualifier = _rName.copy(0,nLen);
+ aName = _rName.copy(nLen+1);
+ }
+ else
+ aName = _rName;
+
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ ::rtl::OUString aSchema,aTable;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+
+ Any aCatalog = m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME));
+ Reference< XResultSet > xResult = m_pTable->getMetaData()->getIndexInfo(aCatalog,aSchema,aTable,sal_False,sal_False);
+
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ while( xResult->next() )
+ {
+ sal_Bool bUnique = !xRow->getBoolean(4);
+ if((!aQualifier.getLength() || xRow->getString(5) == aQualifier ) && xRow->getString(6) == aName)
+ {
+ sal_Int32 nClustered = xRow->getShort(7);
+ sal_Bool bPrimarKeyIndex = sal_False;
+ xRow.clear();
+ xResult.clear();
+ try
+ {
+ xResult = m_pTable->getMetaData()->getPrimaryKeys(aCatalog,aSchema,aTable);
+ xRow.set(xResult,UNO_QUERY);
+
+ if ( xRow.is() && xResult->next() ) // there can be only one primary key
+ {
+ bPrimarKeyIndex = xRow->getString(6) == aName;
+ }
+ }
+ catch(Exception)
+ {
+ }
+ OIndexHelper* pRet = new OIndexHelper(m_pTable,aName,aQualifier,bUnique,
+ bPrimarKeyIndex,
+ nClustered == IndexType::CLUSTERED);
+ xRet = pRet;
+ break;
+ }
+ }
+ }
+
+ return xRet;
+}
+// -------------------------------------------------------------------------
+void OIndexesHelper::impl_refresh() throw(RuntimeException)
+{
+ m_pTable->refreshIndexes();
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OIndexesHelper::createDescriptor()
+{
+ return new OIndexHelper(m_pTable);
+}
+// -------------------------------------------------------------------------
+// XAppend
+sdbcx::ObjectType OIndexesHelper::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ Reference< XConnection> xConnection = m_pTable->getConnection();
+ if ( !xConnection.is() )
+ return NULL;
+ if ( m_pTable->isNew() )
+ return cloneDescriptor( descriptor );
+
+ if ( m_pTable->getIndexService().is() )
+ {
+ m_pTable->getIndexService()->addIndex(m_pTable,descriptor);
+ }
+ else
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ ::rtl::OUStringBuffer aSql( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CREATE ")));
+ ::rtl::OUString aQuote = m_pTable->getMetaData()->getIdentifierQuoteString( );
+ ::rtl::OUString aDot = ::rtl::OUString::createFromAscii(".");
+
+ if(comphelper::getBOOL(descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISUNIQUE))))
+ aSql.appendAscii("UNIQUE ");
+ aSql.appendAscii("INDEX ");
+
+
+ ::rtl::OUString aCatalog,aSchema,aTable;
+ dbtools::qualifiedNameComponents(m_pTable->getMetaData(),m_pTable->getName(),aCatalog,aSchema,aTable,::dbtools::eInDataManipulation);
+ ::rtl::OUString aComposedName;
+
+ aComposedName = dbtools::composeTableName(m_pTable->getMetaData(),aCatalog,aSchema,aTable,sal_True,::dbtools::eInIndexDefinitions);
+ if ( _rForName.getLength() )
+ {
+ aSql.append( ::dbtools::quoteName( aQuote, _rForName ) );
+ aSql.appendAscii(" ON ");
+ aSql.append(aComposedName);
+ aSql.appendAscii(" ( ");
+
+ Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
+ Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
+ Reference< XPropertySet > xColProp;
+ sal_Bool bAddIndexAppendix = ::dbtools::getBooleanDataSourceSetting( m_pTable->getConnection(), "AddIndexAppendix" );
+ sal_Int32 nCount = xColumns->getCount();
+ for(sal_Int32 i = 0 ; i < nCount; ++i)
+ {
+ xColProp.set(xColumns->getByIndex(i),UNO_QUERY);
+ aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))));
+
+ if ( bAddIndexAppendix )
+ {
+
+ aSql.appendAscii(any2bool(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISASCENDING)))
+ ?
+ " ASC"
+ :
+ " DESC");
+ }
+ aSql.appendAscii(",");
+ }
+ aSql.setCharAt(aSql.getLength()-1,')');
+ }
+ else
+ {
+ aSql.append(aComposedName);
+
+ Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
+ Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
+ Reference< XPropertySet > xColProp;
+ if(xColumns->getCount() != 1)
+ throw SQLException();
+
+ xColumns->getByIndex(0) >>= xColProp;
+
+ aSql.append(aDot);
+ aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))));
+ }
+
+ Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
+ if ( xStmt.is() )
+ {
+ ::rtl::OUString sSql = aSql.makeStringAndClear();
+ xStmt->execute(sSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+
+ return createObject( _rForName );
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OIndexesHelper::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString _sElementName)
+{
+ Reference< XConnection> xConnection = m_pTable->getConnection();
+ if( xConnection.is() && !m_pTable->isNew())
+ {
+ if ( m_pTable->getIndexService().is() )
+ {
+ m_pTable->getIndexService()->dropIndex(m_pTable,_sElementName);
+ }
+ else
+ {
+ ::rtl::OUString aName,aSchema;
+ sal_Int32 nLen = _sElementName.indexOf('.');
+ if(nLen != -1)
+ aSchema = _sElementName.copy(0,nLen);
+ aName = _sElementName.copy(nLen+1);
+
+ ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP INDEX ");
+
+ ::rtl::OUString aComposedName = dbtools::composeTableName( m_pTable->getMetaData(), m_pTable, ::dbtools::eInIndexDefinitions, false, false, true );
+ ::rtl::OUString sIndexName,sTemp;
+ sIndexName = dbtools::composeTableName( m_pTable->getMetaData(), sTemp, aSchema, aName, sal_True, ::dbtools::eInIndexDefinitions );
+
+ aSql += sIndexName
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON "))
+ + aComposedName;
+
+ Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
+ if ( xStmt.is() )
+ {
+ xStmt->execute(aSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+
+
diff --git a/connectivity/source/commontools/TKey.cxx b/connectivity/source/commontools/TKey.cxx
new file mode 100644
index 000000000000..464335aa7b44
--- /dev/null
+++ b/connectivity/source/commontools/TKey.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+
+#include "connectivity/TKey.hxx"
+#include "connectivity/TKeyColumns.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include "TConnection.hxx"
+#include "connectivity/TTableHelper.hxx"
+
+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;
+// -------------------------------------------------------------------------
+OTableKeyHelper::OTableKeyHelper(OTableHelper* _pTable) : connectivity::sdbcx::OKey(sal_True)
+ ,m_pTable(_pTable)
+{
+ construct();
+}
+// -------------------------------------------------------------------------
+OTableKeyHelper::OTableKeyHelper( OTableHelper* _pTable
+ ,const ::rtl::OUString& _Name
+ ,const sdbcx::TKeyProperties& _rProps
+ ) : connectivity::sdbcx::OKey(_Name,_rProps,sal_True)
+ ,m_pTable(_pTable)
+{
+ construct();
+ refreshColumns();
+}
+// -------------------------------------------------------------------------
+void OTableKeyHelper::refreshColumns()
+{
+ if ( !m_pTable )
+ return;
+
+ ::std::vector< ::rtl::OUString> aVector;
+ if ( !isNew() )
+ {
+ aVector = m_aProps->m_aKeyColumnNames;
+ if ( aVector.empty() )
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ ::rtl::OUString aSchema,aTable;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+
+ if ( m_Name.getLength() ) // foreign key
+ {
+
+ Reference< XResultSet > xResult = m_pTable->getMetaData()->getImportedKeys(m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),
+ aSchema,aTable);
+
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ while( xResult->next() )
+ {
+ ::rtl::OUString aForeignKeyColumn = xRow->getString(8);
+ if(xRow->getString(12) == m_Name)
+ aVector.push_back(aForeignKeyColumn);
+ }
+ }
+ }
+
+ if ( aVector.empty() )
+ {
+ const Reference< XResultSet > xResult = m_pTable->getMetaData()->getPrimaryKeys(m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),
+ aSchema,aTable);
+
+ if ( xResult.is() )
+ {
+ const Reference< XRow > xRow(xResult,UNO_QUERY);
+ while( xResult->next() )
+ aVector.push_back(xRow->getString(4));
+ } // if ( xResult.is() )
+ }
+ }
+ }
+
+
+ if ( m_pColumns )
+ m_pColumns ->reFill(aVector);
+ else
+ m_pColumns = new OKeyColumnsHelper(this,m_aMutex,aVector);
+}
+// -----------------------------------------------------------------------------
+
diff --git a/connectivity/source/commontools/TKeyColumns.cxx b/connectivity/source/commontools/TKeyColumns.cxx
new file mode 100644
index 000000000000..18cb7cef14dd
--- /dev/null
+++ b/connectivity/source/commontools/TKeyColumns.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TKeyColumns.hxx"
+#include "connectivity/sdbcx/VKeyColumn.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <comphelper/extract.hxx>
+#include <comphelper/property.hxx>
+#include "TConnection.hxx"
+#include "connectivity/TTableHelper.hxx"
+
+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;
+
+// -------------------------------------------------------------------------
+OKeyColumnsHelper::OKeyColumnsHelper( OTableKeyHelper* _pKey,
+ ::osl::Mutex& _rMutex,
+ const ::std::vector< ::rtl::OUString> &_rVector)
+ : connectivity::sdbcx::OCollection(*_pKey,sal_True,_rMutex,_rVector)
+ ,m_pKey(_pKey)
+{
+}
+// -------------------------------------------------------------------------
+sdbcx::ObjectType OKeyColumnsHelper::createObject(const ::rtl::OUString& _rName)
+{
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ ::rtl::OUString aSchema,aTable;
+ m_pKey->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ m_pKey->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+
+ // frist get the related column to _rName
+ Reference< XResultSet > xResult = m_pKey->getTable()->getMetaData()->getImportedKeys(
+ m_pKey->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),aSchema,aTable);
+
+ ::rtl::OUString aRefColumnName;
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ ::rtl::OUString aTemp;
+ while(xResult->next())
+ {
+ aTemp = xRow->getString(4);
+ if(xRow->getString(8) == _rName && m_pKey->getName() == xRow->getString(12))
+ {
+ aRefColumnName = aTemp;
+ break;
+ }
+ }
+ }
+
+ sdbcx::ObjectType xRet;
+
+ // now describe the column _rName and set his related column
+ xResult = m_pKey->getTable()->getMetaData()->getColumns(
+ m_pKey->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)),aSchema,aTable,_rName);
+
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ if ( xResult->next() )
+ {
+ if ( xRow->getString(4) == _rName )
+ {
+ sal_Int32 nDataType = xRow->getInt(5);
+ ::rtl::OUString aTypeName(xRow->getString(6));
+ sal_Int32 nSize = xRow->getInt(7);
+ sal_Int32 nDec = xRow->getInt(9);
+ sal_Int32 nNull = xRow->getInt(11);
+ ::rtl::OUString sColumnDef;
+ try
+ {
+ sColumnDef = xRow->getString(13);
+ }
+ catch(const SQLException&)
+ {
+ // somethimes we get an error when asking for this param
+ }
+
+ OKeyColumn* pRet = new OKeyColumn(aRefColumnName,
+ _rName,
+ aTypeName,
+ sColumnDef,
+ nNull,
+ nSize,
+ nDec,
+ nDataType,
+ sal_False,
+ sal_False,
+ sal_False,
+ isCaseSensitive());
+ xRet = pRet;
+ }
+ }
+ }
+
+ return xRet;
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OKeyColumnsHelper::createDescriptor()
+{
+ return new OKeyColumn(isCaseSensitive());
+}
+// -------------------------------------------------------------------------
+void OKeyColumnsHelper::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
+{
+ m_pKey->refreshColumns();
+}
+// -----------------------------------------------------------------------------
+
+
diff --git a/connectivity/source/commontools/TKeys.cxx b/connectivity/source/commontools/TKeys.cxx
new file mode 100644
index 000000000000..c4d5dfbf20e0
--- /dev/null
+++ b/connectivity/source/commontools/TKeys.cxx
@@ -0,0 +1,320 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TKeys.hxx"
+#include "connectivity/TKey.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include "connectivity/dbtools.hxx"
+#include <comphelper/extract.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/property.hxx>
+#include "TConnection.hxx"
+
+namespace connectivity
+{
+using namespace comphelper;
+using namespace connectivity::sdbcx;
+using namespace dbtools;
+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;
+
+
+
+OKeysHelper::OKeysHelper( OTableHelper* _pTable,
+ ::osl::Mutex& _rMutex,
+ const TStringVector& _rVector
+ ) : OKeys_BASE(*_pTable,sal_True,_rMutex,_rVector,sal_True)
+ ,m_pTable(_pTable)
+{
+}
+// -------------------------------------------------------------------------
+sdbcx::ObjectType OKeysHelper::createObject(const ::rtl::OUString& _rName)
+{
+ sdbcx::ObjectType xRet = NULL;
+
+ if(_rName.getLength())
+ {
+ OTableKeyHelper* pRet = new OTableKeyHelper(m_pTable,_rName,m_pTable->getKeyProperties(_rName));
+ xRet = pRet;
+ }
+
+ if(!xRet.is()) // we have a primary key with a system name
+ {
+ OTableKeyHelper* pRet = new OTableKeyHelper(m_pTable,_rName,m_pTable->getKeyProperties(_rName));
+ xRet = pRet;
+ }
+
+ return xRet;
+}
+// -------------------------------------------------------------------------
+void OKeysHelper::impl_refresh() throw(RuntimeException)
+{
+ m_pTable->refreshKeys();
+}
+// -------------------------------------------------------------------------
+Reference< XPropertySet > OKeysHelper::createDescriptor()
+{
+ return new OTableKeyHelper(m_pTable);
+}
+// -----------------------------------------------------------------------------
+/** returns the keyrule string for the primary key
+*/
+::rtl::OUString getKeyRuleString(sal_Bool _bUpdate,sal_Int32 _nKeyRule)
+{
+ const char* pKeyRule = NULL;
+ switch ( _nKeyRule )
+ {
+ case KeyRule::CASCADE:
+ pKeyRule = _bUpdate ? " ON UPDATE CASCADE " : " ON DELETE CASCADE ";
+ break;
+ case KeyRule::RESTRICT:
+ pKeyRule = _bUpdate ? " ON UPDATE RESTRICT " : " ON DELETE RESTRICT ";
+ break;
+ case KeyRule::SET_NULL:
+ pKeyRule = _bUpdate ? " ON UPDATE SET NULL " : " ON DELETE SET NULL ";
+ break;
+ case KeyRule::SET_DEFAULT:
+ pKeyRule = _bUpdate ? " ON UPDATE SET DEFAULT " : " ON DELETE SET DEFAULT ";
+ break;
+ default:
+ ;
+ }
+ ::rtl::OUString sRet;
+ if ( pKeyRule )
+ sRet = ::rtl::OUString::createFromAscii(pKeyRule);
+ return sRet;
+}
+// -------------------------------------------------------------------------
+void OKeysHelper::cloneDescriptorColumns( const sdbcx::ObjectType& _rSourceDescriptor, const sdbcx::ObjectType& _rDestDescriptor )
+{
+ Reference< XColumnsSupplier > xColSupp( _rSourceDescriptor, UNO_QUERY_THROW );
+ Reference< XIndexAccess > xSourceCols( xColSupp->getColumns(), UNO_QUERY_THROW );
+
+ xColSupp.set( _rDestDescriptor, UNO_QUERY_THROW );
+ Reference< XAppend > xDestAppend( xColSupp->getColumns(), UNO_QUERY_THROW );
+
+ sal_Int32 nCount = xSourceCols->getCount();
+ for ( sal_Int32 i=0; i< nCount; ++i )
+ {
+ Reference< XPropertySet > xColProp( xSourceCols->getByIndex(i), UNO_QUERY );
+ xDestAppend->appendByDescriptor( xColProp );
+ }
+}
+// -------------------------------------------------------------------------
+// XAppend
+sdbcx::ObjectType OKeysHelper::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
+{
+ Reference< XConnection> xConnection = m_pTable->getConnection();
+ if ( !xConnection.is() )
+ return NULL;
+ if ( m_pTable->isNew() )
+ {
+ Reference< XPropertySet > xNewDescriptor( cloneDescriptor( descriptor ) );
+ cloneDescriptorColumns( descriptor, xNewDescriptor );
+ return xNewDescriptor;
+ }
+
+ const ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ sal_Int32 nKeyType = getINT32(descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)));
+ sal_Int32 nUpdateRule = 0, nDeleteRule = 0;
+ ::rtl::OUString sReferencedName;
+
+ if ( nKeyType == KeyType::FOREIGN )
+ {
+ descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE)) >>= sReferencedName;
+ descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_UPDATERULE)) >>= nUpdateRule;
+ descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE)) >>= nDeleteRule;
+ }
+
+ if ( m_pTable->getKeyService().is() )
+ {
+ m_pTable->getKeyService()->addKey(m_pTable,descriptor);
+ }
+ else
+ {
+ // if we're here, we belong to a table which is not new, i.e. already exists in the database.
+ // In this case, really append the new index.
+ ::rtl::OUStringBuffer aSql;
+ aSql.appendAscii("ALTER TABLE ");
+ ::rtl::OUString aQuote = m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString( );
+ ::rtl::OUString aDot = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("."));
+
+ aSql.append(composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable, ::dbtools::eInTableDefinitions, false, false, true ));
+ aSql.appendAscii(" ADD ");
+
+ if ( nKeyType == KeyType::PRIMARY )
+ {
+ aSql.appendAscii(" PRIMARY KEY (");
+ }
+ else if ( nKeyType == KeyType::FOREIGN )
+ {
+ aSql.appendAscii(" FOREIGN KEY (");
+ }
+ else
+ throw SQLException();
+
+ Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
+ Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
+ Reference< XPropertySet > xColProp;
+ for(sal_Int32 i = 0 ; i < xColumns->getCount() ; ++i)
+ {
+ if ( i > 0 )
+ aSql.appendAscii(",");
+ ::cppu::extractInterface(xColProp,xColumns->getByIndex(i));
+ aSql.append( ::dbtools::quoteName( aQuote,getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))) );
+
+ }
+ aSql.appendAscii(")");
+
+ if ( nKeyType == KeyType::FOREIGN )
+ {
+ aSql.appendAscii(" REFERENCES ");
+ aSql.append(::dbtools::quoteTableName(m_pTable->getConnection()->getMetaData(),sReferencedName,::dbtools::eInTableDefinitions));
+ aSql.appendAscii(" (");
+
+ for(sal_Int32 i=0;i<xColumns->getCount();++i)
+ {
+ if ( i > 0 )
+ aSql.appendAscii(",");
+ xColumns->getByIndex(i) >>= xColProp;
+ aSql.append(::dbtools::quoteName( aQuote,getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_RELATEDCOLUMN)))));
+
+ }
+ aSql.appendAscii(")");
+ aSql.append(getKeyRuleString(sal_True ,nUpdateRule));
+ aSql.append(getKeyRuleString(sal_False ,nDeleteRule));
+ }
+
+ Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
+ xStmt->execute(aSql.makeStringAndClear());
+ }
+ // find the name which the database gave the new key
+ ::rtl::OUString sNewName( _rForName );
+ try
+ {
+ ::rtl::OUString aSchema,aTable;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+ Reference< XResultSet > xResult;
+ sal_Int32 nColumn = 12;
+ if ( nKeyType == KeyType::FOREIGN )
+ xResult = m_pTable->getMetaData()->getImportedKeys( m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME))
+ ,aSchema
+ ,aTable);
+ else
+ {
+ xResult = m_pTable->getMetaData()->getPrimaryKeys( m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME))
+ ,aSchema
+ ,aTable);
+ nColumn = 6;
+ }
+ if ( xResult.is() )
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ while( xResult->next() )
+ {
+ ::rtl::OUString sName = xRow->getString(nColumn);
+ if ( !m_pElements->exists(sName) ) // this name wasn't inserted yet so it must be te new one
+ {
+ descriptor->setPropertyValue( rPropMap.getNameByIndex( PROPERTY_ID_NAME ), makeAny( sName ) );
+ sNewName = sName;
+ break;
+ }
+ }
+ ::comphelper::disposeComponent(xResult);
+ }
+ }
+ catch(const SQLException&)
+ {
+ }
+
+ m_pTable->addKey(sNewName,sdbcx::TKeyProperties(new sdbcx::KeyProperties(sReferencedName,nKeyType,nUpdateRule,nDeleteRule)));
+
+ return createObject( sNewName );
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OKeysHelper::getDropForeignKey() const
+{
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DROP CONSTRAINT "));
+}
+// -------------------------------------------------------------------------
+// XDrop
+void OKeysHelper::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
+{
+ Reference< XConnection> xConnection = m_pTable->getConnection();
+ if ( xConnection.is() && !m_pTable->isNew() )
+ {
+ Reference<XPropertySet> xKey(getObject(_nPos),UNO_QUERY);
+ if ( m_pTable->getKeyService().is() )
+ {
+ m_pTable->getKeyService()->dropKey(m_pTable,xKey);
+ }
+ else
+ {
+ ::rtl::OUStringBuffer aSql;
+ aSql.appendAscii("ALTER TABLE ");
+
+ aSql.append( composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable,::dbtools::eInTableDefinitions, false, false, true ));
+
+ sal_Int32 nKeyType = KeyType::PRIMARY;
+ if ( xKey.is() )
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nKeyType;
+ }
+ if ( KeyType::PRIMARY == nKeyType )
+ {
+ aSql.appendAscii(" DROP PRIMARY KEY");
+ }
+ else
+ {
+ aSql.append(getDropForeignKey());
+ const ::rtl::OUString aQuote = m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString();
+ aSql.append( ::dbtools::quoteName( aQuote,_sElementName) );
+ }
+
+ Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
+ if ( xStmt.is() )
+ {
+ xStmt->execute(aSql.makeStringAndClear());
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+} // namespace connectivity
+// -----------------------------------------------------------------------------
diff --git a/connectivity/source/commontools/TPrivilegesResultSet.cxx b/connectivity/source/commontools/TPrivilegesResultSet.cxx
new file mode 100644
index 000000000000..a7e76f643bfe
--- /dev/null
+++ b/connectivity/source/commontools/TPrivilegesResultSet.cxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "TPrivilegesResultSet.hxx"
+
+using namespace connectivity;
+//------------------------------------------------------------------------------
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+//------------------------------------------------------------------------------
+OResultSetPrivileges::OResultSetPrivileges( const Reference< XDatabaseMetaData>& _rxMeta
+ , const Any& catalog
+ , const ::rtl::OUString& schemaPattern
+ , const ::rtl::OUString& tableNamePattern)
+ : ODatabaseMetaDataResultSet(eTablePrivileges)
+ , m_bResetValues(sal_True)
+{
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ ::rtl::OUString sUserWorkingFor;
+ static Sequence< ::rtl::OUString > sTableTypes;
+ if ( sTableTypes.getLength() == 0 )
+ {
+ // we want all catalogues, all schemas, all tables
+ sTableTypes.realloc(3);
+ sTableTypes[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
+ sTableTypes[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TABLE"));
+ sTableTypes[2] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")); // just to be sure to include anything else ....
+ }
+ try
+ {
+ m_xTables = _rxMeta->getTables(catalog,schemaPattern,tableNamePattern,sTableTypes);
+ m_xRow = Reference< XRow>(m_xTables,UNO_QUERY);
+
+ sUserWorkingFor = _rxMeta->getUserName();
+ }
+ catch(Exception&)
+ {
+ }
+
+ ODatabaseMetaDataResultSet::ORows aRows;
+ static ODatabaseMetaDataResultSet::ORow aRow(8);
+ aRow[5] = new ORowSetValueDecorator(sUserWorkingFor);
+ aRow[6] = ODatabaseMetaDataResultSet::getSelectValue();
+ aRow[7] = new ORowSetValueDecorator(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("YES")));
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getInsertValue();
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getDeleteValue();
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getUpdateValue();
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getCreateValue();
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getReadValue();
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getAlterValue();
+ aRows.push_back(aRow);
+ aRow[6] = ODatabaseMetaDataResultSet::getDropValue();
+ aRows.push_back(aRow);
+ aRow[6] = new ORowSetValueDecorator(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("REFERENCE")));
+ aRows.push_back(aRow);
+
+ setRows(aRows);
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+//------------------------------------------------------------------------------
+const ORowSetValue& OResultSetPrivileges::getValue(sal_Int32 columnIndex)
+{
+ switch(columnIndex)
+ {
+ case 1:
+ case 2:
+ case 3:
+ if ( m_xRow.is() && m_bResetValues )
+ {
+ (*m_aRowsIter)[1] = new ORowSetValueDecorator(m_xRow->getString(1));
+ if ( m_xRow->wasNull() )
+ (*m_aRowsIter)[1]->setNull();
+ (*m_aRowsIter)[2] = new ORowSetValueDecorator(m_xRow->getString(2));
+ if ( m_xRow->wasNull() )
+ (*m_aRowsIter)[2]->setNull();
+ (*m_aRowsIter)[3] = new ORowSetValueDecorator(m_xRow->getString(3));
+ if ( m_xRow->wasNull() )
+ (*m_aRowsIter)[3]->setNull();
+
+ m_bResetValues = sal_False;
+ }
+ }
+ return ODatabaseMetaDataResultSet::getValue(columnIndex);
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OResultSetPrivileges::disposing(void)
+{
+ ODatabaseMetaDataResultSet::disposing();
+m_xTables.clear();
+m_xRow.clear();
+}
+// -----------------------------------------------------------------------------
+sal_Bool SAL_CALL OResultSetPrivileges::next( ) throw(SQLException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
+
+ sal_Bool bReturn = sal_False;
+ if ( m_xTables.is() )
+ {
+ if ( m_bBOF )
+ {
+ m_bResetValues = sal_True;
+ if ( !m_xTables->next() )
+ return sal_False;
+ }
+
+ bReturn = ODatabaseMetaDataResultSet::next();
+ if ( !bReturn )
+ {
+ m_bBOF = sal_False;
+ m_bResetValues = bReturn = m_xTables->next();
+ }
+ }
+ return bReturn;
+}
+// -----------------------------------------------------------------------------
diff --git a/connectivity/source/commontools/TSkipDeletedSet.cxx b/connectivity/source/commontools/TSkipDeletedSet.cxx
new file mode 100644
index 000000000000..2d144ab72941
--- /dev/null
+++ b/connectivity/source/commontools/TSkipDeletedSet.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_connectivity.hxx"
+#include "TSkipDeletedSet.hxx"
+#include <osl/diagnose.h>
+#include <rtl/logfile.hxx>
+
+using namespace connectivity;
+// -----------------------------------------------------------------------------
+OSkipDeletedSet::OSkipDeletedSet(IResultSetHelper* _pHelper)
+ : m_pHelper(_pHelper)
+ ,m_bDeletedVisible(false)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::OSkipDeletedSet" );
+ m_aBookmarksPositions.reserve(256);
+}
+// -----------------------------------------------------------------------------
+OSkipDeletedSet::~OSkipDeletedSet()
+{
+ m_aBookmarksPositions.clear();
+ //m_aBookmarks.clear();
+}
+// -----------------------------------------------------------------------------
+sal_Bool OSkipDeletedSet::skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::skipDeleted" );
+ OSL_ENSURE(_eCursorPosition != IResultSetHelper::BOOKMARK,"OSkipDeletedSet::SkipDeleted can't be called for BOOKMARK");
+
+ IResultSetHelper::Movement eDelPosition = _eCursorPosition;
+ sal_Int32 nDelOffset = abs(_nOffset);
+
+ switch (_eCursorPosition)
+ {
+ case IResultSetHelper::ABSOLUTE:
+ return moveAbsolute(_nOffset,_bRetrieveData);
+ case IResultSetHelper::FIRST: // set the movement when positioning failed
+ eDelPosition = IResultSetHelper::NEXT;
+ nDelOffset = 1;
+ break;
+ case IResultSetHelper::LAST:
+ eDelPosition = IResultSetHelper::PRIOR; // lsat row is invalid so position before
+ nDelOffset = 1;
+ break;
+ case IResultSetHelper::RELATIVE:
+ eDelPosition = (_nOffset >= 0) ? IResultSetHelper::NEXT : IResultSetHelper::PRIOR;
+ break;
+ default:
+ break;
+ }
+
+ sal_Bool bDone = sal_True;
+ sal_Bool bDataFound = sal_False;
+
+ if (_eCursorPosition == IResultSetHelper::LAST)
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLogger, "OSkipDeletedSet::skipDeleted: last" );
+ sal_Int32 nBookmark = 0;
+ // first position on the last known row
+ if ( m_aBookmarksPositions.empty() )
+ {
+ bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData);
+ if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
+ m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
+ }
+ else
+ {
+ // I already have a bookmark so we can positioned on that and look if it is the last one
+ nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
+
+ bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
+ OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"A bookmark should not be deleted!");
+ }
+
+
+ // and than move forward until we are after the last row
+ while(bDataFound)
+ {
+ bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, sal_False); // we don't need the data here
+ if( bDataFound && ( m_bDeletedVisible || !m_pHelper->isRowDeleted()) )
+ { // we weren't on the last row we remember it and move on
+ m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
+ }
+ else if(!bDataFound && !m_aBookmarksPositions.empty() )
+ {
+ // i already know the last bookmark :-)
+ // now we only have to repositioning us to the last row
+ nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
+ bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
+ break;
+ }
+ }
+ return bDataFound;
+ }
+ else if (_eCursorPosition != IResultSetHelper::RELATIVE)
+ {
+ bDataFound = m_pHelper->move(_eCursorPosition, _nOffset, _bRetrieveData);
+ bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
+ }
+ else
+ {
+ bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
+ if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
+ {
+ bDone = (--nDelOffset) == 0;
+ if ( !bDone )
+ m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
+ }
+ else
+ bDone = sal_False;
+ }
+
+ while (bDataFound && !bDone) // solange iterieren bis man auf einem gueltigen Satz ist
+ {
+ bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
+ if (_eCursorPosition != IResultSetHelper::RELATIVE)
+ bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
+ else if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
+ {
+ bDone = (--nDelOffset) == 0;
+ if ( !bDone )
+ m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
+ }
+ else
+ bDone = sal_False;
+ }
+
+ if(bDataFound && bDone )
+ {
+ const sal_Int32 nDriverPos = m_pHelper->getDriverPos();
+ if ( ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),nDriverPos) == m_aBookmarksPositions.end() )
+ m_aBookmarksPositions.push_back(nDriverPos);
+ /*sal_Int32 nDriverPos = m_pHelper->getDriverPos();
+ if(m_aBookmarks.find(nDriverPos) == m_aBookmarks.end())
+ m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(nDriverPos,m_aBookmarksPositions.size()+1)).first);*/
+ }
+
+ return bDataFound;
+}
+// -------------------------------------------------------------------------
+sal_Bool OSkipDeletedSet::moveAbsolute(sal_Int32 _nPos,sal_Bool _bRetrieveData)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::moveAbsolute" );
+ sal_Bool bDataFound = sal_False;
+ sal_Int32 nNewPos = _nPos;
+ if(nNewPos > 0)
+ {
+ if((sal_Int32)m_aBookmarksPositions.size() < nNewPos)
+ {
+ // bookmark isn't known yet
+ // start at the last known position
+ sal_Int32 nCurPos = 0,nLastBookmark = 1;
+ if ( m_aBookmarksPositions.empty() )
+ {
+ bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData );
+ if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
+ {
+ ++nCurPos;
+ m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
+ --nNewPos;
+ }
+ } // if ( m_aBookmarksPositions.empty() )
+ else
+ {
+ nLastBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
+ nCurPos = /*(**/m_aBookmarksPositions.size()/*->second*/;
+ nNewPos = nNewPos - nCurPos;
+ bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nLastBookmark, _bRetrieveData);
+ }
+
+ // now move to that row we need and don't count deleted rows
+ while (bDataFound && nNewPos)
+ {
+ bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, _bRetrieveData);
+ if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
+ {
+ ++nCurPos;
+ m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
+ --nNewPos;
+ }
+ }
+ }
+ else
+ {
+ const sal_Int32 nBookmark = m_aBookmarksPositions[nNewPos-1]/*->first*/;
+ bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK,nBookmark, _bRetrieveData);
+ OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"moveAbsolute: row can't be deleted!");
+ }
+ }
+ else
+ {
+ ++nNewPos;
+ bDataFound = skipDeleted(IResultSetHelper::LAST,0,nNewPos == 0);
+
+ for(sal_Int32 i=nNewPos+1;bDataFound && i <= 0;++i)
+ bDataFound = skipDeleted(IResultSetHelper::PRIOR,1,i == 0);
+
+ }
+ return bDataFound;
+}
+// -----------------------------------------------------------------------------
+void OSkipDeletedSet::clear()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::clear" );
+ ::std::vector<sal_Int32>().swap(m_aBookmarksPositions);
+ //TInt2IntMap().swap(m_aBookmarks);
+}
+// -----------------------------------------------------------------------------
+sal_Int32 OSkipDeletedSet::getMappedPosition(sal_Int32 _nPos) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::getMappedPosition" );
+ ::std::vector<sal_Int32>::const_iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos);
+ if ( aFind != m_aBookmarksPositions.end() )
+ return (aFind - m_aBookmarksPositions.begin()) + 1;
+ /*TInt2IntMap::const_iterator aFind = m_aBookmarks.find(_nPos);
+ OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::getMappedPosition() invalid bookmark!");
+ return aFind->second;*/
+ OSL_ENSURE(0,"Why!");
+ return -1;
+}
+// -----------------------------------------------------------------------------
+void OSkipDeletedSet::insertNewPosition(sal_Int32 _nPos)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::insertNewPosition" );
+ //OSL_ENSURE(m_aBookmarks.find(_nPos) == m_aBookmarks.end(),"OSkipDeletedSet::insertNewPosition: Invalid position");
+ //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(_nPos,m_aBookmarksPositions.size()+1)).first);
+ //OSL_ENSURE(::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos) == m_aBookmarksPositions.end(),"Invalid driver pos");
+ m_aBookmarksPositions.push_back(_nPos);
+}
+// -----------------------------------------------------------------------------
+void OSkipDeletedSet::deletePosition(sal_Int32 _nBookmark)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::deletePosition" );
+ ::std::vector<sal_Int32>::iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nBookmark);
+ if ( aFind != m_aBookmarksPositions.end() )
+ {
+ //TInt2IntMap::iterator aFind = m_aBookmarks.find(_nPos);
+ //OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::deletePosition() bookmark not found!");
+ //TInt2IntMap::iterator aIter = aFind;
+ m_aBookmarksPositions.erase(aFind);
+ //for (; aFind != m_aBookmarksPositions.end() ; ++aIter)
+ // --(aFind->second);
+ } // if ( aFind != m_aBookmarksPositions.end() )
+ //m_aBookmarksPositions.erase(m_aBookmarksPositions.begin() + aFind->second-1);
+ //m_aBookmarks.erase(_nPos);
+}
+// -----------------------------------------------------------------------------
diff --git a/connectivity/source/commontools/TSortIndex.cxx b/connectivity/source/commontools/TSortIndex.cxx
new file mode 100644
index 000000000000..c69ff0b89de1
--- /dev/null
+++ b/connectivity/source/commontools/TSortIndex.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "TSortIndex.hxx"
+#include <algorithm>
+#include <functional>
+
+using namespace connectivity;
+//------------------------------------------------------------------
+/// binary_function Functor object for class OSortIndex::TIntValuePairVector::value_type returntype is bool
+struct TKeyValueFunc : ::std::binary_function<OSortIndex::TIntValuePairVector::value_type,OSortIndex::TIntValuePairVector::value_type,bool>
+{
+ OSortIndex* pIndex;
+
+ TKeyValueFunc(OSortIndex* _pIndex) : pIndex(_pIndex)
+ {
+ }
+ // return false if compared values are equal otherwise true
+ inline bool operator()(const OSortIndex::TIntValuePairVector::value_type& lhs,const OSortIndex::TIntValuePairVector::value_type& rhs) const
+ {
+ const ::std::vector<OKeyType>& aKeyType = pIndex->getKeyType();
+ ::std::vector<OKeyType>::const_iterator aIter = aKeyType.begin();
+ for (::std::vector<sal_Int16>::size_type i=0;aIter != aKeyType.end(); ++aIter,++i)
+ {
+ const bool nGreater = (pIndex->getAscending(i) == SQL_ASC) ? false : true;
+ const bool nLess = !nGreater;
+
+ // compare depending for type
+ switch (*aIter)
+ {
+ case SQL_ORDERBYKEY_STRING:
+ {
+ sal_Int32 nRes = lhs.second->getKeyString(i).compareTo(rhs.second->getKeyString(i));
+ if (nRes < 0)
+ return nLess;
+ else if (nRes > 0)
+ return nGreater;
+ }
+ break;
+ case SQL_ORDERBYKEY_DOUBLE:
+ {
+ double d1 = lhs.second->getKeyDouble(i);
+ double d2 = rhs.second->getKeyDouble(i);
+
+ if (d1 < d2)
+ return nLess;
+ else if (d1 > d2)
+ return nGreater;
+ }
+ break;
+ case SQL_ORDERBYKEY_NONE:
+ break;
+ }
+ }
+
+ // know we know that the values are equal
+ return false;
+ }
+};
+
+// -----------------------------------------------------------------------------
+::vos::ORef<OKeySet> OSortIndex::CreateKeySet()
+{
+ Freeze();
+
+ ::vos::ORef<OKeySet> pKeySet = new OKeySet();
+ pKeySet->get().reserve(m_aKeyValues.size());
+ ::std::transform(m_aKeyValues.begin()
+ ,m_aKeyValues.end()
+ ,::std::back_inserter(pKeySet->get())
+ ,::std::select1st<TIntValuePairVector::value_type>());
+ pKeySet->setFrozen();
+ return pKeySet;
+}
+// -----------------------------------------------------------------------------
+OSortIndex::OSortIndex( const ::std::vector<OKeyType>& _aKeyType,
+ const ::std::vector<TAscendingOrder>& _aAscending)
+ :m_aKeyType(_aKeyType)
+ ,m_aAscending(_aAscending)
+ ,m_bFrozen(sal_False)
+{
+}
+//------------------------------------------------------------------
+OSortIndex::~OSortIndex()
+{
+}
+//------------------------------------------------------------------
+void OSortIndex::AddKeyValue(OKeyValue * pKeyValue)
+{
+ OSL_ENSURE(pKeyValue,"Can not be null here!");
+ if(m_bFrozen)
+ {
+ m_aKeyValues.push_back(TIntValuePairVector::value_type(pKeyValue->getValue(),NULL));
+ delete pKeyValue;
+ }
+ else
+ m_aKeyValues.push_back(TIntValuePairVector::value_type(pKeyValue->getValue(),pKeyValue));
+}
+
+
+//------------------------------------------------------------------
+void OSortIndex::Freeze()
+{
+ OSL_ENSURE(! m_bFrozen,"OSortIndex::Freeze: already frozen!");
+ // Sortierung:
+ if (m_aKeyType[0] != SQL_ORDERBYKEY_NONE)
+ // we will sort ourself when the first keyType say so
+ ::std::sort(m_aKeyValues.begin(),m_aKeyValues.end(),TKeyValueFunc(this));
+
+ TIntValuePairVector::iterator aIter = m_aKeyValues.begin();
+ for(;aIter != m_aKeyValues.end();++aIter)
+ {
+ delete aIter->second;
+ aIter->second = NULL;
+ }
+
+ m_bFrozen = sal_True;
+}
+
+//------------------------------------------------------------------
+sal_Int32 OSortIndex::GetValue(sal_Int32 nPos) const
+{
+ OSL_ENSURE(nPos > 0,"OSortIndex::GetValue: nPos == 0");
+ OSL_ENSURE((size_t)nPos <= m_aKeyValues.size(),"OSortIndex::GetValue: Zugriff ausserhalb der Array-Grenzen");
+
+ if (!m_bFrozen && m_aKeyType[0] != SQL_ORDERBYKEY_NONE)
+ {
+ OSL_ASSERT("OSortIndex::GetValue: Invalid use of index!");
+ return 0;
+ }
+ return m_aKeyValues[nPos-1].first;
+}
+// -----------------------------------------------------------------------------
+OKeyValue::OKeyValue()
+{
+}
+// -----------------------------------------------------------------------------
+OKeyValue::OKeyValue(sal_Int32 nVal)
+: m_nValue(nVal)
+{
+}
+// -----------------------------------------------------------------------------
+OKeyValue::~OKeyValue()
+{
+}
+// -----------------------------------------------------------------------------
+OKeyValue* OKeyValue::createKeyValue(sal_Int32 _nVal)
+{
+ return new OKeyValue(_nVal);
+}
+// -----------------------------------------------------------------------------
+
diff --git a/connectivity/source/commontools/TTableHelper.cxx b/connectivity/source/commontools/TTableHelper.cxx
new file mode 100644
index 000000000000..7d020e9fc4a6
--- /dev/null
+++ b/connectivity/source/commontools/TTableHelper.cxx
@@ -0,0 +1,630 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/TTableHelper.hxx"
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <comphelper/implementationreference.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/types.hxx>
+#include "connectivity/dbtools.hxx"
+#include "connectivity/sdbcx/VCollection.hxx"
+#include <unotools/sharedunocomponent.hxx>
+#include "TConnection.hxx"
+
+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;
+namespace
+{
+ /// helper class for column property change events which holds the OComponentDefinition weak
+typedef ::cppu::WeakImplHelper1 < XContainerListener > OTableContainerListener_BASE;
+class OTableContainerListener : public OTableContainerListener_BASE
+{
+ OTableHelper* m_pComponent;
+ ::std::map< ::rtl::OUString,bool> m_aRefNames;
+
+ OTableContainerListener(const OTableContainerListener&);
+ void operator =(const OTableContainerListener&);
+protected:
+ virtual ~OTableContainerListener(){}
+public:
+ OTableContainerListener(OTableHelper* _pComponent) : m_pComponent(_pComponent){}
+ virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& /*Event*/ ) throw (RuntimeException)
+ {
+ }
+ virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException)
+ {
+ ::rtl::OUString sName;
+ Event.Accessor >>= sName;
+ if ( m_aRefNames.find(sName) != m_aRefNames.end() )
+ m_pComponent->refreshKeys();
+ }
+ virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException)
+ {
+ ::rtl::OUString sOldComposedName,sNewComposedName;
+ Event.ReplacedElement >>= sOldComposedName;
+ Event.Accessor >>= sNewComposedName;
+ if ( sOldComposedName != sNewComposedName && m_aRefNames.find(sOldComposedName) != m_aRefNames.end() )
+ m_pComponent->refreshKeys();
+ }
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException)
+ {
+ }
+ void clear() { m_pComponent = NULL; }
+ inline void add(const ::rtl::OUString& _sRefName) { m_aRefNames.insert(::std::map< ::rtl::OUString,bool>::value_type(_sRefName,true)); }
+};
+}
+namespace connectivity
+{
+ ::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;
+ }
+ struct OTableHelperImpl
+ {
+ TKeyMap m_aKeys;
+ // helper services which can be provided by extensions
+ Reference< ::com::sun::star::sdb::tools::XTableRename> m_xRename;
+ Reference< ::com::sun::star::sdb::tools::XTableAlteration> m_xAlter;
+ Reference< ::com::sun::star::sdb::tools::XKeyAlteration> m_xKeyAlter;
+ Reference< ::com::sun::star::sdb::tools::XIndexAlteration> m_xIndexAlter;
+
+ Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData;
+ Reference< ::com::sun::star::sdbc::XConnection > m_xConnection;
+ ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>
+ m_xTablePropertyListener;
+ ::std::vector< ColumnDesc > m_aColumnDesc;
+ OTableHelperImpl(const Reference< ::com::sun::star::sdbc::XConnection >& _xConnection)
+ : m_xConnection(_xConnection)
+ {
+ try
+ {
+ m_xMetaData = m_xConnection->getMetaData();
+ Reference<XMultiServiceFactory> xFac(_xConnection,UNO_QUERY);
+ if ( xFac.is() )
+ {
+ static const ::rtl::OUString s_sTableRename(RTL_CONSTASCII_USTRINGPARAM("TableRenameServiceName"));
+ m_xRename.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sTableRename)),UNO_QUERY);
+ static const ::rtl::OUString s_sTableAlteration(RTL_CONSTASCII_USTRINGPARAM("TableAlterationServiceName"));
+ m_xAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sTableAlteration)),UNO_QUERY);
+ static const ::rtl::OUString s_sKeyAlteration(RTL_CONSTASCII_USTRINGPARAM("KeyAlterationServiceName"));
+ m_xKeyAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sKeyAlteration)),UNO_QUERY);
+ static const ::rtl::OUString s_sIndexAlteration(RTL_CONSTASCII_USTRINGPARAM("IndexAlterationServiceName"));
+ m_xIndexAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sIndexAlteration)),UNO_QUERY);
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ }
+ };
+}
+
+OTableHelper::OTableHelper( sdbcx::OCollection* _pTables,
+ const Reference< XConnection >& _xConnection,
+ sal_Bool _bCase)
+ :OTable_TYPEDEF(_pTables,_bCase)
+ ,m_pImpl(new OTableHelperImpl(_xConnection))
+{
+}
+// -------------------------------------------------------------------------
+OTableHelper::OTableHelper( sdbcx::OCollection* _pTables,
+ const Reference< XConnection >& _xConnection,
+ sal_Bool _bCase,
+ const ::rtl::OUString& _Name,
+ const ::rtl::OUString& _Type,
+ const ::rtl::OUString& _Description ,
+ const ::rtl::OUString& _SchemaName,
+ const ::rtl::OUString& _CatalogName
+ ) : OTable_TYPEDEF(_pTables,
+ _bCase,
+ _Name,
+ _Type,
+ _Description,
+ _SchemaName,
+ _CatalogName)
+ ,m_pImpl(new OTableHelperImpl(_xConnection))
+{
+}
+// -----------------------------------------------------------------------------
+OTableHelper::~OTableHelper()
+{
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableHelper::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if ( m_pImpl->m_xTablePropertyListener.is() )
+ {
+ m_pTables->removeContainerListener(m_pImpl->m_xTablePropertyListener.getRef());
+ m_pImpl->m_xTablePropertyListener->clear();
+ m_pImpl->m_xTablePropertyListener.dispose();
+ }
+ OTable_TYPEDEF::disposing();
+
+ m_pImpl->m_xConnection = NULL;
+ m_pImpl->m_xMetaData = NULL;
+
+}
+
+// -------------------------------------------------------------------------
+namespace
+{
+ /** collects ColumnDesc's from a resultset produced by XDatabaseMetaData::getColumns
+ */
+ void lcl_collectColumnDescs_throw( const Reference< XResultSet >& _rxResult, ::std::vector< ColumnDesc >& _out_rColumns )
+ {
+ Reference< XRow > xRow( _rxResult, UNO_QUERY_THROW );
+ ::rtl::OUString sName;
+ OrdinalPosition nOrdinalPosition( 0 );
+ while ( _rxResult->next() )
+ {
+ sName = xRow->getString( 4 ); // COLUMN_NAME
+ sal_Int32 nField5 = xRow->getInt(5);
+ ::rtl::OUString aField6 = xRow->getString(6);
+ sal_Int32 nField7 = xRow->getInt(7)
+ , nField9 = xRow->getInt(9)
+ , nField11= xRow->getInt(11);
+ ::rtl::OUString sField12 = xRow->getString(12)
+ ,sField13 = xRow->getString(13);
+ nOrdinalPosition = xRow->getInt( 17 ); // ORDINAL_POSITION
+ _out_rColumns.push_back( ColumnDesc( sName,nField5,aField6,nField7,nField9,nField11,sField12,sField13, nOrdinalPosition ) );
+ }
+ }
+
+ /** checks a given array of ColumnDesc's whether it has reasonable ordinal positions. If not,
+ they will be normalized to be the array index.
+ */
+ void lcl_sanitizeColumnDescs( ::std::vector< ColumnDesc >& _rColumns )
+ {
+ if ( _rColumns.empty() )
+ return;
+
+ // collect all used ordinals
+ ::std::set< OrdinalPosition > aUsedOrdinals;
+ for ( ::std::vector< ColumnDesc >::iterator collect = _rColumns.begin();
+ collect != _rColumns.end();
+ ++collect
+ )
+ aUsedOrdinals.insert( collect->nOrdinalPosition );
+
+ // we need to have as much different ordinals as we have different columns
+ bool bDuplicates = aUsedOrdinals.size() != _rColumns.size();
+ // and it needs to be a continuous range
+ size_t nOrdinalsRange = *aUsedOrdinals.rbegin() - *aUsedOrdinals.begin() + 1;
+ bool bGaps = nOrdinalsRange != _rColumns.size();
+
+ // if that's not the case, normalize it
+ if ( bGaps || bDuplicates )
+ {
+ OSL_ENSURE( false, "lcl_sanitizeColumnDescs: database did provide invalid ORDINAL_POSITION values!" );
+
+ OrdinalPosition nNormalizedPosition = 1;
+ for ( ::std::vector< ColumnDesc >::iterator normalize = _rColumns.begin();
+ normalize != _rColumns.end();
+ ++normalize
+ )
+ normalize->nOrdinalPosition = nNormalizedPosition++;
+ return;
+ }
+
+ // what's left is that the range might not be from 1 to <column count>, but for instance
+ // 0 to <column count>-1.
+ size_t nOffset = *aUsedOrdinals.begin() - 1;
+ for ( ::std::vector< ColumnDesc >::iterator offset = _rColumns.begin();
+ offset != _rColumns.end();
+ ++offset
+ )
+ offset->nOrdinalPosition -= nOffset;
+ }
+}
+
+// -------------------------------------------------------------------------
+void OTableHelper::refreshColumns()
+{
+ TStringVector aVector;
+ if(!isNew())
+ {
+ Any aCatalog;
+ if ( m_CatalogName.getLength() )
+ aCatalog <<= m_CatalogName;
+
+ ::utl::SharedUNOComponent< XResultSet > xResult( getMetaData()->getColumns(
+ aCatalog,
+ m_SchemaName,
+ m_Name,
+ ::rtl::OUString::createFromAscii("%")
+ ) );
+
+ // collect the column names, together with their ordinal position
+ m_pImpl->m_aColumnDesc.clear();
+ lcl_collectColumnDescs_throw( xResult, m_pImpl->m_aColumnDesc );
+
+ // ensure that the ordinal positions as obtained from the meta data do make sense
+ lcl_sanitizeColumnDescs( m_pImpl->m_aColumnDesc );
+
+ // sort by ordinal position
+ ::std::map< OrdinalPosition, ::rtl::OUString > aSortedColumns;
+ for ( ::std::vector< ColumnDesc >::const_iterator copy = m_pImpl->m_aColumnDesc.begin();
+ copy != m_pImpl->m_aColumnDesc.end();
+ ++copy
+ )
+ aSortedColumns[ copy->nOrdinalPosition ] = copy->sName;
+
+ // copy them to aVector, now that we have the proper ordering
+ ::std::transform(
+ aSortedColumns.begin(),
+ aSortedColumns.end(),
+ ::std::insert_iterator< TStringVector >( aVector, aVector.begin() ),
+ ::std::select2nd< ::std::map< OrdinalPosition, ::rtl::OUString >::value_type >()
+ );
+ }
+
+ if(m_pColumns)
+ m_pColumns->reFill(aVector);
+ else
+ m_pColumns = createColumns(aVector);
+}
+// -----------------------------------------------------------------------------
+const ColumnDesc* OTableHelper::getColumnDescription(const ::rtl::OUString& _sName) const
+{
+ const ColumnDesc* pRet = NULL;
+ ::std::vector< ColumnDesc >::const_iterator aEnd = m_pImpl->m_aColumnDesc.end();
+ for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter)
+ {
+ if ( aIter->sName == _sName )
+ {
+ pRet = &*aIter;
+ break;
+ }
+ } // for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter)
+ return pRet;
+}
+// -------------------------------------------------------------------------
+void OTableHelper::refreshPrimaryKeys(TStringVector& _rNames)
+{
+ Any aCatalog;
+ if ( m_CatalogName.getLength() )
+ aCatalog <<= m_CatalogName;
+ Reference< XResultSet > xResult = getMetaData()->getPrimaryKeys(aCatalog,m_SchemaName,m_Name);
+
+ if ( xResult.is() )
+ {
+ sdbcx::TKeyProperties pKeyProps(new sdbcx::KeyProperties(::rtl::OUString(),KeyType::PRIMARY,0,0));
+ ::rtl::OUString aPkName;
+ bool bAlreadyFetched = false;
+ const Reference< XRow > xRow(xResult,UNO_QUERY);
+ while ( xResult->next() )
+ {
+ pKeyProps->m_aKeyColumnNames.push_back(xRow->getString(4));
+ if ( !bAlreadyFetched )
+ {
+ aPkName = xRow->getString(6);
+ bAlreadyFetched = true;
+ }
+ }
+
+ m_pImpl->m_aKeys.insert(TKeyMap::value_type(aPkName,pKeyProps));
+ _rNames.push_back(aPkName);
+ } // if ( xResult.is() && xResult->next() )
+ ::comphelper::disposeComponent(xResult);
+}
+// -------------------------------------------------------------------------
+void OTableHelper::refreshForgeinKeys(TStringVector& _rNames)
+{
+ Any aCatalog;
+ if ( m_CatalogName.getLength() )
+ aCatalog <<= m_CatalogName;
+ Reference< XResultSet > xResult = getMetaData()->getImportedKeys(aCatalog,m_SchemaName,m_Name);
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+
+ if ( xRow.is() )
+ {
+ sdbcx::TKeyProperties pKeyProps;
+ ::rtl::OUString aName,sCatalog,aSchema,sOldFKName;
+ while( xResult->next() )
+ {
+ // this must be outsid the "if" because we have to call in a right order
+ sCatalog = xRow->getString(1);
+ if ( xRow->wasNull() )
+ sCatalog = ::rtl::OUString();
+ aSchema = xRow->getString(2);
+ aName = xRow->getString(3);
+
+ const ::rtl::OUString sForeignKeyColumn = xRow->getString(8);
+ const sal_Int32 nUpdateRule = xRow->getInt(10);
+ const sal_Int32 nDeleteRule = xRow->getInt(11);
+ const ::rtl::OUString sFkName = xRow->getString(12);
+
+ if ( pKeyProps.get() )
+ {
+ }
+
+
+ if ( sFkName.getLength() && !xRow->wasNull() )
+ {
+ if ( sOldFKName != sFkName )
+ {
+ if ( pKeyProps.get() )
+ m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps));
+
+ const ::rtl::OUString sReferencedName = ::dbtools::composeTableName(getMetaData(),sCatalog,aSchema,aName,sal_False,::dbtools::eInDataManipulation);
+ pKeyProps.reset(new sdbcx::KeyProperties(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule));
+ pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
+ _rNames.push_back(sFkName);
+ if ( m_pTables->hasByName(sReferencedName) )
+ {
+ if ( !m_pImpl->m_xTablePropertyListener.is() )
+ m_pImpl->m_xTablePropertyListener = ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>( new OTableContainerListener(this) );
+ m_pTables->addContainerListener(m_pImpl->m_xTablePropertyListener.getRef());
+ m_pImpl->m_xTablePropertyListener->add(sReferencedName);
+ } // if ( m_pTables->hasByName(sReferencedName) )
+ sOldFKName = sFkName;
+ } // if ( sOldFKName != sFkName )
+ else if ( pKeyProps.get() )
+ {
+ pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
+ }
+ }
+ } // while( xResult->next() )
+ if ( pKeyProps.get() )
+ m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps));
+ ::comphelper::disposeComponent(xResult);
+ }
+}
+// -------------------------------------------------------------------------
+void OTableHelper::refreshKeys()
+{
+ m_pImpl->m_aKeys.clear();
+
+ TStringVector aNames;
+
+ if(!isNew())
+ {
+ refreshPrimaryKeys(aNames);
+ refreshForgeinKeys(aNames);
+ m_pKeys = createKeys(aNames);
+ } // if(!isNew())
+ else if (!m_pKeys )
+ m_pKeys = createKeys(aNames);
+ /*if(m_pKeys)
+ m_pKeys->reFill(aVector);
+ else*/
+
+}
+// -------------------------------------------------------------------------
+void OTableHelper::refreshIndexes()
+{
+ TStringVector aVector;
+ if(!isNew())
+ {
+ // fill indexes
+ Any aCatalog;
+ if ( m_CatalogName.getLength() )
+ aCatalog <<= m_CatalogName;
+ Reference< XResultSet > xResult = getMetaData()->getIndexInfo(aCatalog,m_SchemaName,m_Name,sal_False,sal_False);
+
+ if(xResult.is())
+ {
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ ::rtl::OUString aName;
+ ::rtl::OUString sCatalogSep = getMetaData()->getCatalogSeparator();
+ ::rtl::OUString sPreviousRoundName;
+ while( xResult->next() )
+ {
+ aName = xRow->getString(5);
+ if(aName.getLength())
+ aName += sCatalogSep;
+ aName += xRow->getString(6);
+ if ( aName.getLength() )
+ {
+ // don't insert the name if the last one we inserted was the same
+ if (sPreviousRoundName != aName)
+ aVector.push_back(aName);
+ }
+ sPreviousRoundName = aName;
+ }
+ ::comphelper::disposeComponent(xResult);
+ }
+ }
+
+ if(m_pIndexes)
+ m_pIndexes->reFill(aVector);
+ else
+ m_pIndexes = createIndexes(aVector);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OTableHelper::getRenameStart() const
+{
+ ::rtl::OUString sSql(RTL_CONSTASCII_USTRINGPARAM("RENAME "));
+ if ( m_Type == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")) )
+ sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" VIEW "));
+ else
+ sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" TABLE "));
+
+ return sSql;
+}
+// -------------------------------------------------------------------------
+// XRename
+void SAL_CALL OTableHelper::rename( const ::rtl::OUString& newName ) throw(SQLException, ElementExistException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ checkDisposed(
+#ifdef GCC
+ ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
+#else
+ rBHelper.bDisposed
+#endif
+ );
+
+ if(!isNew())
+ {
+ if ( m_pImpl->m_xRename.is() )
+ {
+ m_pImpl->m_xRename->rename(this,newName);
+ }
+ else
+ {
+ ::rtl::OUString sSql = getRenameStart();
+ ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( );
+
+ ::rtl::OUString sCatalog,sSchema,sTable;
+ ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
+
+ ::rtl::OUString sComposedName;
+ sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,sal_True,::dbtools::eInDataManipulation);
+ sSql += sComposedName
+ + ::rtl::OUString::createFromAscii(" TO ");
+ sComposedName = ::dbtools::composeTableName(getMetaData(),sCatalog,sSchema,sTable,sal_True,::dbtools::eInDataManipulation);
+ sSql += sComposedName;
+
+ Reference< XStatement > xStmt = m_pImpl->m_xConnection->createStatement( );
+ if ( xStmt.is() )
+ {
+ xStmt->execute(sSql);
+ ::comphelper::disposeComponent(xStmt);
+ }
+ }
+
+ OTable_TYPEDEF::rename(newName);
+ }
+ else
+ ::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::eInTableDefinitions);
+}
+// -----------------------------------------------------------------------------
+Reference< XDatabaseMetaData> OTableHelper::getMetaData() const
+{
+ return m_pImpl->m_xMetaData;
+}
+// -------------------------------------------------------------------------
+void SAL_CALL OTableHelper::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor ) throw(SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, RuntimeException)
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+ checkDisposed(
+#ifdef GCC
+ ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
+#else
+ rBHelper.bDisposed
+#endif
+ );
+
+ Reference< XPropertySet > xOld;
+ if(::cppu::extractInterface(xOld,m_pColumns->getByIndex(index)) && xOld.is())
+ alterColumnByName(getString(xOld->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),descriptor);
+}
+
+// -------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OTableHelper::getName() throw(RuntimeException)
+{
+ ::rtl::OUString sComposedName;
+ sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,sal_False,::dbtools::eInDataManipulation);
+ return sComposedName;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableHelper::acquire() throw()
+{
+ OTable_TYPEDEF::acquire();
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL OTableHelper::release() throw()
+{
+ OTable_TYPEDEF::release();
+}
+// -----------------------------------------------------------------------------
+sdbcx::TKeyProperties OTableHelper::getKeyProperties(const ::rtl::OUString& _sName) const
+{
+ sdbcx::TKeyProperties pKeyProps;
+ TKeyMap::const_iterator aFind = m_pImpl->m_aKeys.find(_sName);
+ if ( aFind != m_pImpl->m_aKeys.end() )
+ {
+ pKeyProps = aFind->second;
+ }
+ else // only a fall back
+ {
+ OSL_ENSURE(0,"No key with the given name found");
+ pKeyProps.reset(new sdbcx::KeyProperties());
+ }
+
+ return pKeyProps;
+}
+// -----------------------------------------------------------------------------
+void OTableHelper::addKey(const ::rtl::OUString& _sName,const sdbcx::TKeyProperties& _aKeyProperties)
+{
+ m_pImpl->m_aKeys.insert(TKeyMap::value_type(_sName,_aKeyProperties));
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString OTableHelper::getTypeCreatePattern() const
+{
+ return ::rtl::OUString();
+}
+// -----------------------------------------------------------------------------
+Reference< XConnection> OTableHelper::getConnection() const
+{
+ return m_pImpl->m_xConnection;
+}
+// -----------------------------------------------------------------------------
+Reference< ::com::sun::star::sdb::tools::XTableRename> OTableHelper::getRenameService() const
+{
+ return m_pImpl->m_xRename;
+}
+// -----------------------------------------------------------------------------
+Reference< ::com::sun::star::sdb::tools::XTableAlteration> OTableHelper::getAlterService() const
+{
+ return m_pImpl->m_xAlter;
+}
+// -----------------------------------------------------------------------------
+Reference< ::com::sun::star::sdb::tools::XKeyAlteration> OTableHelper::getKeyService() const
+{
+ return m_pImpl->m_xKeyAlter;
+}
+// -----------------------------------------------------------------------------
+Reference< ::com::sun::star::sdb::tools::XIndexAlteration> OTableHelper::getIndexService() const
+{
+ return m_pImpl->m_xIndexAlter;
+}
+// -----------------------------------------------------------------------------
diff --git a/connectivity/source/commontools/conncleanup.cxx b/connectivity/source/commontools/conncleanup.cxx
new file mode 100644
index 000000000000..0d8547923e87
--- /dev/null
+++ b/connectivity/source/commontools/conncleanup.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/conncleanup.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <osl/diagnose.h>
+
+//.........................................................................
+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::lang;
+
+ //=====================================================================
+ static const ::rtl::OUString& getActiveConnectionPropertyName()
+ {
+ static const ::rtl::OUString s_sActiveConnectionPropertyName = ::rtl::OUString::createFromAscii("ActiveConnection");
+ return s_sActiveConnectionPropertyName;
+ }
+
+ //=====================================================================
+ //= OAutoConnectionDisposer
+ //=====================================================================
+ //---------------------------------------------------------------------
+ OAutoConnectionDisposer::OAutoConnectionDisposer(const Reference< XRowSet >& _rxRowSet, const Reference< XConnection >& _rxConnection)
+ :m_xRowSet( _rxRowSet )
+ ,m_bRSListening( sal_False )
+ ,m_bPropertyListening( sal_False )
+ {
+ Reference< XPropertySet > xProps(_rxRowSet, UNO_QUERY);
+ OSL_ENSURE(xProps.is(), "OAutoConnectionDisposer::OAutoConnectionDisposer: invalid rowset (no XPropertySet)!");
+
+ if (!xProps.is())
+ return;
+
+ try
+ {
+ xProps->setPropertyValue( getActiveConnectionPropertyName(), makeAny( _rxConnection ) );
+ m_xOriginalConnection = _rxConnection;
+ startPropertyListening( xProps );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OAutoConnectionDisposer::OAutoConnectionDisposer: caught an exception!" );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void OAutoConnectionDisposer::startPropertyListening( const Reference< XPropertySet >& _rxRowSet )
+ {
+ try
+ {
+ _rxRowSet->addPropertyChangeListener( getActiveConnectionPropertyName(), this );
+ m_bPropertyListening = sal_True;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OAutoConnectionDisposer::startPropertyListening: caught an exception!" );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void OAutoConnectionDisposer::stopPropertyListening( const Reference< XPropertySet >& _rxEventSource )
+ {
+ // prevent deletion of ourself while we're herein
+ Reference< XInterface > xKeepAlive(static_cast< XWeak* >(this));
+
+ try
+ { // remove ourself as property change listener
+ OSL_ENSURE( _rxEventSource.is(), "OAutoConnectionDisposer::stopPropertyListening: invalid event source (no XPropertySet)!" );
+ if ( _rxEventSource.is() )
+ {
+ _rxEventSource->removePropertyChangeListener( getActiveConnectionPropertyName(), this );
+ m_bPropertyListening = sal_False;
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OAutoConnectionDisposer::stopPropertyListening: caught an exception!" );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void OAutoConnectionDisposer::startRowSetListening()
+ {
+ OSL_ENSURE( !m_bRSListening, "OAutoConnectionDisposer::startRowSetListening: already listening!" );
+ try
+ {
+ if ( !m_bRSListening )
+ m_xRowSet->addRowSetListener( this );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OAutoConnectionDisposer::startRowSetListening: caught an exception!" );
+ }
+ m_bRSListening = sal_True;
+ }
+
+ //---------------------------------------------------------------------
+ void OAutoConnectionDisposer::stopRowSetListening()
+ {
+ OSL_ENSURE( m_bRSListening, "OAutoConnectionDisposer::stopRowSetListening: not listening!" );
+ try
+ {
+ m_xRowSet->removeRowSetListener( this );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OAutoConnectionDisposer::stopRowSetListening: caught an exception!" );
+ }
+ m_bRSListening = sal_False;
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OAutoConnectionDisposer::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
+ {
+ if ( _rEvent.PropertyName.equals( getActiveConnectionPropertyName() ) )
+ { // somebody set a new ActiveConnection
+
+ Reference< XConnection > xNewConnection;
+ _rEvent.NewValue >>= xNewConnection;
+
+ if ( isRowSetListening() )
+ {
+ // we're listening at the row set, this means that the row set does not have our
+ // m_xOriginalConnection as active connection anymore
+ // So there are two possibilities
+ // a. somebody sets a new connection which is not our original one
+ // b. somebody sets a new connection, which is exactly the original one
+ // a. we're not interested in a, but in b: In this case, we simply need to move to the state
+ // we had originally: listen for property changes, do not listen for row set changes, and
+ // do not dispose the connection until the row set does not need it anymore
+ if ( xNewConnection.get() == m_xOriginalConnection.get() )
+ {
+ stopRowSetListening();
+ }
+ }
+ else
+ {
+ // start listening at the row set. We're allowed to dispose the old connection as soon
+ // as the RowSet changed
+
+ // Unfortunately, the our database form implementations sometimes fire the change of their
+ // ActiveConnection twice. This is a error in forms/source/component/DatabaseForm.cxx, but
+ // changing this would require incompatible changes we can't do for a while.
+ // So for the moment, we have to live with it here.
+ //
+ // The only scenario where this doubled notification causes problems is when the connection
+ // of the form is reset to the one we're responsible for (m_xOriginalConnection), so we
+ // check this here.
+ //
+ // Yes, this is a HACK :(
+ //
+ // 94407 - 08.11.2001 - fs@openoffice.org
+ if ( xNewConnection.get() != m_xOriginalConnection.get() )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ Reference< XConnection > xOldConnection;
+ _rEvent.OldValue >>= xOldConnection;
+ OSL_ENSURE( xOldConnection.get() == m_xOriginalConnection.get(), "OAutoConnectionDisposer::propertyChange: unexpected (original) property value!" );
+#endif
+ startRowSetListening();
+ }
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void SAL_CALL OAutoConnectionDisposer::disposing( const EventObject& _rSource ) throw (RuntimeException)
+ {
+ // the rowset is beeing disposed, and nobody has set a new ActiveConnection in the meantime
+ if ( isRowSetListening() )
+ stopRowSetListening();
+
+ clearConnection();
+
+ if ( isPropertyListening() )
+ stopPropertyListening( Reference< XPropertySet >( _rSource.Source, UNO_QUERY ) );
+ }
+ //---------------------------------------------------------------------
+ void OAutoConnectionDisposer::clearConnection()
+ {
+ try
+ {
+ // dispose the old connection
+ Reference< XComponent > xComp(m_xOriginalConnection, UNO_QUERY);
+ if (xComp.is())
+ xComp->dispose();
+ m_xOriginalConnection.clear();
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(sal_False, "OAutoConnectionDisposer::clearConnection: caught an exception!");
+ }
+ }
+ //---------------------------------------------------------------------
+ void SAL_CALL OAutoConnectionDisposer::cursorMoved( const ::com::sun::star::lang::EventObject& /*event*/ ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ }
+ //---------------------------------------------------------------------
+ void SAL_CALL OAutoConnectionDisposer::rowChanged( const ::com::sun::star::lang::EventObject& /*event*/ ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ }
+ //---------------------------------------------------------------------
+ void SAL_CALL OAutoConnectionDisposer::rowSetChanged( const ::com::sun::star::lang::EventObject& /*event*/ ) throw (::com::sun::star::uno::RuntimeException)
+ {
+ stopRowSetListening();
+ clearConnection();
+
+ }
+ //---------------------------------------------------------------------
+
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
diff --git a/connectivity/source/commontools/dbcharset.cxx b/connectivity/source/commontools/dbcharset.cxx
new file mode 100644
index 000000000000..7cd722781cda
--- /dev/null
+++ b/connectivity/source/commontools/dbcharset.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/dbcharset.hxx>
+#include "diagnose_ex.h"
+#include <osl/diagnose.h>
+#include <rtl/tencinfo.h>
+
+//.........................................................................
+namespace dbtools
+{
+//.........................................................................
+
+ //=========================================================================
+ //= OCharsetMap
+ //=========================================================================
+ //-------------------------------------------------------------------------
+ OCharsetMap::OCharsetMap()
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ void OCharsetMap::lateConstruct()
+ {
+ const rtl_TextEncoding eFirstEncoding = RTL_TEXTENCODING_DONTKNOW;
+ const rtl_TextEncoding eLastEncoding = 100; // TODO: a define in rtl/textenc.h would be fine here ...
+ OSL_ENSURE( 0 == eFirstEncoding, "OCharsetMap::OCharsetMap: somebody changed the numbers!" );
+
+ rtl_TextEncodingInfo aInfo; aInfo.StructSize = sizeof( rtl_TextEncodingInfo );
+ for ( rtl_TextEncoding eEncoding = eFirstEncoding; eEncoding < eLastEncoding; ++eEncoding )
+ {
+ if ( ( RTL_TEXTENCODING_DONTKNOW == eEncoding ) // this is always allowed - it has the special meaning "system encoding"
+ || ( rtl_getTextEncodingInfo( eEncoding, &aInfo )
+ && approveEncoding( eEncoding, aInfo )
+ )
+ )
+ {
+ m_aEncodings.insert( eEncoding );
+ }
+ }
+
+ OSL_ENSURE( find( RTL_TEXTENCODING_MS_1252 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding ANSI!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_APPLE_ROMAN ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding macintosh!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_437 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM437!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_850) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM850!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_860 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM860!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_861 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM861!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_863 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM863!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_865 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM865!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_IBM_866 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding IBM866!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_DONTKNOW ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding SYSTEM!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_UTF8 ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding UTF-8!" );
+ OSL_ENSURE( find( RTL_TEXTENCODING_BIG5_HKSCS ) != end(), "OCharsetMap::lateConstruct: missing compatibility encoding Big5-HKSCS!" );
+ }
+
+ //-------------------------------------------------------------------------
+ sal_Bool OCharsetMap::approveEncoding( const rtl_TextEncoding _eEncoding, const rtl_TextEncodingInfo& _rInfo ) const
+ {
+ sal_Bool bIsMimeEncoding = 0 != ( _rInfo.Flags & RTL_TEXTENCODING_INFO_MIME );
+ OSL_ENSURE( !bIsMimeEncoding || rtl_getMimeCharsetFromTextEncoding( _eEncoding ),
+ "OCharsetMap::OCharsetMap: inconsistence in rtl!" );
+ OSL_UNUSED( _eEncoding );
+ return bIsMimeEncoding;
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::~OCharsetMap()
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator OCharsetMap::begin() const
+ {
+ ensureConstructed( );
+ return CharsetIterator(this, m_aEncodings.begin() );
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator OCharsetMap::find(const rtl_TextEncoding _eEncoding) const
+ {
+ ensureConstructed( );
+ return CharsetIterator( this, m_aEncodings.find( _eEncoding ) );
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator OCharsetMap::find(const ::rtl::OUString& _rIanaName, const IANA&) const
+ {
+ ensureConstructed( );
+
+ rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
+ if ( _rIanaName.getLength() )
+ {
+ // byte string conversion
+ ::rtl::OString sMimeByteString( _rIanaName.getStr(), _rIanaName.getLength(), RTL_TEXTENCODING_ASCII_US );
+ // look up
+ eEncoding = rtl_getTextEncodingFromMimeCharset( sMimeByteString.getStr() );
+
+ if ( RTL_TEXTENCODING_DONTKNOW == eEncoding )
+ { // if we're here, the name is not empty, but unknown -> this is an invalid name
+ return end();
+ }
+ }
+
+ return find( eEncoding );
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator OCharsetMap::end() const
+ {
+ ensureConstructed( );
+
+ return CharsetIterator( this, m_aEncodings.end() );
+ }
+
+ //=========================================================================
+ //= CharsetIteratorDerefHelper
+ //=========================================================================
+ //-------------------------------------------------------------------------
+ CharsetIteratorDerefHelper::CharsetIteratorDerefHelper( const CharsetIteratorDerefHelper& _rSource )
+ :m_eEncoding( _rSource.m_eEncoding )
+ ,m_aIanaName( _rSource.m_aIanaName )
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ CharsetIteratorDerefHelper:: CharsetIteratorDerefHelper(const rtl_TextEncoding _eEncoding, const ::rtl::OUString& _rIanaName )
+ :m_eEncoding( _eEncoding )
+ ,m_aIanaName( _rIanaName )
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ CharsetIteratorDerefHelper::CharsetIteratorDerefHelper()
+ :m_eEncoding(RTL_TEXTENCODING_DONTKNOW)
+ {
+ }
+
+ //=========================================================================
+ //= OCharsetMap::CharsetIterator
+ //=========================================================================
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator::CharsetIterator(const OCharsetMap* _pContainer, OCharsetMap::TextEncBag::const_iterator _aPos )
+ :m_pContainer( _pContainer )
+ ,m_aPos( _aPos )
+ {
+ OSL_ENSURE( m_pContainer, "OCharsetMap::CharsetIterator::CharsetIterator : invalid container!" );
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator::CharsetIterator(const CharsetIterator& _rSource)
+ :m_pContainer( _rSource.m_pContainer )
+ ,m_aPos( _rSource.m_aPos )
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ OCharsetMap::CharsetIterator::~CharsetIterator()
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ CharsetIteratorDerefHelper OCharsetMap::CharsetIterator::operator*() const
+ {
+ OSL_ENSURE( m_aPos != m_pContainer->m_aEncodings.end(), "OCharsetMap::CharsetIterator::operator*: invalid position!");
+
+ rtl_TextEncoding eEncoding = *m_aPos;
+ ::rtl::OUString sIanaName;
+
+ if ( RTL_TEXTENCODING_DONTKNOW != eEncoding )
+ { // it's not the virtual "system charset"
+ const char* pIanaName = rtl_getMimeCharsetFromTextEncoding( eEncoding );
+ OSL_ENSURE( pIanaName, "OCharsetMap::CharsetIterator: invalid mime name!" );
+ if ( pIanaName )
+ sIanaName = ::rtl::OUString::createFromAscii( pIanaName );
+ }
+ return CharsetIteratorDerefHelper( eEncoding, sIanaName );
+ }
+
+ //-------------------------------------------------------------------------
+ const OCharsetMap::CharsetIterator& OCharsetMap::CharsetIterator::operator++()
+ {
+ OSL_ENSURE( m_aPos != m_pContainer->m_aEncodings.end(), "OCharsetMap::CharsetIterator::operator++ : invalid position!" );
+ if ( m_aPos != m_pContainer->m_aEncodings.end())
+ ++m_aPos;
+ return *this;
+ }
+
+ //-------------------------------------------------------------------------
+ const OCharsetMap::CharsetIterator& OCharsetMap::CharsetIterator::operator--()
+ {
+ OSL_ENSURE( m_aPos != m_pContainer->m_aEncodings.begin(), "OCharsetMap::CharsetIterator::operator-- : invalid position!" );
+ if ( m_aPos != m_pContainer->m_aEncodings.begin() )
+ --m_aPos;
+ return *this;
+ }
+
+ //-------------------------------------------------------------------------
+ bool operator==(const OCharsetMap::CharsetIterator& lhs, const OCharsetMap::CharsetIterator& rhs)
+ {
+ return ( lhs.m_pContainer == rhs.m_pContainer ) && ( lhs.m_aPos == rhs.m_aPos );
+ }
+
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
diff --git a/connectivity/source/commontools/dbconversion.cxx b/connectivity/source/commontools/dbconversion.cxx
new file mode 100644
index 000000000000..6149b4748c30
--- /dev/null
+++ b/connectivity/source/commontools/dbconversion.cxx
@@ -0,0 +1,490 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/dbconversion.hxx>
+#include <connectivity/dbcharset.hxx>
+#include <osl/diagnose.h>
+#ifndef _INC_STDIO
+#include <stdio.h>
+#endif
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#define MAX_DAYS 3636532
+
+//.........................................................................
+namespace dbtools
+{
+//.........................................................................
+
+
+ using namespace ::comphelper;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+
+
+ //------------------------------------------------------------------------------
+ ::com::sun::star::util::Date DBTypeConversion::getStandardDate()
+ {
+ static ::com::sun::star::util::Date STANDARD_DB_DATE(1,1,1900);
+ return STANDARD_DB_DATE;
+ }
+ //------------------------------------------------------------------------------
+ ::rtl::OUString DBTypeConversion::toDateString(const Date& rDate)
+ {
+ sal_Char s[11];
+ snprintf(s,
+ sizeof(s),
+ "%04d-%02d-%02d",
+ (int)rDate.Year,
+ (int)rDate.Month,
+ (int)rDate.Day);
+ s[10] = 0;
+ return ::rtl::OUString::createFromAscii(s);
+ }
+ //------------------------------------------------------------------
+ ::rtl::OUString DBTypeConversion::toTimeString(const Time& rTime)
+ {
+ sal_Char s[9];
+ snprintf(s,
+ sizeof(s),
+ "%02d:%02d:%02d",
+ (int)rTime.Hours,
+ (int)rTime.Minutes,
+ (int)rTime.Seconds);
+ s[8] = 0;
+ return ::rtl::OUString::createFromAscii(s);
+ }
+
+ //------------------------------------------------------------------
+ ::rtl::OUString DBTypeConversion::toDateTimeString(const DateTime& _rDateTime)
+ {
+ Date aDate(_rDateTime.Day,_rDateTime.Month,_rDateTime.Year);
+ ::rtl::OUStringBuffer aTemp(toDateString(aDate));
+ aTemp.appendAscii(" ");
+ Time aTime(0,_rDateTime.Seconds,_rDateTime.Minutes,_rDateTime.Hours);
+ aTemp.append( toTimeString(aTime) );
+ aTemp.appendAscii(".");
+ aTemp.append( static_cast<sal_Int32>(_rDateTime.HundredthSeconds));
+ return aTemp.makeStringAndClear();
+ }
+ //------------------------------------------------------------------------------
+ Date DBTypeConversion::toDate(sal_Int32 _nVal)
+ {
+ Date aReturn;
+ aReturn.Day = (sal_uInt16)(_nVal % 100);
+ aReturn.Month = (sal_uInt16)((_nVal / 100) % 100);
+ aReturn.Year = (sal_uInt16)(_nVal / 10000);
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------------
+ Time DBTypeConversion::toTime(sal_Int32 _nVal)
+ {
+ Time aReturn;
+ aReturn.Hours = (sal_uInt16)(((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) / 1000000);
+ aReturn.Minutes = (sal_uInt16)((((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) / 10000) % 100);
+ aReturn.Seconds = (sal_uInt16)((((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) / 100) % 100);
+ aReturn.HundredthSeconds = (sal_uInt16)(((sal_uInt32)(_nVal >= 0 ? _nVal : _nVal*-1)) % 100);
+ return aReturn;
+ }
+
+ const double fMilliSecondsPerDay = 86400000.0;
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::toINT32(const Date& rVal)
+ {
+ return ((sal_Int32)(rVal.Day%100)) +
+ (((sal_Int32)(rVal.Month%100))*100) +
+ (((sal_Int32) rVal.Year%10000)*10000);
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::toINT32(const Time& rVal)
+ {
+ // Zeit normalisieren
+ sal_Int32 nSeconds = rVal.Seconds + rVal.HundredthSeconds / 100;
+ sal_Int32 nHundredthSeconds = rVal.HundredthSeconds % 100;
+ sal_Int32 nMinutes = rVal.Minutes + nSeconds / 60;
+ nSeconds = nSeconds % 60;
+ sal_Int32 nHours = rVal.Hours + nMinutes / 60;
+ nMinutes = nMinutes % 60;
+
+ // Zeit zusammenbauen
+ return (sal_Int32)(nHundredthSeconds + (nSeconds*100) + (nMinutes*10000) + (nHours*1000000));
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Int64 DBTypeConversion::toINT64(const DateTime& rVal)
+ {
+ // Zeit normalisieren
+ sal_Int32 nSeconds = rVal.Seconds + rVal.HundredthSeconds / 100;
+ sal_Int32 nHundredthSeconds = rVal.HundredthSeconds % 100;
+ sal_Int32 nMinutes = rVal.Minutes + nSeconds / 60;
+ nSeconds = nSeconds % 60;
+ sal_Int32 nHours = rVal.Hours + nMinutes / 60;
+ nMinutes = nMinutes % 60;
+
+ // Zeit zusammenbauen
+ sal_Int32 nTime = (sal_Int32)(nHundredthSeconds + (nSeconds*100) + (nMinutes*10000) + (nHours*1000000));
+ sal_Int32 nDate = ((sal_Int32)(rVal.Day%100)) + (((sal_Int32)(rVal.Month%100))*100) + (((sal_Int32) rVal.Year%10000)*10000);
+ sal_Int64 nRet;
+
+ nRet = (sal_Int64) nTime;
+ nRet <<= 32;
+ nRet += nDate;
+
+ return nRet;
+ }
+
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::getMsFromTime(const Time& rVal)
+ {
+ sal_Int32 nHour = rVal.Hours;
+ sal_Int32 nMin = rVal.Minutes;
+ sal_Int32 nSec = rVal.Seconds;
+ sal_Int32 n100Sec = rVal.HundredthSeconds;
+
+ return ((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10));
+ }
+
+ //------------------------------------------------------------------------------
+ static sal_Int32 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31 };
+
+ //------------------------------------------------------------------------------
+ static sal_Bool implIsLeapYear(sal_Int32 _nYear)
+ {
+ return ( ( ((_nYear % 4) == 0)
+ && ((_nYear % 100) != 0)
+ )
+ )
+ || ((_nYear % 400) == 0)
+ ;
+ }
+
+ //------------------------------------------------------------------------------
+ static sal_Int32 implDaysInMonth(sal_Int32 _nMonth, sal_Int32 _nYear)
+ {
+ OSL_ENSURE(_nMonth > 0 && _nMonth < 13,"Month as invalid value!");
+ if (_nMonth != 2)
+ return aDaysInMonth[_nMonth-1];
+ else
+ {
+ if (implIsLeapYear(_nYear))
+ return aDaysInMonth[_nMonth-1] + 1;
+ else
+ return aDaysInMonth[_nMonth-1];
+ }
+ }
+
+ //------------------------------------------------------------------------------
+ static sal_Int32 implRelativeToAbsoluteNull(const Date& _rDate)
+ {
+ sal_Int32 nDays = 0;
+
+ // ripped this code from the implementation of tools::Date
+ sal_Int32 nNormalizedYear = _rDate.Year - 1;
+ nDays = nNormalizedYear * 365;
+ // leap years
+ nDays += (nNormalizedYear / 4) - (nNormalizedYear / 100) + (nNormalizedYear / 400);
+
+ for (sal_Int32 i = 1; i < _rDate.Month; ++i)
+ nDays += implDaysInMonth(i, _rDate.Year);
+
+ nDays += _rDate.Day;
+ return nDays;
+ }
+ //------------------------------------------------------------------------------
+ static void implBuildFromRelative( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear)
+ {
+ sal_Int32 nTempDays;
+ sal_Int32 i = 0;
+ sal_Bool bCalc;
+
+ do
+ {
+ nTempDays = nDays;
+ rYear = (sal_uInt16)((nTempDays / 365) - i);
+ nTempDays -= (rYear-1) * 365;
+ nTempDays -= ((rYear-1) / 4) - ((rYear-1) / 100) + ((rYear-1) / 400);
+ bCalc = sal_False;
+ if ( nTempDays < 1 )
+ {
+ i++;
+ bCalc = sal_True;
+ }
+ else
+ {
+ if ( nTempDays > 365 )
+ {
+ if ( (nTempDays != 366) || !implIsLeapYear( rYear ) )
+ {
+ i--;
+ bCalc = sal_True;
+ }
+ }
+ }
+ }
+ while ( bCalc );
+
+ rMonth = 1;
+ while ( nTempDays > implDaysInMonth( rMonth, rYear ) )
+ {
+ nTempDays -= implDaysInMonth( rMonth, rYear );
+ rMonth++;
+ }
+ rDay = (sal_uInt16)nTempDays;
+ }
+ //------------------------------------------------------------------------------
+ sal_Int32 DBTypeConversion::toDays(const Date& _rVal, const Date& _rNullDate)
+ {
+ return implRelativeToAbsoluteNull(_rVal) - implRelativeToAbsoluteNull(_rNullDate);
+ }
+
+ //------------------------------------------------------------------------------
+ double DBTypeConversion::toDouble(const Date& rVal, const Date& _rNullDate)
+ {
+ return (double)toDays(rVal, _rNullDate);
+ }
+
+ //------------------------------------------------------------------------------
+ double DBTypeConversion::toDouble(const Time& rVal)
+ {
+ return (double)getMsFromTime(rVal) / fMilliSecondsPerDay;
+ }
+
+ //------------------------------------------------------------------------------
+ double DBTypeConversion::toDouble(const DateTime& _rVal, const Date& _rNullDate)
+ {
+ sal_Int64 nTime = toDays(Date(_rVal.Day, _rVal.Month, _rVal.Year), _rNullDate);
+ Time aTimePart;
+
+ aTimePart.Hours = _rVal.Hours;
+ aTimePart.Minutes = _rVal.Minutes;
+ aTimePart.Seconds = _rVal.Seconds;
+ aTimePart.HundredthSeconds = _rVal.HundredthSeconds;
+
+ return ((double)nTime) + toDouble(aTimePart);
+ }
+ // -------------------------------------------------------------------------
+ static void addDays(sal_Int32 nDays, Date& _rDate)
+ {
+ sal_Int32 nTempDays = implRelativeToAbsoluteNull( _rDate );
+
+ nTempDays += nDays;
+ if ( nTempDays > MAX_DAYS )
+ {
+ _rDate.Day = 31;
+ _rDate.Month = 12;
+ _rDate.Year = 9999;
+ }
+ else if ( nTempDays <= 0 )
+ {
+ _rDate.Day = 1;
+ _rDate.Month = 1;
+ _rDate.Year = 00;
+ }
+ else
+ implBuildFromRelative( nTempDays, _rDate.Day, _rDate.Month, _rDate.Year );
+ }
+ // -----------------------------------------------------------------------
+ static void subDays( sal_Int32 nDays, Date& _rDate )
+ {
+ sal_Int32 nTempDays = implRelativeToAbsoluteNull( _rDate );
+
+ nTempDays -= nDays;
+ if ( nTempDays > MAX_DAYS )
+ {
+ _rDate.Day = 31;
+ _rDate.Month = 12;
+ _rDate.Year = 9999;
+ }
+ else if ( nTempDays <= 0 )
+ {
+ _rDate.Day = 1;
+ _rDate.Month = 1;
+ _rDate.Year = 00;
+ }
+ else
+ implBuildFromRelative( nTempDays, _rDate.Day, _rDate.Month, _rDate.Year );
+ }
+ // -------------------------------------------------------------------------
+ Date DBTypeConversion::toDate(double dVal, const Date& _rNullDate)
+ {
+ Date aRet = _rNullDate;
+
+ if (dVal >= 0)
+ addDays((sal_Int32)dVal,aRet);
+ else
+ subDays((sal_uInt32)(-dVal),aRet);
+ // x -= (sal_uInt32)(-nDays);
+
+ return aRet;
+ }
+ // -------------------------------------------------------------------------
+ Time DBTypeConversion::toTime(double dVal)
+ {
+ sal_Int32 nDays = (sal_Int32)dVal;
+ sal_Int32 nMS = sal_Int32((dVal - (double)nDays) * fMilliSecondsPerDay + 0.5);
+
+ sal_Int16 nSign;
+ if ( nMS < 0 )
+ {
+ nMS *= -1;
+ nSign = -1;
+ }
+ else
+ nSign = 1;
+
+ Time xRet;
+ // Zeit normalisieren
+ // we have to sal_Int32 here because otherwise we get an overflow
+ sal_Int32 nHundredthSeconds = nMS/10;
+ sal_Int32 nSeconds = nHundredthSeconds / 100;
+ sal_Int32 nMinutes = nSeconds / 60;
+
+ xRet.HundredthSeconds = (sal_uInt16)(nHundredthSeconds % 100);
+ xRet.Seconds = (sal_uInt16)(nSeconds % 60);
+ xRet.Hours = (sal_uInt16)(nMinutes / 60);
+ xRet.Minutes = (sal_uInt16)(nMinutes % 60);
+
+ // Zeit zusammenbauen
+ sal_Int32 nTime = (sal_Int32)(xRet.HundredthSeconds + (xRet.Seconds*100) + (xRet.Minutes*10000) + (xRet.Hours*1000000)) * nSign;
+
+ if(nTime < 0)
+ {
+ xRet.HundredthSeconds = 99;
+ xRet.Minutes = 59;
+ xRet.Seconds = 59;
+ xRet.Hours = 23;
+ }
+ return xRet;
+ }
+ //------------------------------------------------------------------------------
+ DateTime DBTypeConversion::toDateTime(double dVal, const Date& _rNullDate)
+ {
+ Date aDate = toDate(dVal, _rNullDate);
+ Time aTime = toTime(dVal);
+
+ DateTime xRet;
+
+ xRet.Day = aDate.Day;
+ xRet.Month = aDate.Month;
+ xRet.Year = aDate.Year;
+
+ xRet.HundredthSeconds = aTime.HundredthSeconds;
+ xRet.Minutes = aTime.Minutes;
+ xRet.Seconds = aTime.Seconds;
+ xRet.Hours = aTime.Hours;
+
+
+ return xRet;
+ }
+ //------------------------------------------------------------------------------
+ Date DBTypeConversion::toDate(const ::rtl::OUString& _sSQLString)
+ {
+ // get the token out of a string
+ static sal_Unicode sDateSep = '-';
+
+ sal_Int32 nIndex = 0;
+ sal_uInt16 nYear = 0,
+ nMonth = 0,
+ nDay = 0;
+ nYear = (sal_uInt16)_sSQLString.getToken(0,sDateSep,nIndex).toInt32();
+ if(nIndex != -1)
+ {
+ nMonth = (sal_uInt16)_sSQLString.getToken(0,sDateSep,nIndex).toInt32();
+ if(nIndex != -1)
+ nDay = (sal_uInt16)_sSQLString.getToken(0,sDateSep,nIndex).toInt32();
+ }
+
+ return Date(nDay,nMonth,nYear);
+ }
+
+ //-----------------------------------------------------------------------------
+ DateTime DBTypeConversion::toDateTime(const ::rtl::OUString& _sSQLString)
+ {
+ //@see http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Timestamp.html#valueOf(java.lang.String)
+ //@see http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Date.html#valueOf(java.lang.String)
+ //@see http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Time.html#valueOf(java.lang.String)
+
+ // the date part
+ Date aDate = toDate(_sSQLString);
+ Time aTime;
+ sal_Int32 nSeparation = _sSQLString.indexOf( ' ' );
+ if ( -1 != nSeparation )
+ aTime = toTime( _sSQLString.copy( nSeparation ) );
+
+ return DateTime(aTime.HundredthSeconds,aTime.Seconds,aTime.Minutes,aTime.Hours,aDate.Day,aDate.Month,aDate.Year);
+ }
+
+ //-----------------------------------------------------------------------------
+ Time DBTypeConversion::toTime(const ::rtl::OUString& _sSQLString)
+ {
+ static sal_Unicode sTimeSep = ':';
+
+ sal_Int32 nIndex = 0;
+ sal_uInt16 nHour = 0,
+ nMinute = 0,
+ nSecond = 0,
+ nHundredthSeconds = 0;
+ nHour = (sal_uInt16)_sSQLString.getToken(0,sTimeSep,nIndex).toInt32();
+ if(nIndex != -1)
+ {
+ nMinute = (sal_uInt16)_sSQLString.getToken(0,sTimeSep,nIndex).toInt32();
+ if(nIndex != -1)
+ {
+ nSecond = (sal_uInt16)_sSQLString.getToken(0,sTimeSep,nIndex).toInt32();
+ nIndex = 0;
+ ::rtl::OUString sNano(_sSQLString.getToken(1,'.',nIndex));
+ if ( sNano.getLength() )
+ {
+ // our time struct only supports hundredth seconds
+ sNano = sNano.copy(0,::std::min<sal_Int32>(sNano.getLength(),2));
+ const static ::rtl::OUString s_Zeros(RTL_CONSTASCII_USTRINGPARAM("00"));
+ sNano += s_Zeros.copy(0,s_Zeros.getLength() - sNano.getLength());
+ nHundredthSeconds = static_cast<sal_uInt16>(sNano.toInt32());
+ }
+ }
+ }
+ return Time(nHundredthSeconds,nSecond,nMinute,nHour);
+ }
+
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
+
diff --git a/connectivity/source/commontools/dbexception.cxx b/connectivity/source/commontools/dbexception.cxx
new file mode 100644
index 000000000000..e266a5a83d4f
--- /dev/null
+++ b/connectivity/source/commontools/dbexception.cxx
@@ -0,0 +1,564 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/dbexception.hxx>
+#include <comphelper/types.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/sdb/SQLErrorEvent.hpp>
+#include "TConnection.hxx"
+#include "resource/common_res.hrc"
+#include "resource/sharedresources.hxx"
+
+//.........................................................................
+namespace dbtools
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::comphelper;
+ using namespace ::connectivity;
+
+//==============================================================================
+//= SQLExceptionInfo - encapsulating the type info of an SQLException-derived class
+//==============================================================================
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo()
+ :m_eType(UNDEFINED)
+{
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdbc::SQLException& _rError)
+{
+ m_aContent <<= _rError;
+ implDetermineType();
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdbc::SQLWarning& _rError)
+{
+ m_aContent <<= _rError;
+ implDetermineType();
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdb::SQLContext& _rError)
+{
+ m_aContent <<= _rError;
+ implDetermineType();
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo( const ::rtl::OUString& _rSimpleErrorMessage )
+{
+ SQLException aError;
+ aError.Message = _rSimpleErrorMessage;
+ m_aContent <<= aError;
+ implDetermineType();
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo(const SQLExceptionInfo& _rCopySource)
+ :m_aContent(_rCopySource.m_aContent)
+ ,m_eType(_rCopySource.m_eType)
+{
+}
+
+//------------------------------------------------------------------------------
+const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdbc::SQLException& _rError)
+{
+ m_aContent <<= _rError;
+ implDetermineType();
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdbc::SQLWarning& _rError)
+{
+ m_aContent <<= _rError;
+ implDetermineType();
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdb::SQLContext& _rError)
+{
+ m_aContent <<= _rError;
+ implDetermineType();
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdb::SQLErrorEvent& _rErrorEvent)
+{
+ m_aContent = _rErrorEvent.Reason;
+ implDetermineType();
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::uno::Any& _rCaughtSQLException)
+{
+ m_aContent = _rCaughtSQLException;
+ implDetermineType();
+ return *this;
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdb::SQLErrorEvent& _rError)
+{
+ m_aContent = _rError.Reason;
+ implDetermineType();
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::SQLExceptionInfo(const staruno::Any& _rError)
+{
+ const staruno::Type& aSQLExceptionType = ::getCppuType(reinterpret_cast< ::com::sun::star::sdbc::SQLException*>(NULL));
+ sal_Bool bValid = isAssignableFrom(aSQLExceptionType, _rError.getValueType());
+ if (bValid)
+ m_aContent = _rError;
+ // no assertion here : if used with the NextException member of an SQLException bValid==sal_False is allowed.
+
+ implDetermineType();
+}
+
+//------------------------------------------------------------------------------
+void SQLExceptionInfo::implDetermineType()
+{
+ staruno::Type aContentType = m_aContent.getValueType();
+
+ const Type& aSQLExceptionType = ::getCppuType( reinterpret_cast< SQLException* >( NULL ) );
+ const Type& aSQLWarningType = ::getCppuType( reinterpret_cast< SQLWarning* >( NULL ) );
+ const Type& aSQLContextType = ::getCppuType( reinterpret_cast< SQLContext* >( NULL ) );
+
+ if ( isAssignableFrom( aSQLContextType, m_aContent.getValueType() ) )
+ m_eType = SQL_CONTEXT;
+ else if ( isAssignableFrom( aSQLWarningType, m_aContent.getValueType() ) )
+ m_eType = SQL_WARNING;
+ else if ( isAssignableFrom( aSQLExceptionType, m_aContent.getValueType() ) )
+ m_eType = SQL_EXCEPTION;
+ else
+ {
+ m_eType = UNDEFINED;
+ m_aContent.clear();
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SQLExceptionInfo::isKindOf(TYPE _eType) const
+{
+ switch (_eType)
+ {
+ case SQL_CONTEXT:
+ return (m_eType == SQL_CONTEXT);
+ case SQL_WARNING:
+ return (m_eType == SQL_CONTEXT) || (m_eType == SQL_WARNING);
+ case SQL_EXCEPTION:
+ return (m_eType == SQL_CONTEXT) || (m_eType == SQL_WARNING) || (m_eType == SQL_EXCEPTION);
+ case UNDEFINED:
+ return (m_eType == UNDEFINED);
+ }
+ return sal_False;
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::operator const ::com::sun::star::sdbc::SQLException*() const
+{
+ OSL_ENSURE(isKindOf(SQL_EXCEPTION), "SQLExceptionInfo::operator SQLException* : invalid call !");
+ return reinterpret_cast<const ::com::sun::star::sdbc::SQLException*>(m_aContent.getValue());
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::operator const ::com::sun::star::sdbc::SQLWarning*() const
+{
+ OSL_ENSURE(isKindOf(SQL_WARNING), "SQLExceptionInfo::operator SQLException* : invalid call !");
+ return reinterpret_cast<const ::com::sun::star::sdbc::SQLWarning*>(m_aContent.getValue());
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionInfo::operator const ::com::sun::star::sdb::SQLContext*() const
+{
+ OSL_ENSURE(isKindOf(SQL_CONTEXT), "SQLExceptionInfo::operator SQLException* : invalid call !");
+ return reinterpret_cast<const ::com::sun::star::sdb::SQLContext*>(m_aContent.getValue());
+}
+
+//------------------------------------------------------------------------------
+void SQLExceptionInfo::prepend( const ::rtl::OUString& _rErrorMessage, const sal_Char* _pAsciiSQLState, const sal_Int32 _nErrorCode )
+{
+ SQLException aException;
+ aException.Message = _rErrorMessage;
+ aException.ErrorCode = _nErrorCode;
+ aException.SQLState = ::rtl::OUString::createFromAscii( _pAsciiSQLState ? _pAsciiSQLState : "S1000" );
+ aException.NextException = m_aContent;
+ m_aContent <<= aException;
+
+ m_eType = SQL_EXCEPTION;
+}
+
+//------------------------------------------------------------------------------
+void SQLExceptionInfo::append( TYPE _eType, const ::rtl::OUString& _rErrorMessage, const sal_Char* _pAsciiSQLState, const sal_Int32 _nErrorCode )
+{
+ // create the to-be-appended exception
+ Any aAppend;
+ switch ( _eType )
+ {
+ case SQL_EXCEPTION: aAppend <<= SQLException(); break;
+ case SQL_WARNING: aAppend <<= SQLWarning(); break;
+ case SQL_CONTEXT: aAppend <<= SQLContext(); break;
+ default:
+ OSL_ENSURE( false, "SQLExceptionInfo::append: invalid exception type: this will crash!" );
+ break;
+ }
+
+ SQLException* pAppendException( static_cast< SQLException* >( const_cast< void* >( aAppend.getValue() ) ) );
+ pAppendException->Message = _rErrorMessage;
+ pAppendException->SQLState = ::rtl::OUString::createFromAscii( _pAsciiSQLState );
+ pAppendException->ErrorCode = _nErrorCode;
+
+ // find the end of the current chain
+ Any* pChainIterator = &m_aContent;
+ SQLException* pLastException = NULL;
+ const Type& aSQLExceptionType( ::getCppuType< SQLException >() );
+ while ( pChainIterator )
+ {
+ if ( !pChainIterator->hasValue() )
+ break;
+
+ if ( !isAssignableFrom( aSQLExceptionType, pChainIterator->getValueType() ) )
+ break;
+
+ pLastException = static_cast< SQLException* >( const_cast< void* >( pChainIterator->getValue() ) );
+ pChainIterator = &pLastException->NextException;
+ }
+
+ // append
+ if ( pLastException )
+ pLastException->NextException = aAppend;
+ else
+ {
+ m_aContent = aAppend;
+ m_eType = _eType;
+ }
+}
+
+//------------------------------------------------------------------------------
+void SQLExceptionInfo::doThrow()
+{
+ if ( m_aContent.getValueTypeClass() == TypeClass_EXCEPTION )
+ ::cppu::throwException( m_aContent );
+ throw RuntimeException();
+}
+
+//==============================================================================
+//= SQLExceptionIteratorHelper
+//==============================================================================
+
+//------------------------------------------------------------------------------
+SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const SQLExceptionInfo& _rChainStart )
+ :m_pCurrent( NULL )
+ ,m_eCurrentType( SQLExceptionInfo::UNDEFINED )
+{
+ if ( _rChainStart.isValid() )
+ {
+ m_pCurrent = (const SQLException*)_rChainStart;
+ m_eCurrentType = _rChainStart.getType();
+ }
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const ::com::sun::star::sdbc::SQLException& _rChainStart )
+ :m_pCurrent( &_rChainStart )
+ ,m_eCurrentType( SQLExceptionInfo::SQL_EXCEPTION )
+{
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const ::com::sun::star::sdbc::SQLWarning& _rChainStart )
+ :m_pCurrent( &_rChainStart )
+ ,m_eCurrentType( SQLExceptionInfo::SQL_WARNING )
+{
+}
+
+//------------------------------------------------------------------------------
+SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const ::com::sun::star::sdb::SQLContext& _rChainStart )
+ :m_pCurrent( &_rChainStart )
+ ,m_eCurrentType( SQLExceptionInfo::SQL_CONTEXT )
+{
+}
+
+//------------------------------------------------------------------------------
+void SQLExceptionIteratorHelper::current( SQLExceptionInfo& _out_rInfo ) const
+{
+ switch ( m_eCurrentType )
+ {
+ case SQLExceptionInfo::SQL_EXCEPTION:
+ _out_rInfo = *m_pCurrent;
+ break;
+
+ case SQLExceptionInfo::SQL_WARNING:
+ _out_rInfo = *static_cast< const SQLWarning* >( m_pCurrent );
+ break;
+
+ case SQLExceptionInfo::SQL_CONTEXT:
+ _out_rInfo = *static_cast< const SQLContext* >( m_pCurrent );
+ break;
+
+ default:
+ _out_rInfo = Any();
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+const ::com::sun::star::sdbc::SQLException* SQLExceptionIteratorHelper::next()
+{
+ OSL_ENSURE( hasMoreElements(), "SQLExceptionIteratorHelper::next : invalid call (please use hasMoreElements)!" );
+
+ const ::com::sun::star::sdbc::SQLException* pReturn = current();
+ if ( !m_pCurrent )
+ return pReturn;
+
+ // check for the next element within the chain
+ const Type aTypeException( ::cppu::UnoType< SQLException >::get() );
+
+ Type aNextElementType = m_pCurrent->NextException.getValueType();
+ if ( !isAssignableFrom( aTypeException, aNextElementType ) )
+ {
+ // no SQLException at all in the next chain element
+ m_pCurrent = NULL;
+ m_eCurrentType = SQLExceptionInfo::UNDEFINED;
+ return pReturn;
+ }
+
+ m_pCurrent = static_cast< const SQLException* >( m_pCurrent->NextException.getValue() );
+
+ // no finally determine the proper type of the exception
+ const Type aTypeContext( ::cppu::UnoType< SQLContext >::get() );
+ if ( isAssignableFrom( aTypeContext, aNextElementType ) )
+ {
+ m_eCurrentType = SQLExceptionInfo::SQL_CONTEXT;
+ return pReturn;
+ }
+
+ const Type aTypeWarning( ::cppu::UnoType< SQLWarning >::get() );
+ if ( isAssignableFrom( aTypeWarning, aNextElementType ) )
+ {
+ m_eCurrentType = SQLExceptionInfo::SQL_WARNING;
+ return pReturn;
+ }
+
+ // a simple SQLException
+ m_eCurrentType = SQLExceptionInfo::SQL_EXCEPTION;
+ return pReturn;
+}
+
+//------------------------------------------------------------------------------
+void SQLExceptionIteratorHelper::next( SQLExceptionInfo& _out_rInfo )
+{
+ current( _out_rInfo );
+ next();
+}
+
+//------------------------------------------------------------
+void throwFunctionSequenceException(const Reference< XInterface >& _Context, const Any& _Next) throw ( ::com::sun::star::sdbc::SQLException )
+{
+ ::connectivity::SharedResources aResources;
+ throw SQLException(
+ aResources.getResourceString(STR_ERRORMSG_SEQUENCE),
+ _Context,
+ getStandardSQLState( SQL_FUNCTION_SEQUENCE_ERROR ),
+ 0,
+ _Next
+ );
+}
+// -----------------------------------------------------------------------------
+void throwInvalidIndexException(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _Context,
+ const ::com::sun::star::uno::Any& _Next) throw ( ::com::sun::star::sdbc::SQLException )
+{
+ ::connectivity::SharedResources aResources;
+ throw SQLException(
+ aResources.getResourceString(STR_INVALID_INDEX),
+ _Context,
+ getStandardSQLState( SQL_INVALID_DESCRIPTOR_INDEX ),
+ 0,
+ _Next
+ );
+}
+// -----------------------------------------------------------------------------
+void throwFunctionNotSupportedException(const ::rtl::OUString& _rMsg,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _Context,
+ const ::com::sun::star::uno::Any& _Next) throw ( ::com::sun::star::sdbc::SQLException )
+{
+ throw SQLException(
+ _rMsg,
+ _Context,
+ getStandardSQLState( SQL_FUNCTION_NOT_SUPPORTED ),
+ 0,
+ _Next
+ );
+}
+// -----------------------------------------------------------------------------
+void throwFunctionNotSupportedException( const sal_Char* _pAsciiFunctionName, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContext,
+ const ::com::sun::star::uno::Any* _pNextException ) throw ( ::com::sun::star::sdbc::SQLException )
+{
+ ::connectivity::SharedResources aResources;
+ const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
+ STR_UNSUPPORTED_FUNCTION,
+ "$functionname$", ::rtl::OUString::createFromAscii( _pAsciiFunctionName )
+ ) );
+ throw SQLException(
+ sError,
+ _rxContext,
+ getStandardSQLState( SQL_FUNCTION_NOT_SUPPORTED ),
+ 0,
+ _pNextException ? *_pNextException : Any()
+ );
+}
+// -----------------------------------------------------------------------------
+void throwGenericSQLException(const ::rtl::OUString& _rMsg, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxSource)
+ throw (::com::sun::star::sdbc::SQLException)
+{
+ throwGenericSQLException(_rMsg, _rxSource, Any());
+}
+
+// -----------------------------------------------------------------------------
+void throwGenericSQLException(const ::rtl::OUString& _rMsg, const Reference< XInterface >& _rxSource, const Any& _rNextException)
+ throw (SQLException)
+{
+ throw SQLException( _rMsg, _rxSource, getStandardSQLState( SQL_GENERAL_ERROR ), 0, _rNextException);
+}
+
+// -----------------------------------------------------------------------------
+void throwFeatureNotImplementedException( const sal_Char* _pAsciiFeatureName, const Reference< XInterface >& _rxContext, const Any* _pNextException )
+ throw (SQLException)
+{
+ ::connectivity::SharedResources aResources;
+ const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
+ STR_UNSUPPORTED_FEATURE,
+ "$featurename$", ::rtl::OUString::createFromAscii( _pAsciiFeatureName )
+ ) );
+
+ throw SQLException(
+ sError,
+ _rxContext,
+ getStandardSQLState( SQL_FEATURE_NOT_IMPLEMENTED ),
+ 0,
+ _pNextException ? *_pNextException : Any()
+ );
+}
+
+// -----------------------------------------------------------------------------
+void throwSQLException( const sal_Char* _pAsciiMessage, const sal_Char* _pAsciiState,
+ const Reference< XInterface >& _rxContext, const sal_Int32 _nErrorCode, const Any* _pNextException ) throw (SQLException)
+{
+ throw SQLException(
+ ::rtl::OUString::createFromAscii( _pAsciiMessage ),
+ _rxContext,
+ ::rtl::OUString::createFromAscii( _pAsciiState ),
+ _nErrorCode,
+ _pNextException ? *_pNextException : Any()
+ );
+}
+
+// -----------------------------------------------------------------------------
+void throwSQLException( const sal_Char* _pAsciiMessage, StandardSQLState _eSQLState,
+ const Reference< XInterface >& _rxContext, const sal_Int32 _nErrorCode,
+ const Any* _pNextException ) throw (SQLException)
+{
+ throwSQLException( _pAsciiMessage, getStandardSQLStateAscii( _eSQLState ), _rxContext, _nErrorCode, _pNextException );
+}
+
+// -----------------------------------------------------------------------------
+void throwSQLException( const ::rtl::OUString& _rMessage, StandardSQLState _eSQLState,
+ const Reference< XInterface >& _rxContext, const sal_Int32 _nErrorCode,
+ const Any* _pNextException ) throw (SQLException)
+{
+ throw SQLException(
+ _rMessage,
+ _rxContext,
+ getStandardSQLState( _eSQLState ),
+ _nErrorCode,
+ _pNextException ? *_pNextException : Any()
+ );
+}
+
+// -----------------------------------------------------------------------------
+const sal_Char* getStandardSQLStateAscii( StandardSQLState _eState )
+{
+ const sal_Char* pAsciiState = NULL;
+ switch ( _eState )
+ {
+ case SQL_WRONG_PARAMETER_NUMBER: pAsciiState = "07001"; break;
+ case SQL_INVALID_DESCRIPTOR_INDEX: pAsciiState = "07009"; break;
+ case SQL_UNABLE_TO_CONNECT: pAsciiState = "08001"; break;
+ case SQL_NUMERIC_OUT_OF_RANGE: pAsciiState = "22003"; break;
+ case SQL_INVALID_DATE_TIME: pAsciiState = "22007"; break;
+ case SQL_INVALID_CURSOR_STATE: pAsciiState = "24000"; break;
+ case SQL_TABLE_OR_VIEW_EXISTS: pAsciiState = "42S01"; break;
+ case SQL_TABLE_OR_VIEW_NOT_FOUND: pAsciiState = "42S02"; break;
+ case SQL_INDEX_ESISTS: pAsciiState = "42S11"; break;
+ case SQL_INDEX_NOT_FOUND: pAsciiState = "42S12"; break;
+ case SQL_COLUMN_EXISTS: pAsciiState = "42S21"; break;
+ case SQL_COLUMN_NOT_FOUND: pAsciiState = "42S22"; break;
+ case SQL_GENERAL_ERROR: pAsciiState = "HY000"; break;
+ case SQL_INVALID_SQL_DATA_TYPE: pAsciiState = "HY004"; break;
+ case SQL_OPERATION_CANCELED: pAsciiState = "HY008"; break;
+ case SQL_FUNCTION_SEQUENCE_ERROR: pAsciiState = "HY010"; break;
+ case SQL_INVALID_CURSOR_POSITION: pAsciiState = "HY109"; break;
+ case SQL_INVALID_BOOKMARK_VALUE: pAsciiState = "HY111"; break;
+ case SQL_FEATURE_NOT_IMPLEMENTED: pAsciiState = "HYC00"; break;
+ case SQL_FUNCTION_NOT_SUPPORTED: pAsciiState = "IM001"; break;
+ case SQL_CONNECTION_DOES_NOT_EXIST: pAsciiState = "08003"; break;
+
+ default:
+ break;
+ }
+ if ( !pAsciiState )
+ throw RuntimeException();
+ return pAsciiState;
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString getStandardSQLState( StandardSQLState _eState )
+{
+ return ::rtl::OUString::createFromAscii( getStandardSQLStateAscii( _eState ) );
+}
+
+// -----------------------------------------------------------------------------
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
+
diff --git a/connectivity/source/commontools/dbmetadata.cxx b/connectivity/source/commontools/dbmetadata.cxx
new file mode 100644
index 000000000000..04754ecb2f19
--- /dev/null
+++ b/connectivity/source/commontools/dbmetadata.cxx
@@ -0,0 +1,448 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include "connectivity/dbmetadata.hxx"
+#include "connectivity/dbexception.hxx"
+#include "connectivity/DriversConfig.hxx"
+#include "resource/common_res.hrc"
+#include "resource/sharedresources.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/sdb/BooleanComparisonMode.hpp>
+#include <com/sun/star/sdbc/XDatabaseMetaData2.hpp>
+#include <com/sun/star/sdbcx/XUsersSupplier.hpp>
+#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
+#include <com/sun/star/sdbc/XDriverAccess.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <boost/optional.hpp>
+
+//........................................................................
+namespace dbtools
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::sdbc::XDatabaseMetaData;
+ using ::com::sun::star::sdbc::XDatabaseMetaData2;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::container::XChild;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::sdbcx::XUsersSupplier;
+ using ::com::sun::star::sdbcx::XDataDefinitionSupplier;
+ using ::com::sun::star::sdbc::XDriverAccess;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ /** === end UNO using === **/
+ namespace BooleanComparisonMode = ::com::sun::star::sdb::BooleanComparisonMode;
+
+ //====================================================================
+ //= DatabaseMetaData_Impl
+ //====================================================================
+ struct DatabaseMetaData_Impl
+ {
+ Reference< XConnection > xConnection;
+ Reference< XDatabaseMetaData > xConnectionMetaData;
+ ::connectivity::DriversConfig aDriverConfig;
+
+ ::boost::optional< ::rtl::OUString > sCachedIdentifierQuoteString;
+ ::boost::optional< ::rtl::OUString > sCachedCatalogSeparator;
+
+ DatabaseMetaData_Impl()
+ :xConnection()
+ ,xConnectionMetaData()
+ ,aDriverConfig( ::comphelper::getProcessServiceFactory() )
+ ,sCachedIdentifierQuoteString()
+ ,sCachedCatalogSeparator()
+ {
+ }
+ };
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //................................................................
+ static void lcl_construct( DatabaseMetaData_Impl& _metaDataImpl, const Reference< XConnection >& _connection )
+ {
+ _metaDataImpl.xConnection = _connection;
+ if ( !_metaDataImpl.xConnection.is() )
+ return;
+
+ _metaDataImpl.xConnectionMetaData = _connection->getMetaData();
+ if ( !_metaDataImpl.xConnectionMetaData.is() )
+ throw IllegalArgumentException();
+ }
+
+ //................................................................
+ static void lcl_checkConnected( const DatabaseMetaData_Impl& _metaDataImpl )
+ {
+ if ( !_metaDataImpl.xConnection.is() || !_metaDataImpl.xConnectionMetaData.is() )
+ {
+ ::connectivity::SharedResources aResources;
+ const ::rtl::OUString sError( aResources.getResourceString(STR_NO_CONNECTION_GIVEN));
+ throwSQLException( sError, SQL_CONNECTION_DOES_NOT_EXIST, NULL );
+ }
+ }
+
+ //................................................................
+ static bool lcl_getDriverSetting( const sal_Char* _asciiName, const DatabaseMetaData_Impl& _metaData, Any& _out_setting )
+ {
+ lcl_checkConnected( _metaData );
+ const ::comphelper::NamedValueCollection& rDriverMetaData = _metaData.aDriverConfig.getMetaData( _metaData.xConnectionMetaData->getURL() );
+ if ( !rDriverMetaData.has( _asciiName ) )
+ return false;
+ _out_setting = rDriverMetaData.get( _asciiName );
+ return true;
+ }
+
+ //................................................................
+ static bool lcl_getConnectionSetting( const sal_Char* _asciiName, const DatabaseMetaData_Impl& _metaData, Any& _out_setting )
+ {
+ try
+ {
+ Reference< XChild > xConnectionAsChild( _metaData.xConnection, UNO_QUERY );
+ if ( xConnectionAsChild.is() )
+ {
+ Reference< XPropertySet > xDataSource( xConnectionAsChild->getParent(), UNO_QUERY_THROW );
+ Reference< XPropertySet > xDataSourceSettings(
+ xDataSource->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings" ) ) ),
+ UNO_QUERY_THROW );
+
+ _out_setting = xDataSourceSettings->getPropertyValue( ::rtl::OUString::createFromAscii( _asciiName ) );
+ }
+ else
+ {
+ Reference< XDatabaseMetaData2 > xExtendedMetaData( _metaData.xConnectionMetaData, UNO_QUERY_THROW );
+ ::comphelper::NamedValueCollection aSettings( xExtendedMetaData->getConnectionInfo() );
+ _out_setting = aSettings.get( _asciiName );
+ return _out_setting.hasValue();
+ }
+ return true;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return false;
+ }
+
+ //................................................................
+ static const ::rtl::OUString& lcl_getConnectionStringSetting(
+ const DatabaseMetaData_Impl& _metaData, ::boost::optional< ::rtl::OUString >& _cachedSetting,
+ ::rtl::OUString (SAL_CALL XDatabaseMetaData::*_getter)() )
+ {
+ if ( !_cachedSetting )
+ {
+ lcl_checkConnected( _metaData );
+ try
+ {
+ _cachedSetting.reset( (_metaData.xConnectionMetaData.get()->*_getter)() );
+ }
+ catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
+ }
+ return *_cachedSetting;
+ }
+ }
+
+ //====================================================================
+ //= DatabaseMetaData
+ //====================================================================
+ //--------------------------------------------------------------------
+ DatabaseMetaData::DatabaseMetaData()
+ :m_pImpl( new DatabaseMetaData_Impl )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DatabaseMetaData::DatabaseMetaData( const Reference< XConnection >& _connection )
+ :m_pImpl( new DatabaseMetaData_Impl )
+ {
+ lcl_construct( *m_pImpl, _connection );
+ }
+
+ //--------------------------------------------------------------------
+ DatabaseMetaData::DatabaseMetaData( const DatabaseMetaData& _copyFrom )
+ :m_pImpl( new DatabaseMetaData_Impl( *_copyFrom.m_pImpl ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DatabaseMetaData& DatabaseMetaData::operator=( const DatabaseMetaData& _copyFrom )
+ {
+ if ( this == &_copyFrom )
+ return *this;
+
+ m_pImpl.reset( new DatabaseMetaData_Impl( *_copyFrom.m_pImpl ) );
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ DatabaseMetaData::~DatabaseMetaData()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::isConnected() const
+ {
+ return m_pImpl->xConnection.is();
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::supportsSubqueriesInFrom() const
+ {
+ lcl_checkConnected( *m_pImpl );
+
+ bool supportsSubQueries = false;
+ try
+ {
+ sal_Int32 maxTablesInselect = m_pImpl->xConnectionMetaData->getMaxTablesInSelect();
+ supportsSubQueries = ( maxTablesInselect > 1 ) || ( maxTablesInselect == 0 );
+ // TODO: is there a better way to determine this? The above is not really true. More precise,
+ // it's a *very* generous heuristics ...
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return supportsSubQueries;
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::supportsPrimaryKeys() const
+ {
+ lcl_checkConnected( *m_pImpl );
+
+ bool doesSupportPrimaryKeys = false;
+ try
+ {
+ Any setting;
+ if ( !( lcl_getConnectionSetting( "PrimaryKeySupport", *m_pImpl, setting ) )
+ || !( setting >>= doesSupportPrimaryKeys )
+ )
+ doesSupportPrimaryKeys = m_pImpl->xConnectionMetaData->supportsCoreSQLGrammar();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return doesSupportPrimaryKeys;
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& DatabaseMetaData::getIdentifierQuoteString() const
+ {
+ return lcl_getConnectionStringSetting( *m_pImpl, m_pImpl->sCachedIdentifierQuoteString, &XDatabaseMetaData::getIdentifierQuoteString );
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& DatabaseMetaData::getCatalogSeparator() const
+ {
+ return lcl_getConnectionStringSetting( *m_pImpl, m_pImpl->sCachedCatalogSeparator, &XDatabaseMetaData::getCatalogSeparator );
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::restrictIdentifiersToSQL92() const
+ {
+ lcl_checkConnected( *m_pImpl );
+
+ bool restrict( false );
+ Any setting;
+ if ( lcl_getConnectionSetting( "EnableSQL92Check", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= restrict );
+ return restrict;
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::generateASBeforeCorrelationName() const
+ {
+ bool doGenerate( true );
+ Any setting;
+ if ( lcl_getConnectionSetting( "GenerateASBeforeCorrelationName", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= doGenerate );
+ return doGenerate;
+ }
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::shouldEscapeDateTime() const
+ {
+ bool doGenerate( true );
+ Any setting;
+ if ( lcl_getConnectionSetting( "EscapeDateTime", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= doGenerate );
+ return doGenerate;
+ }
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::isAutoIncrementPrimaryKey() const
+ {
+ bool is( true );
+ Any setting;
+ if ( lcl_getDriverSetting( "AutoIncrementIsPrimaryKey", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= is );
+ return is;
+ }
+ //--------------------------------------------------------------------
+ sal_Int32 DatabaseMetaData::getBooleanComparisonMode() const
+ {
+ sal_Int32 mode( BooleanComparisonMode::EQUAL_INTEGER );
+ Any setting;
+ if ( lcl_getConnectionSetting( "BooleanComparisonMode", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= mode );
+ return mode;
+ }
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::supportsRelations() const
+ {
+ lcl_checkConnected( *m_pImpl );
+ bool bSupport = false;
+ try
+ {
+ bSupport = m_pImpl->xConnectionMetaData->supportsIntegrityEnhancementFacility();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ try
+ {
+ if ( !bSupport )
+ {
+ const ::rtl::OUString url = m_pImpl->xConnectionMetaData->getURL();
+ char pMySQL[] = "sdbc:mysql";
+ bSupport = url.matchAsciiL(pMySQL,(sizeof(pMySQL)/sizeof(pMySQL[0]))-1);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bSupport;
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::supportsColumnAliasInOrderBy() const
+ {
+ bool doGenerate( true );
+ Any setting;
+ if ( lcl_getConnectionSetting( "ColumnAliasInOrderBy", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= doGenerate );
+ return doGenerate;
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::supportsUserAdministration( const ::comphelper::ComponentContext& _rContext ) const
+ {
+ lcl_checkConnected( *m_pImpl );
+
+ bool isSupported( false );
+ try
+ {
+ // find the XUsersSupplier interface
+ // - either directly at the connection
+ Reference< XUsersSupplier > xUsersSupp( m_pImpl->xConnection, UNO_QUERY );
+ if ( !xUsersSupp.is() )
+ {
+ // - or at the driver manager
+ Reference< XDriverAccess > xDriverManager(
+ _rContext.createComponent( "com.sun.star.sdbc.DriverManager" ), UNO_QUERY_THROW );
+ Reference< XDataDefinitionSupplier > xDriver( xDriverManager->getDriverByURL( m_pImpl->xConnectionMetaData->getURL() ), UNO_QUERY );
+ if ( xDriver.is() )
+ xUsersSupp.set( xDriver->getDataDefinitionByConnection( m_pImpl->xConnection ), UNO_QUERY );
+ }
+
+ isSupported = ( xUsersSupp.is() && xUsersSupp->getUsers().is() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return isSupported;
+ }
+
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::displayEmptyTableFolders() const
+ {
+ bool doDisplay( true );
+#ifdef IMPLEMENTED_LATER
+ Any setting;
+ if ( lcl_getConnectionSetting( "DisplayEmptyTableFolders", *m_pImpl, setting ) )
+ OSL_VERIFY( setting >>= doDisplay );
+#else
+ try
+ {
+ Reference< XDatabaseMetaData > xMeta( m_pImpl->xConnectionMetaData, UNO_SET_THROW );
+ ::rtl::OUString sConnectionURL( xMeta->getURL() );
+ doDisplay = sConnectionURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:mysqlc" ) ) == 0;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+#endif
+ return doDisplay;
+ }
+ //--------------------------------------------------------------------
+ bool DatabaseMetaData::supportsThreads() const
+ {
+ bool bSupported( true );
+ try
+ {
+ Reference< XDatabaseMetaData > xMeta( m_pImpl->xConnectionMetaData, UNO_SET_THROW );
+ ::rtl::OUString sConnectionURL( xMeta->getURL() );
+ bSupported = sConnectionURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:mysqlc" ) ) != 0;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bSupported;
+ }
+
+//........................................................................
+} // namespace dbtools
+//........................................................................
+
diff --git a/connectivity/source/commontools/dbtools.cxx b/connectivity/source/commontools/dbtools.cxx
new file mode 100644
index 000000000000..05bcf997268f
--- /dev/null
+++ b/connectivity/source/commontools/dbtools.cxx
@@ -0,0 +1,2173 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include "connectivity/CommonTools.hxx"
+#include "diagnose_ex.h"
+#include "TConnection.hxx"
+#include "connectivity/ParameterCont.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/BooleanComparisonMode.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/ParametersRequest.hpp>
+#include <com/sun/star/sdb/RowSetVetoException.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdbc/XDriverManager.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XRowUpdate.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>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/uno/XNamingService.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/extract.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/property.hxx>
+#include <connectivity/conncleanup.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/statementcomposer.hxx>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <tools/diagnose_ex.h>
+
+#include "resource/common_res.hrc"
+#include "resource/sharedresources.hxx"
+#include "OSubComponent.hxx"
+
+#include <algorithm>
+
+using namespace ::comphelper;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::form;
+using namespace connectivity;
+
+//.........................................................................
+namespace dbtools
+{
+//.........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::task;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::task;
+// using namespace cppu;
+// using namespace osl;
+
+//==============================================================================
+//==============================================================================
+namespace
+{
+ typedef sal_Bool (SAL_CALL XDatabaseMetaData::*FMetaDataSupport)();
+}
+//==============================================================================
+//==============================================================================
+sal_Int32 getDefaultNumberFormat(const Reference< XPropertySet >& _xColumn,
+ const Reference< XNumberFormatTypes >& _xTypes,
+ const Locale& _rLocale)
+{
+ OSL_ENSURE(_xTypes.is() && _xColumn.is(), "dbtools::getDefaultNumberFormat: invalid arg !");
+ if (!_xTypes.is() || !_xColumn.is())
+ return NumberFormat::UNDEFINED;
+
+ sal_Int32 nDataType = 0;
+ sal_Int32 nScale = 0;
+ try
+ {
+ // determine the datatype of the column
+ _xColumn->getPropertyValue(::rtl::OUString::createFromAscii("Type")) >>= nDataType;
+
+ if (DataType::NUMERIC == nDataType || DataType::DECIMAL == nDataType)
+ _xColumn->getPropertyValue(::rtl::OUString::createFromAscii("Scale")) >>= nScale;
+ }
+ catch (Exception&)
+ {
+ return NumberFormat::UNDEFINED;
+ }
+ return getDefaultNumberFormat(nDataType,
+ nScale,
+ ::cppu::any2bool(_xColumn->getPropertyValue(::rtl::OUString::createFromAscii("IsCurrency"))),
+ _xTypes,
+ _rLocale);
+}
+
+//------------------------------------------------------------------
+sal_Int32 getDefaultNumberFormat(sal_Int32 _nDataType,
+ sal_Int32 _nScale,
+ sal_Bool _bIsCurrency,
+ const Reference< XNumberFormatTypes >& _xTypes,
+ const Locale& _rLocale)
+{
+ OSL_ENSURE(_xTypes.is() , "dbtools::getDefaultNumberFormat: invalid arg !");
+ if (!_xTypes.is())
+ return NumberFormat::UNDEFINED;
+
+ sal_Int32 nFormat = 0;
+ sal_Int32 nNumberType = _bIsCurrency ? NumberFormat::CURRENCY : NumberFormat::NUMBER;
+ switch (_nDataType)
+ {
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ nFormat = _xTypes->getStandardFormat(NumberFormat::LOGICAL, _rLocale);
+ break;
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ case DataType::BIGINT:
+ case DataType::FLOAT:
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ {
+ try
+ {
+ nFormat = _xTypes->getStandardFormat((sal_Int16)nNumberType, _rLocale);
+ if(_nScale > 0)
+ {
+ // generate a new format if necessary
+ Reference< XNumberFormats > xFormats(_xTypes, UNO_QUERY);
+ ::rtl::OUString sNewFormat = xFormats->generateFormat( 0L, _rLocale, sal_False, sal_False, (sal_Int16)_nScale, sal_True);
+
+ // and add it to the formatter if necessary
+ nFormat = xFormats->queryKey(sNewFormat, _rLocale, sal_False);
+ if (nFormat == (sal_Int32)-1)
+ nFormat = xFormats->addNew(sNewFormat, _rLocale);
+ }
+ }
+ catch (Exception&)
+ {
+ nFormat = _xTypes->getStandardFormat((sal_Int16)nNumberType, _rLocale);
+ }
+ } break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ case DataType::CLOB:
+ nFormat = _xTypes->getStandardFormat(NumberFormat::TEXT, _rLocale);
+ break;
+ case DataType::DATE:
+ nFormat = _xTypes->getStandardFormat(NumberFormat::DATE, _rLocale);
+ break;
+ case DataType::TIME:
+ nFormat = _xTypes->getStandardFormat(NumberFormat::TIME, _rLocale);
+ break;
+ case DataType::TIMESTAMP:
+ nFormat = _xTypes->getStandardFormat(NumberFormat::DATETIME, _rLocale);
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::SQLNULL:
+ case DataType::OTHER:
+ case DataType::OBJECT:
+ case DataType::DISTINCT:
+ case DataType::STRUCT:
+ case DataType::ARRAY:
+ case DataType::BLOB:
+ case DataType::REF:
+ default:
+ nFormat = _xTypes->getStandardFormat(NumberFormat::UNDEFINED, _rLocale);
+ //nFormat = NumberFormat::UNDEFINED;
+ }
+ return nFormat;
+}
+
+//==============================================================================
+//------------------------------------------------------------------------------
+Reference< XConnection> findConnection(const Reference< XInterface >& xParent)
+{
+ Reference< XConnection> xConnection(xParent, UNO_QUERY);
+ if (!xConnection.is())
+ {
+ Reference< XChild> xChild(xParent, UNO_QUERY);
+ if (xChild.is())
+ xConnection = findConnection(xChild->getParent());
+ }
+ return xConnection;
+}
+
+//------------------------------------------------------------------------------
+Reference< XDataSource> getDataSource_allowException(
+ const ::rtl::OUString& _rsTitleOrPath,
+ const Reference< XMultiServiceFactory >& _rxFactory )
+{
+ OSL_ENSURE( _rsTitleOrPath.getLength(), "getDataSource_allowException: invalid arg !" );
+
+ Reference< XNameAccess> xDatabaseContext(
+ _rxFactory->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.sdb.DatabaseContext" ) ),UNO_QUERY );
+ OSL_ENSURE( xDatabaseContext.is(), "getDataSource_allowException: could not obtain the database context!" );
+
+ return Reference< XDataSource >( xDatabaseContext->getByName( _rsTitleOrPath ), UNO_QUERY );
+}
+
+//------------------------------------------------------------------------------
+Reference< XDataSource > getDataSource(
+ const ::rtl::OUString& _rsTitleOrPath,
+ const Reference< XMultiServiceFactory >& _rxFactory )
+{
+ Reference< XDataSource > xDS;
+ try
+ {
+ xDS = getDataSource_allowException( _rsTitleOrPath, _rxFactory );
+ }
+ catch(Exception)
+ {
+ }
+
+ return xDS;
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection > getConnection_allowException(
+ const ::rtl::OUString& _rsTitleOrPath,
+ const ::rtl::OUString& _rsUser,
+ const ::rtl::OUString& _rsPwd,
+ const Reference< XMultiServiceFactory>& _rxFactory)
+{
+ Reference< XDataSource> xDataSource( getDataSource_allowException(_rsTitleOrPath, _rxFactory) );
+ Reference<XConnection> xConnection;
+ if (xDataSource.is())
+ {
+ // do it with interaction handler
+ if(!_rsUser.getLength() || !_rsPwd.getLength())
+ {
+ Reference<XPropertySet> xProp(xDataSource,UNO_QUERY);
+ ::rtl::OUString sPwd, sUser;
+ sal_Bool bPwdReq = sal_False;
+ try
+ {
+ xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
+ bPwdReq = ::cppu::any2bool(xProp->getPropertyValue(::rtl::OUString::createFromAscii("IsPasswordRequired")));
+ xProp->getPropertyValue(::rtl::OUString::createFromAscii("User")) >>= sUser;
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(sal_False, "dbtools::getConnection: error while retrieving data source properties!");
+ }
+ if(bPwdReq && !sPwd.getLength())
+ { // password required, but empty -> connect using an interaction handler
+ Reference<XCompletedConnection> xConnectionCompletion(xProp, UNO_QUERY);
+ if (xConnectionCompletion.is())
+ { // instantiate the default SDB interaction handler
+ Reference< XInteractionHandler > xHandler(_rxFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler")), UNO_QUERY);
+ OSL_ENSURE(xHandler.is(), "dbtools::getConnection service com.sun.star.task.InteractionHandler not available!");
+ if (xHandler.is())
+ {
+ xConnection = xConnectionCompletion->connectWithCompletion(xHandler);
+ }
+ }
+ }
+ else
+ xConnection = xDataSource->getConnection(sUser, sPwd);
+ }
+ if(!xConnection.is()) // try to get one if not already have one, just to make sure
+ xConnection = xDataSource->getConnection(_rsUser, _rsPwd);
+ }
+ return xConnection;
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection> getConnection_withFeedback(const ::rtl::OUString& _rDataSourceName,
+ const ::rtl::OUString& _rUser, const ::rtl::OUString& _rPwd, const Reference< XMultiServiceFactory>& _rxFactory)
+ SAL_THROW ( (SQLException) )
+{
+ Reference< XConnection > xReturn;
+ try
+ {
+ xReturn = getConnection_allowException(_rDataSourceName, _rUser, _rPwd, _rxFactory);
+ }
+ catch(SQLException&)
+ {
+ // allowed to pass
+ throw;
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(sal_False, "::dbtools::getConnection_withFeedback: unexpected (non-SQL) exception caught!");
+ }
+ return xReturn;
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection> getConnection(
+ const ::rtl::OUString& _rsTitleOrPath,
+ const ::rtl::OUString& _rsUser,
+ const ::rtl::OUString& _rsPwd,
+ const Reference< XMultiServiceFactory>& _rxFactory)
+{
+ Reference< XConnection > xReturn;
+ try
+ {
+ xReturn = getConnection_allowException(_rsTitleOrPath, _rsUser, _rsPwd, _rxFactory);
+ }
+ catch(Exception&)
+ {
+ }
+
+ // TODO: if there were not dozens of places which rely on getConnection not throwing an exception ....
+ // I would change this ...
+
+ return xReturn;
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection> getConnection(const Reference< XRowSet>& _rxRowSet) throw (RuntimeException)
+{
+ Reference< XConnection> xReturn;
+ Reference< XPropertySet> xRowSetProps(_rxRowSet, UNO_QUERY);
+ if (xRowSetProps.is())
+ xRowSetProps->getPropertyValue(::rtl::OUString::createFromAscii("ActiveConnection")) >>= xReturn;
+ return xReturn;
+}
+
+//------------------------------------------------------------------------------
+// helper function which allows to implement both the connectRowset and the ensureRowSetConnection semantics
+// if connectRowset (which is deprecated) is removed, this function and one of its parameters are
+// not needed anymore, the whole implementation can be moved into ensureRowSetConnection then)
+SharedConnection lcl_connectRowSet(const Reference< XRowSet>& _rxRowSet, const Reference< XMultiServiceFactory>& _rxFactory,
+ bool _bSetAsActiveConnection, bool _bAttachAutoDisposer )
+ SAL_THROW ( ( SQLException, WrappedTargetException, RuntimeException ) )
+{
+ SharedConnection xConnection;
+
+ do
+ {
+ Reference< XPropertySet> xRowSetProps(_rxRowSet, UNO_QUERY);
+ if ( !xRowSetProps.is() )
+ break;
+
+ // 1. already connected?
+ Reference< XConnection > xExistingConn(
+ xRowSetProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ) ),
+ UNO_QUERY );
+
+ if ( xExistingConn.is()
+ // 2. embedded in a database?
+ || isEmbeddedInDatabase( _rxRowSet, xExistingConn )
+ // 3. is there a connection in the parent hierarchy?
+ || ( xExistingConn = findConnection( _rxRowSet ) ).is()
+ )
+ {
+ if ( _bSetAsActiveConnection )
+ {
+ xRowSetProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ), makeAny( xExistingConn ) );
+ // no auto disposer needed, since we did not create the connection
+ }
+
+ xConnection.reset( xExistingConn, SharedConnection::NoTakeOwnership );
+ break;
+ }
+
+ // build a connection with it's current settings (4. data source name, or 5. URL)
+
+ const ::rtl::OUString sUserProp = ::rtl::OUString::createFromAscii("User");
+ ::rtl::OUString sDataSourceName;
+ xRowSetProps->getPropertyValue(::rtl::OUString::createFromAscii("DataSourceName")) >>= sDataSourceName;
+ ::rtl::OUString sURL;
+ xRowSetProps->getPropertyValue(::rtl::OUString::createFromAscii("URL")) >>= sURL;
+
+ Reference< XConnection > xPureConnection;
+ if (sDataSourceName.getLength())
+ { // the row set's data source property is set
+ // -> try to connect, get user and pwd setting for that
+ ::rtl::OUString sUser, sPwd;
+
+ if (hasProperty(sUserProp, xRowSetProps))
+ xRowSetProps->getPropertyValue(sUserProp) >>= sUser;
+ if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), xRowSetProps))
+ xRowSetProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
+
+ xPureConnection = getConnection_allowException( sDataSourceName, sUser, sPwd, _rxFactory );
+ }
+ else if (sURL.getLength())
+ { // the row set has no data source, but a connection url set
+ // -> try to connection with that url
+ Reference< XDriverManager > xDriverManager(
+ _rxFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ConnectionPool")), UNO_QUERY);
+ if (xDriverManager.is())
+ {
+ ::rtl::OUString sUser, sPwd;
+ if (hasProperty(sUserProp, xRowSetProps))
+ xRowSetProps->getPropertyValue(sUserProp) >>= sUser;
+ if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), xRowSetProps))
+ xRowSetProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
+ if (sUser.getLength())
+ { // use user and pwd together with the url
+ Sequence< PropertyValue> aInfo(2);
+ aInfo.getArray()[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user"));
+ aInfo.getArray()[0].Value <<= sUser;
+ aInfo.getArray()[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("password"));
+ aInfo.getArray()[1].Value <<= sPwd;
+ xPureConnection = xDriverManager->getConnectionWithInfo( sURL, aInfo );
+ }
+ else
+ // just use the url
+ xPureConnection = xDriverManager->getConnection( sURL );
+ }
+ }
+ xConnection.reset(
+ xPureConnection,
+ _bAttachAutoDisposer ? SharedConnection::NoTakeOwnership : SharedConnection::TakeOwnership
+ /* take ownership if and only if we're *not* going to auto-dispose the connection */
+ );
+
+ // now if we created a connection, forward it to the row set
+ if ( xConnection.is() && _bSetAsActiveConnection )
+ {
+ try
+ {
+ if ( _bAttachAutoDisposer )
+ {
+ OAutoConnectionDisposer* pAutoDispose = new OAutoConnectionDisposer( _rxRowSet, xConnection );
+ Reference< XPropertyChangeListener > xEnsureDelete(pAutoDispose);
+ }
+ else
+ xRowSetProps->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ),
+ makeAny( xConnection.getTyped() )
+ );
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(0,"EXception when we set the new active connection!");
+ }
+ }
+ }
+ while ( false );
+
+ return xConnection;
+}
+
+//------------------------------------------------------------------------------
+Reference< XConnection> connectRowset(const Reference< XRowSet>& _rxRowSet, const Reference< XMultiServiceFactory>& _rxFactory,
+ sal_Bool _bSetAsActiveConnection ) SAL_THROW ( ( SQLException, WrappedTargetException, RuntimeException ) )
+{
+ SharedConnection xConnection = lcl_connectRowSet( _rxRowSet, _rxFactory, _bSetAsActiveConnection, true );
+ return xConnection.getTyped();
+}
+
+//------------------------------------------------------------------------------
+SharedConnection ensureRowSetConnection(const Reference< XRowSet>& _rxRowSet, const Reference< XMultiServiceFactory>& _rxFactory,
+ bool _bUseAutoConnectionDisposer ) SAL_THROW ( ( SQLException, WrappedTargetException, RuntimeException ) )
+{
+ return lcl_connectRowSet( _rxRowSet, _rxFactory, true, _bUseAutoConnectionDisposer );
+}
+
+//------------------------------------------------------------------------------
+Reference< XNameAccess> getTableFields(const Reference< XConnection>& _rxConn,const ::rtl::OUString& _rName)
+{
+ Reference< XComponent > xDummy;
+ return getFieldsByCommandDescriptor( _rxConn, CommandType::TABLE, _rName, xDummy );
+}
+//------------------------------------------------------------------------------
+Reference< XNameAccess> getPrimaryKeyColumns_throw(const Any& i_aTable)
+{
+ const Reference< XPropertySet > xTable(i_aTable,UNO_QUERY_THROW);
+ return getPrimaryKeyColumns_throw(xTable);
+}
+//------------------------------------------------------------------------------
+Reference< XNameAccess> getPrimaryKeyColumns_throw(const Reference< XPropertySet >& i_xTable)
+{
+ Reference<XNameAccess> xKeyColumns;
+ const Reference<XKeysSupplier> xKeySup(i_xTable,UNO_QUERY);
+ if ( xKeySup.is() )
+ {
+ const Reference<XIndexAccess> xKeys = xKeySup->getKeys();
+ if ( xKeys.is() )
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ const ::rtl::OUString sPropName = rPropMap.getNameByIndex(PROPERTY_ID_TYPE);
+ Reference<XPropertySet> xProp;
+ const sal_Int32 nCount = xKeys->getCount();
+ for(sal_Int32 i = 0;i< nCount;++i)
+ {
+ xProp.set(xKeys->getByIndex(i),UNO_QUERY_THROW);
+ if ( xProp.is() )
+ {
+ sal_Int32 nKeyType = 0;
+ xProp->getPropertyValue(sPropName) >>= nKeyType;
+ if(KeyType::PRIMARY == nKeyType)
+ {
+ const Reference<XColumnsSupplier> xKeyColsSup(xProp,UNO_QUERY_THROW);
+ xKeyColumns = xKeyColsSup->getColumns();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return xKeyColumns;
+}
+
+//------------------------------------------------------------------------------
+namespace
+{
+ enum FieldLookupState
+ {
+ HANDLE_TABLE, HANDLE_QUERY, HANDLE_SQL, RETRIEVE_OBJECT, RETRIEVE_COLUMNS, DONE, FAILED
+ };
+}
+
+//------------------------------------------------------------------------------
+Reference< XNameAccess > getFieldsByCommandDescriptor( const Reference< XConnection >& _rxConnection,
+ const sal_Int32 _nCommandType, const ::rtl::OUString& _rCommand,
+ Reference< XComponent >& _rxKeepFieldsAlive, SQLExceptionInfo* _pErrorInfo ) SAL_THROW( ( ) )
+{
+ OSL_PRECOND( _rxConnection.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection!" );
+ OSL_PRECOND( ( CommandType::TABLE == _nCommandType ) || ( CommandType::QUERY == _nCommandType ) || ( CommandType::COMMAND == _nCommandType ),
+ "::dbtools::getFieldsByCommandDescriptor: invalid command type!" );
+ OSL_PRECOND( _rCommand.getLength(), "::dbtools::getFieldsByCommandDescriptor: invalid command (empty)!" );
+
+ Reference< XNameAccess > xFields;
+
+ // reset the error
+ if ( _pErrorInfo )
+ *_pErrorInfo = SQLExceptionInfo();
+ // reset the ownership holder
+ _rxKeepFieldsAlive.clear();
+
+ // go for the fields
+ try
+ {
+ // some kind of state machine to ease the sharing of code
+ FieldLookupState eState = FAILED;
+ switch ( _nCommandType )
+ {
+ case CommandType::TABLE:
+ eState = HANDLE_TABLE;
+ break;
+ case CommandType::QUERY:
+ eState = HANDLE_QUERY;
+ break;
+ case CommandType::COMMAND:
+ eState = HANDLE_SQL;
+ break;
+ }
+
+ // needed in various states:
+ Reference< XNameAccess > xObjectCollection;
+ Reference< XColumnsSupplier > xSupplyColumns;
+
+ // go!
+ while ( ( DONE != eState ) && ( FAILED != eState ) )
+ {
+ switch ( eState )
+ {
+ case HANDLE_TABLE:
+ {
+ // initial state for handling the tables
+
+ // get the table objects
+ Reference< XTablesSupplier > xSupplyTables( _rxConnection, UNO_QUERY );
+ if ( xSupplyTables.is() )
+ xObjectCollection = xSupplyTables->getTables();
+ // if something went wrong 'til here, then this will be handled in the next state
+
+ // next state: get the object
+ eState = RETRIEVE_OBJECT;
+ }
+ break;
+
+ case HANDLE_QUERY:
+ {
+ // initial state for handling the tables
+
+ // get the table objects
+ Reference< XQueriesSupplier > xSupplyQueries( _rxConnection, UNO_QUERY );
+ if ( xSupplyQueries.is() )
+ xObjectCollection = xSupplyQueries->getQueries();
+ // if something went wrong 'til here, then this will be handled in the next state
+
+ // next state: get the object
+ eState = RETRIEVE_OBJECT;
+ }
+ break;
+
+ case RETRIEVE_OBJECT:
+ // here we should have an object (aka query or table) collection, and are going
+ // to retrieve the desired object
+
+ // next state: default to FAILED
+ eState = FAILED;
+
+ OSL_ENSURE( xObjectCollection.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection (no sdb.Connection, or no Tables-/QueriesSupplier)!");
+ if ( xObjectCollection.is() )
+ {
+ if ( xObjectCollection.is() && xObjectCollection->hasByName( _rCommand ) )
+ {
+ xObjectCollection->getByName( _rCommand ) >>= xSupplyColumns;
+ // (xSupplyColumns being NULL will be handled in the next state)
+
+ // next: go for the columns
+ eState = RETRIEVE_COLUMNS;
+ }
+ }
+ break;
+
+ case RETRIEVE_COLUMNS:
+ OSL_ENSURE( xSupplyColumns.is(), "::dbtools::getFieldsByCommandDescriptor: could not retrieve the columns supplier!" );
+
+ // next state: default to FAILED
+ eState = FAILED;
+
+ if ( xSupplyColumns.is() )
+ {
+ xFields = xSupplyColumns->getColumns();
+ // that's it
+ eState = DONE;
+ }
+ break;
+
+ case HANDLE_SQL:
+ {
+ ::rtl::OUString sStatementToExecute( _rCommand );
+
+ // well, the main problem here is to handle statements which contain a parameter
+ // If we would simply execute a parametrized statement, then this will fail because
+ // we cannot supply any parameter values.
+ // Thus, we try to analyze the statement, and to append a WHERE 0=1 filter criterion
+ // This should cause every driver to not really execute the statement, but to return
+ // an empty result set with the proper structure. We then can use this result set
+ // to retrieve the columns.
+
+ try
+ {
+ Reference< XMultiServiceFactory > xComposerFac( _rxConnection, UNO_QUERY );
+
+ if ( xComposerFac.is() )
+ {
+ Reference< XSingleSelectQueryComposer > xComposer(xComposerFac->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.SingleSelectQueryComposer"))),UNO_QUERY);
+ if ( xComposer.is() )
+ {
+ xComposer->setQuery( sStatementToExecute );
+
+ // Now set the filter to a dummy restriction which will result in an empty
+ // result set.
+ xComposer->setFilter( ::rtl::OUString::createFromAscii( "0=1" ) );
+ sStatementToExecute = xComposer->getQuery( );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ // silent this error, this was just a try. If we're here, we did not change sStatementToExecute,
+ // so it will still be _rCommand, which then will be executed without being touched
+ }
+
+ // now execute
+ Reference< XPreparedStatement > xStatement = _rxConnection->prepareStatement( sStatementToExecute );
+ // transfer ownership of this temporary object to the caller
+ _rxKeepFieldsAlive = _rxKeepFieldsAlive.query( xStatement );
+
+ // set the "MaxRows" to 0. This is just in case our attempt to append a 0=1 filter
+ // failed - in this case, the MaxRows restriction should at least ensure that there
+ // is no data returned (which would be potentially expensive)
+ Reference< XPropertySet > xStatementProps( xStatement,UNO_QUERY );
+ try
+ {
+ if ( xStatementProps.is() )
+ xStatementProps->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxRows" ) ),
+ makeAny( sal_Int32( 0 ) )
+ );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "::dbtools::getFieldsByCommandDescriptor: could not set the MaxRows!" );
+ // oh damn. Not much of a chance to recover, we will no retrieve the complete
+ // full blown result set
+ }
+
+ xSupplyColumns = xSupplyColumns.query( xStatement->executeQuery() );
+ // this should have given us a result set which does not contain any data, but
+ // the structural information we need
+
+ // so the next state is to get the columns
+ eState = RETRIEVE_COLUMNS;
+ }
+ break;
+
+ default:
+ OSL_ENSURE( sal_False, "::dbtools::getFieldsByCommandDescriptor: oops! unhandled state here!" );
+ eState = FAILED;
+ }
+ }
+ }
+ catch( const SQLContext& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); }
+ catch( const SQLWarning& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); }
+ catch( const SQLException& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "::dbtools::getFieldsByCommandDescriptor: caught an exception while retrieving the fields!" );
+ }
+
+ return xFields;
+}
+
+//------------------------------------------------------------------------------
+Sequence< ::rtl::OUString > getFieldNamesByCommandDescriptor( const Reference< XConnection >& _rxConnection,
+ const sal_Int32 _nCommandType, const ::rtl::OUString& _rCommand,
+ SQLExceptionInfo* _pErrorInfo ) SAL_THROW( ( ) )
+{
+ // get the container for the fields
+ Reference< XComponent > xKeepFieldsAlive;
+ Reference< XNameAccess > xFieldContainer = getFieldsByCommandDescriptor( _rxConnection, _nCommandType, _rCommand, xKeepFieldsAlive, _pErrorInfo );
+
+ // get the names of the fields
+ Sequence< ::rtl::OUString > aNames;
+ if ( xFieldContainer.is() )
+ aNames = xFieldContainer->getElementNames();
+
+ // clean up any temporary objects which have been created
+ disposeComponent( xKeepFieldsAlive );
+
+ // outta here
+ return aNames;
+}
+
+//------------------------------------------------------------------------------
+SQLContext prependContextInfo(const SQLException& _rException, const Reference< XInterface >& _rxContext, const ::rtl::OUString& _rContextDescription, const ::rtl::OUString& _rContextDetails)
+{
+ return SQLContext( _rContextDescription, _rxContext, ::rtl::OUString(), 0, makeAny( _rException ), _rContextDetails );
+}
+//------------------------------------------------------------------------------
+SQLException prependErrorInfo( const SQLException& _rChainedException, const Reference< XInterface >& _rxContext,
+ const ::rtl::OUString& _rAdditionalError, const StandardSQLState _eSQLState, const sal_Int32 _nErrorCode )
+{
+ return SQLException( _rAdditionalError, _rxContext,
+ _eSQLState == SQL_ERROR_UNSPECIFIED ? ::rtl::OUString() : getStandardSQLState( _eSQLState ),
+ _nErrorCode, makeAny( _rChainedException ) );
+}
+
+//--------------------------------------------------------------------------
+namespace
+{
+ struct NameComponentSupport
+ {
+ const bool bCatalogs;
+ const bool bSchemas;
+
+ NameComponentSupport( )
+ :bCatalogs( true )
+ ,bSchemas( true )
+ {
+ }
+
+ NameComponentSupport( const bool _bCatalogs, const bool _bSchemas )
+ :bCatalogs( _bCatalogs )
+ ,bSchemas( _bSchemas )
+ {
+ }
+ };
+
+ NameComponentSupport lcl_getNameComponentSupport( const Reference< XDatabaseMetaData >& _rxMetaData, EComposeRule _eComposeRule )
+ {
+ OSL_PRECOND( _rxMetaData.is(), "lcl_getNameComponentSupport: invalid meta data!" );
+
+ FMetaDataSupport pCatalogCall = &XDatabaseMetaData::supportsCatalogsInDataManipulation;
+ FMetaDataSupport pSchemaCall = &XDatabaseMetaData::supportsSchemasInDataManipulation;
+ bool bIgnoreMetaData = false;
+
+ switch ( _eComposeRule )
+ {
+ case eInTableDefinitions:
+ pCatalogCall = &XDatabaseMetaData::supportsCatalogsInTableDefinitions;
+ pSchemaCall = &XDatabaseMetaData::supportsSchemasInTableDefinitions;
+ break;
+ case eInIndexDefinitions:
+ pCatalogCall = &XDatabaseMetaData::supportsCatalogsInIndexDefinitions;
+ pSchemaCall = &XDatabaseMetaData::supportsSchemasInIndexDefinitions;
+ break;
+ case eInProcedureCalls:
+ pCatalogCall = &XDatabaseMetaData::supportsCatalogsInProcedureCalls;
+ pSchemaCall = &XDatabaseMetaData::supportsSchemasInProcedureCalls;
+ break;
+ case eInPrivilegeDefinitions:
+ pCatalogCall = &XDatabaseMetaData::supportsCatalogsInPrivilegeDefinitions;
+ pSchemaCall = &XDatabaseMetaData::supportsSchemasInPrivilegeDefinitions;
+ break;
+ case eComplete:
+ bIgnoreMetaData = true;
+ break;
+ case eInDataManipulation:
+ // already properly set above
+ break;
+ }
+ return NameComponentSupport(
+ bIgnoreMetaData ? true : (_rxMetaData.get()->*pCatalogCall)(),
+ bIgnoreMetaData ? true : (_rxMetaData.get()->*pSchemaCall)()
+ );
+ }
+}
+
+//--------------------------------------------------------------------------
+static ::rtl::OUString impl_doComposeTableName( const Reference< XDatabaseMetaData >& _rxMetaData,
+ const ::rtl::OUString& _rCatalog, const ::rtl::OUString& _rSchema, const ::rtl::OUString& _rName,
+ sal_Bool _bQuote, EComposeRule _eComposeRule )
+{
+ OSL_ENSURE(_rxMetaData.is(), "impl_doComposeTableName : invalid meta data !");
+ if ( !_rxMetaData.is() )
+ return ::rtl::OUString();
+ OSL_ENSURE(_rName.getLength(), "impl_doComposeTableName : at least the name should be non-empty !");
+
+ const ::rtl::OUString sQuoteString = _rxMetaData->getIdentifierQuoteString();
+ const NameComponentSupport aNameComps( lcl_getNameComponentSupport( _rxMetaData, _eComposeRule ) );
+
+ ::rtl::OUStringBuffer aComposedName;
+
+ ::rtl::OUString sCatalogSep;
+ sal_Bool bCatlogAtStart = sal_True;
+ if ( _rCatalog.getLength() && aNameComps.bCatalogs )
+ {
+ sCatalogSep = _rxMetaData->getCatalogSeparator();
+ bCatlogAtStart = _rxMetaData->isCatalogAtStart();
+
+ if ( bCatlogAtStart && sCatalogSep.getLength())
+ {
+ aComposedName.append( _bQuote ? quoteName( sQuoteString, _rCatalog ) : _rCatalog );
+ aComposedName.append( sCatalogSep );
+ }
+ }
+
+ if ( _rSchema.getLength() && aNameComps.bSchemas )
+ {
+ aComposedName.append( _bQuote ? quoteName( sQuoteString, _rSchema ) : _rSchema );
+ aComposedName.appendAscii( "." );
+ }
+
+ aComposedName.append( _bQuote ? quoteName( sQuoteString, _rName ) : _rName );
+
+ if ( _rCatalog.getLength()
+ && !bCatlogAtStart
+ && sCatalogSep.getLength()
+ && aNameComps.bCatalogs
+ )
+ {
+ aComposedName.append( sCatalogSep );
+ aComposedName.append( _bQuote ? quoteName( sQuoteString, _rCatalog ) : _rCatalog );
+ }
+
+ return aComposedName.makeStringAndClear();
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString quoteTableName(const Reference< XDatabaseMetaData>& _rxMeta
+ , const ::rtl::OUString& _rName
+ , EComposeRule _eComposeRule)
+{
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ qualifiedNameComponents(_rxMeta,_rName,sCatalog,sSchema,sTable,_eComposeRule);
+ return impl_doComposeTableName( _rxMeta, sCatalog, sSchema, sTable, sal_True, _eComposeRule );
+}
+
+//------------------------------------------------------------------------------
+void qualifiedNameComponents(const Reference< XDatabaseMetaData >& _rxConnMetaData, const ::rtl::OUString& _rQualifiedName, ::rtl::OUString& _rCatalog, ::rtl::OUString& _rSchema, ::rtl::OUString& _rName,EComposeRule _eComposeRule)
+{
+ OSL_ENSURE(_rxConnMetaData.is(), "QualifiedNameComponents : invalid meta data!");
+
+ NameComponentSupport aNameComps( lcl_getNameComponentSupport( _rxConnMetaData, _eComposeRule ) );
+
+ ::rtl::OUString sSeparator = _rxConnMetaData->getCatalogSeparator();
+
+ ::rtl::OUString sName(_rQualifiedName);
+ // do we have catalogs ?
+ if ( aNameComps.bCatalogs )
+ {
+ if (_rxConnMetaData->isCatalogAtStart())
+ {
+ // search for the catalog name at the beginning
+ sal_Int32 nIndex = sName.indexOf(sSeparator);
+ if (-1 != nIndex)
+ {
+ _rCatalog = sName.copy(0, nIndex);
+ sName = sName.copy(nIndex + 1);
+ }
+ }
+ else
+ {
+ // Katalogname am Ende
+ sal_Int32 nIndex = sName.lastIndexOf(sSeparator);
+ if (-1 != nIndex)
+ {
+ _rCatalog = sName.copy(nIndex + 1);
+ sName = sName.copy(0, nIndex);
+ }
+ }
+ }
+
+ if ( aNameComps.bSchemas )
+ {
+ sal_Int32 nIndex = sName.indexOf((sal_Unicode)'.');
+ // OSL_ENSURE(-1 != nIndex, "QualifiedNameComponents : no schema separator!");
+ if ( nIndex != -1 )
+ _rSchema = sName.copy(0, nIndex);
+ sName = sName.copy(nIndex + 1);
+ }
+
+ _rName = sName;
+}
+
+//------------------------------------------------------------------------------
+Reference< XNumberFormatsSupplier> getNumberFormats(
+ const Reference< XConnection>& _rxConn,
+ sal_Bool _bAlloweDefault,
+ const Reference< XMultiServiceFactory>& _rxFactory)
+{
+ // ask the parent of the connection (should be an DatabaseAccess)
+ Reference< XNumberFormatsSupplier> xReturn;
+ Reference< XChild> xConnAsChild(_rxConn, UNO_QUERY);
+ ::rtl::OUString sPropFormatsSupplier = ::rtl::OUString::createFromAscii("NumberFormatsSupplier");
+ if (xConnAsChild.is())
+ {
+ Reference< XPropertySet> xConnParentProps(xConnAsChild->getParent(), UNO_QUERY);
+ if (xConnParentProps.is() && hasProperty(sPropFormatsSupplier, xConnParentProps))
+ xConnParentProps->getPropertyValue(sPropFormatsSupplier) >>= xReturn;
+ }
+ else if(_bAlloweDefault && _rxFactory.is())
+ {
+ xReturn = Reference< XNumberFormatsSupplier>(_rxFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier")),UNO_QUERY);
+ }
+ return xReturn;
+}
+
+//==============================================================================
+//------------------------------------------------------------------------------
+void TransferFormComponentProperties(
+ const Reference< XPropertySet>& xOldProps,
+ const Reference< XPropertySet>& xNewProps,
+ const Locale& _rLocale)
+{
+try
+{
+ OSL_ENSURE( xOldProps.is() && xNewProps.is(), "TransferFormComponentProperties: invalid source/dest!" );
+ if ( !xOldProps.is() || !xNewProps.is() )
+ return;
+
+ // kopieren wir erst mal alle Props, die in Quelle und Ziel vorhanden sind und identische Beschreibungen haben
+ Reference< XPropertySetInfo> xOldInfo( xOldProps->getPropertySetInfo());
+ Reference< XPropertySetInfo> xNewInfo( xNewProps->getPropertySetInfo());
+
+ Sequence< Property> aOldProperties = xOldInfo->getProperties();
+ Sequence< Property> aNewProperties = xNewInfo->getProperties();
+ int nNewLen = aNewProperties.getLength();
+
+ Property* pOldProps = aOldProperties.getArray();
+ Property* pNewProps = aNewProperties.getArray();
+
+ ::rtl::OUString sPropDefaultControl(::rtl::OUString::createFromAscii("DefaultControl"));
+ ::rtl::OUString sPropLabelControl(::rtl::OUString::createFromAscii("LabelControl"));
+ ::rtl::OUString sPropFormatsSupplier(::rtl::OUString::createFromAscii("FormatsSupplier"));
+ ::rtl::OUString sPropCurrencySymbol(::rtl::OUString::createFromAscii("CurrencySymbol"));
+ ::rtl::OUString sPropDecimals(::rtl::OUString::createFromAscii("Decimals"));
+ ::rtl::OUString sPropEffectiveMin(::rtl::OUString::createFromAscii("EffectiveMin"));
+ ::rtl::OUString sPropEffectiveMax(::rtl::OUString::createFromAscii("EffectiveMax"));
+ ::rtl::OUString sPropEffectiveDefault(::rtl::OUString::createFromAscii("EffectiveDefault"));
+ ::rtl::OUString sPropDefaultText(::rtl::OUString::createFromAscii("DefaultText"));
+ ::rtl::OUString sPropDefaultDate(::rtl::OUString::createFromAscii("DefaultDate"));
+ ::rtl::OUString sPropDefaultTime(::rtl::OUString::createFromAscii("DefaultTime"));
+ ::rtl::OUString sPropValueMin(::rtl::OUString::createFromAscii("ValueMin"));
+ ::rtl::OUString sPropValueMax(::rtl::OUString::createFromAscii("ValueMax"));
+ ::rtl::OUString sPropDecimalAccuracy(::rtl::OUString::createFromAscii("DecimalAccuracy"));
+ ::rtl::OUString sPropClassId(::rtl::OUString::createFromAscii("ClassId"));
+ ::rtl::OUString sFormattedServiceName( ::rtl::OUString::createFromAscii( "com.sun.star.form.component.FormattedField" ) );
+
+ for (sal_Int16 i=0; i<aOldProperties.getLength(); ++i)
+ {
+ if ( (!pOldProps[i].Name.equals(sPropDefaultControl))
+ && (!pOldProps[i].Name.equals(sPropLabelControl))
+ )
+ {
+ // binaere Suche
+ Property* pResult = ::std::lower_bound(pNewProps, pNewProps + nNewLen,pOldProps[i].Name, ::comphelper::PropertyStringLessFunctor());
+ if ( pResult
+ && ( pResult != pNewProps + nNewLen && pResult->Name == pOldProps[i].Name )
+ && ( (pResult->Attributes & PropertyAttribute::READONLY) == 0 )
+ && ( pResult->Type.equals(pOldProps[i].Type)) )
+ { // Attribute stimmen ueberein und Property ist nicht read-only
+ try
+ {
+ xNewProps->setPropertyValue(pResult->Name, xOldProps->getPropertyValue(pResult->Name));
+ }
+ catch(IllegalArgumentException& e)
+ {
+ OSL_UNUSED( e );
+#ifdef DBG_UTIL
+ ::rtl::OUString sMessage = ::rtl::OUString::createFromAscii("TransferFormComponentProperties : could not transfer the value for property \"");
+ sMessage += pResult->Name;
+ sMessage += ::rtl::OUString::createFromAscii("\"");;
+ OSL_ENSURE(sal_False, ::rtl::OUStringToOString(sMessage, RTL_TEXTENCODING_ASCII_US));
+#endif
+ }
+ }
+ }
+ }
+
+
+ // fuer formatierte Felder (entweder alt oder neu) haben wir ein paar Sonderbehandlungen
+ Reference< XServiceInfo > xSI( xOldProps, UNO_QUERY );
+ sal_Bool bOldIsFormatted = xSI.is() && xSI->supportsService( sFormattedServiceName );
+ xSI = Reference< XServiceInfo >( xNewProps, UNO_QUERY );
+ sal_Bool bNewIsFormatted = xSI.is() && xSI->supportsService( sFormattedServiceName );
+
+ if (!bOldIsFormatted && !bNewIsFormatted)
+ return; // nothing to do
+
+ if (bOldIsFormatted && bNewIsFormatted)
+ // nein, wenn beide formatierte Felder sind, dann machen wir keinerlei Konvertierungen
+ // Das geht zu weit ;)
+ return;
+
+ if (bOldIsFormatted)
+ {
+ // aus dem eingestellten Format ein paar Properties rausziehen und zum neuen Set durchschleifen
+ Any aFormatKey( xOldProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) );
+ if (aFormatKey.hasValue())
+ {
+ Reference< XNumberFormatsSupplier> xSupplier;
+ xOldProps->getPropertyValue(sPropFormatsSupplier) >>= xSupplier;
+ if (xSupplier.is())
+ {
+ Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
+ Reference< XPropertySet> xFormat(xFormats->getByKey(getINT32(aFormatKey)));
+ if (hasProperty(sPropCurrencySymbol, xFormat))
+ {
+ Any aVal( xFormat->getPropertyValue(sPropCurrencySymbol) );
+ if (aVal.hasValue() && hasProperty(sPropCurrencySymbol, xNewProps))
+ // (wenn die Quelle das nicht gesetzt hat, dann auch nicht kopieren, um den
+ // Default-Wert nicht zu ueberschreiben
+ xNewProps->setPropertyValue(sPropCurrencySymbol, aVal);
+ }
+ if (hasProperty(sPropDecimals, xFormat) && hasProperty(sPropDecimals, xNewProps))
+ xNewProps->setPropertyValue(sPropDecimals, xFormat->getPropertyValue(sPropDecimals));
+ }
+ }
+
+ // eine eventuelle-Min-Max-Konvertierung
+ Any aEffectiveMin( xOldProps->getPropertyValue(sPropEffectiveMin) );
+ if (aEffectiveMin.hasValue())
+ { // im Gegensatz zu ValueMin kann EffectiveMin void sein
+ if (hasProperty(sPropValueMin, xNewProps))
+ {
+ OSL_ENSURE(aEffectiveMin.getValueType().getTypeClass() == TypeClass_DOUBLE,
+ "TransferFormComponentProperties : invalid property type !");
+ xNewProps->setPropertyValue(sPropValueMin, aEffectiveMin);
+ }
+ }
+ Any aEffectiveMax( xOldProps->getPropertyValue(sPropEffectiveMax) );
+ if (aEffectiveMax.hasValue())
+ { // analog
+ if (hasProperty(sPropValueMax, xNewProps))
+ {
+ OSL_ENSURE(aEffectiveMax.getValueType().getTypeClass() == TypeClass_DOUBLE,
+ "TransferFormComponentProperties : invalid property type !");
+ xNewProps->setPropertyValue(sPropValueMax, aEffectiveMax);
+ }
+ }
+
+ // dann koennen wir noch Default-Werte konvertieren und uebernehmen
+ Any aEffectiveDefault( xOldProps->getPropertyValue(sPropEffectiveDefault) );
+ if (aEffectiveDefault.hasValue())
+ {
+ sal_Bool bIsString = aEffectiveDefault.getValueType().getTypeClass() == TypeClass_STRING;
+ OSL_ENSURE(bIsString || aEffectiveDefault.getValueType().getTypeClass() == TypeClass_DOUBLE,
+ "TransferFormComponentProperties : invalid property type !");
+ // die Effective-Properties sollten immer void oder string oder double sein ....
+
+ if (hasProperty(sPropDefaultDate, xNewProps) && !bIsString)
+ { // (einen ::rtl::OUString in ein Datum zu konvertieren muss nicht immer klappen, denn das ganze kann ja an
+ // eine Textspalte gebunden gewesen sein, aber mit einem double koennen wir was anfangen)
+ Date aDate = DBTypeConversion::toDate(getDouble(aEffectiveDefault));
+ xNewProps->setPropertyValue(sPropDefaultDate, makeAny(aDate));
+ }
+
+ if (hasProperty(sPropDefaultTime, xNewProps) && !bIsString)
+ { // voellig analog mit Zeit
+ Time aTime = DBTypeConversion::toTime(getDouble(aEffectiveDefault));
+ xNewProps->setPropertyValue(sPropDefaultTime, makeAny(aTime));
+ }
+
+ if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), xNewProps) && !bIsString)
+ { // hier koennen wir einfach das double durchreichen
+ xNewProps->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), aEffectiveDefault);
+ }
+
+ if (hasProperty(sPropDefaultText, xNewProps) && bIsString)
+ { // und hier den ::rtl::OUString
+ xNewProps->setPropertyValue(sPropDefaultText, aEffectiveDefault);
+ }
+
+ // nyi: die Uebersetzung zwischen doubles und ::rtl::OUString wuerde noch mehr Moeglichkeien eroeffnen
+ }
+ }
+
+ // die andere Richtung : das neu Control soll formatiert sein
+ if (bNewIsFormatted)
+ {
+ // zuerst die Formatierung
+ // einen Supplier koennen wir nicht setzen, also muss das neue Set schon einen mitbringen
+ Reference< XNumberFormatsSupplier> xSupplier;
+ xNewProps->getPropertyValue(sPropFormatsSupplier) >>= xSupplier;
+ if (xSupplier.is())
+ {
+ Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
+
+ // Dezimal-Stellen
+ sal_Int16 nDecimals = 2;
+ if (hasProperty(sPropDecimalAccuracy, xOldProps))
+ xOldProps->getPropertyValue(sPropDecimalAccuracy) >>= nDecimals;
+
+ // Grund-Format (je nach ClassId des alten Sets)
+ sal_Int32 nBaseKey = 0;
+ if (hasProperty(sPropClassId, xOldProps))
+ {
+ Reference< XNumberFormatTypes> xTypeList(xFormats, UNO_QUERY);
+ if (xTypeList.is())
+ {
+ sal_Int16 nClassId = 0;
+ xOldProps->getPropertyValue(sPropClassId) >>= nClassId;
+ switch (nClassId)
+ {
+ case FormComponentType::DATEFIELD :
+ nBaseKey = xTypeList->getStandardFormat(NumberFormat::DATE, _rLocale);
+ break;
+
+ case FormComponentType::TIMEFIELD :
+ nBaseKey = xTypeList->getStandardFormat(NumberFormat::TIME, _rLocale);
+ break;
+
+ case FormComponentType::CURRENCYFIELD :
+ nBaseKey = xTypeList->getStandardFormat(NumberFormat::CURRENCY, _rLocale);
+ break;
+ }
+ }
+ }
+
+ // damit koennen wir ein neues Format basteln ...
+ ::rtl::OUString sNewFormat = xFormats->generateFormat(nBaseKey, _rLocale, sal_False, sal_False, nDecimals, 0);
+ // kein Tausender-Trennzeichen, negative Zahlen nicht in Rot, keine fuehrenden Nullen
+
+ // ... und zum FormatsSupplier hinzufuegen (wenn noetig)
+ sal_Int32 nKey = xFormats->queryKey(sNewFormat, _rLocale, sal_False);
+ if (nKey == (sal_Int32)-1)
+ { // noch nicht vorhanden in meinem Formatter ...
+ nKey = xFormats->addNew(sNewFormat, _rLocale);
+ }
+
+ xNewProps->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY), makeAny((sal_Int32)nKey));
+ }
+
+ // min-/max-Werte
+ Any aNewMin, aNewMax;
+ if (hasProperty(sPropValueMin, xOldProps))
+ aNewMin = xOldProps->getPropertyValue(sPropValueMin);
+ if (hasProperty(sPropValueMax, xOldProps))
+ aNewMax = xOldProps->getPropertyValue(sPropValueMax);
+ xNewProps->setPropertyValue(sPropEffectiveMin, aNewMin);
+ xNewProps->setPropertyValue(sPropEffectiveMax, aNewMax);
+
+ // Default-Wert
+ Any aNewDefault;
+ if (hasProperty(sPropDefaultDate, xOldProps))
+ {
+ Any aDate( xOldProps->getPropertyValue(sPropDefaultDate) );
+ if (aDate.hasValue())
+ aNewDefault <<= DBTypeConversion::toDouble(*(Date*)aDate.getValue());
+ }
+
+ if (hasProperty(sPropDefaultTime, xOldProps))
+ {
+ Any aTime( xOldProps->getPropertyValue(sPropDefaultTime) );
+ if (aTime.hasValue())
+ aNewDefault <<= DBTypeConversion::toDouble(*(Time*)aTime.getValue());
+ }
+
+ // double oder ::rtl::OUString werden direkt uebernommen
+ if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), xOldProps))
+ aNewDefault = xOldProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE));
+ if (hasProperty(sPropDefaultText, xOldProps))
+ aNewDefault = xOldProps->getPropertyValue(sPropDefaultText);
+
+ if (aNewDefault.hasValue())
+ xNewProps->setPropertyValue(sPropEffectiveDefault, aNewDefault);
+ }
+}
+catch(const Exception&)
+{
+ OSL_ENSURE( sal_False, "TransferFormComponentProperties: caught an exception!" );
+}
+}
+
+//------------------------------------------------------------------------------
+sal_Bool canInsert(const Reference< XPropertySet>& _rxCursorSet)
+{
+ return ((_rxCursorSet.is() && (getINT32(_rxCursorSet->getPropertyValue(::rtl::OUString::createFromAscii("Privileges"))) & Privilege::INSERT) != 0));
+}
+
+//------------------------------------------------------------------------------
+sal_Bool canUpdate(const Reference< XPropertySet>& _rxCursorSet)
+{
+ return ((_rxCursorSet.is() && (getINT32(_rxCursorSet->getPropertyValue(::rtl::OUString::createFromAscii("Privileges"))) & Privilege::UPDATE) != 0));
+}
+
+//------------------------------------------------------------------------------
+sal_Bool canDelete(const Reference< XPropertySet>& _rxCursorSet)
+{
+ return ((_rxCursorSet.is() && (getINT32(_rxCursorSet->getPropertyValue(::rtl::OUString::createFromAscii("Privileges"))) & Privilege::DELETE) != 0));
+}
+// -----------------------------------------------------------------------------
+Reference< XDataSource> findDataSource(const Reference< XInterface >& _xParent)
+{
+ Reference< XOfficeDatabaseDocument> xDatabaseDocument(_xParent, UNO_QUERY);
+ Reference< XDataSource> xDataSource;
+ if ( xDatabaseDocument.is() )
+ xDataSource = xDatabaseDocument->getDataSource();
+ if ( !xDataSource.is() )
+ xDataSource.set(_xParent, UNO_QUERY);
+ if (!xDataSource.is())
+ {
+ Reference< XChild> xChild(_xParent, UNO_QUERY);
+ if ( xChild.is() )
+ xDataSource = findDataSource(xChild->getParent());
+ }
+ return xDataSource;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString getComposedRowSetStatement( const Reference< XPropertySet >& _rxRowSet, const Reference< XMultiServiceFactory>& _rxFactory,
+ sal_Bool _bUseRowSetFilter, sal_Bool _bUseRowSetOrder, Reference< XSingleSelectQueryComposer >* _pxComposer )
+ SAL_THROW( ( SQLException ) )
+{
+ ::rtl::OUString sStatement;
+ try
+ {
+ Reference< XConnection> xConn = connectRowset( Reference< XRowSet >( _rxRowSet, UNO_QUERY ), _rxFactory, sal_True );
+ if ( xConn.is() ) // implies _rxRowSet.is()
+ {
+ // build the statement the row set is based on (can't use the ActiveCommand property of the set
+ // as this reflects the status after the last execute, not the currently set properties)
+
+ sal_Int32 nCommandType = CommandType::COMMAND;
+ ::rtl::OUString sCommand;
+ sal_Bool bEscapeProcessing = sal_False;
+
+ OSL_VERIFY( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "CommandType" ) ) >>= nCommandType );
+ OSL_VERIFY( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "Command" ) ) >>= sCommand );
+ OSL_VERIFY( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "EscapeProcessing" ) ) >>= bEscapeProcessing );
+
+ StatementComposer aComposer( xConn, sCommand, nCommandType, bEscapeProcessing );
+ // append sort
+ if ( _bUseRowSetOrder )
+ aComposer.setOrder( getString( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "Order" ) ) ) );
+
+ // append filter
+ if ( _bUseRowSetFilter )
+ {
+ sal_Bool bApplyFilter = sal_True;
+ _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "ApplyFilter" ) ) >>= bApplyFilter;
+ if ( bApplyFilter )
+ aComposer.setFilter( getString( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "Filter" ) ) ) );
+ }
+
+ sStatement = aComposer.getQuery();
+
+ if ( _pxComposer )
+ {
+ *_pxComposer = aComposer.getComposer();
+ aComposer.setDisposeComposer( false );
+ }
+ }
+ }
+ catch( const SQLException& )
+ {
+ throw;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return sStatement;
+}
+
+//------------------------------------------------------------------------------
+::rtl::OUString getComposedRowSetStatement(
+ const Reference< XPropertySet >& _rxRowSet, const Reference< XMultiServiceFactory>& _rxFactory,
+ sal_Bool _bUseRowSetFilter, sal_Bool _bUseRowSetOrder )
+{
+ return getComposedRowSetStatement( _rxRowSet, _rxFactory, _bUseRowSetFilter, _bUseRowSetOrder, NULL );
+}
+
+//------------------------------------------------------------------------------
+Reference< XSingleSelectQueryComposer > getCurrentSettingsComposer(
+ const Reference< XPropertySet>& _rxRowSetProps,
+ const Reference< XMultiServiceFactory>& _rxFactory)
+{
+ Reference< XSingleSelectQueryComposer > xReturn;
+ try
+ {
+ getComposedRowSetStatement( _rxRowSetProps, _rxFactory, sal_True, sal_True, &xReturn );
+ }
+ catch( const SQLException& )
+ {
+ throw;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "::getCurrentSettingsComposer : caught an exception !" );
+ }
+
+ return xReturn;
+}
+//--------------------------------------------------------------------------
+::rtl::OUString composeTableName( const Reference< XDatabaseMetaData >& _rxMetaData,
+ const ::rtl::OUString& _rCatalog,
+ const ::rtl::OUString& _rSchema,
+ const ::rtl::OUString& _rName,
+ sal_Bool _bQuote,
+ EComposeRule _eComposeRule)
+{
+ return impl_doComposeTableName( _rxMetaData, _rCatalog, _rSchema, _rName, _bQuote, _eComposeRule );
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString composeTableNameForSelect( const Reference< XConnection >& _rxConnection,
+ const ::rtl::OUString& _rCatalog, const ::rtl::OUString& _rSchema, const ::rtl::OUString& _rName )
+{
+ sal_Bool bUseCatalogInSelect = isDataSourcePropertyEnabled( _rxConnection, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCatalogInSelect" ) ), sal_True );
+ sal_Bool bUseSchemaInSelect = isDataSourcePropertyEnabled( _rxConnection, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseSchemaInSelect" ) ), sal_True );
+
+ return impl_doComposeTableName(
+ _rxConnection->getMetaData(),
+ bUseCatalogInSelect ? _rCatalog : ::rtl::OUString(),
+ bUseSchemaInSelect ? _rSchema : ::rtl::OUString(),
+ _rName,
+ true,
+ eInDataManipulation
+ );
+}
+
+// -----------------------------------------------------------------------------
+namespace
+{
+ static void lcl_getTableNameComponents( const Reference<XPropertySet>& _xTable,
+ ::rtl::OUString& _out_rCatalog, ::rtl::OUString& _out_rSchema, ::rtl::OUString& _out_rName )
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ Reference< XPropertySetInfo > xInfo = _xTable->getPropertySetInfo();
+ if ( xInfo.is()
+ && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) )
+ {
+
+ ::rtl::OUString aCatalog;
+ ::rtl::OUString aSchema;
+ ::rtl::OUString aTable;
+ if ( xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME))
+ && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) )
+ {
+ _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)) >>= _out_rCatalog;
+ _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= _out_rSchema;
+ }
+ _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= _out_rName;
+ }
+ else
+ OSL_ENSURE( false, "::dbtools::lcl_getTableNameComponents: this is no table object!" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString composeTableNameForSelect( const Reference< XConnection >& _rxConnection, const Reference<XPropertySet>& _xTable )
+{
+ ::rtl::OUString sCatalog, sSchema, sName;
+ lcl_getTableNameComponents( _xTable, sCatalog, sSchema, sName );
+
+ return composeTableNameForSelect( _rxConnection, sCatalog, sSchema, sName );
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString composeTableName(const Reference<XDatabaseMetaData>& _xMetaData,
+ const Reference<XPropertySet>& _xTable,
+ EComposeRule _eComposeRule,
+ bool _bSuppressCatalog,
+ bool _bSuppressSchema,
+ bool _bQuote )
+{
+ ::rtl::OUString sCatalog, sSchema, sName;
+ lcl_getTableNameComponents( _xTable, sCatalog, sSchema, sName );
+
+ return impl_doComposeTableName(
+ _xMetaData,
+ _bSuppressCatalog ? ::rtl::OUString() : sCatalog,
+ _bSuppressSchema ? ::rtl::OUString() : sSchema,
+ sName,
+ _bQuote,
+ _eComposeRule
+ );
+}
+// -----------------------------------------------------------------------------
+sal_Int32 getSearchColumnFlag( const Reference< XConnection>& _rxConn,sal_Int32 _nDataType)
+{
+ sal_Int32 nSearchFlag = 0;
+ Reference<XResultSet> xSet = _rxConn->getMetaData()->getTypeInfo();
+ if(xSet.is())
+ {
+ Reference<XRow> xRow(xSet,UNO_QUERY);
+ while(xSet->next())
+ {
+ if(xRow->getInt(2) == _nDataType)
+ {
+ nSearchFlag = xRow->getInt(9);
+ break;
+ }
+ }
+ }
+ return nSearchFlag;
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString createUniqueName( const Sequence< ::rtl::OUString >& _rNames, const ::rtl::OUString& _rBaseName, sal_Bool _bStartWithNumber )
+{
+ ::std::set< ::rtl::OUString > aUsedNames;
+ ::std::copy(
+ _rNames.getConstArray(),
+ _rNames.getConstArray() + _rNames.getLength(),
+ ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aUsedNames, aUsedNames.end() )
+ );
+
+ ::rtl::OUString sName( _rBaseName );
+ sal_Int32 nPos = 1;
+ if ( _bStartWithNumber )
+ sName += ::rtl::OUString::valueOf( nPos );
+
+ while ( aUsedNames.find( sName ) != aUsedNames.end() )
+ {
+ sName = _rBaseName;
+ sName += ::rtl::OUString::valueOf( ++nPos );
+ }
+ return sName;
+}
+
+// -----------------------------------------------------------------------------
+::rtl::OUString createUniqueName(const Reference<XNameAccess>& _rxContainer,const ::rtl::OUString& _rBaseName,sal_Bool _bStartWithNumber)
+{
+ Sequence< ::rtl::OUString > aElementNames;
+
+ OSL_ENSURE( _rxContainer.is(), "createUniqueName: invalid container!" );
+ if ( _rxContainer.is() )
+ aElementNames = _rxContainer->getElementNames();
+
+ return createUniqueName( aElementNames, _rBaseName, _bStartWithNumber );
+}
+
+// -----------------------------------------------------------------------------
+void showError(const SQLExceptionInfo& _rInfo,
+ const Reference< XWindow>& _xParent,
+ const Reference< XMultiServiceFactory >& _xFactory)
+{
+ if (_rInfo.isValid())
+ {
+ try
+ {
+ Sequence< Any > aArgs(2);
+ aArgs[0] <<= PropertyValue(::rtl::OUString::createFromAscii("SQLException"), 0, _rInfo.get(), PropertyState_DIRECT_VALUE);
+ aArgs[1] <<= PropertyValue(::rtl::OUString::createFromAscii("ParentWindow"), 0, makeAny(_xParent), PropertyState_DIRECT_VALUE);
+
+ static ::rtl::OUString s_sDialogServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.ErrorMessageDialog");
+ Reference< XExecutableDialog > xErrorDialog(
+ _xFactory->createInstanceWithArguments(s_sDialogServiceName, aArgs), UNO_QUERY);
+ if (xErrorDialog.is())
+ xErrorDialog->execute();
+ else
+ {
+ OSL_ENSURE(0,"dbtools::showError: no XExecutableDialog found!");
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_ENSURE(0,"showError: could not display the error message!");
+ }
+ }
+}
+
+// -------------------------------------------------------------------------
+sal_Bool implUpdateObject(const Reference< XRowUpdate >& _rxUpdatedObject,
+ const sal_Int32 _nColumnIndex, const Any& _rValue) SAL_THROW ( ( SQLException, RuntimeException ) )
+{
+ sal_Bool bSuccessfullyReRouted = sal_True;
+ switch (_rValue.getValueTypeClass())
+ {
+ case TypeClass_ANY:
+ {
+ Any aInnerValue;
+ _rValue >>= aInnerValue;
+ bSuccessfullyReRouted = implUpdateObject(_rxUpdatedObject, _nColumnIndex, aInnerValue);
+ }
+ break;
+
+ case TypeClass_VOID:
+ _rxUpdatedObject->updateNull(_nColumnIndex);
+ break;
+
+ case TypeClass_STRING:
+ _rxUpdatedObject->updateString(_nColumnIndex, *(rtl::OUString*)_rValue.getValue());
+ break;
+
+ case TypeClass_BOOLEAN:
+ _rxUpdatedObject->updateBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue());
+ break;
+
+ case TypeClass_BYTE:
+ _rxUpdatedObject->updateByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue());
+ break;
+
+ case TypeClass_UNSIGNED_SHORT:
+ case TypeClass_SHORT:
+ _rxUpdatedObject->updateShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue());
+ break;
+
+ case TypeClass_CHAR:
+ _rxUpdatedObject->updateString(_nColumnIndex,::rtl::OUString((sal_Unicode *)_rValue.getValue(),1));
+ break;
+
+ case TypeClass_UNSIGNED_LONG:
+ case TypeClass_LONG:
+ _rxUpdatedObject->updateInt(_nColumnIndex, *(sal_Int32*)_rValue.getValue());
+ break;
+
+ case TypeClass_HYPER:
+ {
+ sal_Int64 nValue = 0;
+ OSL_VERIFY( _rValue >>= nValue );
+ _rxUpdatedObject->updateLong( _nColumnIndex, nValue );
+ }
+ break;
+
+ case TypeClass_FLOAT:
+ _rxUpdatedObject->updateFloat(_nColumnIndex, *(float*)_rValue.getValue());
+ break;
+
+ case TypeClass_DOUBLE:
+ _rxUpdatedObject->updateDouble(_nColumnIndex, *(double*)_rValue.getValue());
+ break;
+
+ case TypeClass_SEQUENCE:
+ if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0))
+ _rxUpdatedObject->updateBytes(_nColumnIndex, *(Sequence<sal_Int8>*)_rValue.getValue());
+ else
+ bSuccessfullyReRouted = sal_False;
+ break;
+ case TypeClass_STRUCT:
+ if (_rValue.getValueType() == ::getCppuType((const DateTime*)0))
+ _rxUpdatedObject->updateTimestamp(_nColumnIndex, *(DateTime*)_rValue.getValue());
+ else if (_rValue.getValueType() == ::getCppuType((const Date*)0))
+ _rxUpdatedObject->updateDate(_nColumnIndex, *(Date*)_rValue.getValue());
+ else if (_rValue.getValueType() == ::getCppuType((const Time*)0))
+ _rxUpdatedObject->updateTime(_nColumnIndex, *(Time*)_rValue.getValue());
+ else
+ bSuccessfullyReRouted = sal_False;
+ break;
+
+ case TypeClass_INTERFACE:
+ if (_rValue.getValueType() == ::getCppuType(static_cast<Reference< XInputStream>*>(NULL)))
+ {
+ Reference< XInputStream > xStream;
+ _rValue >>= xStream;
+ _rxUpdatedObject->updateBinaryStream(_nColumnIndex, xStream, xStream->available());
+ break;
+ }
+ // run through
+ default:
+ bSuccessfullyReRouted = sal_False;
+ }
+
+ return bSuccessfullyReRouted;
+}
+// -------------------------------------------------------------------------
+sal_Bool implSetObject( const Reference< XParameters >& _rxParameters,
+ const sal_Int32 _nColumnIndex, const Any& _rValue) SAL_THROW ( ( SQLException, RuntimeException ) )
+{
+ sal_Bool bSuccessfullyReRouted = sal_True;
+ switch (_rValue.getValueTypeClass())
+ {
+ case TypeClass_HYPER:
+ {
+ sal_Int64 nValue = 0;
+ OSL_VERIFY( _rValue >>= nValue );
+ _rxParameters->setLong( _nColumnIndex, nValue );
+ }
+ break;
+
+ case TypeClass_ANY:
+ {
+ Any aInnerValue;
+ _rValue >>= aInnerValue;
+ bSuccessfullyReRouted = implSetObject(_rxParameters, _nColumnIndex, aInnerValue);
+ }
+ break;
+
+ case TypeClass_VOID:
+ _rxParameters->setNull(_nColumnIndex,DataType::VARCHAR);
+ break;
+
+ case TypeClass_STRING:
+ _rxParameters->setString(_nColumnIndex, *(rtl::OUString*)_rValue.getValue());
+ break;
+
+ case TypeClass_BOOLEAN:
+ _rxParameters->setBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue());
+ break;
+
+ case TypeClass_BYTE:
+ _rxParameters->setByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue());
+ break;
+
+ case TypeClass_UNSIGNED_SHORT:
+ case TypeClass_SHORT:
+ _rxParameters->setShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue());
+ break;
+
+ case TypeClass_CHAR:
+ _rxParameters->setString(_nColumnIndex, ::rtl::OUString((sal_Unicode *)_rValue.getValue(),1));
+ break;
+
+ case TypeClass_UNSIGNED_LONG:
+ case TypeClass_LONG:
+ _rxParameters->setInt(_nColumnIndex, *(sal_Int32*)_rValue.getValue());
+ break;
+
+ case TypeClass_FLOAT:
+ _rxParameters->setFloat(_nColumnIndex, *(float*)_rValue.getValue());
+ break;
+
+ case TypeClass_DOUBLE:
+ _rxParameters->setDouble(_nColumnIndex, *(double*)_rValue.getValue());
+ break;
+
+ case TypeClass_SEQUENCE:
+ if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0))
+ {
+ _rxParameters->setBytes(_nColumnIndex, *(Sequence<sal_Int8>*)_rValue.getValue());
+ }
+ else
+ bSuccessfullyReRouted = sal_False;
+ break;
+ case TypeClass_STRUCT:
+ if (_rValue.getValueType() == ::getCppuType((const DateTime*)0))
+ _rxParameters->setTimestamp(_nColumnIndex, *(DateTime*)_rValue.getValue());
+ else if (_rValue.getValueType() == ::getCppuType((const Date*)0))
+ _rxParameters->setDate(_nColumnIndex, *(Date*)_rValue.getValue());
+ else if (_rValue.getValueType() == ::getCppuType((const Time*)0))
+ _rxParameters->setTime(_nColumnIndex, *(Time*)_rValue.getValue());
+ else
+ bSuccessfullyReRouted = sal_False;
+ break;
+
+ case TypeClass_INTERFACE:
+ if (_rValue.getValueType() == ::getCppuType(static_cast<Reference< XInputStream>*>(NULL)))
+ {
+ Reference< XInputStream > xStream;
+ _rValue >>= xStream;
+ _rxParameters->setBinaryStream(_nColumnIndex, xStream, xStream->available());
+ break;
+ }
+ // run through
+ default:
+ bSuccessfullyReRouted = sal_False;
+
+ }
+
+ return bSuccessfullyReRouted;
+}
+
+//..................................................................
+namespace
+{
+ class OParameterWrapper : public ::cppu::WeakImplHelper1< XIndexAccess >
+ {
+ ::std::bit_vector m_aSet;
+ Reference<XIndexAccess> m_xSource;
+ public:
+ OParameterWrapper(const ::std::bit_vector& _aSet,const Reference<XIndexAccess>& _xSource) : m_aSet(_aSet),m_xSource(_xSource){}
+ private:
+ // ::com::sun::star::container::XElementAccess
+ virtual Type SAL_CALL getElementType() throw(RuntimeException)
+ {
+ return m_xSource->getElementType();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) throw(RuntimeException)
+ {
+ if ( m_aSet.empty() )
+ return m_xSource->hasElements();
+ return ::std::count(m_aSet.begin(),m_aSet.end(),false) != 0;
+ }
+ // ::com::sun::star::container::XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) throw(RuntimeException)
+ {
+ if ( m_aSet.empty() )
+ return m_xSource->getCount();
+ return ::std::count(m_aSet.begin(),m_aSet.end(),false);
+ }
+ virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+ {
+ if ( m_aSet.empty() )
+ return m_xSource->getByIndex(Index);
+ if ( m_aSet.size() < (size_t)Index )
+ throw IndexOutOfBoundsException();
+
+ ::std::bit_vector::iterator aIter = m_aSet.begin();
+ ::std::bit_vector::iterator aEnd = m_aSet.end();
+ sal_Int32 i = 0;
+ sal_Int32 nParamPos = -1;
+ for(; aIter != aEnd && i <= Index; ++aIter)
+ {
+ ++nParamPos;
+ if ( !*aIter )
+ {
+ ++i;
+ }
+ }
+ return m_xSource->getByIndex(nParamPos);
+ }
+ };
+}
+
+// -----------------------------------------------------------------------------
+void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer,
+ const Reference<XParameters>& _xParameters,
+ const Reference< XConnection>& _xConnection,
+ const Reference< XInteractionHandler >& _rxHandler,
+ const ::std::bit_vector& _aParametersSet)
+{
+ OSL_ENSURE(_xComposer.is(),"dbtools::askForParameters XSQLQueryComposer is null!");
+ OSL_ENSURE(_xParameters.is(),"dbtools::askForParameters XParameters is null!");
+ OSL_ENSURE(_xConnection.is(),"dbtools::askForParameters XConnection is null!");
+ OSL_ENSURE(_rxHandler.is(),"dbtools::askForParameters XInteractionHandler is null!");
+
+ // we have to set this here again because getCurrentSettingsComposer can force a setpropertyvalue
+ Reference<XParametersSupplier> xParameters = Reference<XParametersSupplier> (_xComposer, UNO_QUERY);
+
+ Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>();
+ Reference<XNameAccess> xParamsAsNames(xParamsAsIndicies, UNO_QUERY);
+ sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0;
+ ::std::bit_vector aNewParameterSet( _aParametersSet );
+ if ( nParamCount || ::std::count(aNewParameterSet.begin(),aNewParameterSet.end(),true) != nParamCount )
+ {
+ static const ::rtl::OUString PROPERTY_NAME(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME));
+ aNewParameterSet.resize(nParamCount ,false);
+ typedef ::std::map< ::rtl::OUString, ::std::vector<sal_Int32> > TParameterPositions;
+ TParameterPositions aParameterNames;
+ for(sal_Int32 i = 0; i < nParamCount; ++i)
+ {
+ Reference<XPropertySet> xParam(xParamsAsIndicies->getByIndex(i),UNO_QUERY);
+ ::rtl::OUString sName;
+ xParam->getPropertyValue(PROPERTY_NAME) >>= sName;
+
+ TParameterPositions::iterator aFind = aParameterNames.find(sName);
+ if ( aFind != aParameterNames.end() )
+ aNewParameterSet[i] = true;
+ aParameterNames[sName].push_back(i+1);
+ }
+ // build an interaction request
+ // two continuations (Ok and Cancel)
+ OInteractionAbort* pAbort = new OInteractionAbort;
+ OParameterContinuation* pParams = new OParameterContinuation;
+ // the request
+ ParametersRequest aRequest;
+ Reference<XIndexAccess> xWrappedParameters = new OParameterWrapper(aNewParameterSet,xParamsAsIndicies);
+ aRequest.Parameters = xWrappedParameters;
+ aRequest.Connection = _xConnection;
+ OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
+ Reference< XInteractionRequest > xRequest(pRequest);
+ // some knittings
+ pRequest->addContinuation(pAbort);
+ pRequest->addContinuation(pParams);
+
+ // execute the request
+ _rxHandler->handle(xRequest);
+
+ if (!pParams->wasSelected())
+ {
+ // canceled by the user (i.e. (s)he canceled the dialog)
+ RowSetVetoException e;
+ e.ErrorCode = ParameterInteractionCancelled;
+ throw e;
+ }
+
+ // now transfer the values from the continuation object to the parameter columns
+ Sequence< PropertyValue > aFinalValues = pParams->getValues();
+ const PropertyValue* pFinalValues = aFinalValues.getConstArray();
+ for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
+ {
+ Reference< XPropertySet > xParamColumn(xWrappedParameters->getByIndex(i),UNO_QUERY);
+ if (xParamColumn.is())
+ {
+ ::rtl::OUString sName;
+ xParamColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
+ OSL_ENSURE(sName.equals(pFinalValues->Name), "::dbaui::askForParameters: inconsistent parameter names!");
+
+ // determine the field type and ...
+ sal_Int32 nParamType = 0;
+ xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nParamType;
+ // ... the scale of the parameter column
+ sal_Int32 nScale = 0;
+ if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE), xParamColumn))
+ xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale;
+ // (the index of the parameters is one-based)
+ TParameterPositions::iterator aFind = aParameterNames.find(pFinalValues->Name);
+ ::std::vector<sal_Int32>::iterator aIterPos = aFind->second.begin();
+ ::std::vector<sal_Int32>::iterator aEndPos = aFind->second.end();
+ for(;aIterPos != aEndPos;++aIterPos)
+ {
+ if ( _aParametersSet.empty() || !_aParametersSet[(*aIterPos)-1] )
+ {
+ _xParameters->setObjectWithInfo(*aIterPos, pFinalValues->Value, nParamType, nScale);
+ }
+ }
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void setObjectWithInfo(const Reference<XParameters>& _xParams,
+ sal_Int32 parameterIndex,
+ const Any& x,
+ sal_Int32 sqlType,
+ sal_Int32 scale) throw(SQLException, RuntimeException)
+{
+ ORowSetValue aVal;
+ aVal.fill(x);
+ setObjectWithInfo(_xParams,parameterIndex,aVal,sqlType,scale);
+}
+// -----------------------------------------------------------------------------
+void setObjectWithInfo(const Reference<XParameters>& _xParams,
+ sal_Int32 parameterIndex,
+ const ::connectivity::ORowSetValue& _rValue,
+ sal_Int32 sqlType,
+ sal_Int32 scale) throw(SQLException, RuntimeException)
+{
+ if ( _rValue.isNull() )
+ _xParams->setNull(parameterIndex,sqlType);
+ else
+ {
+ switch(sqlType)
+ {
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ _xParams->setObjectWithInfo(parameterIndex,_rValue.makeAny(),sqlType,scale);
+ break;
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ _xParams->setString(parameterIndex,_rValue);
+ break;
+ case DataType::CLOB:
+ {
+ Any x(_rValue.makeAny());
+ ::rtl::OUString sValue;
+ if ( x >>= sValue )
+ _xParams->setString(parameterIndex,sValue);
+ else
+ {
+ Reference< XClob > xClob;
+ if(x >>= xClob)
+ _xParams->setClob(parameterIndex,xClob);
+ else
+ {
+ Reference< ::com::sun::star::io::XInputStream > xStream;
+ if(x >>= xStream)
+ _xParams->setCharacterStream(parameterIndex,xStream,xStream->available());
+ }
+ }
+ }
+ break;
+ case DataType::BIGINT:
+ if ( _rValue.isSigned() )
+ _xParams->setLong(parameterIndex,_rValue);
+ else
+ _xParams->setString(parameterIndex,_rValue);
+ break;
+
+ case DataType::FLOAT:
+ _xParams->setFloat(parameterIndex,_rValue);
+ break;
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ _xParams->setDouble(parameterIndex,_rValue);
+ break;
+ case DataType::DATE:
+ _xParams->setDate(parameterIndex,_rValue);
+ break;
+ case DataType::TIME:
+ _xParams->setTime(parameterIndex,_rValue);
+ break;
+ case DataType::TIMESTAMP:
+ _xParams->setTimestamp(parameterIndex,_rValue);
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ case DataType::BLOB:
+ {
+ Any x(_rValue.makeAny());
+ Sequence< sal_Int8> aBytes;
+ if(x >>= aBytes)
+ _xParams->setBytes(parameterIndex,aBytes);
+ else
+ {
+ Reference< XBlob > xBlob;
+ if(x >>= xBlob)
+ _xParams->setBlob(parameterIndex,xBlob);
+ else
+ {
+ Reference< XClob > xClob;
+ if(x >>= xClob)
+ _xParams->setClob(parameterIndex,xClob);
+ else
+ {
+ Reference< ::com::sun::star::io::XInputStream > xBinStream;
+ if(x >>= xBinStream)
+ _xParams->setBinaryStream(parameterIndex,xBinStream,xBinStream->available());
+ }
+ }
+ }
+ }
+ break;
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ _xParams->setBoolean(parameterIndex,_rValue);
+ break;
+ case DataType::TINYINT:
+ if ( _rValue.isSigned() )
+ _xParams->setByte(parameterIndex,_rValue);
+ else
+ _xParams->setShort(parameterIndex,_rValue);
+ break;
+ case DataType::SMALLINT:
+ if ( _rValue.isSigned() )
+ _xParams->setShort(parameterIndex,_rValue);
+ else
+ _xParams->setInt(parameterIndex,_rValue);
+ break;
+ case DataType::INTEGER:
+ if ( _rValue.isSigned() )
+ _xParams->setInt(parameterIndex,_rValue);
+ else
+ _xParams->setLong(parameterIndex,_rValue);
+ break;
+ default:
+ {
+ ::connectivity::SharedResources aResources;
+ const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
+ STR_UNKNOWN_PARA_TYPE,
+ "$position$", ::rtl::OUString::valueOf(parameterIndex)
+ ) );
+ ::dbtools::throwGenericSQLException(sError,NULL);
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+void getBoleanComparisonPredicate( const ::rtl::OUString& _rExpression, const sal_Bool _bValue, const sal_Int32 _nBooleanComparisonMode,
+ ::rtl::OUStringBuffer& _out_rSQLPredicate )
+{
+ switch ( _nBooleanComparisonMode )
+ {
+ case BooleanComparisonMode::IS_LITERAL:
+ _out_rSQLPredicate.append( _rExpression );
+ if ( _bValue )
+ _out_rSQLPredicate.appendAscii( " IS TRUE" );
+ else
+ _out_rSQLPredicate.appendAscii( " IS FALSE" );
+ break;
+
+ case BooleanComparisonMode::EQUAL_LITERAL:
+ _out_rSQLPredicate.append( _rExpression );
+ _out_rSQLPredicate.appendAscii( _bValue ? " = TRUE" : " = FALSE" );
+ break;
+
+ case BooleanComparisonMode::ACCESS_COMPAT:
+ if ( _bValue )
+ {
+ _out_rSQLPredicate.appendAscii( " NOT ( ( " );
+ _out_rSQLPredicate.append( _rExpression );
+ _out_rSQLPredicate.appendAscii( " = 0 ) OR ( " );
+ _out_rSQLPredicate.append( _rExpression );
+ _out_rSQLPredicate.appendAscii( " IS NULL ) )" );
+ }
+ else
+ {
+ _out_rSQLPredicate.append( _rExpression );
+ _out_rSQLPredicate.appendAscii( " = 0" );
+ }
+ break;
+
+ case BooleanComparisonMode::EQUAL_INTEGER:
+ // fall through
+ default:
+ _out_rSQLPredicate.append( _rExpression );
+ _out_rSQLPredicate.appendAscii( _bValue ? " = 1" : " = 0" );
+ break;
+ }
+}
+
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
+//.........................................................................
+namespace connectivity
+{
+//.........................................................................
+
+void release(oslInterlockedCount& _refCount,
+ ::cppu::OBroadcastHelper& rBHelper,
+ Reference< XInterface >& _xInterface,
+ ::com::sun::star::lang::XComponent* _pObject)
+{
+ if (osl_decrementInterlockedCount( &_refCount ) == 0)
+ {
+ osl_incrementInterlockedCount( &_refCount );
+
+ if (!rBHelper.bDisposed && !rBHelper.bInDispose)
+ {
+ // remember the parent
+ Reference< XInterface > xParent;
+ {
+ ::osl::MutexGuard aGuard( rBHelper.rMutex );
+ xParent = _xInterface;
+ _xInterface = NULL;
+ }
+
+ // First dispose
+ _pObject->dispose();
+
+ // only the alive ref holds the object
+ OSL_ASSERT( _refCount == 1 );
+
+ // release the parent in the ~
+ if (xParent.is())
+ {
+ ::osl::MutexGuard aGuard( rBHelper.rMutex );
+ _xInterface = xParent;
+ }
+
+// // destroy the object if xHoldAlive decrement the refcount to 0
+// m_pDerivedImplementation->WEAK::release();
+ }
+ }
+ else
+ osl_incrementInterlockedCount( &_refCount );
+}
+
+void checkDisposed(sal_Bool _bThrow) throw ( DisposedException )
+{
+ if (_bThrow)
+ throw DisposedException();
+
+}
+// -------------------------------------------------------------------------
+ OSQLColumns::Vector::const_iterator find( OSQLColumns::Vector::const_iterator __first,
+ OSQLColumns::Vector::const_iterator __last,
+ const ::rtl::OUString& _rVal,
+ const ::comphelper::UStringMixEqual& _rCase)
+ {
+ ::rtl::OUString sName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME);
+ return find(__first,__last,sName,_rVal,_rCase);
+ }
+ // -------------------------------------------------------------------------
+ OSQLColumns::Vector::const_iterator findRealName( OSQLColumns::Vector::const_iterator __first,
+ OSQLColumns::Vector::const_iterator __last,
+ const ::rtl::OUString& _rVal,
+ const ::comphelper::UStringMixEqual& _rCase)
+ {
+ ::rtl::OUString sRealName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME);
+ return find(__first,__last,sRealName,_rVal,_rCase);
+ }
+ // -------------------------------------------------------------------------
+ OSQLColumns::Vector::const_iterator find( OSQLColumns::Vector::const_iterator __first,
+ OSQLColumns::Vector::const_iterator __last,
+ const ::rtl::OUString& _rProp,
+ const ::rtl::OUString& _rVal,
+ const ::comphelper::UStringMixEqual& _rCase)
+ {
+ while (__first != __last && !_rCase(getString((*__first)->getPropertyValue(_rProp)),_rVal))
+ ++__first;
+ return __first;
+ }
+
+// -----------------------------------------------------------------------------
+} //namespace connectivity
+// -----------------------------------------------------------------------------
+
diff --git a/connectivity/source/commontools/dbtools2.cxx b/connectivity/source/commontools/dbtools2.cxx
new file mode 100644
index 000000000000..c9a878fe1840
--- /dev/null
+++ b/connectivity/source/commontools/dbtools2.cxx
@@ -0,0 +1,974 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/dbtools.hxx"
+#include "connectivity/dbconversion.hxx"
+#include "connectivity/dbcharset.hxx"
+#include "connectivity/SQLStatementHelper.hxx"
+#include <unotools/confignode.hxx>
+#include "resource/sharedresources.hxx"
+#include "resource/common_res.hrc"
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
+#include <com/sun/star/sdbc/XDriverAccess.hpp>
+#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sdbc/KeyRule.hpp>
+#include <com/sun/star/sdbcx/KeyType.hpp>
+#include "TConnection.hxx"
+#include "connectivity/sdbcx/VColumn.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/container/XChild.hpp>
+
+#include <tools/diagnose_ex.h>
+#include <unotools/sharedunocomponent.hxx>
+#include <comphelper/configurationhelper.hxx>
+
+//.........................................................................
+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::sdbcx;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+ using namespace ::com::sun::star::frame;
+ using namespace connectivity;
+ using namespace comphelper;
+
+::rtl::OUString createStandardColumnPart(const Reference< XPropertySet >& xColProp,const Reference< XConnection>& _xConnection,ISQLStatementHelper* _pHelper,const ::rtl::OUString& _sCreatePattern)
+{
+
+ Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
+
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+
+ ::rtl::OUString sTypeName;
+ sal_Int32 nDataType = 0;
+ sal_Int32 nPrecision = 0;
+ sal_Int32 nScale = 0;
+
+ const ::rtl::OUString sQuoteString = xMetaData->getIdentifierQuoteString();
+ ::rtl::OUStringBuffer aSql = ::dbtools::quoteName(sQuoteString,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))));
+
+ aSql.appendAscii(" ");
+
+ nDataType = nPrecision = nScale = 0;
+ sal_Bool bIsAutoIncrement = sal_False;
+ xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPENAME)) >>= sTypeName;
+ xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nDataType;
+ xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nPrecision;
+ xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale;
+ xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bIsAutoIncrement;
+
+ // check if the user enter a specific string to create autoincrement values
+ ::rtl::OUString sAutoIncrementValue;
+ Reference<XPropertySetInfo> xPropInfo = xColProp->getPropertySetInfo();
+ if ( xPropInfo.is() && xPropInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION)) )
+ xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION)) >>= sAutoIncrementValue;
+ // look if we have to use precisions
+ sal_Bool bUseLiteral = sal_False;
+ ::rtl::OUString sPreFix,sPostFix,sCreateParams;
+ {
+ Reference<XResultSet> xRes = xMetaData->getTypeInfo();
+ if(xRes.is())
+ {
+ Reference<XRow> xRow(xRes,UNO_QUERY);
+ while(xRes->next())
+ {
+ ::rtl::OUString sTypeName2Cmp = xRow->getString(1);
+ sal_Int32 nType = xRow->getShort(2);
+ sPreFix = xRow->getString (4);
+ sPostFix = xRow->getString (5);
+ sCreateParams = xRow->getString(6);
+ // first identical type will be used if typename is empty
+ if ( !sTypeName.getLength() && nType == nDataType )
+ sTypeName = sTypeName2Cmp;
+
+ if( sTypeName.equalsIgnoreAsciiCase(sTypeName2Cmp) && nType == nDataType && sCreateParams.getLength() && !xRow->wasNull())
+ {
+ bUseLiteral = sal_True;
+ break;
+ }
+ }
+ }
+ }
+
+ sal_Int32 nIndex = 0;
+ if ( sAutoIncrementValue.getLength() && (nIndex = sTypeName.indexOf(sAutoIncrementValue)) != -1 )
+ {
+ sTypeName = sTypeName.replaceAt(nIndex,sTypeName.getLength() - nIndex,::rtl::OUString());
+ }
+
+ if ( (nPrecision > 0 || nScale > 0) && bUseLiteral )
+ {
+ sal_Int32 nParenPos = sTypeName.indexOf('(');
+ if ( nParenPos == -1 )
+ {
+ aSql.append(sTypeName);
+ aSql.appendAscii("(");
+ }
+ else
+ {
+ aSql.append(sTypeName.copy(0,++nParenPos));
+ }
+
+ if ( nPrecision > 0 && nDataType != DataType::TIMESTAMP )
+ {
+ aSql.append(nPrecision);
+ if ( (nScale > 0) || (_sCreatePattern.getLength() && sCreateParams.indexOf(_sCreatePattern) != -1) )
+ aSql.appendAscii(",");
+ }
+ if ( (nScale > 0) || (_sCreatePattern.getLength() && sCreateParams.indexOf(_sCreatePattern) != -1 ) || nDataType == DataType::TIMESTAMP )
+ aSql.append(nScale);
+
+ if ( nParenPos == -1 )
+ aSql.appendAscii(")");
+ else
+ {
+ nParenPos = sTypeName.indexOf(')',nParenPos);
+ aSql.append(sTypeName.copy(nParenPos));
+ }
+ }
+ else
+ aSql.append(sTypeName); // simply add the type name
+
+ ::rtl::OUString aDefault = ::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)));
+ if ( aDefault.getLength() )
+ {
+ aSql.append(::rtl::OUString::createFromAscii(" DEFAULT "));
+ aSql.append(sPreFix);
+ aSql.append(aDefault);
+ aSql.append(sPostFix);
+ } // if ( aDefault.getLength() )
+
+ if(::comphelper::getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISNULLABLE))) == ColumnValue::NO_NULLS)
+ aSql.append(::rtl::OUString::createFromAscii(" NOT NULL"));
+
+ if ( bIsAutoIncrement && sAutoIncrementValue.getLength())
+ {
+ aSql.appendAscii(" ");
+ aSql.append(sAutoIncrementValue);
+ }
+
+ if ( _pHelper )
+ _pHelper->addComment(xColProp,aSql);
+
+ return aSql.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+
+::rtl::OUString createStandardCreateStatement(const Reference< XPropertySet >& descriptor,const Reference< XConnection>& _xConnection,ISQLStatementHelper* _pHelper,const ::rtl::OUString& _sCreatePattern)
+{
+ ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("CREATE TABLE ");
+ ::rtl::OUString sCatalog,sSchema,sTable,sComposedName;
+
+ Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+
+ descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)) >>= sCatalog;
+ descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= sSchema;
+ descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= sTable;
+
+ sComposedName = ::dbtools::composeTableName( xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions );
+ if ( !sComposedName.getLength() )
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ aSql.append(sComposedName);
+ aSql.append(::rtl::OUString::createFromAscii(" ("));
+
+ // columns
+ Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
+ Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
+ // check if there are columns
+ if(!xColumns.is() || !xColumns->getCount())
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ Reference< XPropertySet > xColProp;
+
+ sal_Int32 nCount = xColumns->getCount();
+ for(sal_Int32 i=0;i<nCount;++i)
+ {
+ if ( (xColumns->getByIndex(i) >>= xColProp) && xColProp.is() )
+ {
+ aSql.append(createStandardColumnPart(xColProp,_xConnection,_pHelper,_sCreatePattern));
+ aSql.appendAscii(",");
+ }
+ }
+ return aSql.makeStringAndClear();
+}
+namespace
+{
+ ::rtl::OUString generateColumnNames(const Reference<XIndexAccess>& _xColumns,const Reference<XDatabaseMetaData>& _xMetaData)
+ {
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ static const ::rtl::OUString sComma(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")));
+
+ const ::rtl::OUString sQuote(_xMetaData->getIdentifierQuoteString());
+ ::rtl::OUString sSql = ::rtl::OUString::createFromAscii(" (");
+ Reference< XPropertySet > xColProp;
+
+ sal_Int32 nColCount = _xColumns->getCount();
+ for(sal_Int32 i=0;i<nColCount;++i)
+ {
+ if ( (_xColumns->getByIndex(i) >>= xColProp) && xColProp.is() )
+ sSql += ::dbtools::quoteName(sQuote,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))
+ + sComma;
+ }
+
+ if ( nColCount )
+ sSql = sSql.replaceAt(sSql.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
+ return sSql;
+ }
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString createStandardKeyStatement(const Reference< XPropertySet >& descriptor,const Reference< XConnection>& _xConnection)
+{
+ Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+
+ ::rtl::OUStringBuffer aSql;
+ // keys
+ Reference<XKeysSupplier> xKeySup(descriptor,UNO_QUERY);
+ Reference<XIndexAccess> xKeys = xKeySup->getKeys();
+ if ( xKeys.is() )
+ {
+ Reference< XPropertySet > xColProp;
+ Reference<XIndexAccess> xColumns;
+ Reference<XColumnsSupplier> xColumnSup;
+ ::rtl::OUString sCatalog,sSchema,sTable,sComposedName;
+ sal_Bool bPKey = sal_False;
+ for(sal_Int32 i=0;i<xKeys->getCount();++i)
+ {
+ if ( (xKeys->getByIndex(i) >>= xColProp) && xColProp.is() )
+ {
+
+ sal_Int32 nKeyType = ::comphelper::getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)));
+
+ if ( nKeyType == KeyType::PRIMARY )
+ {
+ if(bPKey)
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ bPKey = sal_True;
+ xColumnSup = Reference<XColumnsSupplier>(xColProp,UNO_QUERY);
+ xColumns = Reference<XIndexAccess>(xColumnSup->getColumns(),UNO_QUERY);
+ if(!xColumns.is() || !xColumns->getCount())
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString();
+ aSql.append(::rtl::OUString::createFromAscii(" PRIMARY KEY "));
+ aSql.append(generateColumnNames(xColumns,xMetaData));
+ }
+ else if(nKeyType == KeyType::UNIQUE)
+ {
+ xColumnSup = Reference<XColumnsSupplier>(xColProp,UNO_QUERY);
+ xColumns = Reference<XIndexAccess>(xColumnSup->getColumns(),UNO_QUERY);
+ if(!xColumns.is() || !xColumns->getCount())
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString();
+ aSql.append(::rtl::OUString::createFromAscii(" UNIQUE "));
+ aSql.append(generateColumnNames(xColumns,xMetaData));
+ }
+ else if(nKeyType == KeyType::FOREIGN)
+ {
+ sal_Int32 nDeleteRule = getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE)));
+
+ xColumnSup = Reference<XColumnsSupplier>(xColProp,UNO_QUERY);
+ xColumns = Reference<XIndexAccess>(xColumnSup->getColumns(),UNO_QUERY);
+ if(!xColumns.is() || !xColumns->getCount())
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ aSql.append(::rtl::OUString::createFromAscii(" FOREIGN KEY "));
+ ::rtl::OUString sRefTable = getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE)));
+ ::dbtools::qualifiedNameComponents(xMetaData,
+ sRefTable,
+ sCatalog,
+ sSchema,
+ sTable,
+ ::dbtools::eInDataManipulation);
+ sComposedName = ::dbtools::composeTableName( xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions );
+
+
+ if ( !sComposedName.getLength() )
+ ::dbtools::throwFunctionSequenceException(_xConnection);
+
+ aSql.append(generateColumnNames(xColumns,xMetaData));
+
+ switch(nDeleteRule)
+ {
+ case KeyRule::CASCADE:
+ aSql.append(::rtl::OUString::createFromAscii(" ON DELETE CASCADE "));
+ break;
+ case KeyRule::RESTRICT:
+ aSql.append(::rtl::OUString::createFromAscii(" ON DELETE RESTRICT "));
+ break;
+ case KeyRule::SET_NULL:
+ aSql.append(::rtl::OUString::createFromAscii(" ON DELETE SET NULL "));
+ break;
+ case KeyRule::SET_DEFAULT:
+ aSql.append(::rtl::OUString::createFromAscii(" ON DELETE SET DEFAULT "));
+ break;
+ default:
+ ;
+ }
+ }
+ }
+ }
+ }
+
+ if ( aSql.getLength() )
+ {
+ if ( aSql.charAt(aSql.getLength()-1) == ',' )
+ aSql.setCharAt(aSql.getLength()-1,')');
+ else
+ aSql.appendAscii(")");
+ }
+
+ return aSql.makeStringAndClear();
+
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString createSqlCreateTableStatement( const Reference< XPropertySet >& descriptor,
+ const Reference< XConnection>& _xConnection,
+ ISQLStatementHelper* _pHelper,
+ const ::rtl::OUString& _sCreatePattern)
+{
+ ::rtl::OUString aSql = ::dbtools::createStandardCreateStatement(descriptor,_xConnection,_pHelper,_sCreatePattern);
+ const ::rtl::OUString sKeyStmt = ::dbtools::createStandardKeyStatement(descriptor,_xConnection);
+ if ( sKeyStmt.getLength() )
+ aSql += sKeyStmt;
+ else
+ {
+ if ( aSql.lastIndexOf(',') == (aSql.getLength()-1) )
+ aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString::createFromAscii(")"));
+ else
+ aSql += ::rtl::OUString::createFromAscii(")");
+ }
+ return aSql;
+}
+namespace
+{
+ Reference<XPropertySet> lcl_createSDBCXColumn(const Reference<XNameAccess>& _xPrimaryKeyColumns,
+ const Reference<XConnection>& _xConnection,
+ const Any& _aCatalog,
+ const ::rtl::OUString& _aSchema,
+ const ::rtl::OUString& _aTable,
+ const ::rtl::OUString& _rQueryName,
+ const ::rtl::OUString& _rName,
+ sal_Bool _bCase,
+ sal_Bool _bQueryForInfo,
+ sal_Bool _bIsAutoIncrement,
+ sal_Bool _bIsCurrency,
+ sal_Int32 _nDataType)
+ {
+ Reference<XPropertySet> xProp;
+ Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
+ Reference< XResultSet > xResult = xMetaData->getColumns(_aCatalog, _aSchema, _aTable, _rQueryName);
+
+ if ( xResult.is() )
+ {
+ UStringMixEqual aMixCompare(_bCase);
+ Reference< XRow > xRow(xResult,UNO_QUERY);
+ while( xResult->next() )
+ {
+ if ( aMixCompare(xRow->getString(4),_rName) )
+ {
+ sal_Int32 nField5 = xRow->getInt(5);
+ ::rtl::OUString aField6 = xRow->getString(6);
+ sal_Int32 nField7 = xRow->getInt(7)
+ , nField9 = xRow->getInt(9)
+ , nField11= xRow->getInt(11);
+ ::rtl::OUString sField12 = xRow->getString(12),
+ sField13 = xRow->getString(13);
+ ::comphelper::disposeComponent(xRow);
+
+ sal_Bool bAutoIncrement = _bIsAutoIncrement
+ ,bIsCurrency = _bIsCurrency;
+ if ( _bQueryForInfo )
+ {
+ const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString();
+ ::rtl::OUString sQuotedName = ::dbtools::quoteName(sQuote,_rName);
+ ::rtl::OUString sComposedName;
+ sComposedName = composeTableNameForSelect(_xConnection, getString( _aCatalog ), _aSchema, _aTable );
+
+ ColumnInformationMap aInfo(_bCase);
+ collectColumnInformation(_xConnection,sComposedName,sQuotedName,aInfo);
+ ColumnInformationMap::iterator aIter = aInfo.begin();
+ if ( aIter != aInfo.end() )
+ {
+ bAutoIncrement = aIter->second.first.first;
+ bIsCurrency = aIter->second.first.second;
+ if ( DataType::OTHER == nField5 )
+ nField5 = aIter->second.second;
+ }
+ }
+ else if ( DataType::OTHER == nField5 )
+ nField5 = _nDataType;
+
+ if ( nField11 != ColumnValue::NO_NULLS )
+ {
+ try
+ {
+ if ( _xPrimaryKeyColumns.is() )
+ {
+ if ( _xPrimaryKeyColumns->hasByName(_rName) )
+ nField11 = ColumnValue::NO_NULLS;
+
+ }
+ else
+ {
+ Reference< XResultSet > xPKeys = xMetaData->getPrimaryKeys( _aCatalog, _aSchema, _aTable );
+ Reference< XRow > xPKeyRow( xPKeys, UNO_QUERY_THROW );
+ while( xPKeys->next() ) // there can be only one primary key
+ {
+ ::rtl::OUString sKeyColumn = xPKeyRow->getString(4);
+ if ( aMixCompare(_rName,sKeyColumn) )
+ {
+ nField11 = ColumnValue::NO_NULLS;
+ break;
+ }
+ }
+ }
+ }
+ catch(SQLException&)
+ {
+ OSL_ENSURE( false, "lcl_createSDBCXColumn: caught an exception!" );
+ }
+ }
+
+ connectivity::sdbcx::OColumn* pRet = new connectivity::sdbcx::OColumn(_rName,
+ aField6,
+ sField13,
+ sField12,
+ nField11,
+ nField7,
+ nField9,
+ nField5,
+ bAutoIncrement,
+ sal_False,
+ bIsCurrency,
+ _bCase);
+
+ xProp = pRet;
+ break;
+ }
+ }
+ }
+
+ return xProp;
+ }
+ //------------------------------------------------------------------
+ Reference< XModel> lcl_getXModel(const Reference< XInterface>& _xIface)
+ {
+ Reference< XInterface > xParent = _xIface;
+ Reference< XModel > xModel(xParent,UNO_QUERY);;
+ while( xParent.is() && !xModel.is() )
+ {
+ Reference<XChild> xChild(xParent,UNO_QUERY);
+ xParent.set(xChild.is() ? xChild->getParent() : Reference< XInterface >(),UNO_QUERY);
+ xModel.set(xParent,UNO_QUERY);
+ }
+ return xModel;
+ }
+}
+// -----------------------------------------------------------------------------
+Reference<XPropertySet> createSDBCXColumn(const Reference<XPropertySet>& _xTable,
+ const Reference<XConnection>& _xConnection,
+ const ::rtl::OUString& _rName,
+ sal_Bool _bCase,
+ sal_Bool _bQueryForInfo,
+ sal_Bool _bIsAutoIncrement,
+ sal_Bool _bIsCurrency,
+ sal_Int32 _nDataType)
+{
+ Reference<XPropertySet> xProp;
+ OSL_ENSURE(_xTable.is(),"Table is NULL!");
+ if ( !_xTable.is() )
+ return xProp;
+
+ ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
+ Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData();
+ Any aCatalog;
+ aCatalog = _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME));
+
+ ::rtl::OUString aSchema, aTable;
+ _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
+ _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
+
+ Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(_xTable);
+
+ xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, _rName,_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType);
+ if ( !xProp.is() )
+ {
+ xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")),_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType);
+ if ( !xProp.is() )
+ xProp = new connectivity::sdbcx::OColumn(_rName,
+ ::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),
+ ColumnValue::NULLABLE_UNKNOWN,
+ 0,
+ 0,
+ DataType::VARCHAR,
+ _bIsAutoIncrement,
+ sal_False,
+ _bIsCurrency,
+ _bCase);
+
+ }
+
+ return xProp;
+}
+
+// -----------------------------------------------------------------------------
+bool getBooleanDataSourceSetting( const Reference< XConnection >& _rxConnection, const sal_Char* _pAsciiSettingName )
+{
+ bool bValue( false );
+ try
+ {
+ Reference< XPropertySet> xDataSourceProperties( findDataSource( _rxConnection ), UNO_QUERY );
+ OSL_ENSURE( xDataSourceProperties.is(), "::dbtools::getBooleanDataSourceSetting: somebody is using this with a non-SDB-level connection!" );
+ if ( xDataSourceProperties.is() )
+ {
+ Reference< XPropertySet > xSettings(
+ xDataSourceProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings") ) ),
+ UNO_QUERY_THROW
+ );
+ OSL_VERIFY( xSettings->getPropertyValue( ::rtl::OUString::createFromAscii( _pAsciiSettingName ) ) >>= bValue );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bValue;
+}
+// -------------------------------------------------------------------------
+bool getDataSourceSetting( const Reference< XInterface >& _xChild, const ::rtl::OUString& _sAsciiSettingsName,
+ Any& /* [out] */ _rSettingsValue )
+{
+ bool bIsPresent = false;
+ try
+ {
+ const Reference< XPropertySet> xDataSourceProperties( findDataSource( _xChild ), UNO_QUERY );
+ OSL_ENSURE( xDataSourceProperties.is(), "getDataSourceSetting: invalid data source object!" );
+ if ( !xDataSourceProperties.is() )
+ return false;
+
+ const Reference< XPropertySet > xSettings(
+ xDataSourceProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings") ) ),
+ UNO_QUERY_THROW
+ );
+
+ _rSettingsValue = xSettings->getPropertyValue( _sAsciiSettingsName );
+ bIsPresent = true;
+ }
+ catch( const Exception& )
+ {
+ bIsPresent = false;
+ }
+ return bIsPresent;
+}
+// -------------------------------------------------------------------------
+bool getDataSourceSetting( const Reference< XInterface >& _rxDataSource, const sal_Char* _pAsciiSettingsName,
+ Any& /* [out] */ _rSettingsValue )
+{
+ ::rtl::OUString sAsciiSettingsName = ::rtl::OUString::createFromAscii(_pAsciiSettingsName);
+ return getDataSourceSetting( _rxDataSource, sAsciiSettingsName,_rSettingsValue );
+}
+// -----------------------------------------------------------------------------
+sal_Bool isDataSourcePropertyEnabled(const Reference<XInterface>& _xProp,const ::rtl::OUString& _sProperty,sal_Bool _bDefault)
+{
+ sal_Bool bEnabled = _bDefault;
+ try
+ {
+ Reference< XPropertySet> xProp(findDataSource(_xProp),UNO_QUERY);
+ if ( xProp.is() )
+ {
+ Sequence< PropertyValue > aInfo;
+ xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Info"))) >>= aInfo;
+ const PropertyValue* pValue =::std::find_if(aInfo.getConstArray(),
+ aInfo.getConstArray() + aInfo.getLength(),
+ ::std::bind2nd(TPropertyValueEqualFunctor(),_sProperty));
+ if ( pValue && pValue != (aInfo.getConstArray() + aInfo.getLength()) )
+ pValue->Value >>= bEnabled;
+ }
+ }
+ catch(SQLException&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bEnabled;
+}
+// -----------------------------------------------------------------------------
+Reference< XTablesSupplier> getDataDefinitionByURLAndConnection(
+ const ::rtl::OUString& _rsUrl,
+ const Reference< XConnection>& _xConnection,
+ const Reference< XMultiServiceFactory>& _rxFactory)
+{
+ Reference< XTablesSupplier> xTablesSup;
+ try
+ {
+ Reference< XDriverAccess> xManager(
+ _rxFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.sdbc.DriverManager") ),
+ UNO_QUERY_THROW );
+ Reference< XDataDefinitionSupplier > xSupp( xManager->getDriverByURL( _rsUrl ), UNO_QUERY );
+
+ if ( xSupp.is() )
+ {
+ xTablesSup = xSupp->getDataDefinitionByConnection( _xConnection );
+ OSL_ENSURE(xTablesSup.is(),"No table supplier!");
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return xTablesSup;
+}
+
+// -----------------------------------------------------------------------------
+sal_Int32 getTablePrivileges(const Reference< XDatabaseMetaData>& _xMetaData,
+ const ::rtl::OUString& _sCatalog,
+ const ::rtl::OUString& _sSchema,
+ const ::rtl::OUString& _sTable)
+{
+ OSL_ENSURE(_xMetaData.is(),"Invalid metadata!");
+ sal_Int32 nPrivileges = 0;
+ try
+ {
+ Any aVal;
+ if(_sCatalog.getLength())
+ aVal <<= _sCatalog;
+ Reference< XResultSet > xPrivileges = _xMetaData->getTablePrivileges(aVal, _sSchema, _sTable);
+ Reference< XRow > xCurrentRow(xPrivileges, UNO_QUERY);
+
+ if ( xCurrentRow.is() )
+ {
+ ::rtl::OUString sUserWorkingFor = _xMetaData->getUserName();
+ static const ::rtl::OUString sSELECT = ::rtl::OUString::createFromAscii("SELECT");
+ static const ::rtl::OUString sINSERT = ::rtl::OUString::createFromAscii("INSERT");
+ static const ::rtl::OUString sUPDATE = ::rtl::OUString::createFromAscii("UPDATE");
+ static const ::rtl::OUString sDELETE = ::rtl::OUString::createFromAscii("DELETE");
+ static const ::rtl::OUString sREAD = ::rtl::OUString::createFromAscii("READ");
+ static const ::rtl::OUString sCREATE = ::rtl::OUString::createFromAscii("CREATE");
+ static const ::rtl::OUString sALTER = ::rtl::OUString::createFromAscii("ALTER");
+ static const ::rtl::OUString sREFERENCE = ::rtl::OUString::createFromAscii("REFERENCE");
+ static const ::rtl::OUString sDROP = ::rtl::OUString::createFromAscii("DROP");
+ // after creation the set is positioned before the first record, per definitionem
+#ifdef DBG_UTIL
+ Reference< XResultSetMetaDataSupplier > xSup(xPrivileges,UNO_QUERY);
+ if ( xSup.is() )
+ {
+ Reference< XResultSetMetaData > xRsMetaData = xSup->getMetaData();
+ if ( xRsMetaData.is() )
+ {
+ sal_Int32 nCount = xRsMetaData->getColumnCount();
+ for (sal_Int32 i=1; i<=nCount; ++i)
+ {
+ ::rtl::OUString sColumnName = xRsMetaData->getColumnName(i);
+ }
+ }
+ }
+#endif
+
+ ::rtl::OUString sPrivilege, sGrantee;
+ while ( xPrivileges->next() )
+ {
+#ifdef DBG_UTIL
+ ::rtl::OUString sCat, sSchema, sName, sGrantor, sGrantable;
+ sCat = xCurrentRow->getString(1);
+ sSchema = xCurrentRow->getString(2);
+ sName = xCurrentRow->getString(3);
+ sGrantor = xCurrentRow->getString(4);
+#endif
+ sGrantee = xCurrentRow->getString(5);
+ sPrivilege = xCurrentRow->getString(6);
+#ifdef DBG_UTIL
+ sGrantable = xCurrentRow->getString(7);
+#endif
+
+ if (!sUserWorkingFor.equalsIgnoreAsciiCase(sGrantee))
+ continue;
+
+ if (sPrivilege.equalsIgnoreAsciiCase(sSELECT))
+ nPrivileges |= Privilege::SELECT;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sINSERT))
+ nPrivileges |= Privilege::INSERT;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sUPDATE))
+ nPrivileges |= Privilege::UPDATE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sDELETE))
+ nPrivileges |= Privilege::DELETE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sREAD))
+ nPrivileges |= Privilege::READ;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sCREATE))
+ nPrivileges |= Privilege::CREATE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sALTER))
+ nPrivileges |= Privilege::ALTER;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sREFERENCE))
+ nPrivileges |= Privilege::REFERENCE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sDROP))
+ nPrivileges |= Privilege::DROP;
+ }
+ }
+ disposeComponent(xPrivileges);
+ }
+ catch(const SQLException& e)
+ {
+ static ::rtl::OUString sNotSupportedState = ::rtl::OUString::createFromAscii("IM001");
+ // some drivers don't support any privileges so we assume that we are allowed to do all we want :-)
+ if(e.SQLState == sNotSupportedState)
+ nPrivileges |= Privilege::DROP |
+ Privilege::REFERENCE |
+ Privilege::ALTER |
+ Privilege::CREATE |
+ Privilege::READ |
+ Privilege::DELETE |
+ Privilege::UPDATE |
+ Privilege::INSERT |
+ Privilege::SELECT;
+ else
+ OSL_ENSURE(0,"Could not collect the privileges !");
+ }
+ return nPrivileges;
+}
+// -----------------------------------------------------------------------------
+// we need some more information about the column
+void collectColumnInformation(const Reference< XConnection>& _xConnection,
+ const ::rtl::OUString& _sComposedName,
+ const ::rtl::OUString& _rName,
+ ColumnInformationMap& _rInfo)
+{
+ static ::rtl::OUString STR_WHERE = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE "));
+
+ ::rtl::OUString sSelect = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT "));
+ sSelect += _rName;
+ sSelect += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM "));
+ sSelect += _sComposedName;
+ sSelect += STR_WHERE;
+ sSelect += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0 = 1"));
+
+ try
+ {
+ ::utl::SharedUNOComponent< XStatement > xStmt( _xConnection->createStatement() );
+ Reference< XPropertySet > xStatementProps( xStmt, UNO_QUERY_THROW );
+ xStatementProps->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ), makeAny( (sal_Bool)sal_False ) );
+ Reference< XResultSet > xResult( xStmt->executeQuery( sSelect ), UNO_QUERY_THROW );
+ Reference< XResultSetMetaDataSupplier > xSuppMeta( xResult, UNO_QUERY_THROW );
+ Reference< XResultSetMetaData > xMeta( xSuppMeta->getMetaData(), UNO_QUERY_THROW );
+
+ sal_Int32 nCount = xMeta->getColumnCount();
+ OSL_ENSURE( nCount != 0, "::dbtools::collectColumnInformation: result set has empty (column-less) meta data!" );
+ for (sal_Int32 i=1; i <= nCount ; ++i)
+ {
+ _rInfo.insert(ColumnInformationMap::value_type(xMeta->getColumnName(i),
+ ColumnInformation(TBoolPair(xMeta->isAutoIncrement(i),xMeta->isCurrency(i)),xMeta->getColumnType(i))));
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+// -----------------------------------------------------------------------------
+bool isEmbeddedInDatabase( const Reference< XInterface >& _rxComponent, Reference< XConnection >& _rxActualConnection )
+{
+ bool bIsEmbedded = false;
+ try
+ {
+ Reference< XModel > xModel = lcl_getXModel( _rxComponent );
+
+ if ( xModel.is() )
+ {
+ Sequence< PropertyValue > aArgs = xModel->getArgs();
+ const PropertyValue* pIter = aArgs.getConstArray();
+ const PropertyValue* pEnd = pIter + aArgs.getLength();
+ for(;pIter != pEnd;++pIter)
+ {
+ if ( pIter->Name.equalsAscii("ComponentData") )
+ {
+ Sequence<PropertyValue> aDocumentContext;
+ pIter->Value >>= aDocumentContext;
+ const PropertyValue* pContextIter = aDocumentContext.getConstArray();
+ const PropertyValue* pContextEnd = pContextIter + aDocumentContext.getLength();
+ for(;pContextIter != pContextEnd;++pContextIter)
+ {
+ if ( pContextIter->Name.equalsAscii( "ActiveConnection" )
+ && ( pContextIter->Value >>= _rxActualConnection )
+ )
+ {
+ bIsEmbedded = true;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch(Exception&)
+ {
+ // not intereseted in
+ }
+ return bIsEmbedded;
+}
+// -----------------------------------------------------------------------------
+namespace
+{
+ ::rtl::OUString lcl_getEncodingName( rtl_TextEncoding _eEncoding )
+ {
+ ::rtl::OUString sEncodingName;
+
+ OCharsetMap aCharsets;
+ OCharsetMap::CharsetIterator aEncodingPos = aCharsets.find( _eEncoding );
+ OSL_ENSURE( aEncodingPos != aCharsets.end(), "lcl_getEncodingName: *which* encoding?" );
+ if ( aEncodingPos != aCharsets.end() )
+ sEncodingName = (*aEncodingPos).getIanaName();
+
+ return sEncodingName;
+ }
+}
+
+// -----------------------------------------------------------------------------
+sal_Int32 DBTypeConversion::convertUnicodeString( const ::rtl::OUString& _rSource, ::rtl::OString& _rDest, rtl_TextEncoding _eEncoding ) SAL_THROW((com::sun::star::sdbc::SQLException))
+{
+ if ( !rtl_convertUStringToString( &_rDest.pData, _rSource.getStr(), _rSource.getLength(),
+ _eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 |
+ RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE )
+ )
+ {
+ SharedResources aResources;
+ ::rtl::OUString sMessage = aResources.getResourceStringWithSubstitution( STR_CANNOT_CONVERT_STRING,
+ "$string$", _rSource,
+ "$charset$", lcl_getEncodingName( _eEncoding )
+ );
+
+ throw SQLException(
+ sMessage,
+ NULL,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22018" ) ),
+ 22018,
+ Any()
+ );
+ }
+
+ return _rDest.getLength();
+}
+
+// -----------------------------------------------------------------------------
+sal_Int32 DBTypeConversion::convertUnicodeStringToLength( const ::rtl::OUString& _rSource, ::rtl::OString& _rDest,
+ sal_Int32 _nMaxLen, rtl_TextEncoding _eEncoding ) SAL_THROW((SQLException))
+{
+ sal_Int32 nLen = convertUnicodeString( _rSource, _rDest, _eEncoding );
+ if ( nLen > _nMaxLen )
+ {
+ SharedResources aResources;
+ ::rtl::OUString sMessage = aResources.getResourceStringWithSubstitution( STR_STRING_LENGTH_EXCEEDED,
+ "$string$", _rSource,
+ "$maxlen$", ::rtl::OUString::valueOf( _nMaxLen ),
+ "$charset$", lcl_getEncodingName( _eEncoding )
+ );
+
+ throw SQLException(
+ sMessage,
+ NULL,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22001" ) ),
+ 22001,
+ Any()
+ );
+ }
+
+ return nLen;
+}
+::rtl::OUString lcl_getReportEngines()
+{
+ static ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/ReportEngines"));
+ return s_sNodeName;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString lcl_getDefaultReportEngine()
+{
+ static ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("DefaultReportEngine"));
+ return s_sNodeName;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString lcl_getReportEngineNames()
+{
+ static ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("ReportEngineNames"));
+ return s_sNodeName;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString getDefaultReportEngineServiceName(const Reference< XMultiServiceFactory >& _rxORB)
+{
+ ::utl::OConfigurationTreeRoot aReportEngines = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
+ _rxORB, lcl_getReportEngines(), -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
+
+ if ( aReportEngines.isValid() )
+ {
+ ::rtl::OUString sDefaultReportEngineName;
+ aReportEngines.getNodeValue(lcl_getDefaultReportEngine()) >>= sDefaultReportEngineName;
+ if ( sDefaultReportEngineName.getLength() )
+ {
+ ::utl::OConfigurationNode aReportEngineNames = aReportEngines.openNode(lcl_getReportEngineNames());
+ if ( aReportEngineNames.isValid() )
+ {
+ ::utl::OConfigurationNode aReportEngine = aReportEngineNames.openNode(sDefaultReportEngineName);
+ if ( aReportEngine.isValid() )
+ {
+ ::rtl::OUString sRet;
+ const static ::rtl::OUString s_sService(RTL_CONSTASCII_USTRINGPARAM("ServiceName"));
+ aReportEngine.getNodeValue(s_sService) >>= sRet;
+ return sRet;
+ }
+ }
+ }
+ else
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
+ }
+ else
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
+ return ::rtl::OUString();
+}
+// -----------------------------------------------------------------------------
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
diff --git a/connectivity/source/commontools/filtermanager.cxx b/connectivity/source/commontools/filtermanager.cxx
new file mode 100644
index 000000000000..bab2ec4ed144
--- /dev/null
+++ b/connectivity/source/commontools/filtermanager.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/filtermanager.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
+/** === end UNO includes === **/
+#include "TConnection.hxx"
+#include <osl/diagnose.h>
+#include "connectivity/dbtools.hxx"
+
+//........................................................................
+namespace dbtools
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace connectivity;
+
+ //====================================================================
+ //= FilterManager
+ //====================================================================
+ //--------------------------------------------------------------------
+ FilterManager::FilterManager( const Reference< XMultiServiceFactory >& _rxORB )
+ :m_xORB( _rxORB )
+ ,m_aFilterComponents( FC_COMPONENT_COUNT )
+ ,m_bApplyPublicFilter( true )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void FilterManager::initialize( const Reference< XPropertySet >& _rxComponentAggregate )
+ {
+ m_xComponentAggregate = _rxComponentAggregate;
+ OSL_ENSURE( m_xComponentAggregate.is(), "FilterManager::initialize: invalid arguments!" );
+
+ if ( m_xComponentAggregate.is() )
+ m_xComponentAggregate->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_APPLYFILTER), makeAny( (sal_Bool)sal_True ) );
+ }
+
+ //--------------------------------------------------------------------
+ void FilterManager::dispose( )
+ {
+ m_xComponentAggregate.clear();
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& FilterManager::getFilterComponent( FilterComponent _eWhich ) const
+ {
+ return m_aFilterComponents[ _eWhich ];
+ }
+
+ //--------------------------------------------------------------------
+ void FilterManager::setFilterComponent( FilterComponent _eWhich, const ::rtl::OUString& _rComponent )
+ {
+ m_aFilterComponents[ _eWhich ] = _rComponent;
+ try
+ {
+ if ( m_xComponentAggregate.is() && (( _eWhich != fcPublicFilter ) || m_bApplyPublicFilter ) )
+ m_xComponentAggregate->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FILTER), makeAny( getComposedFilter() ) );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "FilterManager::setFilterComponent: setting the filter failed!" );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void FilterManager::setApplyPublicFilter( sal_Bool _bApply )
+ {
+ if ( m_bApplyPublicFilter == _bApply )
+ return;
+
+ m_bApplyPublicFilter = _bApply;
+
+ try
+ {
+ if ( m_xComponentAggregate.is() && getFilterComponent( fcPublicFilter ).getLength() )
+ { // only if there changed something
+ m_xComponentAggregate->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FILTER), makeAny( getComposedFilter() ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "FilterManager::setApplyPublicFilter: setting the filter failed!" );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ void lcl_ensureBracketed( ::rtl::OUString& /* [inout] */ _rExpression )
+ {
+ OSL_ENSURE( _rExpression.getLength(), "lcl_ensureBracketed: expression is empty!" );
+ if ( _rExpression.getLength() )
+ {
+ if ( ( _rExpression.getStr()[0] != '(' ) || ( _rExpression.getStr()[ _rExpression.getLength() - 1 ] != ')' ) )
+ {
+ ::rtl::OUString sComposed( RTL_CONSTASCII_USTRINGPARAM( "(" ) );
+ sComposed += _rExpression;
+ sComposed += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
+ _rExpression = sComposed;
+ }
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+ void FilterManager::appendFilterComponent( ::rtl::OUString& /* [inout] */ _rAppendTo, const ::rtl::OUString& _rComponent ) const
+ {
+ if ( _rAppendTo.getLength() )
+ _rAppendTo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " AND " ) );
+
+ ::rtl::OUString sComponent( _rComponent );
+ lcl_ensureBracketed( sComponent );
+ _rAppendTo += sComponent;
+ }
+
+ //--------------------------------------------------------------------
+ bool FilterManager::isThereAtMostOneComponent( ::rtl::OUString& _rOnlyComponent ) const
+ {
+ sal_Int32 nOnlyNonEmpty = -1;
+ sal_Int32 i;
+ for ( i = getFirstApplicableFilterIndex(); i < FC_COMPONENT_COUNT; ++i )
+ {
+ if ( m_aFilterComponents[ i ].getLength() )
+ {
+ if ( nOnlyNonEmpty != -1 )
+ // it's the second non-empty component
+ break;
+ else
+ nOnlyNonEmpty = i;
+ }
+ }
+ if ( nOnlyNonEmpty == -1 )
+ {
+ _rOnlyComponent = ::rtl::OUString();
+ return true;
+ }
+
+ if ( i == FC_COMPONENT_COUNT )
+ {
+ // we found only one non-empty filter component
+ _rOnlyComponent = m_aFilterComponents[ nOnlyNonEmpty ];
+ return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString FilterManager::getComposedFilter( ) const
+ {
+ ::rtl::OUString sComposedFilter;
+
+ // if we have only one non-empty component, then there's no need to compose anything
+ if ( isThereAtMostOneComponent( sComposedFilter ) )
+ return sComposedFilter;
+
+ // append the single components
+ for ( sal_Int32 i = getFirstApplicableFilterIndex(); i < FC_COMPONENT_COUNT; ++i )
+ appendFilterComponent( sComposedFilter, m_aFilterComponents[ i ] );
+
+ return sComposedFilter;
+ }
+
+//........................................................................
+} // namespace dbtools
+//........................................................................
diff --git a/connectivity/source/commontools/formattedcolumnvalue.cxx b/connectivity/source/commontools/formattedcolumnvalue.cxx
new file mode 100644
index 000000000000..d63c83524389
--- /dev/null
+++ b/connectivity/source/commontools/formattedcolumnvalue.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include "connectivity/formattedcolumnvalue.hxx"
+#include "connectivity/dbtools.hxx"
+#include "connectivity/dbconversion.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+/** === end UNO includes === **/
+
+//#include <unotools/syslocale.hxx>
+#include <tools/diagnose_ex.h>
+#include <i18npool/mslangid.hxx>
+#include <comphelper/numbers.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <unotools/sharedunocomponent.hxx>
+
+//........................................................................
+namespace dbtools
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ 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::sdbc::XRowSet;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::util::XNumberFormatter;
+ using ::com::sun::star::util::Date;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::util::XNumberFormatsSupplier;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::lang::Locale;
+ using ::com::sun::star::util::XNumberFormatTypes;
+ using ::com::sun::star::sdb::XColumn;
+ using ::com::sun::star::sdb::XColumnUpdate;
+ using ::com::sun::star::lang::XComponent;
+ /** === end UNO using === **/
+ namespace DataType = ::com::sun::star::sdbc::DataType;
+ namespace NumberFormat = ::com::sun::star::util::NumberFormat;
+
+ //====================================================================
+ //= FormattedColumnValue_Data
+ //====================================================================
+ struct FormattedColumnValue_Data
+ {
+ Reference< XNumberFormatter > m_xFormatter;
+ Date m_aNullDate;
+ sal_Int32 m_nFormatKey;
+ sal_Int32 m_nFieldType;
+ sal_Int16 m_nKeyType;
+ bool m_bNumericField;
+
+ Reference< XColumn > m_xColumn;
+ Reference< XColumnUpdate > m_xColumnUpdate;
+
+ FormattedColumnValue_Data()
+ :m_xFormatter()
+ ,m_aNullDate( DBTypeConversion::getStandardDate() )
+ ,m_nFormatKey( 0 )
+ ,m_nFieldType( DataType::OTHER )
+ ,m_nKeyType( NumberFormat::UNDEFINED )
+ ,m_bNumericField( false )
+ ,m_xColumn()
+ ,m_xColumnUpdate()
+ {
+ }
+ };
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //................................................................
+ void lcl_clear_nothrow( FormattedColumnValue_Data& _rData )
+ {
+ _rData.m_xFormatter.clear();
+ _rData.m_nFormatKey = 0;
+ _rData.m_nFieldType = DataType::OTHER;
+ _rData.m_nKeyType = NumberFormat::UNDEFINED;
+ _rData.m_bNumericField = false;
+
+ _rData.m_xColumn.clear();
+ _rData.m_xColumnUpdate.clear();
+ }
+
+ //................................................................
+ void lcl_initColumnDataValue_nothrow( FormattedColumnValue_Data& _rData,
+ const Reference< XNumberFormatter >& i_rNumberFormatter, const Reference< XPropertySet >& _rxColumn )
+ {
+ lcl_clear_nothrow( _rData );
+
+ OSL_PRECOND( i_rNumberFormatter.is(), "lcl_initColumnDataValue_nothrow: no number formats -> no formatted values!" );
+ if ( !i_rNumberFormatter.is() )
+ return;
+
+ try
+ {
+ Reference< XNumberFormatsSupplier > xNumberFormatsSupp( i_rNumberFormatter->getNumberFormatsSupplier(), UNO_SET_THROW );
+
+ // remember the column
+ _rData.m_xColumn.set( _rxColumn, UNO_QUERY_THROW );
+ _rData.m_xColumnUpdate.set( _rxColumn, UNO_QUERY );
+
+ // determine the field type, and whether it's a numeric field
+ OSL_VERIFY( _rxColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= _rData.m_nFieldType );
+
+ switch ( _rData.m_nFieldType )
+ {
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ case DataType::REAL:
+ case DataType::BIGINT:
+ case DataType::DOUBLE:
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ _rData.m_bNumericField = true;
+ break;
+ default:
+ _rData.m_bNumericField = false;
+ break;
+ }
+
+ // get the format key of our bound field
+ Reference< XPropertySetInfo > xPSI( _rxColumn->getPropertySetInfo(), UNO_QUERY_THROW );
+ bool bHaveFieldFormat = false;
+ const ::rtl::OUString sFormatKeyProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FormatKey" ) ) );
+ if ( xPSI->hasPropertyByName( sFormatKeyProperty ) )
+ {
+ bHaveFieldFormat = ( _rxColumn->getPropertyValue( sFormatKeyProperty ) >>= _rData.m_nFormatKey );
+ }
+ if ( !bHaveFieldFormat )
+ {
+ // fall back to a format key as indicated by the field type
+ Locale aSystemLocale;
+ MsLangId::convertLanguageToLocale( MsLangId::getSystemLanguage(), aSystemLocale );
+ Reference< XNumberFormatTypes > xNumTypes( xNumberFormatsSupp->getNumberFormats(), UNO_QUERY_THROW );
+ _rData.m_nFormatKey = getDefaultNumberFormat( _rxColumn, xNumTypes, aSystemLocale );
+ }
+
+ // some more formatter settings
+ _rData.m_nKeyType = ::comphelper::getNumberFormatType( xNumberFormatsSupp->getNumberFormats(), _rData.m_nFormatKey );
+ Reference< XPropertySet > xFormatSettings( xNumberFormatsSupp->getNumberFormatSettings(), UNO_QUERY_THROW );
+ OSL_VERIFY( xFormatSettings->getPropertyValue( ::rtl::OUString::createFromAscii( "NullDate" ) ) >>= _rData.m_aNullDate );
+
+ // remember the formatter
+ _rData.m_xFormatter = i_rNumberFormatter;
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //................................................................
+ void lcl_initColumnDataValue_nothrow( const ::comphelper::ComponentContext& i_rContext, FormattedColumnValue_Data& i_rData,
+ const Reference< XRowSet >& i_rRowSet, const Reference< XPropertySet >& i_rColumn )
+ {
+ OSL_PRECOND( i_rRowSet.is(), "lcl_initColumnDataValue_nothrow: no row set!" );
+ if ( !i_rRowSet.is() )
+ return;
+
+ Reference< XNumberFormatter > xNumberFormatter;
+ try
+ {
+ // get the number formats supplier of the connection of the form
+ Reference< XConnection > xConnection( getConnection( i_rRowSet ), UNO_QUERY_THROW );
+ Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( xConnection, sal_True, i_rContext.getLegacyServiceFactory() ), UNO_SET_THROW );
+
+ // create a number formatter for it
+ xNumberFormatter.set( i_rContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW );
+ xNumberFormatter->attachNumberFormatsSupplier( xSupplier );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ lcl_initColumnDataValue_nothrow( i_rData, xNumberFormatter, i_rColumn );
+ }
+ }
+
+ //====================================================================
+ //= FormattedColumnValue
+ //====================================================================
+ //--------------------------------------------------------------------
+ FormattedColumnValue::FormattedColumnValue( const ::comphelper::ComponentContext& i_rContext,
+ const Reference< XRowSet >& _rxRowSet, const Reference< XPropertySet >& i_rColumn )
+ :m_pData( new FormattedColumnValue_Data )
+ {
+ lcl_initColumnDataValue_nothrow( i_rContext, *m_pData, _rxRowSet, i_rColumn );
+ }
+
+ //--------------------------------------------------------------------
+ FormattedColumnValue::FormattedColumnValue( const Reference< XNumberFormatter >& i_rNumberFormatter,
+ const Reference< XPropertySet >& _rxColumn )
+ :m_pData( new FormattedColumnValue_Data )
+ {
+ lcl_initColumnDataValue_nothrow( *m_pData, i_rNumberFormatter, _rxColumn );
+ }
+
+ //--------------------------------------------------------------------
+ void FormattedColumnValue::clear()
+ {
+ lcl_clear_nothrow( *m_pData );
+ }
+
+ //--------------------------------------------------------------------
+ FormattedColumnValue::~FormattedColumnValue()
+ {
+ clear();
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 FormattedColumnValue::getFormatKey() const
+ {
+ return m_pData->m_nFormatKey;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 FormattedColumnValue::getFieldType() const
+ {
+ return m_pData->m_nFieldType;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int16 FormattedColumnValue::getKeyType() const
+ {
+ return m_pData->m_nKeyType;
+ }
+
+ //--------------------------------------------------------------------
+ bool FormattedColumnValue::isNumericField() const
+ {
+ return m_pData->m_bNumericField;
+ }
+
+ //--------------------------------------------------------------------
+ const Reference< XColumn >& FormattedColumnValue::getColumn() const
+ {
+ return m_pData->m_xColumn;
+ }
+
+ //--------------------------------------------------------------------
+ const Reference< XColumnUpdate >& FormattedColumnValue::getColumnUpdate() const
+ {
+ return m_pData->m_xColumnUpdate;
+ }
+
+ //--------------------------------------------------------------------
+ bool FormattedColumnValue::setFormattedValue( const ::rtl::OUString& _rFormattedStringValue ) const
+ {
+ OSL_PRECOND( m_pData->m_xColumnUpdate.is(), "FormattedColumnValue::setFormattedValue: no column!" );
+ if ( !m_pData->m_xColumnUpdate.is() )
+ return false;
+
+ try
+ {
+ if ( m_pData->m_bNumericField )
+ {
+ ::dbtools::DBTypeConversion::setValue( m_pData->m_xColumnUpdate, m_pData->m_xFormatter, m_pData->m_aNullDate,
+ _rFormattedStringValue, m_pData->m_nFormatKey, ::sal::static_int_cast< sal_Int16 >( m_pData->m_nFieldType ),
+ m_pData->m_nKeyType );
+ }
+ else
+ {
+ m_pData->m_xColumnUpdate->updateString( _rFormattedStringValue );
+ }
+ }
+ catch( const Exception& )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString FormattedColumnValue::getFormattedValue() const
+ {
+ OSL_PRECOND( m_pData->m_xColumn.is(), "FormattedColumnValue::setFormattedValue: no column!" );
+
+ ::rtl::OUString sStringValue;
+ if ( m_pData->m_xColumn.is() )
+ {
+ if ( m_pData->m_bNumericField )
+ {
+ sStringValue = DBTypeConversion::getValue(
+ m_pData->m_xColumn, m_pData->m_xFormatter, m_pData->m_aNullDate, m_pData->m_nFormatKey, m_pData->m_nKeyType
+ );
+ }
+ else
+ {
+ sStringValue = m_pData->m_xColumn->getString();
+ }
+ }
+ return sStringValue;
+ }
+
+//........................................................................
+} // namespace dbtools
+//........................................................................
diff --git a/connectivity/source/commontools/makefile.mk b/connectivity/source/commontools/makefile.mk
new file mode 100644
index 000000000000..cab216092241
--- /dev/null
+++ b/connectivity/source/commontools/makefile.mk
@@ -0,0 +1,103 @@
+#*************************************************************************
+#
+# 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=..$/..
+
+PRJNAME=connectivity
+TARGET=commontools
+
+# --- Settings -----------------------------------------------------
+.IF "$(DBGUTIL_OJ)"!=""
+ENVCFLAGS+=/FR$(SLO)$/
+.ENDIF
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/dbtools.pmk
+
+# Disable optimization for SunCC SPARC and MACOSX (funny loops
+# when parsing e.g. "x+width/2"),
+# also http://gcc.gnu.org/PR22392
+.IF ("$(OS)$(CPU)"=="SOLARISS" && "$(COM)"!="GCC") || "$(OS)"=="MACOSX" || ("$(OS)"=="LINUX" && "$(CPU)"=="P")
+NOOPTFILES= $(SLO)$/RowFunctionParser.obj
+.ENDIF
+
+ENVCFLAGS += -DBOOST_SPIRIT_USE_OLD_NAMESPACE
+
+# --- Files --------------------------------------------------------
+EXCEPTIONSFILES=\
+ $(SLO)$/predicateinput.obj \
+ $(SLO)$/ConnectionWrapper.obj \
+ $(SLO)$/TConnection.obj \
+ $(SLO)$/conncleanup.obj \
+ $(SLO)$/dbtools.obj \
+ $(SLO)$/dbtools2.obj \
+ $(SLO)$/dbexception.obj \
+ $(SLO)$/CommonTools.obj \
+ $(SLO)$/TColumnsHelper.obj \
+ $(SLO)$/TTableHelper.obj \
+ $(SLO)$/TKeys.obj \
+ $(SLO)$/TKey.obj \
+ $(SLO)$/TKeyColumns.obj \
+ $(SLO)$/TIndexes.obj \
+ $(SLO)$/TIndex.obj \
+ $(SLO)$/TIndexColumns.obj \
+ $(SLO)$/DateConversion.obj \
+ $(SLO)$/FDatabaseMetaDataResultSetMetaData.obj \
+ $(SLO)$/FDatabaseMetaDataResultSet.obj \
+ $(SLO)$/TDatabaseMetaDataBase.obj \
+ $(SLO)$/TPrivilegesResultSet.obj \
+ $(SLO)$/TSkipDeletedSet.obj \
+ $(SLO)$/dbmetadata.obj \
+ $(SLO)$/TSortIndex.obj \
+ $(SLO)$/dbcharset.obj \
+ $(SLO)$/propertyids.obj \
+ $(SLO)$/FValue.obj \
+ $(SLO)$/paramwrapper.obj \
+ $(SLO)$/statementcomposer.obj \
+ $(SLO)$/RowFunctionParser.obj \
+ $(SLO)$/sqlerror.obj \
+ $(SLO)$/filtermanager.obj \
+ $(SLO)$/parameters.obj \
+ $(SLO)$/ParamterSubstitution.obj \
+ $(SLO)$/DriversConfig.obj \
+ $(SLO)$/formattedcolumnvalue.obj \
+ $(SLO)$/BlobHelper.obj \
+ $(SLO)$/warningscontainer.obj
+
+SLOFILES=\
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/AutoRetrievingBase.obj \
+ $(SLO)$/dbconversion.obj
+
+
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/connectivity/source/commontools/parameters.cxx b/connectivity/source/commontools/parameters.cxx
new file mode 100644
index 000000000000..1eb75415917e
--- /dev/null
+++ b/connectivity/source/commontools/parameters.cxx
@@ -0,0 +1,1120 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include "connectivity/parameters.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/form/DatabaseParameterEvent.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
+#include <com/sun/star/sdb/ParametersRequest.hpp>
+/** === end UNO includes === **/
+
+#include <connectivity/dbtools.hxx>
+#include "connectivity/filtermanager.hxx"
+#include "TConnection.hxx"
+
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <comphelper/uno3.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/broadcasthelper.hxx>
+#include "connectivity/ParameterCont.hxx"
+#include <rtl/ustrbuf.hxx>
+
+//........................................................................
+namespace dbtools
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdbcx;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::task;
+ using namespace ::com::sun::star::form;
+ using namespace ::com::sun::star::container;
+
+ using namespace ::comphelper;
+ using namespace ::connectivity;
+
+ //====================================================================
+ //= ParameterManager
+ //====================================================================
+ //--------------------------------------------------------------------
+ ParameterManager::ParameterManager( ::osl::Mutex& _rMutex, const Reference< XMultiServiceFactory >& _rxORB )
+ :m_rMutex ( _rMutex )
+ ,m_aParameterListeners( _rMutex )
+ ,m_xORB ( _rxORB )
+ ,m_pOuterParameters ( NULL )
+ ,m_nInnerCount ( 0 )
+ ,m_bUpToDate ( false )
+ {
+ OSL_ENSURE( m_xORB.is(), "ParameterManager::ParameterManager: no service factory!" );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::initialize( const Reference< XPropertySet >& _rxComponent, const Reference< XAggregation >& _rxComponentAggregate )
+ {
+ OSL_ENSURE( !m_xComponent.get().is(), "ParameterManager::initialize: already initialized!" );
+
+ m_xComponent = _rxComponent;
+ m_xAggregatedRowSet = _rxComponentAggregate;
+ if ( m_xAggregatedRowSet.is() )
+ m_xAggregatedRowSet->queryAggregation( ::getCppuType( &m_xInnerParamUpdate ) ) >>= m_xInnerParamUpdate;
+ OSL_ENSURE( m_xComponent.get().is() && m_xInnerParamUpdate.is(), "ParameterManager::initialize: invalid arguments!" );
+ if ( !m_xComponent.get().is() || !m_xInnerParamUpdate.is() )
+ return;
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::dispose( )
+ {
+ clearAllParameterInformation();
+
+ m_xComposer.clear();
+ m_xParentComposer.clear();
+ //m_xComponent.clear();
+ m_xInnerParamUpdate.clear();
+ m_xAggregatedRowSet.clear();
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::clearAllParameterInformation()
+ {
+ m_xInnerParamColumns.clear();
+ if ( m_pOuterParameters.is() )
+ m_pOuterParameters->dispose();
+ m_pOuterParameters = NULL;
+ m_nInnerCount = 0;
+ ParameterInformation aEmptyInfo;
+ m_aParameterInformation.swap( aEmptyInfo );
+ m_aMasterFields.realloc( 0 );
+ m_aDetailFields.realloc( 0 );
+ m_sIdentifierQuoteString = ::rtl::OUString();
+ ::std::vector< bool > aEmptyArray;
+ m_aParametersVisited.swap( aEmptyArray );
+ m_bUpToDate = false;
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::disposing( const EventObject& /*_rDisposingEvent*/ )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setAllParametersNull() SAL_THROW( ( SQLException, RuntimeException ) )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::setAllParametersNull: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return;
+
+ for ( sal_Int32 i = 1; i <= m_nInnerCount; ++i )
+ m_xInnerParamUpdate->setNull( i, DataType::VARCHAR );
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::initializeComposerByComponent( const Reference< XPropertySet >& _rxComponent )
+ {
+ OSL_PRECOND( _rxComponent.is(), "ParameterManager::initializeComposerByComponent: invalid !" );
+
+ m_xComposer.clear();
+ m_xInnerParamColumns.clear();
+ m_nInnerCount = 0;
+
+ // create and fill a composer
+ try
+ {
+ // get a query composer for the 's settings
+ m_xComposer.reset( getCurrentSettingsComposer( _rxComponent, m_xORB ), SharedQueryComposer::TakeOwnership );
+
+ // see if the composer found parameters
+ Reference< XParametersSupplier > xParamSupp( m_xComposer, UNO_QUERY );
+ if ( xParamSupp.is() )
+ m_xInnerParamColumns = xParamSupp->getParameters();
+
+ if ( m_xInnerParamColumns.is() )
+ m_nInnerCount = m_xInnerParamColumns->getCount();
+ }
+ catch( const SQLException& )
+ {
+ }
+
+ return m_xInnerParamColumns.is();
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::collectInnerParameters( bool _bSecondRun )
+ {
+ OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::collectInnerParameters: missing some internal data!" );
+ if ( !m_xInnerParamColumns.is() )
+ return;
+
+ // strip previous index informations
+ if ( _bSecondRun )
+ {
+ for ( ParameterInformation::iterator aParamInfo = m_aParameterInformation.begin();
+ aParamInfo != m_aParameterInformation.end();
+ ++aParamInfo
+ )
+ {
+ aParamInfo->second.aInnerIndexes.clear();
+ }
+ }
+
+ // we need to map the parameter names (which is all we get from the 's
+ // MasterFields property) to indicies, which are needed by the XParameters
+ // interface of the row set)
+ Reference<XPropertySet> xParam;
+ for ( sal_Int32 i = 0; i < m_nInnerCount; ++i )
+ {
+ try
+ {
+ xParam.clear();
+ m_xInnerParamColumns->getByIndex( i ) >>= xParam;
+
+ ::rtl::OUString sName;
+ xParam->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
+
+ // only append additonal paramters when they are not already in the list
+ ParameterInformation::iterator aExistentPos = m_aParameterInformation.find( sName );
+ OSL_ENSURE( !_bSecondRun || ( aExistentPos != m_aParameterInformation.end() ),
+ "ParameterManager::collectInnerParameters: the parameter information should already exist in the second run!" );
+
+ if ( aExistentPos == m_aParameterInformation.end() )
+ {
+ aExistentPos = m_aParameterInformation.insert( ParameterInformation::value_type(
+ sName, xParam ) ).first;
+ }
+ else
+ aExistentPos->second.xComposerColumn = xParam;
+
+ aExistentPos->second.aInnerIndexes.push_back( i );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::collectInnerParameters: caught an exception!" );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString ParameterManager::createFilterConditionFromColumnLink(
+ const ::rtl::OUString& _rMasterColumn, const ::rtl::OUString& _rDetailLink, ::rtl::OUString& _rNewParamName )
+ {
+ ::rtl::OUString sFilter;
+
+ // format is:
+ // <detail_column> = :<new_param_name>
+ sFilter = quoteName( m_sIdentifierQuoteString, _rDetailLink );
+ sFilter += ::rtl::OUString::createFromAscii( " = :" );
+
+ // generate a parameter name which is not already used
+ _rNewParamName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "link_from_" ) );
+ _rNewParamName += convertName2SQLName( _rMasterColumn, m_sSpecialCharacters );
+ while ( m_aParameterInformation.find( _rNewParamName ) != m_aParameterInformation.end() )
+ {
+ _rNewParamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_" ) );
+ }
+
+ return sFilter += _rNewParamName;
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::classifyLinks( const Reference< XNameAccess >& _rxParentColumns,
+ const Reference< XNameAccess >& _rxColumns, ::std::vector< ::rtl::OUString >& _out_rAdditionalFilterComponents ) SAL_THROW(( Exception ))
+ {
+ OSL_PRECOND( m_aMasterFields.getLength() == m_aDetailFields.getLength(),
+ "ParameterManager::classifyLinks: master and detail fields should have the same length!" );
+ OSL_ENSURE( _rxColumns.is(), "ParameterManager::classifyLinks: invalid columns!" );
+
+ if ( !_rxColumns.is() )
+ return;
+
+ // we may need to strip any links which are invalid, so here go the containers
+ // for temporarirly holding the new pairs
+ ::std::vector< ::rtl::OUString > aStrippedMasterFields;
+ ::std::vector< ::rtl::OUString > aStrippedDetailFields;
+
+ bool bNeedExchangeLinks = false;
+
+ // classify the links
+ const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
+ const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
+ const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
+ for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
+ {
+ if ( !pMasterFields->getLength() || !pDetailFields->getLength() )
+ continue;
+
+ // if not even the master part of the relationship exists in the parent , the
+ // link is invalid as a whole
+ // #i63674# / 2006-03-28 / frank.schoenheit@sun.com
+ if ( !_rxParentColumns->hasByName( *pMasterFields ) )
+ {
+ bNeedExchangeLinks = true;
+ continue;
+ }
+
+ bool bValidLink = true;
+
+ // is there an inner parameter with this name? That is, a parameter which is already part of
+ // the very original statement (not the one we create ourselve, with the additional parameters)
+ ParameterInformation::iterator aPos = m_aParameterInformation.find( *pDetailFields );
+ if ( aPos != m_aParameterInformation.end() )
+ { // there is an inner parameter with this name
+ aPos->second.eType = eLinkedByParamName;
+ aStrippedDetailFields.push_back( *pDetailFields );
+ }
+ else
+ {
+ // does the detail name denote a column?
+ if ( _rxColumns->hasByName( *pDetailFields ) )
+ {
+ ::rtl::OUString sNewParamName;
+ const ::rtl::OUString sFilterCondition = createFilterConditionFromColumnLink( *pMasterFields, *pDetailFields, sNewParamName );
+ OSL_PRECOND( sNewParamName.getLength(), "ParameterManager::classifyLinks: createFilterConditionFromColumnLink returned nonsense!" );
+
+ // remember meta information about this new parameter
+ ::std::pair< ParameterInformation::iterator, bool > aInsertionPos =
+ m_aParameterInformation.insert(
+ ParameterInformation::value_type( sNewParamName, ParameterMetaData( NULL ) )
+ );
+ OSL_ENSURE( aInsertionPos.second, "ParameterManager::classifyLinks: there already was a parameter with this name!" );
+ aInsertionPos.first->second.eType = eLinkedByColumnName;
+
+ // remember the filter component
+ _out_rAdditionalFilterComponents.push_back( sFilterCondition );
+
+ // remember the new "detail field" for this link
+ aStrippedDetailFields.push_back( sNewParamName );
+ bNeedExchangeLinks = true;
+ }
+ else
+ {
+ // the detail field neither denotes a column name, nor a parameter name
+ bValidLink = false;
+ bNeedExchangeLinks = true;
+ }
+ }
+
+ if ( bValidLink )
+ aStrippedMasterFields.push_back( *pMasterFields );
+ }
+ OSL_POSTCOND( aStrippedMasterFields.size() == aStrippedDetailFields.size(),
+ "ParameterManager::classifyLinks: inconsistency in new link pairs!" );
+
+ if ( bNeedExchangeLinks )
+ {
+ ::rtl::OUString *pFields = aStrippedMasterFields.empty() ? 0 : &aStrippedMasterFields[0];
+ m_aMasterFields = Sequence< ::rtl::OUString >( pFields, aStrippedMasterFields.size() );
+ pFields = aStrippedDetailFields.empty() ? 0 : &aStrippedDetailFields[0];
+ m_aDetailFields = Sequence< ::rtl::OUString >( pFields, aStrippedDetailFields.size() );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::analyzeFieldLinks: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return;
+
+ _rColumnsInLinkDetails = false;
+ try
+ {
+ // the links as determined by the properties
+ Reference< XPropertySet > xProp = m_xComponent;
+ OSL_ENSURE(xProp.is(),"Some already released my component!");
+ if ( xProp.is() )
+ {
+ xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MASTERFIELDS) ) >>= m_aMasterFields;
+ xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DETAILFIELDS) ) >>= m_aDetailFields;
+ }
+
+ {
+ // normalize to equal length
+ sal_Int32 nMasterLength = m_aMasterFields.getLength();
+ sal_Int32 nDetailLength = m_aDetailFields.getLength();
+
+ if ( nMasterLength > nDetailLength )
+ m_aMasterFields.realloc( nDetailLength );
+ else if ( nDetailLength > nMasterLength )
+ m_aDetailFields.realloc( nMasterLength );
+ }
+
+ Reference< XNameAccess > xColumns;
+ if ( !getColumns( xColumns, true ) )
+ // already asserted in getColumns
+ return;
+
+ Reference< XNameAccess > xParentColumns;
+ if ( !getParentColumns( xParentColumns, true ) )
+ return;
+
+ // classify the links - depending on what the detail fields in each link pair denotes
+ ::std::vector< ::rtl::OUString > aAdditionalFilterComponents;
+ classifyLinks( xParentColumns, xColumns, aAdditionalFilterComponents );
+
+ // did we find links where the detail field refers to a detail column (instead of a parameter name)?
+ if ( !aAdditionalFilterComponents.empty() )
+ {
+ const static ::rtl::OUString s_sAnd( RTL_CONSTASCII_USTRINGPARAM( " AND " ) );
+ // build a conjunction of all the filter components
+ ::rtl::OUStringBuffer sAdditionalFilter;
+ for ( ::std::vector< ::rtl::OUString >::const_iterator aComponent = aAdditionalFilterComponents.begin();
+ aComponent != aAdditionalFilterComponents.end();
+ ++aComponent
+ )
+ {
+ if ( sAdditionalFilter.getLength() )
+ sAdditionalFilter.append(s_sAnd);
+
+ sAdditionalFilter.appendAscii("( ",((sal_Int32)(sizeof("( ")-1)));
+ sAdditionalFilter.append(*aComponent);
+ sAdditionalFilter.appendAscii(" )",((sal_Int32)(sizeof(" )")-1)));
+ }
+
+ // now set this filter at the 's filter manager
+ _rFilterManager.setFilterComponent( FilterManager::fcLinkFilter, sAdditionalFilter.makeStringAndClear() );
+
+ _rColumnsInLinkDetails = true;
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::analyzeFieldLinks: caught an exception!" );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::createOuterParameters()
+ {
+ OSL_PRECOND( !m_pOuterParameters.is(), "ParameterManager::createOuterParameters: outer parameters not initialized!" );
+ OSL_PRECOND( m_xInnerParamUpdate.is(), "ParameterManager::createOuterParameters: no write access to the inner parameters!" );
+ if ( !m_xInnerParamUpdate.is() )
+ return;
+
+ m_pOuterParameters = new param::ParameterWrapperContainer;
+
+#if OSL_DEBUG_LEVEL > 0
+ sal_Int32 nSmallestIndexLinkedByColumnName = -1;
+ sal_Int32 nLargestIndexNotLinkedByColumnName = -1;
+#endif
+ ::rtl::OUString sName;
+ for ( ParameterInformation::iterator aParam = m_aParameterInformation.begin();
+ aParam != m_aParameterInformation.end();
+ ++aParam
+ )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ if ( aParam->second.aInnerIndexes.size() )
+ if ( aParam->second.eType == eLinkedByColumnName )
+ {
+ if ( nSmallestIndexLinkedByColumnName == -1 )
+ nSmallestIndexLinkedByColumnName = aParam->second.aInnerIndexes[ 0 ];
+ }
+ else
+ {
+ nLargestIndexNotLinkedByColumnName = aParam->second.aInnerIndexes[ aParam->second.aInnerIndexes.size() - 1 ];
+ }
+#endif
+ if ( aParam->second.eType != eFilledExternally )
+ continue;
+
+ // check which of the parameters have already been visited (e.g. filled via XParameters)
+ size_t nAlreadyVisited = 0;
+ for ( ::std::vector< sal_Int32 >::iterator aIndex = aParam->second.aInnerIndexes.begin();
+ aIndex != aParam->second.aInnerIndexes.end();
+ ++aIndex
+ )
+ {
+ if ( ( m_aParametersVisited.size() > (size_t)*aIndex ) && m_aParametersVisited[ *aIndex ] )
+ { // exclude this index
+ *aIndex = -1;
+ ++nAlreadyVisited;
+ }
+ }
+ if ( nAlreadyVisited == aParam->second.aInnerIndexes.size() )
+ continue;
+
+ // need a wrapper for this .... the "inner parameters" as supplied by a result set don't have a "Value"
+ // property, but the parameter listeners expect such a property. So we need an object "aggregating"
+ // xParam and supplying an additional property ("Value")
+ // (it's no real aggregation of course ...)
+ m_pOuterParameters->push_back( new param::ParameterWrapper( aParam->second.xComposerColumn, m_xInnerParamUpdate, aParam->second.aInnerIndexes ) );
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ OSL_ENSURE( ( nSmallestIndexLinkedByColumnName == -1 ) || ( nLargestIndexNotLinkedByColumnName == -1 ) ||
+ ( nSmallestIndexLinkedByColumnName > nLargestIndexNotLinkedByColumnName ),
+ "ParameterManager::createOuterParameters: inconsistency!" );
+
+ // for the master-detail links, where the detail field denoted a column name, we created an addtional ("artificial")
+ // filter, and *appended* it to all other (potentially) existing filters of the row set. This means that the indexes
+ // for the parameters resulting from the artifical filter should be larger than any other parameter index, and this
+ // is what the assertion checks.
+ // If the assertion fails, then we would need another handling for the "parameters visited" flags, since they're based
+ // on parameter indexes *without* the artificial filter (because this filter is not visible from the outside).
+#endif
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::updateParameterInfo( FilterManager& _rFilterManager )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::updateParameterInfo: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return;
+
+ clearAllParameterInformation();
+ cacheConnectionInfo();
+
+ // check whether the is based on a statement/query which requires parameters
+ Reference< XPropertySet > xProp = m_xComponent;
+ OSL_ENSURE(xProp.is(),"Some already released my component!");
+ if ( xProp.is() )
+ {
+ if ( !initializeComposerByComponent( xProp ) )
+ { // okay, nothing to do
+ m_bUpToDate = true;
+ return;
+ } // if ( !initializeComposerByComponent( m_xComponent ) )
+ }
+ OSL_POSTCOND( m_xInnerParamColumns.is(), "ParameterManager::updateParameterInfo: initializeComposerByComponent did nonsense (1)!" );
+
+ // collect all parameters which are defined by the "inner parameters"
+ collectInnerParameters( false );
+
+ // analyze the master-detail relationships
+ bool bColumnsInLinkDetails = false;
+ analyzeFieldLinks( _rFilterManager, bColumnsInLinkDetails );
+
+ if ( bColumnsInLinkDetails )
+ {
+ // okay, in this case, analyzeFieldLinks modified the "real" filter at the RowSet, to contain
+ // an additional restriction (which we created ourself)
+ // So we need to update all information about our inner parameter columns
+ Reference< XPropertySet > xDirectRowSetProps;
+ m_xAggregatedRowSet->queryAggregation( ::getCppuType( &xDirectRowSetProps ) ) >>= xDirectRowSetProps;
+ OSL_VERIFY( initializeComposerByComponent( xDirectRowSetProps ) );
+ collectInnerParameters( true );
+ }
+
+ if ( !m_nInnerCount )
+ { // no parameters at all
+ m_bUpToDate = true;
+ return;
+ }
+
+ // for what now remains as outer parameters, create the wrappers for the single
+ // parameter columns
+ createOuterParameters();
+
+ m_bUpToDate = true;
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::fillLinkedParameters( const Reference< XNameAccess >& _rxParentColumns )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::fillLinkedParameters: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return;
+ OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::fillLinkedParameters: no inner parameters found!" );
+ OSL_ENSURE ( _rxParentColumns.is(), "ParameterManager::fillLinkedParameters: invalid parent columns!" );
+
+ try
+ {
+ // the master and detail field( name)s of the
+ const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
+ const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
+
+ sal_Int32 nMasterLen = m_aMasterFields.getLength();
+ Any aParamType, aScale, aValue;
+
+ // loop through all master fields. For each of them, get the respective column from the
+ // parent , and forward it's current value as paramter value to the (inner) row set
+ for ( sal_Int32 i = 0; i < nMasterLen; ++i, ++pMasterFields, ++pDetailFields )
+ {
+ // does the name denote a valid column in the parent?
+ if ( !_rxParentColumns->hasByName( *pMasterFields ) )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::fillLinkedParameters: invalid master names should have been stripped long before!" );
+ continue;
+ }
+
+ // do we, for this name, know where to place the values?
+ ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
+ if ( ( aParamInfo == m_aParameterInformation.end() )
+ || ( aParamInfo->second.aInnerIndexes.empty() )
+ )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::fillLinkedParameters: nothing known about this detail field!" );
+ continue;
+ }
+
+ // the concrete master field
+ Reference< XPropertySet > xMasterField(_rxParentColumns->getByName( *pMasterFields ),UNO_QUERY);
+
+ // the positions where we have to fill in values for the current parameter name
+ for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
+ aPosition != aParamInfo->second.aInnerIndexes.end();
+ ++aPosition
+ )
+ {
+ // the concrete detail field
+ Reference< XPropertySet > xDetailField(m_xInnerParamColumns->getByIndex( *aPosition ),UNO_QUERY);
+ OSL_ENSURE( xDetailField.is(), "ParameterManager::fillLinkedParameters: invalid detail field!" );
+ if ( !xDetailField.is() )
+ continue;
+
+ // type and scale of the parameter field
+ sal_Int32 nParamType = DataType::VARCHAR;
+ OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE) ) >>= nParamType );
+
+ sal_Int32 nScale = 0;
+ if ( xDetailField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) )
+ OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) >>= nScale );
+
+ // transfer the param value
+ try
+ {
+ m_xInnerParamUpdate->setObjectWithInfo(
+ *aPosition + 1, // parameters are based at 1
+ xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ),
+ nParamType,
+ nScale
+ );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False,
+ ::rtl::OString( "ParameterManager::fillLinkedParameters: master-detail parameter number " )
+ += ::rtl::OString::valueOf( sal_Int32( *aPosition + 1 ) )
+ += ::rtl::OString( " could not be filled!" ) );
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::completeParameters( const Reference< XInteractionHandler >& _rxCompletionHandler, const Reference< XConnection > _rxConnection )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::completeParameters: not initialized, or already disposed!" );
+ OSL_ENSURE ( _rxCompletionHandler.is(), "ParameterManager::completeParameters: invalid interaction handler!" );
+
+ // two continuations (Ok and Cancel)
+ OInteractionAbort* pAbort = new OInteractionAbort;
+ OParameterContinuation* pParams = new OParameterContinuation;
+
+ // the request
+ ParametersRequest aRequest;
+ aRequest.Parameters = m_pOuterParameters.get();
+ aRequest.Connection = _rxConnection;
+ OInteractionRequest* pRequest = new OInteractionRequest( makeAny( aRequest ) );
+ Reference< XInteractionRequest > xRequest( pRequest );
+
+ // some knittings
+ pRequest->addContinuation( pAbort );
+ pRequest->addContinuation( pParams );
+
+ // execute the request
+ try
+ {
+ _rxCompletionHandler->handle( xRequest );
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::completeParameters: caught an exception while calling the handler!" );
+ }
+
+ if ( !pParams->wasSelected() )
+ // canceled by the user (i.e. (s)he canceled the dialog)
+ return false;
+
+ try
+ {
+ // transfer the values from the continuation object to the parameter columns
+ Sequence< PropertyValue > aFinalValues = pParams->getValues();
+ const PropertyValue* pFinalValues = aFinalValues.getConstArray();
+ for ( sal_Int32 i = 0; i < aFinalValues.getLength(); ++i, ++pFinalValues )
+ {
+ Reference< XPropertySet > xParamColumn(aRequest.Parameters->getByIndex( i ),UNO_QUERY);
+ if ( xParamColumn.is() )
+ {
+ #ifdef DBG_UTIL
+ ::rtl::OUString sName;
+ xParamColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
+ OSL_ENSURE( sName == pFinalValues->Name, "ParameterManager::completeParameters: inconsistent parameter names!" );
+ #endif
+ xParamColumn->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), pFinalValues->Value );
+ // the property sets are wrapper classes, translating the Value property into a call to
+ // the appropriate XParameters interface
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::completeParameters: caught an exception while propagating the values!" );
+ }
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies )
+ {
+ bool bCanceled = false;
+
+ sal_Int32 nParamsLeft = m_pOuterParameters->getParameters().size();
+ // TODO: shouldn't we subtract all the parameters which were already visited?
+ if ( nParamsLeft )
+ {
+ ::cppu::OInterfaceIteratorHelper aIter( m_aParameterListeners );
+ Reference< XPropertySet > xProp = m_xComponent;
+ OSL_ENSURE(xProp.is(),"Some already released my component!");
+ DatabaseParameterEvent aEvent( xProp.get(), m_pOuterParameters.get() );
+
+ _rClearForNotifies.clear();
+ while ( aIter.hasMoreElements() && !bCanceled )
+ bCanceled = !static_cast< XDatabaseParameterListener* >( aIter.next() )->approveParameter( aEvent );
+ _rClearForNotifies.reset();
+ }
+
+ return !bCanceled;
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::fillParameterValues( const Reference< XInteractionHandler >& _rxCompletionHandler, ::osl::ResettableMutexGuard& _rClearForNotifies )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::fillParameterValues: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return true;
+
+ if ( m_nInnerCount == 0 )
+ // no parameters at all
+ return true;
+
+ // fill the parameters from the master-detail relationship
+ Reference< XNameAccess > xParentColumns;
+ if ( getParentColumns( xParentColumns, false ) && xParentColumns->hasElements() && m_aMasterFields.getLength() )
+ fillLinkedParameters( xParentColumns );
+
+ // let the user (via the interaction handler) fill all remaining parameters
+ Reference< XConnection > xConnection;
+ getConnection( xConnection );
+
+ if ( _rxCompletionHandler.is() )
+ return completeParameters( _rxCompletionHandler, xConnection );
+
+ return consultParameterListeners( _rClearForNotifies );
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::getConnection( Reference< XConnection >& /* [out] */ _rxConnection )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::getConnection: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return false;
+
+ _rxConnection.clear();
+ try
+ {
+ Reference< XPropertySet > xProp = m_xComponent;
+ OSL_ENSURE(xProp.is(),"Some already released my component!");
+ if ( xProp.is() )
+ xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ACTIVE_CONNECTION) ) >>= _rxConnection;
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::getConnection: could not retrieve the connection of the !" );
+ }
+ return _rxConnection.is();
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::cacheConnectionInfo() SAL_THROW(( ))
+ {
+ try
+ {
+ Reference< XConnection > xConnection;
+ getConnection( xConnection );
+ Reference< XDatabaseMetaData > xMeta;
+ if ( xConnection.is() )
+ xMeta = xConnection->getMetaData();
+ if ( xMeta.is() )
+ {
+ m_sIdentifierQuoteString = xMeta->getIdentifierQuoteString();
+ m_sSpecialCharacters = xMeta->getExtraNameCharacters();
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::cacheConnectionInfo: caught an exception!" );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::getColumns( Reference< XNameAccess >& /* [out] */ _rxColumns, bool _bFromComposer ) SAL_THROW(( Exception ))
+ {
+ _rxColumns.clear();
+
+ Reference< XColumnsSupplier > xColumnSupp;
+ if ( _bFromComposer )
+ xColumnSupp = xColumnSupp.query( m_xComposer );
+ else
+ xColumnSupp.set( m_xComponent.get(),UNO_QUERY);
+ if ( xColumnSupp.is() )
+ _rxColumns = xColumnSupp->getColumns();
+ OSL_ENSURE( _rxColumns.is(), "ParameterManager::getColumns: could not retrieve the columns for the detail !" );
+
+ return _rxColumns.is();
+ }
+
+ //--------------------------------------------------------------------
+ bool ParameterManager::getParentColumns( Reference< XNameAccess >& /* [out] */ _out_rxParentColumns, bool _bFromComposer )
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::getParentColumns: not initialized, or already disposed!" );
+
+ _out_rxParentColumns.clear();
+ try
+ {
+ // get the parent of the component we're working for
+ Reference< XChild > xAsChild( m_xComponent.get(), UNO_QUERY_THROW );
+ Reference< XPropertySet > xParent( xAsChild->getParent(), UNO_QUERY );
+ if ( !xParent.is() )
+ return false;
+
+ // the columns supplier: either from a composer, or directly from the
+ Reference< XColumnsSupplier > xParentColSupp;
+ if ( _bFromComposer )
+ {
+ // re-create the parent composer all the time. Else, we'd have to bother with
+ // being a listener at its properties, its loaded state, and event the parent-relationship.
+ m_xParentComposer.reset(
+ getCurrentSettingsComposer( xParent, m_xORB ),
+ SharedQueryComposer::TakeOwnership
+ );
+ xParentColSupp = xParentColSupp.query( m_xParentComposer );
+ }
+ else
+ xParentColSupp = xParentColSupp.query( xParent );
+
+ // get the columns of the parent
+ if ( xParentColSupp.is() )
+ _out_rxParentColumns = xParentColSupp->getColumns();
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::getParentColumns: caught an exception!" );
+ }
+ return _out_rxParentColumns.is();
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::addParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
+ {
+ if ( _rxListener.is() )
+ m_aParameterListeners.addInterface( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::removeParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
+ {
+ m_aParameterListeners.removeInterface( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::resetParameterValues( ) SAL_THROW(())
+ {
+ OSL_PRECOND( isAlive(), "ParameterManager::resetParameterValues: not initialized, or already disposed!" );
+ if ( !isAlive() )
+ return;
+
+ if ( !m_nInnerCount )
+ // no parameters at all
+ return;
+
+ try
+ {
+ Reference< XNameAccess > xColumns;
+ if ( !getColumns( xColumns, false ) )
+ // already asserted in getColumns
+ return;
+
+ Reference< XNameAccess > xParentColumns;
+ if ( !getParentColumns( xParentColumns, false ) )
+ return;
+
+ // loop through all links pairs
+ const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
+ const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
+
+ Reference< XPropertySet > xMasterField;
+ Reference< XPropertySet > xDetailField;
+
+ // now really ....
+ const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
+ for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
+ {
+ if ( !xParentColumns->hasByName( *pMasterFields ) )
+ {
+ // if this name is unknown in the parent columns, then we don't have a source
+ // for copying the value to the detail columns
+ OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: this should have been stripped long before!" );
+ continue;
+ }
+
+ // for all inner parameters which are bound to the name as specified by the
+ // slave element of the link, propagate the value from the master column to this
+ // parameter column
+ ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
+ if ( ( aParamInfo == m_aParameterInformation.end() )
+ || ( aParamInfo->second.aInnerIndexes.empty() )
+ )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: nothing known about this detail field!" );
+ continue;
+ }
+
+ xParentColumns->getByName( *pMasterFields ) >>= xMasterField;
+ if ( !xMasterField.is() )
+ continue;
+
+ for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
+ aPosition != aParamInfo->second.aInnerIndexes.end();
+ ++aPosition
+ )
+ {
+ Reference< XPropertySet > xInnerParameter;
+ m_xInnerParamColumns->getByIndex( *aPosition ) >>= xInnerParameter;
+ if ( !xInnerParameter.is() )
+ continue;
+
+ ::rtl::OUString sParamColumnRealName;
+ xInnerParameter->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME) ) >>= sParamColumnRealName;
+ if ( xColumns->hasByName( sParamColumnRealName ) )
+ { // our own columns have a column which's name equals the real name of the param column
+ // -> transfer the value property
+ xColumns->getByName( sParamColumnRealName ) >>= xDetailField;
+ if ( xDetailField.is() )
+ xDetailField->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ) );
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: caught an exception!" );
+ }
+
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::externalParameterVisited( sal_Int32 _nIndex )
+ {
+ if ( m_aParametersVisited.size() < (size_t)_nIndex )
+ {
+ m_aParametersVisited.reserve( _nIndex );
+ for ( sal_Int32 i = m_aParametersVisited.size(); i < _nIndex; ++i )
+ m_aParametersVisited.push_back( false );
+ }
+ m_aParametersVisited[ _nIndex - 1 ] = true;
+ }
+
+#define VISIT_PARAMETER( method ) \
+ ::osl::MutexGuard aGuard( m_rMutex ); \
+ OSL_ENSURE( m_xInnerParamUpdate.is(), "ParameterManager::XParameters::setXXX: no XParameters access to the RowSet!" ); \
+ if ( !m_xInnerParamUpdate.is() ) \
+ return; \
+ m_xInnerParamUpdate->method; \
+ externalParameterVisited( _nIndex ) \
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setNull( sal_Int32 _nIndex, sal_Int32 sqlType )
+ {
+ VISIT_PARAMETER( setNull( _nIndex, sqlType ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setObjectNull( sal_Int32 _nIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName )
+ {
+ VISIT_PARAMETER( setObjectNull( _nIndex, sqlType, typeName ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setBoolean( sal_Int32 _nIndex, sal_Bool x )
+ {
+ VISIT_PARAMETER( setBoolean( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setByte( sal_Int32 _nIndex, sal_Int8 x )
+ {
+ VISIT_PARAMETER( setByte( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setShort( sal_Int32 _nIndex, sal_Int16 x )
+ {
+ VISIT_PARAMETER( setShort( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setInt( sal_Int32 _nIndex, sal_Int32 x )
+ {
+ VISIT_PARAMETER( setInt( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setLong( sal_Int32 _nIndex, sal_Int64 x )
+ {
+ VISIT_PARAMETER( setLong( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setFloat( sal_Int32 _nIndex, float x )
+ {
+ VISIT_PARAMETER( setFloat( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setDouble( sal_Int32 _nIndex, double x )
+ {
+ VISIT_PARAMETER( setDouble( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setString( sal_Int32 _nIndex, const ::rtl::OUString& x )
+ {
+ VISIT_PARAMETER( setString( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setBytes( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x )
+ {
+ VISIT_PARAMETER( setBytes( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setDate( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x )
+ {
+ VISIT_PARAMETER( setDate( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setTime( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x )
+ {
+ VISIT_PARAMETER( setTime( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setTimestamp( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x )
+ {
+ VISIT_PARAMETER( setTimestamp( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setBinaryStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
+ {
+ VISIT_PARAMETER( setBinaryStream( _nIndex, x, length ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setCharacterStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
+ {
+ VISIT_PARAMETER( setCharacterStream( _nIndex, x, length ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setObject( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x )
+ {
+ VISIT_PARAMETER( setObject( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setObjectWithInfo( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale )
+ {
+ VISIT_PARAMETER( setObjectWithInfo( _nIndex, x, targetSqlType, scale ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setRef( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x )
+ {
+ VISIT_PARAMETER( setRef( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setBlob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x )
+ {
+ VISIT_PARAMETER( setBlob( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setClob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x )
+ {
+ VISIT_PARAMETER( setClob( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::setArray( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x )
+ {
+ VISIT_PARAMETER( setArray( _nIndex, x ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterManager::clearParameters( )
+ {
+ if ( m_xInnerParamUpdate.is() )
+ m_xInnerParamUpdate->clearParameters( );
+ }
+
+ //====================================================================
+ //= OParameterContinuation
+ //====================================================================
+ //--------------------------------------------------------------------
+ void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw( RuntimeException )
+ {
+ m_aValues = _rValues;
+ }
+
+//........................................................................
+} // namespace frm
+//........................................................................
+
diff --git a/connectivity/source/commontools/paramwrapper.cxx b/connectivity/source/commontools/paramwrapper.cxx
new file mode 100644
index 000000000000..cef4508e3b30
--- /dev/null
+++ b/connectivity/source/commontools/paramwrapper.cxx
@@ -0,0 +1,364 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/paramwrapper.hxx>
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+#include <comphelper/enumhelper.hxx>
+
+#define PROPERTY_ID_VALUE 1000
+
+//........................................................................
+namespace dbtools
+{
+namespace param
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::sdbc::XParameters;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::XWeak;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::beans::XFastPropertySet;
+ using ::com::sun::star::beans::XMultiPropertySet;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::beans::Property;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::sdbc::SQLException;
+ using ::com::sun::star::lang::WrappedTargetException;
+ using ::com::sun::star::lang::IndexOutOfBoundsException;
+ using ::com::sun::star::container::XEnumeration;
+ using ::com::sun::star::sdb::XSingleSelectQueryAnalyzer;
+ using ::com::sun::star::sdb::XParametersSupplier;
+ using ::com::sun::star::lang::DisposedException;
+ /** === end UNO using === **/
+ namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
+ namespace DataType = ::com::sun::star::sdbc::DataType;
+
+ //====================================================================
+ //= ParameterWrapper
+ //====================================================================
+ //--------------------------------------------------------------------
+ ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn )
+ :PropertyBase( m_aBHelper )
+ ,m_xDelegator( _rxColumn )
+ {
+ if ( m_xDelegator.is() )
+ m_xDelegatorPSI = m_xDelegator->getPropertySetInfo();
+ if ( !m_xDelegatorPSI.is() )
+ throw RuntimeException();
+ }
+
+ //--------------------------------------------------------------------
+ ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn,
+ const Reference< XParameters >& _rxAllParameters, const ::std::vector< sal_Int32 >& _rIndexes )
+ :PropertyBase( m_aBHelper )
+ ,m_aIndexes( _rIndexes )
+ ,m_xDelegator( _rxColumn )
+ ,m_xValueDestination( _rxAllParameters )
+ {
+ if ( m_xDelegator.is() )
+ m_xDelegatorPSI = m_xDelegator->getPropertySetInfo();
+ if ( !m_xDelegatorPSI.is() )
+ throw RuntimeException();
+
+ OSL_ENSURE( !m_aIndexes.empty(), "ParameterWrapper::ParameterWrapper: sure about the indexes?" );
+ }
+
+ //--------------------------------------------------------------------
+ ParameterWrapper::~ParameterWrapper()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_FORWARD_XINTERFACE2( ParameterWrapper, UnoBase, PropertyBase )
+
+ //--------------------------------------------------------------------
+ Sequence< Type > SAL_CALL ParameterWrapper::getTypes( ) throw(RuntimeException)
+ {
+ Sequence< Type > aTypes( 4 );
+ aTypes[ 1 ] = ::getCppuType( static_cast< Reference< XWeak >* >( NULL ) );
+ aTypes[ 1 ] = ::getCppuType( static_cast< Reference< XPropertySet >* >( NULL ) );
+ aTypes[ 2 ] = ::getCppuType( static_cast< Reference< XFastPropertySet >* >( NULL ) );
+ aTypes[ 3 ] = ::getCppuType( static_cast< Reference< XMultiPropertySet >* >( NULL ) );
+ return aTypes;
+ }
+
+ //--------------------------------------------------------------------
+ IMPLEMENT_GET_IMPLEMENTATION_ID( ParameterWrapper )
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString ParameterWrapper::impl_getPseudoAggregatePropertyName( sal_Int32 _nHandle ) const
+ {
+ Reference< XPropertySetInfo > xInfo = const_cast<ParameterWrapper*>( this )->getPropertySetInfo();
+ Sequence< Property > aProperties = xInfo->getProperties();
+ const Property* pProperties = aProperties.getConstArray();
+ for ( sal_Int32 i = 0; i < aProperties.getLength(); ++i, ++pProperties )
+ {
+ if ( pProperties->Handle == _nHandle )
+ return pProperties->Name;
+ }
+
+ OSL_ENSURE( sal_False, "ParameterWrapper::impl_getPseudoAggregatePropertyName: invalid argument!" );
+ return ::rtl::OUString();
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XPropertySetInfo > ParameterWrapper::getPropertySetInfo() throw( RuntimeException )
+ {
+ return createPropertySetInfo( getInfoHelper() );
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper& ParameterWrapper::getInfoHelper()
+ {
+ if ( !m_pInfoHelper.get() )
+ {
+ Sequence< Property > aProperties;
+ try
+ {
+ aProperties = m_xDelegatorPSI->getProperties();
+ sal_Int32 nProperties( aProperties.getLength() );
+ aProperties.realloc( nProperties + 1 );
+ aProperties[ nProperties ] = Property(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ) ),
+ PROPERTY_ID_VALUE,
+ ::cppu::UnoType< Any >::get(),
+ PropertyAttribute::TRANSIENT | PropertyAttribute::MAYBEVOID
+ );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ m_pInfoHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties, false ) );
+ }
+ return *m_pInfoHelper;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool ParameterWrapper::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw( IllegalArgumentException )
+ {
+ OSL_ENSURE( PROPERTY_ID_VALUE == nHandle, "ParameterWrapper::convertFastPropertyValue: the only non-readonly prop should be our PROPERTY_VALUE!" );
+ (void)nHandle;
+
+ // we're lazy here ...
+ rOldValue = m_aValue.makeAny();
+ rConvertedValue = rValue;
+ return sal_True; // assume "modified" ...
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception )
+ {
+ if ( nHandle == PROPERTY_ID_VALUE )
+ {
+ try
+ {
+ // TODO : aParamType & nScale can be obtained within the constructor ....
+ sal_Int32 nParamType = DataType::VARCHAR;
+ OSL_VERIFY( m_xDelegator->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nParamType );
+
+ sal_Int32 nScale = 0;
+ if ( m_xDelegatorPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) )
+ OSL_VERIFY( m_xDelegator->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) >>= nScale );
+
+ if ( m_xValueDestination.is() )
+ {
+ for ( ::std::vector< sal_Int32 >::iterator aIter = m_aIndexes.begin(); aIter != m_aIndexes.end(); ++aIter )
+ {
+ m_xValueDestination->setObjectWithInfo( *aIter + 1, rValue, nParamType, nScale );
+ // (the index of the parameters is one-based)
+ }
+ }
+
+ m_aValue = rValue;
+ }
+ catch( SQLException& e )
+ {
+ WrappedTargetException aExceptionWrapper;
+ aExceptionWrapper.Context = e.Context;
+ aExceptionWrapper.Message = e.Message;
+ aExceptionWrapper.TargetException <<= e;
+ throw WrappedTargetException( aExceptionWrapper );
+ }
+ }
+ else
+ {
+ ::rtl::OUString aName = impl_getPseudoAggregatePropertyName( nHandle );
+ m_xDelegator->setPropertyValue( aName, rValue );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
+ {
+ if ( nHandle == PROPERTY_ID_VALUE )
+ {
+ rValue = m_aValue.makeAny();
+ }
+ else
+ {
+ ::rtl::OUString aName = impl_getPseudoAggregatePropertyName( nHandle );
+ rValue = m_xDelegator->getPropertyValue( aName );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ParameterWrapper::dispose()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_aValue.setNull();
+ m_aIndexes.resize(0);
+ m_xDelegator.clear();
+ m_xDelegatorPSI.clear();
+ m_xValueDestination.clear();
+
+ m_aBHelper.bDisposed = sal_True;
+ }
+
+ //====================================================================
+ //= ParameterWrapperContainer
+ //====================================================================
+ //--------------------------------------------------------------------
+ ParameterWrapperContainer::ParameterWrapperContainer()
+ :ParameterWrapperContainer_Base( m_aMutex )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ParameterWrapperContainer::ParameterWrapperContainer( const Reference< XSingleSelectQueryAnalyzer >& _rxComposer )
+ :ParameterWrapperContainer_Base( m_aMutex )
+ {
+ Reference< XParametersSupplier > xSuppParams( _rxComposer, UNO_QUERY_THROW );
+ Reference< XIndexAccess > xParameters( xSuppParams->getParameters(), UNO_QUERY_THROW );
+ sal_Int32 nParamCount( xParameters->getCount() );
+ m_aParameters.reserve( nParamCount );
+ for ( sal_Int32 i=0; i<nParamCount; ++i )
+ {
+ m_aParameters.push_back( new ParameterWrapper( Reference< XPropertySet >( xParameters->getByIndex( i ), UNO_QUERY_THROW ) ) );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ ParameterWrapperContainer::~ParameterWrapperContainer()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ Type SAL_CALL ParameterWrapperContainer::getElementType() throw( RuntimeException )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+ return ::getCppuType( static_cast< Reference< XPropertySet >* >( NULL ) );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SAL_CALL ParameterWrapperContainer::hasElements() throw( RuntimeException )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+ return !m_aParameters.empty();
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 SAL_CALL ParameterWrapperContainer::getCount() throw( RuntimeException )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+ return m_aParameters.size();
+ }
+
+ //--------------------------------------------------------------------
+ Any SAL_CALL ParameterWrapperContainer::getByIndex( sal_Int32 _nIndex ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+
+ if ( ( _nIndex < 0 ) || ( _nIndex >= (sal_Int32)m_aParameters.size() ) )
+ throw IndexOutOfBoundsException();
+
+ return makeAny( Reference< XPropertySet >( m_aParameters[ _nIndex ].get() ) );
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XEnumeration > ParameterWrapperContainer::createEnumeration() throw( RuntimeException )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+
+ return new ::comphelper::OEnumerationByIndex( static_cast< XIndexAccess* >( this ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ParameterWrapperContainer::impl_checkDisposed_throw()
+ {
+ if ( rBHelper.bDisposed )
+ throw DisposedException( ::rtl::OUString(), *this );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ParameterWrapperContainer::disposing()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+
+ for ( Parameters::const_iterator param = m_aParameters.begin();
+ param != m_aParameters.end();
+ ++param
+ )
+ {
+ (*param)->dispose();
+ }
+
+ Parameters aEmpty;
+ m_aParameters.swap( aEmpty );
+ }
+
+//........................................................................
+} } // namespace dbtools::param
+//........................................................................
+
diff --git a/connectivity/source/commontools/predicateinput.cxx b/connectivity/source/commontools/predicateinput.cxx
new file mode 100644
index 000000000000..8ffebb0cfbda
--- /dev/null
+++ b/connectivity/source/commontools/predicateinput.cxx
@@ -0,0 +1,391 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/predicateinput.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <osl/diagnose.h>
+#include <connectivity/sqlnode.hxx>
+#include <comphelper/numbers.hxx>
+
+//.........................................................................
+namespace dbtools
+{
+//.........................................................................
+
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::util::XNumberFormatsSupplier;
+ using ::com::sun::star::util::XNumberFormatter;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::lang::Locale;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::i18n::XLocaleData;
+ using ::com::sun::star::i18n::LocaleDataItem;
+
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::connectivity;
+
+ using ::connectivity::OSQLParseNode;
+
+ #define Reference ::com::sun::star::uno::Reference
+
+ //=====================================================================
+ //---------------------------------------------------------------------
+ static sal_Unicode lcl_getSeparatorChar( const ::rtl::OUString& _rSeparator, sal_Unicode _nFallback )
+ {
+ OSL_ENSURE( 0 < _rSeparator.getLength(), "::lcl_getSeparatorChar: invalid separator string!" );
+
+ sal_Unicode nReturn( _nFallback );
+ if ( _rSeparator.getLength() )
+ nReturn = static_cast< sal_Char >( _rSeparator.getStr()[0] );
+ return nReturn;
+ }
+
+ //=====================================================================
+ //= OPredicateInputController
+ //=====================================================================
+ //---------------------------------------------------------------------
+ sal_Bool OPredicateInputController::getSeparatorChars( const Locale& _rLocale, sal_Unicode& _rDecSep, sal_Unicode& _rThdSep ) const
+ {
+ _rDecSep = '.';
+ _rThdSep = ',';
+ try
+ {
+ LocaleDataItem aLocaleData;
+ if ( m_xLocaleData.is() )
+ {
+ aLocaleData = m_xLocaleData->getLocaleItem( _rLocale );
+ _rDecSep = lcl_getSeparatorChar( aLocaleData.decimalSeparator, _rDecSep );
+ _rThdSep = lcl_getSeparatorChar( aLocaleData.decimalSeparator, _rThdSep );
+ return sal_True;
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OPredicateInputController::getSeparatorChars: caught an exception!" );
+ }
+ return sal_False;
+ }
+
+ //---------------------------------------------------------------------
+ OPredicateInputController::OPredicateInputController(
+ const Reference< XMultiServiceFactory >& _rxORB, const Reference< XConnection >& _rxConnection, const IParseContext* _pParseContext )
+ :m_xORB( _rxORB )
+ ,m_xConnection( _rxConnection )
+ ,m_aParser( m_xORB, _pParseContext )
+ {
+ try
+ {
+ // create a number formatter / number formats supplier pair
+ OSL_ENSURE( m_xORB.is(), "OPredicateInputController::OPredicateInputController: need a service factory!" );
+ if ( m_xORB.is() )
+ {
+ m_xFormatter = Reference< XNumberFormatter >( m_xORB->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" ) ) ),
+ UNO_QUERY
+ );
+ }
+
+ Reference< XNumberFormatsSupplier > xNumberFormats = ::dbtools::getNumberFormats( m_xConnection, sal_True );
+ if ( !xNumberFormats.is() )
+ ::comphelper::disposeComponent( m_xFormatter );
+ else if ( m_xFormatter.is() )
+ m_xFormatter->attachNumberFormatsSupplier( xNumberFormats );
+
+ // create the locale data
+ if ( m_xORB.is() )
+ {
+ m_xLocaleData = m_xLocaleData.query( m_xORB->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.LocaleData" ) ) )
+ );
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OPredicateInputController::OPredicateInputController: caught an exception!" );
+ }
+ }
+
+ //---------------------------------------------------------------------
+ OSQLParseNode* OPredicateInputController::implPredicateTree(::rtl::OUString& _rErrorMessage, const ::rtl::OUString& _rStatement, const Reference< XPropertySet > & _rxField) const
+ {
+ OSQLParseNode* pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, _rStatement, m_xFormatter, _rxField );
+ if ( !pReturn )
+ { // is it a text field ?
+ sal_Int32 nType = DataType::OTHER;
+ _rxField->getPropertyValue( ::rtl::OUString::createFromAscii( "Type" ) ) >>= nType;
+
+ if ( ( DataType::CHAR == nType )
+ || ( DataType::VARCHAR == nType )
+ || ( DataType::LONGVARCHAR == nType )
+ || ( DataType::CLOB == nType )
+ )
+ { // yes -> force a quoted text and try again
+ ::rtl::OUString sQuoted( _rStatement );
+ if ( sQuoted.getLength()
+ && ( (sQuoted.getStr()[0] != '\'')
+ || (sQuoted.getStr()[ sQuoted.getLength() - 1 ] != '\'' )
+ )
+ )
+ {
+ static const ::rtl::OUString sSingleQuote( RTL_CONSTASCII_USTRINGPARAM( "'" ) );
+ static const ::rtl::OUString sDoubleQuote( RTL_CONSTASCII_USTRINGPARAM( "''" ) );
+
+ sal_Int32 nIndex = -1;
+ sal_Int32 nTemp = 0;
+ while ( -1 != ( nIndex = sQuoted.indexOf( '\'',nTemp ) ) )
+ {
+ sQuoted = sQuoted.replaceAt( nIndex, 1, sDoubleQuote );
+ nTemp = nIndex+2;
+ }
+
+ ::rtl::OUString sTemp( sSingleQuote );
+ ( sTemp += sQuoted ) += sSingleQuote;
+ sQuoted = sTemp;
+ }
+ pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sQuoted, m_xFormatter, _rxField );
+ }
+
+ // one more fallback: for numeric fields, and value strings containing a decimal/thousands separator
+ // problem which is to be solved with this:
+ // * a system locale "german"
+ // * a column formatted with an english number format
+ // => the output is german (as we use the system locale for this), i.e. "3,4"
+ // => the input does not recognize the german text, as predicateTree uses the number format
+ // of the column to determine the main locale - the locale on the context is only a fallback
+ if ( ( DataType::FLOAT == nType )
+ || ( DataType::REAL == nType )
+ || ( DataType::DOUBLE == nType )
+ || ( DataType::NUMERIC == nType )
+ || ( DataType::DECIMAL == nType )
+ )
+ {
+ const IParseContext& rParseContext = m_aParser.getContext();
+ // get the separators for the locale of our parse context
+ sal_Unicode nCtxDecSep;
+ sal_Unicode nCtxThdSep;
+ getSeparatorChars( rParseContext.getPreferredLocale(), nCtxDecSep, nCtxThdSep );
+
+ // determine the locale of the column we're building a predicate string for
+ sal_Unicode nFmtDecSep( nCtxDecSep );
+ sal_Unicode nFmtThdSep( nCtxThdSep );
+ try
+ {
+ Reference< XPropertySetInfo > xPSI( _rxField->getPropertySetInfo() );
+ if ( xPSI.is() && xPSI->hasPropertyByName( ::rtl::OUString::createFromAscii( "FormatKey" ) ) )
+ {
+ sal_Int32 nFormatKey = 0;
+ _rxField->getPropertyValue( ::rtl::OUString::createFromAscii( "FormatKey" ) ) >>= nFormatKey;
+ if ( nFormatKey && m_xFormatter.is() )
+ {
+ Locale aFormatLocale;
+ ::comphelper::getNumberFormatProperty(
+ m_xFormatter,
+ nFormatKey,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Locale" ) )
+ ) >>= aFormatLocale;
+
+ // valid locale
+ if ( aFormatLocale.Language.getLength() )
+ {
+ getSeparatorChars( aFormatLocale, nFmtDecSep, nCtxThdSep );
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ OSL_ENSURE( sal_False, "OPredicateInputController::implPredicateTree: caught an exception while dealing with the formats!" );
+ }
+
+ sal_Bool bDecDiffers = ( nCtxDecSep != nFmtDecSep );
+ sal_Bool bFmtDiffers = ( nCtxThdSep != nFmtThdSep );
+ if ( bDecDiffers || bFmtDiffers )
+ { // okay, at least one differs
+ // "translate" the value into the "format locale"
+ ::rtl::OUString sTranslated( _rStatement );
+ const sal_Unicode nIntermediate( '_' );
+ sTranslated = sTranslated.replace( nCtxDecSep, nIntermediate );
+ sTranslated = sTranslated.replace( nCtxThdSep, nFmtThdSep );
+ sTranslated = sTranslated.replace( nIntermediate, nFmtDecSep );
+
+ pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sTranslated, m_xFormatter, _rxField );
+ }
+ }
+ }
+ return pReturn;
+ }
+
+ //---------------------------------------------------------------------
+ sal_Bool OPredicateInputController::normalizePredicateString(
+ ::rtl::OUString& _rPredicateValue, const Reference< XPropertySet > & _rxField, ::rtl::OUString* _pErrorMessage ) const
+ {
+ OSL_ENSURE( m_xConnection.is() && m_xFormatter.is() && _rxField.is(),
+ "OPredicateInputController::normalizePredicateString: invalid state or params!" );
+
+ sal_Bool bSuccess = sal_False;
+ if ( m_xConnection.is() && m_xFormatter.is() && _rxField.is() )
+ {
+ // parse the string
+ ::rtl::OUString sError;
+ ::rtl::OUString sTransformedText( _rPredicateValue );
+ OSQLParseNode* pParseNode = implPredicateTree( sError, sTransformedText, _rxField );
+ if ( _pErrorMessage ) *_pErrorMessage = sError;
+
+ if ( pParseNode )
+ {
+ const IParseContext& rParseContext = m_aParser.getContext();
+ sal_Unicode nDecSeparator, nThousandSeparator;
+ getSeparatorChars( rParseContext.getPreferredLocale(), nDecSeparator, nThousandSeparator );
+
+ // translate it back into a string
+ sTransformedText = ::rtl::OUString();
+ pParseNode->parseNodeToPredicateStr(
+ sTransformedText, m_xConnection, m_xFormatter, _rxField,
+ rParseContext.getPreferredLocale(), (sal_Char)nDecSeparator, &rParseContext
+ );
+ _rPredicateValue = sTransformedText;
+ delete pParseNode;
+
+ bSuccess = sal_True;
+ }
+ }
+
+ return bSuccess;
+ }
+
+ //---------------------------------------------------------------------
+ ::rtl::OUString OPredicateInputController::getPredicateValue(
+ const ::rtl::OUString& _rPredicateValue, const Reference< XPropertySet > & _rxField,
+ sal_Bool _bForStatementUse, ::rtl::OUString* _pErrorMessage ) const
+ {
+ OSL_ENSURE( _rxField.is(), "OPredicateInputController::getPredicateValue: invalid params!" );
+ ::rtl::OUString sReturn;
+ if ( _rxField.is() )
+ {
+ ::rtl::OUString sValue( _rPredicateValue );
+
+ // a little problem : if the field is a text field, the normalizePredicateString added two
+ // '-characters to the text. If we would give this to predicateTree this would add
+ // two additional '-characters which we don't want. So check the field format.
+ // FS - 06.01.00 - 71532
+ sal_Bool bValidQuotedText = ( sValue.getLength() >= 2 )
+ && ( sValue.getStr()[0] == '\'' )
+ && ( sValue.getStr()[ sValue.getLength() - 1 ] == '\'' );
+ // again : as normalizePredicateString always did a conversion on the value text,
+ // bValidQuotedText == sal_True implies that we have a text field, as no other field
+ // values will be formatted with the quote characters
+ if ( bValidQuotedText )
+ {
+ sValue = sValue.copy( 1, sValue.getLength() - 2 );
+ static const ::rtl::OUString sSingleQuote( RTL_CONSTASCII_USTRINGPARAM( "'" ) );
+ static const ::rtl::OUString sDoubleQuote( RTL_CONSTASCII_USTRINGPARAM( "''" ) );
+
+ sal_Int32 nIndex = -1;
+ sal_Int32 nTemp = 0;
+ while ( -1 != ( nIndex = sValue.indexOf( sDoubleQuote,nTemp ) ) )
+ {
+ sValue = sValue.replaceAt( nIndex, 2, sSingleQuote );
+ nTemp = nIndex+2;
+ }
+ }
+
+ // The following is mostly stolen from the former implementation in the parameter dialog
+ // (dbaccess/source/ui/dlg/paramdialog.cxx). I do not fully understand this .....
+
+ ::rtl::OUString sError;
+ OSQLParseNode* pParseNode = implPredicateTree( sError, sValue, _rxField );
+ if ( _pErrorMessage ) *_pErrorMessage = sError;
+
+ if ( pParseNode )
+ {
+ OSQLParseNode* pOdbcSpec = pParseNode->getByRule( OSQLParseNode::odbc_fct_spec );
+ if ( pOdbcSpec )
+ {
+ if ( !_bForStatementUse )
+ {
+ if ( ( pOdbcSpec->count() >= 2 )
+ && ( SQL_NODE_STRING == pOdbcSpec->getChild(1)->getNodeType() )
+ )
+ {
+
+ sReturn = pOdbcSpec->getChild(1)->getTokenValue();
+ }
+ else
+ OSL_ENSURE( sal_False, "OPredicateInputController::getPredicateValue: unknown/invalid structure (odbc + param use)!" );
+ }
+ else
+ {
+ OSQLParseNode* pFuncSpecParent = pOdbcSpec->getParent();
+ OSL_ENSURE( pFuncSpecParent, "OPredicateInputController::getPredicateValue: an ODBC func spec node without parent?" );
+ if ( pFuncSpecParent )
+ pFuncSpecParent->parseNodeToStr(
+ sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True
+ );
+ }
+ }
+ else
+ {
+ if ( pParseNode->count() >= 3 )
+ {
+ OSQLParseNode* pValueNode = pParseNode->getChild(2);
+ OSL_ENSURE( pValueNode, "OPredicateInputController::getPredicateValue: invalid node child!" );
+ if ( !_bForStatementUse )
+ {
+ if ( SQL_NODE_STRING == pValueNode->getNodeType() )
+ sReturn = pValueNode->getTokenValue();
+ else
+ pValueNode->parseNodeToStr(
+ sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True
+ );
+ }
+ else
+ pValueNode->parseNodeToStr(
+ sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True
+ );
+ }
+ else
+ OSL_ENSURE( sal_False, "OPredicateInputController::getPredicateValue: unknown/invalid structure (noodbc)!" );
+ }
+
+ delete pParseNode;
+ }
+ }
+
+ return sReturn;
+ }
+//.........................................................................
+} // namespace dbtools
+//.........................................................................
+
+
diff --git a/connectivity/source/commontools/propertyids.cxx b/connectivity/source/commontools/propertyids.cxx
new file mode 100644
index 000000000000..b6bae373a7db
--- /dev/null
+++ b/connectivity/source/commontools/propertyids.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include "propertyids.hxx"
+
+namespace dbtools
+{
+ const sal_Char* getPROPERTY_QUERYTIMEOUT() { return "QueryTimeOut"; }
+ const sal_Char* getPROPERTY_MAXFIELDSIZE() { return "MaxFieldSize"; }
+ const sal_Char* getPROPERTY_MAXROWS() { return "MaxRows"; }
+ const sal_Char* getPROPERTY_CURSORNAME() { return "CursorName"; }
+ const sal_Char* getPROPERTY_RESULTSETCONCURRENCY() { return "ResultSetConcurrency"; }
+ const sal_Char* getPROPERTY_RESULTSETTYPE() { return "ResultSetType"; }
+ const sal_Char* getPROPERTY_FETCHDIRECTION() { return "FetchDirection"; }
+ const sal_Char* getPROPERTY_FETCHSIZE() { return "FetchSize"; }
+ const sal_Char* getPROPERTY_ESCAPEPROCESSING() { return "EscapeProcessing"; }
+ const sal_Char* getPROPERTY_USEBOOKMARKS() { return "UseBookmarks"; }
+
+ const sal_Char* getPROPERTY_NAME() { return "Name"; }
+ const sal_Char* getPROPERTY_TYPE() { return "Type"; }
+ const sal_Char* getPROPERTY_TYPENAME() { return "TypeName"; }
+ const sal_Char* getPROPERTY_PRECISION() { return "Precision"; }
+ const sal_Char* getPROPERTY_SCALE() { return "Scale"; }
+ const sal_Char* getPROPERTY_ISNULLABLE() { return "IsNullable"; }
+ const sal_Char* getPROPERTY_ISAUTOINCREMENT() { return "IsAutoIncrement"; }
+ const sal_Char* getPROPERTY_ISROWVERSION() { return "IsRowVersion"; }
+ const sal_Char* getPROPERTY_DESCRIPTION() { return "Description"; }
+ const sal_Char* getPROPERTY_DEFAULTVALUE() { return "DefaultValue"; }
+
+ const sal_Char* getPROPERTY_REFERENCEDTABLE() { return "ReferencedTable"; }
+ const sal_Char* getPROPERTY_UPDATERULE() { return "UpdateRule"; }
+ const sal_Char* getPROPERTY_DELETERULE() { return "DeleteRule"; }
+ const sal_Char* getPROPERTY_CATALOG() { return "Catalog"; }
+ const sal_Char* getPROPERTY_ISUNIQUE() { return "IsUnique"; }
+ const sal_Char* getPROPERTY_ISPRIMARYKEYINDEX() { return "IsPrimaryKeyIndex"; }
+ const sal_Char* getPROPERTY_ISCLUSTERED() { return "IsClustered"; }
+ const sal_Char* getPROPERTY_ISASCENDING() { return "IsAscending"; }
+ const sal_Char* getPROPERTY_SCHEMANAME() { return "SchemaName"; }
+ const sal_Char* getPROPERTY_CATALOGNAME() { return "CatalogName"; }
+ const sal_Char* getPROPERTY_COMMAND() { return "Command"; }
+ const sal_Char* getPROPERTY_CHECKOPTION() { return "CheckOption"; }
+ const sal_Char* getPROPERTY_PASSWORD() { return "Password"; }
+ const sal_Char* getPROPERTY_RELATEDCOLUMN() { return "RelatedColumn"; }
+
+ const sal_Char* getPROPERTY_FUNCTION() { return "Function"; }
+ const sal_Char* getPROPERTY_AGGREGATEFUNCTION() { return "AggregateFunction"; }
+ const sal_Char* getPROPERTY_TABLENAME() { return "TableName"; }
+ const sal_Char* getPROPERTY_REALNAME() { return "RealName"; }
+ const sal_Char* getPROPERTY_DBASEPRECISIONCHANGED() { return "DbasePrecisionChanged"; }
+ const sal_Char* getPROPERTY_ISCURRENCY() { return "IsCurrency"; }
+ const sal_Char* getPROPERTY_ISBOOKMARKABLE() { return "IsBookmarkable"; }
+
+ const sal_Char* getPROPERTY_FORMATKEY() { return "FormatKey"; }
+ const sal_Char* getPROPERTY_LOCALE() { return "Locale"; }
+
+ const sal_Char* getPROPERTY_AUTOINCREMENTCREATION() { return "AutoIncrementCreation"; }
+ const sal_Char* getPROPERTY_PRIVILEGES() { return "Privileges"; }
+ const sal_Char* getPROPERTY_ID_HAVINGCLAUSE() { return "HavingClause"; }
+ const sal_Char* getPROPERTY_ID_ISSIGNED() { return "IsSigned"; }
+ const sal_Char* getPROPERTY_ID_ISSEARCHABLE() { return "IsSearchable"; }
+
+ const sal_Char* getPROPERTY_ID_APPLYFILTER() { return "ApplyFilter"; }
+ const sal_Char* getPROPERTY_ID_FILTER() { return "Filter"; }
+ const sal_Char* getPROPERTY_ID_MASTERFIELDS() { return "MasterFields"; }
+ const sal_Char* getPROPERTY_ID_DETAILFIELDS() { return "DetailFields"; }
+ const sal_Char* getPROPERTY_ID_FIELDTYPE() { return "FieldType"; }
+ const sal_Char* getPROPERTY_ID_VALUE() { return "Value"; }
+ const sal_Char* getPROPERTY_ID_ACTIVE_CONNECTION() { return "ActiveConnection"; }
+ const sal_Char* getPROPERTY_ID_LABEL() { return "Label"; }
+
+ //============================================================
+ //= error messages
+ //============================================================
+ const sal_Char* getSQLSTATE_SEQUENCE() { return "HY010"; }
+ const sal_Char* getSTR_DELIMITER() { return "/"; }
+
+
+
+ OPropertyMap::~OPropertyMap()
+ {
+ ::std::map<sal_Int32 , rtl_uString*>::iterator aIter = m_aPropertyMap.begin();
+ for(;aIter != m_aPropertyMap.end();++aIter)
+ if(aIter->second)
+ rtl_uString_release(aIter->second);
+ }
+ // ------------------------------------------------------------------------------
+ ::rtl::OUString OPropertyMap::getNameByIndex(sal_Int32 _nIndex) const
+ {
+ ::rtl::OUString sRet;
+ ::std::map<sal_Int32 , rtl_uString*>::const_iterator aIter = m_aPropertyMap.find(_nIndex);
+ if(aIter == m_aPropertyMap.end())
+ sRet = const_cast<OPropertyMap*>(this)->fillValue(_nIndex);
+ else
+ sRet = aIter->second;
+ return sRet;
+ }
+ // ------------------------------------------------------------------------------
+ ::rtl::OUString OPropertyMap::fillValue(sal_Int32 _nIndex)
+ {
+ rtl_uString* pStr = NULL;
+ switch(_nIndex)
+ {
+ case PROPERTY_ID_QUERYTIMEOUT: { rtl_uString_newFromAscii(&pStr,getPROPERTY_QUERYTIMEOUT() ); break; }
+ case PROPERTY_ID_MAXFIELDSIZE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_MAXFIELDSIZE() ); break; }
+ case PROPERTY_ID_MAXROWS: { rtl_uString_newFromAscii(&pStr,getPROPERTY_MAXROWS() ); break; }
+ case PROPERTY_ID_CURSORNAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_CURSORNAME() ); break; }
+ case PROPERTY_ID_RESULTSETCONCURRENCY: { rtl_uString_newFromAscii(&pStr,getPROPERTY_RESULTSETCONCURRENCY() ); break; }
+ case PROPERTY_ID_RESULTSETTYPE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_RESULTSETTYPE() ); break; }
+ case PROPERTY_ID_FETCHDIRECTION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_FETCHDIRECTION() ); break; }
+ case PROPERTY_ID_FETCHSIZE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_FETCHSIZE() ); break; }
+ case PROPERTY_ID_ESCAPEPROCESSING: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ESCAPEPROCESSING() ); break; }
+ case PROPERTY_ID_USEBOOKMARKS: { rtl_uString_newFromAscii(&pStr,getPROPERTY_USEBOOKMARKS() ); break; }
+ // Column
+ case PROPERTY_ID_NAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_NAME() ); break; }
+ case PROPERTY_ID_TYPE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_TYPE() ); break; }
+ case PROPERTY_ID_TYPENAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_TYPENAME() ); break; }
+ case PROPERTY_ID_PRECISION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_PRECISION() ); break; }
+ case PROPERTY_ID_SCALE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_SCALE() ); break; }
+ case PROPERTY_ID_ISNULLABLE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISNULLABLE() ); break; }
+ case PROPERTY_ID_ISAUTOINCREMENT: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISAUTOINCREMENT() ); break; }
+ case PROPERTY_ID_ISROWVERSION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISROWVERSION() ); break; }
+ case PROPERTY_ID_DESCRIPTION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_DESCRIPTION() ); break; }
+ case PROPERTY_ID_DEFAULTVALUE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_DEFAULTVALUE() ); break; }
+
+ case PROPERTY_ID_REFERENCEDTABLE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_REFERENCEDTABLE() ); break; }
+ case PROPERTY_ID_UPDATERULE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_UPDATERULE() ); break; }
+ case PROPERTY_ID_DELETERULE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_DELETERULE() ); break; }
+ case PROPERTY_ID_CATALOG: { rtl_uString_newFromAscii(&pStr,getPROPERTY_CATALOG() ); break; }
+ case PROPERTY_ID_ISUNIQUE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISUNIQUE() ); break; }
+ case PROPERTY_ID_ISPRIMARYKEYINDEX: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISPRIMARYKEYINDEX() ); break; }
+ case PROPERTY_ID_ISCLUSTERED: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISCLUSTERED() ); break; }
+ case PROPERTY_ID_ISASCENDING: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISASCENDING() ); break; }
+ case PROPERTY_ID_SCHEMANAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_SCHEMANAME() ); break; }
+ case PROPERTY_ID_CATALOGNAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_CATALOGNAME() ); break; }
+
+ case PROPERTY_ID_COMMAND: { rtl_uString_newFromAscii(&pStr,getPROPERTY_COMMAND() ); break; }
+ case PROPERTY_ID_CHECKOPTION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_CHECKOPTION() ); break; }
+ case PROPERTY_ID_PASSWORD: { rtl_uString_newFromAscii(&pStr,getPROPERTY_PASSWORD() ); break; }
+ case PROPERTY_ID_RELATEDCOLUMN: { rtl_uString_newFromAscii(&pStr,getPROPERTY_RELATEDCOLUMN() ); break; }
+
+ case PROPERTY_ID_FUNCTION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_FUNCTION() ); break; }
+ case PROPERTY_ID_AGGREGATEFUNCTION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_AGGREGATEFUNCTION() ); break; }
+ case PROPERTY_ID_TABLENAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_TABLENAME() ); break; }
+ case PROPERTY_ID_REALNAME: { rtl_uString_newFromAscii(&pStr,getPROPERTY_REALNAME() ); break; }
+ case PROPERTY_ID_DBASEPRECISIONCHANGED: { rtl_uString_newFromAscii(&pStr,getPROPERTY_DBASEPRECISIONCHANGED()); break; }
+ case PROPERTY_ID_ISCURRENCY: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISCURRENCY() ); break; }
+ case PROPERTY_ID_ISBOOKMARKABLE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ISBOOKMARKABLE() ); break; }
+ case PROPERTY_ID_HY010: { rtl_uString_newFromAscii(&pStr,getSQLSTATE_SEQUENCE() ); break; }
+ case PROPERTY_ID_DELIMITER: { rtl_uString_newFromAscii(&pStr,getSTR_DELIMITER() ); break; }
+ case PROPERTY_ID_FORMATKEY: { rtl_uString_newFromAscii(&pStr,getPROPERTY_FORMATKEY() ); break; }
+ case PROPERTY_ID_LOCALE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_LOCALE() ); break; }
+ case PROPERTY_ID_AUTOINCREMENTCREATION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_AUTOINCREMENTCREATION()); break; }
+ case PROPERTY_ID_PRIVILEGES: { rtl_uString_newFromAscii(&pStr,getPROPERTY_PRIVILEGES() ); break; }
+ case PROPERTY_ID_HAVINGCLAUSE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_HAVINGCLAUSE() ); break; }
+ case PROPERTY_ID_ISSIGNED: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_ISSIGNED() ); break; }
+ case PROPERTY_ID_ISSEARCHABLE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_ISSEARCHABLE() ); break; }
+ case PROPERTY_ID_LABEL: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_LABEL() ); break; }
+ case PROPERTY_ID_APPLYFILTER: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_APPLYFILTER() ); break; }
+ case PROPERTY_ID_FILTER: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_FILTER() ); break; }
+ case PROPERTY_ID_MASTERFIELDS: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_MASTERFIELDS() ); break; }
+ case PROPERTY_ID_DETAILFIELDS: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_DETAILFIELDS() ); break; }
+ case PROPERTY_ID_FIELDTYPE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_FIELDTYPE() ); break; }
+ case PROPERTY_ID_VALUE: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_VALUE() ); break; }
+ case PROPERTY_ID_ACTIVE_CONNECTION: { rtl_uString_newFromAscii(&pStr,getPROPERTY_ID_ACTIVE_CONNECTION() ); break; }
+ }
+ m_aPropertyMap[_nIndex] = pStr;
+ return pStr;
+ }
+}
+
+
diff --git a/connectivity/source/commontools/sqlerror.cxx b/connectivity/source/commontools/sqlerror.cxx
new file mode 100644
index 000000000000..a04284799894
--- /dev/null
+++ b/connectivity/source/commontools/sqlerror.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+
+#include "connectivity/sqlerror.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdbc/SQLException.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/officeresourcebundle.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <string.h>
+
+//........................................................................
+namespace connectivity
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_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::XInterface;
+ using ::com::sun::star::sdbc::SQLException;
+ using ::com::sun::star::uno::Type;
+ /** === end UNO using === **/
+
+ //using SQLError::ParamValue; // GCC (unxlngi6) does not like this
+ namespace
+ {
+ typedef SQLError::ParamValue ParamValue;
+ }
+
+ //====================================================================
+ //= SQLError_Impl - declaration
+ //====================================================================
+ class SQLError_Impl
+ {
+ public:
+ SQLError_Impl( const ::comphelper::ComponentContext& _rContext );
+ ~SQLError_Impl();
+
+ // versions of the public SQLError methods which are just delegated to this impl-class
+ static const ::rtl::OUString& getMessagePrefix();
+ ::rtl::OUString getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
+ ::rtl::OUString getSQLState( const ErrorCondition _eCondition );
+ static ErrorCode getErrorCode( const ErrorCondition _eCondition );
+ void raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
+ void raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
+ void raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
+ SQLException getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
+
+ private:
+ /// returns the basic error message associated with the given error condition, without any parameter replacements
+ ::rtl::OUString
+ impl_getErrorMessage( const ErrorCondition& _eCondition );
+
+ /// returns the SQLState associated with the given error condition
+ ::rtl::OUString
+ impl_getSQLState( const ErrorCondition& _eCondition );
+
+ /// returns an SQLException describing the given error condition
+ SQLException
+ impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
+ const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 );
+
+ /// initializes our resource bundle
+ bool impl_initResources();
+
+ private:
+ ::osl::Mutex m_aMutex;
+ ::comphelper::ComponentContext m_aContext;
+ ::std::auto_ptr< ::comphelper::OfficeResourceBundle > m_pResources;
+ bool m_bAttemptedInit;
+ };
+
+ //====================================================================
+ //= SQLError_Impl - implementation
+ //====================================================================
+ //--------------------------------------------------------------------
+ SQLError_Impl::SQLError_Impl( const ::comphelper::ComponentContext& _rContext )
+ :m_aContext( _rContext )
+ ,m_pResources( )
+ ,m_bAttemptedInit( false )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ SQLError_Impl::~SQLError_Impl()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& SQLError_Impl::getMessagePrefix()
+ {
+ static ::rtl::OUString s_sMessagePrefix( RTL_CONSTASCII_USTRINGPARAM( "[OOoBase]" ) );
+ return s_sMessagePrefix;
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //................................................................
+ /** substitutes a given placeholder in the given message with the given value
+ */
+ void lcl_substitutePlaceholder( ::rtl::OUString& _rMessage, const sal_Char* _pPlaceholder, ParamValue _rParamValue )
+ {
+ size_t nPlaceholderLen( strlen( _pPlaceholder ) );
+ sal_Int32 nIndex = _rMessage.indexOfAsciiL( _pPlaceholder, nPlaceholderLen );
+
+ bool bHasPlaceholder = ( nIndex != -1 );
+ bool bWantsPlaceholder = _rParamValue.is();
+ OSL_ENSURE( bHasPlaceholder == bWantsPlaceholder, "lcl_substitutePlaceholder: placeholder where none is expected, or no placeholder where one is needed!" );
+
+ if ( bHasPlaceholder && bWantsPlaceholder )
+ _rMessage = _rMessage.replaceAt( nIndex, nPlaceholderLen, *_rParamValue );
+ }
+
+ //................................................................
+ sal_Int32 lcl_getResourceID( const ErrorCondition _eCondition, bool _bSQLState )
+ {
+ return 256
+ + 2 * ::sal::static_int_cast< sal_Int32, ErrorCondition >( _eCondition )
+ + ( _bSQLState ? 1 : 0 );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SQLError_Impl::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
+ {
+ ::rtl::OUString sErrorMessage( impl_getErrorMessage( _eCondition ) );
+
+ lcl_substitutePlaceholder( sErrorMessage, "$1$", _rParamValue1 );
+ lcl_substitutePlaceholder( sErrorMessage, "$2$", _rParamValue2 );
+ lcl_substitutePlaceholder( sErrorMessage, "$3$", _rParamValue3 );
+
+ return sErrorMessage;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SQLError_Impl::getSQLState( const ErrorCondition _eCondition )
+ {
+ return impl_getSQLState( _eCondition );
+ }
+
+ //--------------------------------------------------------------------
+ ErrorCode SQLError_Impl::getErrorCode( const ErrorCondition _eCondition )
+ {
+ return 0 - ::sal::static_int_cast< ErrorCode, ErrorCondition >( _eCondition );
+ }
+
+ //--------------------------------------------------------------------
+ void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
+ {
+ raiseTypedException(
+ _eCondition,
+ _rxContext,
+ ::cppu::UnoType< SQLException >::get(),
+ _rParamValue1,
+ _rParamValue2,
+ _rParamValue3
+ );
+ }
+
+ //--------------------------------------------------------------------
+ void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
+ {
+ raiseTypedException(
+ _eCondition,
+ NULL,
+ ::cppu::UnoType< SQLException >::get(),
+ _rParamValue1,
+ _rParamValue2,
+ _rParamValue3
+ );
+ }
+
+ //--------------------------------------------------------------------
+ void SQLError_Impl::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
+ const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
+ {
+ if ( !::cppu::UnoType< SQLException >::get().isAssignableFrom( _rExceptionType ) )
+ throw ::std::bad_cast();
+
+ // default-construct an exception of the desired type
+ Any aException( NULL, _rExceptionType );
+
+ // fill it
+ SQLException* pException = static_cast< SQLException* >( aException.pData );
+ *pException = impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
+
+ // throw it
+ ::cppu::throwException( aException );
+ }
+
+ //--------------------------------------------------------------------
+ SQLException SQLError_Impl::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
+ const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
+ {
+ return impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
+ }
+
+ //--------------------------------------------------------------------
+ SQLException SQLError_Impl::impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
+ const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 )
+ {
+ return SQLException(
+ getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 ),
+ _rxContext,
+ getSQLState( _eCondition ),
+ getErrorCode( _eCondition ),
+ Any()
+ );
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SQLError_Impl::impl_getErrorMessage( const ErrorCondition& _eCondition )
+ {
+ ::rtl::OUStringBuffer aMessage;
+
+ if ( impl_initResources() )
+ {
+ ::rtl::OUString sResMessage( m_pResources->loadString( lcl_getResourceID( _eCondition, false ) ) );
+ OSL_ENSURE( sResMessage.getLength(), "SQLError_Impl::impl_getErrorMessage: illegal error condition, or invalid resource!" );
+ aMessage.append( getMessagePrefix() ).appendAscii( " " ).append( sResMessage );
+ }
+
+ return aMessage.makeStringAndClear();
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SQLError_Impl::impl_getSQLState( const ErrorCondition& _eCondition )
+ {
+ ::rtl::OUString sState;
+
+ if ( impl_initResources() )
+ {
+ sal_Int32 nResourceId( lcl_getResourceID( _eCondition, true ) );
+ if ( m_pResources->hasString( nResourceId ) )
+ sState = m_pResources->loadString( nResourceId );
+ }
+
+ if ( !sState.getLength() )
+ sState = ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) );
+
+ return sState;
+ }
+
+ //--------------------------------------------------------------------
+ bool SQLError_Impl::impl_initResources()
+ {
+ if ( m_pResources.get() )
+ return true;
+ if ( m_bAttemptedInit )
+ return false;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bAttemptedInit = true;
+
+ m_pResources.reset( new ::comphelper::OfficeResourceBundle( m_aContext.getUNOContext(), "sdberr" ) );
+ return m_pResources.get() != NULL;
+ }
+
+ //====================================================================
+ //= SQLError
+ //====================================================================
+ //--------------------------------------------------------------------
+ SQLError::SQLError( const ::comphelper::ComponentContext& _rContext )
+ :m_pImpl( new SQLError_Impl( _rContext ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ SQLError::~SQLError()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& SQLError::getMessagePrefix()
+ {
+ return SQLError_Impl::getMessagePrefix();
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SQLError::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
+ {
+ return m_pImpl->getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 );
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SQLError::getSQLState( const ErrorCondition _eCondition ) const
+ {
+ return m_pImpl->getSQLState( _eCondition );
+ }
+
+ //--------------------------------------------------------------------
+ ErrorCode SQLError::getErrorCode( const ErrorCondition _eCondition )
+ {
+ return SQLError_Impl::getErrorCode( _eCondition );
+ }
+
+ //--------------------------------------------------------------------
+ void SQLError::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
+ {
+ m_pImpl->raiseException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
+ }
+
+ //--------------------------------------------------------------------
+ void SQLError::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
+ {
+ m_pImpl->raiseException( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 );
+ }
+
+ //--------------------------------------------------------------------
+ void SQLError::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
+ const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
+ {
+ m_pImpl->raiseTypedException( _eCondition, _rxContext, _rExceptionType, _rParamValue1, _rParamValue2, _rParamValue3 );
+ }
+
+ //--------------------------------------------------------------------
+ SQLException SQLError::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext,
+ const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const
+ {
+ return m_pImpl->getSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 );
+ }
+
+//........................................................................
+} // namespace connectivity
+//........................................................................
diff --git a/connectivity/source/commontools/statementcomposer.cxx b/connectivity/source/commontools/statementcomposer.cxx
new file mode 100644
index 000000000000..0996eaaaaf86
--- /dev/null
+++ b/connectivity/source/commontools/statementcomposer.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * 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_connectivity.hxx"
+#include <connectivity/statementcomposer.hxx>
+
+#include <connectivity/dbtools.hxx>
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+/** === end UNO includes === **/
+
+#include <unotools/sharedunocomponent.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/property.hxx>
+
+//........................................................................
+namespace dbtools
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::sdbc::XConnection;
+ using ::com::sun::star::sdb::XSingleSelectQueryComposer;
+ using ::com::sun::star::lang::NullPointerException;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::sdb::XQueriesSupplier;
+ using ::com::sun::star::container::XNameAccess;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::beans::XPropertySet;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::sdbc::SQLException;
+ /** === end UNO using === **/
+ namespace CommandType = ::com::sun::star::sdb::CommandType;
+
+ //====================================================================
+ //= StatementComposer_Data
+ //====================================================================
+ struct StatementComposer_Data
+ {
+ const Reference< XConnection > xConnection;
+ Reference< XSingleSelectQueryComposer > xComposer;
+ ::rtl::OUString sCommand;
+ ::rtl::OUString sFilter;
+ ::rtl::OUString sOrder;
+ sal_Int32 nCommandType;
+ sal_Bool bEscapeProcessing;
+ bool bComposerDirty;
+ bool bDisposeComposer;
+
+ StatementComposer_Data( const Reference< XConnection >& _rxConnection )
+ :xConnection( _rxConnection )
+ ,sCommand()
+ ,sFilter()
+ ,sOrder()
+ ,nCommandType( CommandType::COMMAND )
+ ,bEscapeProcessing( sal_True )
+ ,bComposerDirty( true )
+ ,bDisposeComposer( true )
+ {
+ if ( !_rxConnection.is() )
+ throw NullPointerException();
+ }
+ };
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //----------------------------------------------------------------
+ void lcl_resetComposer( StatementComposer_Data& _rData )
+ {
+ if ( _rData.bDisposeComposer && _rData.xComposer.is() )
+ {
+ try
+ {
+ Reference< XComponent > xComposerComponent( _rData.xComposer, UNO_QUERY_THROW );
+ xComposerComponent->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ _rData.xComposer.clear();
+ }
+
+ //----------------------------------------------------------------
+ bool lcl_ensureUpToDateComposer_nothrow( StatementComposer_Data& _rData )
+ {
+ if ( !_rData.bComposerDirty )
+ return _rData.xComposer.is();
+ lcl_resetComposer( _rData );
+
+ try
+ {
+ ::rtl::OUString sStatement;
+ switch ( _rData.nCommandType )
+ {
+ case CommandType::COMMAND:
+ if ( _rData.bEscapeProcessing )
+ sStatement = _rData.sCommand;
+ // (in case of no escape processing we assume a not parseable statement)
+ break;
+
+ case CommandType::TABLE:
+ {
+ if ( !_rData.sCommand.getLength() )
+ break;
+
+ sStatement = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SELECT * FROM " ) );
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ qualifiedNameComponents( _rData.xConnection->getMetaData(), _rData.sCommand, sCatalog, sSchema, sTable, eInDataManipulation );
+
+ sStatement += composeTableNameForSelect( _rData.xConnection, sCatalog, sSchema, sTable );
+ }
+ break;
+
+ case CommandType::QUERY:
+ {
+ // ask the connection for the query
+ Reference< XQueriesSupplier > xSupplyQueries( _rData.xConnection, UNO_QUERY_THROW );
+ Reference< XNameAccess > xQueries( xSupplyQueries->getQueries(), UNO_QUERY_THROW );
+
+ if ( !xQueries->hasByName( _rData.sCommand ) )
+ break;
+
+ Reference< XPropertySet > xQuery( xQueries->getByName( _rData.sCommand ), UNO_QUERY_THROW );
+
+ // a native query ?
+ sal_Bool bQueryEscapeProcessing = sal_False;
+ xQuery->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EscapeProcessing" ) ) ) >>= bQueryEscapeProcessing;
+ if ( !bQueryEscapeProcessing )
+ break;
+
+ // the command used by the query
+ xQuery->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command" ) ) ) >>= sStatement;
+ if ( !sStatement.getLength() )
+ break;
+
+ // use a composer to build a statement from the query filter/order props
+ Reference< XMultiServiceFactory > xFactory( _rData.xConnection, UNO_QUERY_THROW );
+ ::utl::SharedUNOComponent< XSingleSelectQueryComposer > xComposer;
+ xComposer.set(
+ xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
+ UNO_QUERY_THROW
+ );
+
+ // the "basic" statement
+ xComposer->setElementaryQuery( sStatement );
+
+ // the sort order
+ const ::rtl::OUString sPropOrder( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Order" ) ) );
+ if ( ::comphelper::hasProperty( sPropOrder, xQuery ) )
+ {
+ ::rtl::OUString sOrder;
+ OSL_VERIFY( xQuery->getPropertyValue( sPropOrder ) >>= sOrder );
+ xComposer->setOrder( sOrder );
+ }
+
+ // the filter
+ sal_Bool bApplyFilter = sal_True;
+ const ::rtl::OUString sPropApply = ::rtl::OUString::createFromAscii( "ApplyFilter" );
+ if ( ::comphelper::hasProperty( sPropApply, xQuery ) )
+ {
+ OSL_VERIFY( xQuery->getPropertyValue( sPropApply ) >>= bApplyFilter );
+ }
+
+ if ( bApplyFilter )
+ {
+ ::rtl::OUString sFilter;
+ OSL_VERIFY( xQuery->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Filter" ) ) ) >>= sFilter );
+ xComposer->setFilter( sFilter );
+ }
+
+ // the composed statement
+ sStatement = xComposer->getQuery();
+ }
+ break;
+
+ default:
+ OSL_ENSURE(sal_False, "lcl_ensureUpToDateComposer_nothrow: no table, no query, no statement - what else ?!");
+ break;
+ }
+
+ if ( sStatement.getLength() )
+ {
+ // create an composer
+ Reference< XMultiServiceFactory > xFactory( _rData.xConnection, UNO_QUERY_THROW );
+ Reference< XSingleSelectQueryComposer > xComposer( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
+ UNO_QUERY_THROW );
+ xComposer->setElementaryQuery( sStatement );
+
+ // append sort/filter
+ xComposer->setOrder( _rData.sOrder );
+ xComposer->setFilter( _rData.sFilter );
+
+ sStatement = xComposer->getQuery();
+
+ _rData.xComposer = xComposer;
+ _rData.bComposerDirty = false;
+ }
+ }
+ catch( const SQLException& )
+ {
+ // allowed to leave here
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return _rData.xComposer.is();
+ }
+ }
+
+ //====================================================================
+ //= StatementComposer
+ //====================================================================
+ //--------------------------------------------------------------------
+ StatementComposer::StatementComposer( const Reference< XConnection >& _rxConnection,
+ const ::rtl::OUString& _rCommand, const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing )
+ :m_pData( new StatementComposer_Data( _rxConnection ) )
+ {
+ OSL_PRECOND( _rxConnection.is(), "StatementComposer::StatementComposer: illegal connection!" );
+ m_pData->sCommand = _rCommand;
+ m_pData->nCommandType = _nCommandType;
+ m_pData->bEscapeProcessing = _bEscapeProcessing;
+ }
+
+ //--------------------------------------------------------------------
+ StatementComposer::~StatementComposer()
+ {
+ lcl_resetComposer( *m_pData );
+ }
+
+ //--------------------------------------------------------------------
+ void StatementComposer::setDisposeComposer( bool _bDoDispose )
+ {
+ m_pData->bDisposeComposer = _bDoDispose;
+ }
+
+ //--------------------------------------------------------------------
+ bool StatementComposer::getDisposeComposer() const
+ {
+ return m_pData->bDisposeComposer;
+ }
+
+ //--------------------------------------------------------------------
+ void StatementComposer::setFilter( const ::rtl::OUString& _rFilter )
+ {
+ m_pData->sFilter = _rFilter;
+ m_pData->bComposerDirty = true;
+ }
+
+ //--------------------------------------------------------------------
+ void StatementComposer::setOrder( const ::rtl::OUString& _rOrder )
+ {
+ m_pData->sOrder = _rOrder;
+ m_pData->bComposerDirty = true;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XSingleSelectQueryComposer > StatementComposer::getComposer()
+ {
+ lcl_ensureUpToDateComposer_nothrow( *m_pData );
+ return m_pData->xComposer;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString StatementComposer::getQuery()
+ {
+ if ( lcl_ensureUpToDateComposer_nothrow( *m_pData ) )
+ {
+ return m_pData->xComposer->getQuery();
+ }
+
+ return ::rtl::OUString();
+ }
+
+//........................................................................
+} // namespace dbtools
+//........................................................................
diff --git a/connectivity/source/commontools/warningscontainer.cxx b/connectivity/source/commontools/warningscontainer.cxx
new file mode 100644
index 000000000000..91890e8149df
--- /dev/null
+++ b/connectivity/source/commontools/warningscontainer.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_connectivity.hxx"
+
+#include "connectivity/warningscontainer.hxx"
+#include "connectivity/dbexception.hxx"
+
+#include <osl/diagnose.h>
+
+//........................................................................
+namespace dbtools
+{
+//........................................................................
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdbc;
+ using namespace ::com::sun::star::sdb;
+
+ //====================================================================
+ //= WarningsContainer
+ //====================================================================
+ //--------------------------------------------------------------------
+ static void lcl_concatWarnings( Any& _rChainLeft, const Any& _rChainRight )
+ {
+ if ( !_rChainLeft.hasValue() )
+ _rChainLeft = _rChainRight;
+ else
+ {
+ // to travel the chain by reference (and not by value), we need the getValue ...
+ // looks like a hack, but the meaning of getValue is documented, and it's the only chance for reference-traveling ....
+
+ OSL_ENSURE( SQLExceptionInfo( _rChainLeft ).isValid(),
+ "lcl_concatWarnings: invalid warnings chain (this will crash)!" );
+
+ const SQLException* pChainTravel = static_cast< const SQLException* >( _rChainLeft.getValue() );
+ SQLExceptionIteratorHelper aReferenceIterHelper( *pChainTravel );
+ while ( aReferenceIterHelper.hasMoreElements() )
+ pChainTravel = aReferenceIterHelper.next();
+
+ // reached the end of the chain, and pChainTravel points to the last element
+ const_cast< SQLException* >( pChainTravel )->NextException = _rChainRight;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ WarningsContainer::~WarningsContainer()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void WarningsContainer::appendWarning(const SQLException& _rWarning)
+ {
+ lcl_concatWarnings( m_aOwnWarnings, makeAny( _rWarning ) );
+ }
+
+ //--------------------------------------------------------------------
+ void WarningsContainer::appendWarning( const SQLContext& _rContext )
+ {
+ lcl_concatWarnings( m_aOwnWarnings, makeAny( _rContext ));
+ }
+
+ //--------------------------------------------------------------------
+ void WarningsContainer::appendWarning(const SQLWarning& _rWarning)
+ {
+ lcl_concatWarnings( m_aOwnWarnings, makeAny( _rWarning ) );
+ }
+
+ //--------------------------------------------------------------------
+ Any SAL_CALL WarningsContainer::getWarnings( ) const
+ {
+ Any aAllWarnings;
+ if ( m_xExternalWarnings.is() )
+ aAllWarnings = m_xExternalWarnings->getWarnings();
+
+ if ( m_aOwnWarnings.hasValue() )
+ lcl_concatWarnings( aAllWarnings, m_aOwnWarnings );
+
+ return aAllWarnings;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL WarningsContainer::clearWarnings( )
+ {
+ if ( m_xExternalWarnings.is() )
+ m_xExternalWarnings->clearWarnings();
+ m_aOwnWarnings.clear();
+ }
+
+ //--------------------------------------------------------------------
+ void WarningsContainer::appendWarning( const ::rtl::OUString& _rWarning, const sal_Char* _pAsciiSQLState, const Reference< XInterface >& _rxContext )
+ {
+ appendWarning( SQLWarning( _rWarning, _rxContext, ::rtl::OUString::createFromAscii( _pAsciiSQLState ), 0, Any() ) );
+ }
+
+//........................................................................
+} // namespace dbtools
+//........................................................................