diff options
Diffstat (limited to 'connectivity')
72 files changed, 1902 insertions, 560 deletions
diff --git a/connectivity/com/sun/star/sdbcx/comp/hsqldb/NativeInputStreamHelper.java b/connectivity/com/sun/star/sdbcx/comp/hsqldb/NativeInputStreamHelper.java index 60b5bed9dc..53a83c4425 100644 --- a/connectivity/com/sun/star/sdbcx/comp/hsqldb/NativeInputStreamHelper.java +++ b/connectivity/com/sun/star/sdbcx/comp/hsqldb/NativeInputStreamHelper.java @@ -1,4 +1,33 @@ -/* +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: StorageFileAccess.java,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + /* * NativeInputStreamHelper.java * * Created on 9. September 2004, 11:51 diff --git a/connectivity/com/sun/star/sdbcx/comp/hsqldb/StorageNativeInputStream.java b/connectivity/com/sun/star/sdbcx/comp/hsqldb/StorageNativeInputStream.java index 55439f2c3b..38caa8bd96 100644 --- a/connectivity/com/sun/star/sdbcx/comp/hsqldb/StorageNativeInputStream.java +++ b/connectivity/com/sun/star/sdbcx/comp/hsqldb/StorageNativeInputStream.java @@ -1,3 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: StorageFileAccess.java,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ /* * StorageNativeInputStream.java * diff --git a/connectivity/inc/connectivity/BlobHelper.hxx b/connectivity/inc/connectivity/BlobHelper.hxx new file mode 100644 index 0000000000..10142513ed --- /dev/null +++ b/connectivity/inc/connectivity/BlobHelper.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FValue.cxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CONNECTIVITY_BLOBHELPER_HXX_ +#define _CONNECTIVITY_BLOBHELPER_HXX_ + +#include "connectivity/dbtoolsdllapi.hxx" +#include <com/sun/star/sdbc/XBlob.hpp> +#include <cppuhelper/implbase1.hxx> + +namespace connectivity +{ + class OOO_DLLPUBLIC_DBTOOLS BlobHelper : public ::cppu::WeakImplHelper1< com::sun::star::sdbc::XBlob > + { + ::com::sun::star::uno::Sequence< sal_Int8 > m_aValue; + public: + BlobHelper(const ::com::sun::star::uno::Sequence< sal_Int8 >& _val); + private: + virtual ::sal_Int64 SAL_CALL length( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getBytes( ::sal_Int64 pos, ::sal_Int32 length ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getBinaryStream( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int64 SAL_CALL position( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& pattern, ::sal_Int64 start ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int64 SAL_CALL 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); + }; +} + +#endif //_CONNECTIVITY_BLOBHELPER_HXX_ + diff --git a/connectivity/inc/connectivity/TTableHelper.hxx b/connectivity/inc/connectivity/TTableHelper.hxx index ea9d4a57d4..bef9ce7240 100644 --- a/connectivity/inc/connectivity/TTableHelper.hxx +++ b/connectivity/inc/connectivity/TTableHelper.hxx @@ -36,6 +36,10 @@ #include "connectivity/sdbcx/VKey.hxx" #include "connectivity/StdTypeDefs.hxx" #include <comphelper/stl_types.hxx> +#include <com/sun/star/sdb/tools/XTableRename.hpp> +#include <com/sun/star/sdb/tools/XTableAlteration.hpp> +#include <com/sun/star/sdb/tools/XKeyAlteration.hpp> +#include <com/sun/star/sdb/tools/XIndexAlteration.hpp> namespace connectivity { @@ -158,6 +162,11 @@ namespace connectivity void addKey(const ::rtl::OUString& _sName,const sdbcx::TKeyProperties& _aKeyProperties); virtual ::rtl::OUString getTypeCreatePattern() const; + + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XTableRename> getRenameService() const; + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XTableAlteration> getAlterService() const; + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XKeyAlteration> getKeyService() const; + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::tools::XIndexAlteration> getIndexService() const; }; } #endif // CONNECTIVITY_TABLEHELPER_HXX diff --git a/connectivity/inc/connectivity/dbmetadata.hxx b/connectivity/inc/connectivity/dbmetadata.hxx index 6a0757ad2c..a09b698e8c 100644 --- a/connectivity/inc/connectivity/dbmetadata.hxx +++ b/connectivity/inc/connectivity/dbmetadata.hxx @@ -121,6 +121,17 @@ namespace dbtools */ bool supportsSubqueriesInFrom() const; + /** checks whether the database supports primary keys + + Since there's no dedicated API to ask a database for this, a heuristics needs to be applied. + First, the <code>PrimaryKeySupport<code> settings of the data source is examined. If it is <TRUE/> + or <FALSE/>, then value is returned. If it is <NULL/>, then the database meta data are examined + for support of core SQL grammar, and the result is returned. The assumption is that a database/driver + which supports core SQL grammar usually also supports primary keys, and vice versa. At least, experience + shows this is true most of the time. + */ + bool supportsPrimaryKeys() const; + /** determines whether names in the database should be restricted to SQL-92 identifiers Effectively, this method checks the EnableSQL92Check property of the data source settings, diff --git a/connectivity/inc/connectivity/dbtools.hxx b/connectivity/inc/connectivity/dbtools.hxx index 8afd0b7fa6..2f3b808089 100644 --- a/connectivity/inc/connectivity/dbtools.hxx +++ b/connectivity/inc/connectivity/dbtools.hxx @@ -37,6 +37,7 @@ #include <comphelper/stl_types.hxx> #include <unotools/sharedunocomponent.hxx> #include "connectivity/dbtoolsdllapi.hxx" +#include "connectivity/FValue.hxx" namespace com { namespace sun { namespace star { @@ -352,6 +353,33 @@ namespace dbtools ,const ::rtl::OUString& _sProperty, sal_Bool _bDefault = sal_False); + /** retrieves a particular indirect data source setting + + @param _rxDataSource + a data source component + @param _pAsciiSettingsName + the ASCII name of the setting to obtain + @param _rSettingsValue + the value of the setting, upon successfull return + + @return + <FALSE/> if the setting is not present in the <member scope="com::sun::star::sdb">DataSource::Info</member> + member of the data source + <TRUE/> otherwise + */ + OOO_DLLPUBLIC_DBTOOLS + bool getDataSourceSetting( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxDataSource, + const sal_Char* _pAsciiSettingsName, + ::com::sun::star::uno::Any& /* [out] */ _rSettingsValue + ); + OOO_DLLPUBLIC_DBTOOLS + bool getDataSourceSetting( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxDataSource, + const ::rtl::OUString& _sSettingsName, + ::com::sun::star::uno::Any& /* [out] */ _rSettingsValue + ); + OOO_DLLPUBLIC_DBTOOLS ::rtl::OUString getDefaultReportEngineServiceName(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory); /** quote the given name with the given quote string. @@ -593,6 +621,20 @@ namespace dbtools sal_Int32 sqlType, sal_Int32 scale=0) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + /** call the appropiate set method for the specific sql type @see com::sun::star::sdbc::DataType + @param _xParams the parameters where to set the value + @param parameterIndex the index of the parameter, 1 based + @param x the value to set + @param sqlType the corresponding sql type @see com::sun::star::sdbc::DataType + @param scale the scale of the sql type can be 0 + */ + OOO_DLLPUBLIC_DBTOOLS + void setObjectWithInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XParameters>& _xParameters, + sal_Int32 parameterIndex, + const ::connectivity::ORowSetValue& x, + sal_Int32 sqlType, + sal_Int32 scale=0) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + /** implements <method scope="com.sun.star.sdb">XParameters::setObject</method> <p>The object which is to be set is analyzed, and in case it is a simlpe scalar type for which there diff --git a/connectivity/inc/connectivity/formattedcolumnvalue.hxx b/connectivity/inc/connectivity/formattedcolumnvalue.hxx index adaf558b98..1b3ef1060b 100644 --- a/connectivity/inc/connectivity/formattedcolumnvalue.hxx +++ b/connectivity/inc/connectivity/formattedcolumnvalue.hxx @@ -36,6 +36,7 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/sdb/XColumn.hpp> #include <com/sun/star/sdb/XColumnUpdate.hpp> +#include <com/sun/star/util/XNumberFormatter.hpp> /** === end UNO includes === **/ #include <boost/noncopyable.hpp> @@ -77,6 +78,19 @@ namespace dbtools const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxColumn ); + /** constructs an instance + + The format key for the string value exchange is taken from the given column object. + If it has a non-<NULL/> property value <code>FormatKey</code>, this key is taken. + Otherwise, a default format matching the column type is determined. + + The locale of this fallback format is the current system locale. + */ + FormattedColumnValue( + const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& i_rNumberFormatter, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& i_rColumn + ); + // note that all methods of this class need to be virtual, since it's // used in a load-on-demand context in module SVX diff --git a/connectivity/inc/connectivity/sqliterator.hxx b/connectivity/inc/connectivity/sqliterator.hxx index 9d39e2a997..ea11a64c7e 100644 --- a/connectivity/inc/connectivity/sqliterator.hxx +++ b/connectivity/inc/connectivity/sqliterator.hxx @@ -279,6 +279,9 @@ namespace connectivity // return true when the tableNode is a rule like catalog_name, schema_name or table_name sal_Bool isTableNode(const OSQLParseNode* _pTableNode) const; + + // tries to find the correct type of the function + sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode ); private: /** traverses the list of table names, and filles _rTables */ diff --git a/connectivity/inc/connectivity/sqlnode.hxx b/connectivity/inc/connectivity/sqlnode.hxx index ad04cd29f4..637fb1a8f3 100644 --- a/connectivity/inc/connectivity/sqlnode.hxx +++ b/connectivity/inc/connectivity/sqlnode.hxx @@ -225,6 +225,10 @@ namespace connectivity as, op_column_commalist, table_primary_as_range_column, + datetime_primary, + concatenation, + char_factor, + bit_value_fct, rule_count, // letzter_wert UNKNOWN_RULE // ID indicating that a node is no rule with a matching Rule-enum value (see getKnownRuleID) }; diff --git a/connectivity/qa/connectivity/GeneralTest.java b/connectivity/qa/connectivity/GeneralTest.java index f6284ff390..29c8dc15fb 100644 --- a/connectivity/qa/connectivity/GeneralTest.java +++ b/connectivity/qa/connectivity/GeneralTest.java @@ -30,21 +30,13 @@ package complex.connectivity; import com.sun.star.uno.UnoRuntime; -import com.sun.star.util.XCloseable; import com.sun.star.sdbc.*; -import com.sun.star.sdb.*; -import com.sun.star.beans.PropertyValue; -import com.sun.star.beans.XPropertySet; import com.sun.star.lang.XMultiServiceFactory; import complexlib.ComplexTestCase; -import java.io.PrintWriter; -import util.utils; -import java.util.*; -import java.io.*; //import complex.connectivity.DBaseStringFunctions; public class GeneralTest extends ComplexTestCase { @@ -63,7 +55,7 @@ public class GeneralTest extends ComplexTestCase { public void test() throws com.sun.star.uno.Exception,com.sun.star.beans.UnknownPropertyException { try { - XDriverManager driverManager = (XDriverManager)UnoRuntime.queryInterface(XDriverManager.class,((XMultiServiceFactory)param.getMSF()).createInstance("com.sun.star.sdbc.DriverManager")); + XDriverManager driverManager = UnoRuntime.queryInterface( XDriverManager.class, ((XMultiServiceFactory)param.getMSF()).createInstance( "com.sun.star.sdbc.DriverManager" ) ); String databaseURL = "sdbc:calc:singin' in the rain" ; XConnection catalogConnection = driverManager.getConnection(databaseURL); failed(); diff --git a/connectivity/qa/connectivity/tools/AbstractDatabase.java b/connectivity/qa/connectivity/tools/AbstractDatabase.java index 60a35c1d3d..fca1e60b41 100755 --- a/connectivity/qa/connectivity/tools/AbstractDatabase.java +++ b/connectivity/qa/connectivity/tools/AbstractDatabase.java @@ -38,10 +38,10 @@ import com.sun.star.sdb.XDocumentDataSource; import com.sun.star.sdb.XOfficeDatabaseDocument; import com.sun.star.sdbc.SQLException; import com.sun.star.sdbc.XCloseable; -import com.sun.star.sdbc.XConnection; import com.sun.star.sdbc.XStatement; import com.sun.star.uno.UnoRuntime; import com.sun.star.util.CloseVetoException; +import connectivity.tools.sdb.Connection; import java.io.File; /** @@ -60,7 +60,7 @@ public abstract class AbstractDatabase implements DatabaseAccess // the data source belonging to the database document protected DataSource m_dataSource; // the default connection - protected XConnection m_connection; + protected Connection m_connection; public AbstractDatabase(final XMultiServiceFactory orb) throws Exception { @@ -80,12 +80,10 @@ public abstract class AbstractDatabase implements DatabaseAccess * the ownership of the connection, so you don't need to (and should not) dispose/close it. * */ - public XConnection defaultConnection() throws SQLException + public Connection defaultConnection() throws SQLException { - if (m_connection == null) - { - m_connection = m_databaseDocument.getDataSource().getConnection("", ""); - } + if ( m_connection == null ) + m_connection = new Connection( m_databaseDocument.getDataSource().getConnection("", "") ); return m_connection; } @@ -104,8 +102,7 @@ public abstract class AbstractDatabase implements DatabaseAccess { if (m_databaseDocument != null) { - final XStorable storeDoc = (XStorable) UnoRuntime.queryInterface(XStorable.class, - m_databaseDocument); + final XStorable storeDoc = UnoRuntime.queryInterface(XStorable.class, m_databaseDocument); storeDoc.store(); } } @@ -118,8 +115,8 @@ public abstract class AbstractDatabase implements DatabaseAccess public void close() { // close connection - final XCloseable closeConn = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, - m_connection); + final XCloseable closeConn = UnoRuntime.queryInterface( XCloseable.class, + m_connection != null ? m_connection.getXConnection() : null ); if (closeConn != null) { try @@ -133,8 +130,7 @@ public abstract class AbstractDatabase implements DatabaseAccess m_connection = null; // close document - final com.sun.star.util.XCloseable closeDoc = (com.sun.star.util.XCloseable) UnoRuntime.queryInterface( - com.sun.star.util.XCloseable.class, m_databaseDocument); + final com.sun.star.util.XCloseable closeDoc = UnoRuntime.queryInterface( com.sun.star.util.XCloseable.class, m_databaseDocument ); if (closeDoc != null) { try @@ -178,7 +174,7 @@ public abstract class AbstractDatabase implements DatabaseAccess */ public XModel getModel() { - return (XModel) UnoRuntime.queryInterface(XModel.class, m_databaseDocument); + return UnoRuntime.queryInterface( XModel.class, m_databaseDocument ); } public XMultiServiceFactory getORB() @@ -191,10 +187,9 @@ public abstract class AbstractDatabase implements DatabaseAccess { m_databaseDocumentFile = _docURL; - final XNameAccess dbContext = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, - m_orb.createInstance("com.sun.star.sdb.DatabaseContext")); - final XDocumentDataSource dataSource = (XDocumentDataSource) UnoRuntime.queryInterface(XDocumentDataSource.class, - dbContext.getByName(_docURL)); + final XNameAccess dbContext = UnoRuntime.queryInterface( XNameAccess.class, + m_orb.createInstance( "com.sun.star.sdb.DatabaseContext" ) ); + final XDocumentDataSource dataSource = UnoRuntime.queryInterface( XDocumentDataSource.class, dbContext.getByName( _docURL ) ); m_databaseDocument = dataSource.getDatabaseDocument(); m_dataSource = new DataSource(m_orb, m_databaseDocument.getDataSource()); diff --git a/connectivity/qa/connectivity/tools/CRMDatabase.java b/connectivity/qa/connectivity/tools/CRMDatabase.java new file mode 100644 index 0000000000..3b840f3deb --- /dev/null +++ b/connectivity/qa/connectivity/tools/CRMDatabase.java @@ -0,0 +1,295 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CRMDatabase.java,v $ + * $Revision: 1.6.2.1 $ + * + * 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. + * + ************************************************************************/ +package connectivity.tools; + +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.PropertyState; +import com.sun.star.container.ElementExistException; +import com.sun.star.container.NoSuchElementException; +import com.sun.star.frame.XComponentLoader; +import com.sun.star.frame.XController; +import com.sun.star.frame.XModel; +import com.sun.star.io.IOException; +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.sdb.XSingleSelectQueryComposer; +import com.sun.star.sdb.application.XDatabaseDocumentUI; +import com.sun.star.sdbc.SQLException; +import com.sun.star.sdbcx.XTablesSupplier; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.util.XRefreshable; +import connectivity.tools.sdb.Connection; + +/** implements a small Customer Relationship Management database + * + * Not finished, by far. Feel free to add features as you need them. + */ +public class CRMDatabase +{ + private static final String INTEGER = "INTEGER"; + private static final String VARCHAR50 = "VARCHAR(50)"; + private final XMultiServiceFactory m_orb; + private final HsqlDatabase m_database; + private final DataSource m_dataSource; + private final Connection m_connection; + + /** constructs the CRM database + */ + public CRMDatabase( XMultiServiceFactory _orb, boolean _withUI ) throws Exception + { + m_orb = _orb; + + m_database = new HsqlDatabase( m_orb ); + m_dataSource = m_database.getDataSource(); + + if ( _withUI ) + { + final XComponentLoader loader = UnoRuntime.queryInterface( XComponentLoader.class, + m_orb.createInstance( "com.sun.star.frame.Desktop" ) ); + PropertyValue[] loadArgs = new PropertyValue[] { + new PropertyValue( "PickListEntry", 0, false, PropertyState.DIRECT_VALUE ) + }; + loader.loadComponentFromURL( m_database.getDocumentURL(), "_blank", 0, loadArgs ); + getDocumentUI().connect(); + m_connection = new Connection( getDocumentUI().getActiveConnection() ); + } + else + { + m_connection = m_database.defaultConnection(); + } + + createTables(); + createQueries(); + } + + /** + * creates a CRMDatabase from an existing document, given by URL + * @param _orb + * @param _existingDocumentURL + * @throws Exceptio + */ + public CRMDatabase( XMultiServiceFactory _orb, final String _existingDocumentURL ) throws Exception + { + m_orb = _orb; + + m_database = new HsqlDatabase( m_orb, _existingDocumentURL ); + m_dataSource = m_database.getDataSource(); + m_connection = m_database.defaultConnection(); + } + + // -------------------------------------------------------------------------------------------------------- + /** returns the database document underlying the CRM database + */ + public final HsqlDatabase getDatabase() + { + return m_database; + } + + // -------------------------------------------------------------------------------------------------------- + /** returns the default connection to the database + */ + public final Connection getConnection() + { + return m_connection; + } + + // -------------------------------------------------------------------------------------------------------- + public void saveAndClose() throws SQLException, IOException + { + XDatabaseDocumentUI ui = getDocumentUI(); + if ( ui != null ) + ui.closeSubComponents(); + m_database.store(); + m_database.closeAndDelete(); + } + + // -------------------------------------------------------------------------------------------------------- + public XDatabaseDocumentUI getDocumentUI() + { + XModel docModel = UnoRuntime.queryInterface( XModel.class, m_database.getDatabaseDocument() ); + return UnoRuntime.queryInterface( XDatabaseDocumentUI.class, docModel.getCurrentController() ); + } + + // -------------------------------------------------------------------------------------------------------- + public XController loadSubComponent( final int _objectType, final String _name ) throws IllegalArgumentException, SQLException, NoSuchElementException + { + XDatabaseDocumentUI docUI = getDocumentUI(); + if ( !docUI.isConnected() ) + docUI.connect(); + + XComponent subComponent = docUI.loadComponent( _objectType, _name, false ); + XController controller = UnoRuntime.queryInterface( XController.class, subComponent ); + if ( controller != null ) + return controller; + XModel document = UnoRuntime.queryInterface( XModel.class, subComponent ); + return document.getCurrentController(); + } + + // -------------------------------------------------------------------------------------------------------- + private void createTables() throws SQLException + { + HsqlTableDescriptor table = new HsqlTableDescriptor( "categories", + new HsqlColumnDescriptor[] { + new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), + new HsqlColumnDescriptor( "Name",VARCHAR50), + new HsqlColumnDescriptor( "Description", "VARCHAR(1024)" ), + new HsqlColumnDescriptor( "Image", "LONGVARBINARY" ) } ); + m_database.createTable( table, true ); + + m_database.executeSQL( "INSERT INTO \"categories\" ( \"ID\", \"Name\" ) VALUES ( 1, 'Food' )" ); + m_database.executeSQL( "INSERT INTO \"categories\" ( \"ID\", \"Name\" ) VALUES ( 2, 'Furniture' )" ); + + table = new HsqlTableDescriptor( "products", + new HsqlColumnDescriptor[] { + new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), + new HsqlColumnDescriptor( "Name",VARCHAR50), + new HsqlColumnDescriptor( "CategoryID",INTEGER, HsqlColumnDescriptor.REQUIRED, "categories", "ID" ) } ); + m_database.createTable( table, true ); + + m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 1, 'Oranges', 1 )" ); + m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 2, 'Apples', 1 )" ); + m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 3, 'Pears', 1 )" ); + m_database.executeSQL( "INSERT INTO \"products\" VALUES ( 4, 'Strawberries', 1 )" ); + + table = new HsqlTableDescriptor( "customers", + new HsqlColumnDescriptor[] { + new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), + new HsqlColumnDescriptor( "Name",VARCHAR50), + new HsqlColumnDescriptor( "Address",VARCHAR50), + new HsqlColumnDescriptor( "City",VARCHAR50), + new HsqlColumnDescriptor( "Postal",VARCHAR50), + new HsqlColumnDescriptor( "Comment","LONGVARCHAR")} ); + m_database.createTable( table, true ); + + m_database.executeSQL( "INSERT INTO \"customers\" VALUES(1,'Food, Inc.','Down Under','Melbourne','509','Prefered') " ); + m_database.executeSQL( "INSERT INTO \"customers\" VALUES(2,'Simply Delicious','Down Under','Melbourne','518',null) " ); + m_database.executeSQL( "INSERT INTO \"customers\" VALUES(3,'Pure Health','10 Fish St.','San Francisco','94107',null) " ); + m_database.executeSQL( "INSERT INTO \"customers\" VALUES(4,'Milk And More','Arlington Road 21','Dublin','31021','Good one.') " ); + + table = new HsqlTableDescriptor( "orders", + new HsqlColumnDescriptor[] { + new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), + new HsqlColumnDescriptor( "CustomerID",INTEGER, HsqlColumnDescriptor.REQUIRED, "customers", "ID" ), + new HsqlColumnDescriptor( "OrderDate", "DATE" ), + new HsqlColumnDescriptor( "ShipDate", "DATE" ) } ); + m_database.createTable( table, true ); + + m_database.executeSQL( "INSERT INTO \"orders\" (\"ID\", \"CustomerID\", \"OrderDate\") VALUES(1, 1, {D '2009-01-01'})" ); + m_database.executeSQL( "INSERT INTO \"orders\" VALUES(2, 2, {D '2009-01-01'}, {D '2009-01-23'})" ); + + table = new HsqlTableDescriptor( "orders_details", + new HsqlColumnDescriptor[] { + new HsqlColumnDescriptor( "OrderID",INTEGER, HsqlColumnDescriptor.PRIMARY, "orders", "ID" ), + new HsqlColumnDescriptor( "ProductID",INTEGER, HsqlColumnDescriptor.PRIMARY, "products", "ID" ), + new HsqlColumnDescriptor( "Quantity",INTEGER) } ); + m_database.createTable( table, true ); + + m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(1, 1, 100)" ); + m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(1, 2, 100)" ); + m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(2, 2, 2000)" ); + m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(2, 3, 2000)" ); + m_database.executeSQL( "INSERT INTO \"orders_details\" VALUES(2, 4, 2000)" ); + + // since we created the tables by directly executing the SQL statements, we need to refresh + // the tables container + m_connection.refreshTables(); + } + + // -------------------------------------------------------------------------------------------------------- + private void validateUnparseable() + { + // The "unparseable" query should be indeed be unparseable by OOo (though a valid HSQL query) + XSingleSelectQueryComposer composer; + QueryDefinition unparseableQuery; + try + { + final XMultiServiceFactory factory = UnoRuntime.queryInterface( + XMultiServiceFactory.class, m_database.defaultConnection().getXConnection() ); + composer = UnoRuntime.queryInterface( + XSingleSelectQueryComposer.class, factory.createInstance( "com.sun.star.sdb.SingleSelectQueryComposer" ) ); + unparseableQuery = m_dataSource.getQueryDefinition( "unparseable" ); + } + catch( Exception e ) + { + throw new RuntimeException( "caught an unexpected exception: " + e.getMessage() ); + } + + boolean caughtExpected = false; + try + { + composer.setQuery( unparseableQuery.getCommand() ); + } + catch (WrappedTargetException e) { } + catch( SQLException e ) + { + caughtExpected = true; + } + + if ( !caughtExpected ) + throw new RuntimeException( "Somebody improved the parser! This is bad :), since we need an unparsable query here!" ); + } + + // -------------------------------------------------------------------------------------------------------- + private void createQueries() throws ElementExistException, WrappedTargetException, com.sun.star.lang.IllegalArgumentException + { + m_database.getDataSource().createQuery( + "all orders", + "SELECT \"orders\".\"ID\" AS \"Order No.\", " + + "\"customers\".\"Name\" AS \"Customer Name\", " + + "\"orders\".\"OrderDate\" AS \"Order Date\", " + + "\"orders\".\"ShipDate\" AS \"Ship Date\", " + + "\"orders_details\".\"Quantity\", " + + "\"products\".\"Name\" AS \"Product Name\" " + + "FROM \"orders_details\" AS \"orders_details\", " + + "\"orders\" AS \"orders\", " + + "\"products\" AS \"products\", " + + "\"customers\" AS \"customers\" " + + "WHERE ( \"orders_details\".\"OrderID\" = \"orders\".\"ID\" " + + "AND \"orders_details\".\"ProductID\" = \"products\".\"ID\" " + + "AND \"orders\".\"CustomerID\" = \"customers\".\"ID\" )" + ); + + m_database.getDataSource().createQuery( + "unshipped orders", + "SELECT * " + + "FROM \"all orders\"" + + "WHERE ( \"ShipDate\" IS NULL )" + ); + + m_database.getDataSource().createQuery( "parseable", "SELECT * FROM \"customers\"" ); + m_database.getDataSource().createQuery( "parseable native", "SELECT * FROM INFORMATION_SCHEMA.SYSTEM_VIEWS", false ); + m_database.getDataSource().createQuery( "unparseable", + "SELECT CAST( \"ID\" AS VARCHAR(3) ) AS \"ID_VARCHAR\" FROM \"products\"", false ); + + validateUnparseable(); + } +} diff --git a/connectivity/qa/connectivity/tools/DataSource.java b/connectivity/qa/connectivity/tools/DataSource.java index 578d906fb2..df43ee5eee 100644 --- a/connectivity/qa/connectivity/tools/DataSource.java +++ b/connectivity/qa/connectivity/tools/DataSource.java @@ -39,10 +39,8 @@ import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.beans.XPropertySet; import com.sun.star.sdb.XQueryDefinitionsSupplier; import com.sun.star.sdbc.XDataSource; -import com.sun.star.sdbcx.XTablesSupplier; import com.sun.star.uno.Exception; import com.sun.star.uno.UnoRuntime; -import com.sun.star.util.XRefreshable; import java.util.logging.Level; import java.util.logging.Logger; @@ -57,11 +55,10 @@ public class DataSource { m_orb = _orb; - final XNameAccess dbContext = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, - _orb.createInstance("com.sun.star.sdb.DatabaseContext")); + final XNameAccess dbContext = UnoRuntime.queryInterface( + XNameAccess.class, _orb.createInstance( "com.sun.star.sdb.DatabaseContext" ) ); - m_dataSource = (XDataSource) UnoRuntime.queryInterface(XDataSource.class, - dbContext.getByName(_registeredName)); + m_dataSource = UnoRuntime.queryInterface( XDataSource.class, dbContext.getByName( _registeredName ) ); } public DataSource(final XMultiServiceFactory _orb,final XDataSource _dataSource) @@ -86,13 +83,11 @@ public class DataSource */ public void createQuery(final String _name, final String _sqlCommand, final boolean _escapeProcessing) throws ElementExistException, WrappedTargetException, com.sun.star.lang.IllegalArgumentException { - final XSingleServiceFactory queryDefsFac = (XSingleServiceFactory) UnoRuntime.queryInterface( - XSingleServiceFactory.class, getQueryDefinitions()); + final XSingleServiceFactory queryDefsFac = UnoRuntime.queryInterface( XSingleServiceFactory.class, getQueryDefinitions() ); XPropertySet queryDef = null; try { - queryDef = (XPropertySet) UnoRuntime.queryInterface( - XPropertySet.class, queryDefsFac.createInstance()); + queryDef = UnoRuntime.queryInterface( XPropertySet.class, queryDefsFac.createInstance() ); queryDef.setPropertyValue("Command", _sqlCommand); queryDef.setPropertyValue("EscapeProcessing", Boolean.valueOf(_escapeProcessing)); } @@ -101,8 +96,7 @@ public class DataSource e.printStackTrace(System.err); } - final XNameContainer queryDefsContainer = (XNameContainer) UnoRuntime.queryInterface( - XNameContainer.class, getQueryDefinitions()); + final XNameContainer queryDefsContainer = UnoRuntime.queryInterface( XNameContainer.class, getQueryDefinitions() ); queryDefsContainer.insertByName(_name, queryDef); } @@ -113,8 +107,7 @@ public class DataSource final XNameAccess allDefs = getQueryDefinitions(); try { - return new QueryDefinition( - (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, allDefs.getByName(_name))); + return new QueryDefinition( UnoRuntime.queryInterface( XPropertySet.class, allDefs.getByName( _name) ) ); } catch (WrappedTargetException e) { @@ -126,25 +119,11 @@ public class DataSource */ public XNameAccess getQueryDefinitions() { - final XQueryDefinitionsSupplier suppQueries = (XQueryDefinitionsSupplier) UnoRuntime.queryInterface( + final XQueryDefinitionsSupplier suppQueries = UnoRuntime.queryInterface( XQueryDefinitionsSupplier.class, m_dataSource); return suppQueries.getQueryDefinitions(); } - /** refreshs the table container of a given connection - * - * This is usually necessary if you created tables by directly executing SQL statements, - * bypassing the SDBCX layer. - */ - public void refreshTables(final com.sun.star.sdbc.XConnection _connection) - { - final XTablesSupplier suppTables = (XTablesSupplier) UnoRuntime.queryInterface( - XTablesSupplier.class, _connection); - final XRefreshable refreshTables = (XRefreshable) UnoRuntime.queryInterface( - XRefreshable.class, suppTables.getTables()); - refreshTables.refresh(); - } - /** returns the name of the data source * * If a data source is registered at the database context, the name is the registration @@ -157,8 +136,7 @@ public class DataSource String name = null; try { - final XPropertySet dataSourceProps = (XPropertySet) UnoRuntime.queryInterface( - XPropertySet.class, m_dataSource); + final XPropertySet dataSourceProps = UnoRuntime.queryInterface( XPropertySet.class, m_dataSource ); name = (String) dataSourceProps.getPropertyValue("Name"); } catch (Exception ex) diff --git a/connectivity/qa/connectivity/tools/DatabaseAccess.java b/connectivity/qa/connectivity/tools/DatabaseAccess.java index bc39bb0990..78608063e6 100755 --- a/connectivity/qa/connectivity/tools/DatabaseAccess.java +++ b/connectivity/qa/connectivity/tools/DatabaseAccess.java @@ -34,7 +34,7 @@ import com.sun.star.io.IOException; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.sdb.XOfficeDatabaseDocument; import com.sun.star.sdbc.SQLException; -import com.sun.star.sdbc.XConnection; +import connectivity.tools.sdb.Connection; /** * @@ -42,7 +42,7 @@ import com.sun.star.sdbc.XConnection; */ public interface DatabaseAccess { - XConnection defaultConnection() throws SQLException; + Connection defaultConnection() throws SQLException; void executeSQL(final String statementString) throws SQLException; diff --git a/connectivity/qa/connectivity/tools/HsqlDatabase.java b/connectivity/qa/connectivity/tools/HsqlDatabase.java index 036edd9a6a..b3fd724c17 100644 --- a/connectivity/qa/connectivity/tools/HsqlDatabase.java +++ b/connectivity/qa/connectivity/tools/HsqlDatabase.java @@ -30,6 +30,7 @@ package connectivity.tools; import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.PropertyState; import com.sun.star.beans.XPropertySet; import com.sun.star.container.ElementExistException; import com.sun.star.frame.XStorable; @@ -83,9 +84,9 @@ public class HsqlDatabase extends AbstractDatabase dsProperties.setPropertyValue("URL", "sdbc:embedded:hsqldb"); final XStorable storable = (XStorable) UnoRuntime.queryInterface(XStorable.class, m_databaseDocument); - storable.storeAsURL(m_databaseDocumentFile, new PropertyValue[] - { - }); + storable.storeAsURL( m_databaseDocumentFile, new PropertyValue[] + { new PropertyValue( "PickListEntry", 0, false, PropertyState.DIRECT_VALUE ) + } ); } /** drops the table with a given name @@ -208,10 +209,8 @@ public class HsqlDatabase extends AbstractDatabase public void createTableInSDBCX(final HsqlTableDescriptor _tableDesc) throws SQLException, ElementExistException { final XPropertySet sdbcxDescriptor = _tableDesc.createSdbcxDescriptor(defaultConnection()); - final XTablesSupplier suppTables = (XTablesSupplier) UnoRuntime.queryInterface( - XTablesSupplier.class, defaultConnection()); - final XAppend appendTable = (XAppend) UnoRuntime.queryInterface( - XAppend.class, suppTables.getTables()); + final XTablesSupplier suppTables = UnoRuntime.queryInterface( XTablesSupplier.class, defaultConnection().getXConnection() ); + final XAppend appendTable = UnoRuntime.queryInterface( XAppend.class, suppTables.getTables() ); appendTable.appendByDescriptor(sdbcxDescriptor); } } diff --git a/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java b/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java index 483241904b..4b900c7056 100644 --- a/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java +++ b/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java @@ -33,11 +33,11 @@ package connectivity.tools; import com.sun.star.beans.XPropertySet; import com.sun.star.container.XNameAccess; import com.sun.star.sdbc.ColumnValue; -import com.sun.star.sdbc.XConnection; import com.sun.star.sdbcx.XColumnsSupplier; import com.sun.star.sdbcx.XDataDescriptorFactory; import com.sun.star.sdbcx.XTablesSupplier; import com.sun.star.uno.UnoRuntime; +import connectivity.tools.sdb.Connection; /** is a very simply descriptor of a HSQL table, to be used with a HsqlDatabase.createTable method */ @@ -67,12 +67,10 @@ public class HsqlTableDescriptor return m_columns; } - public XPropertySet createSdbcxDescriptor( XConnection _forConnection ) + public XPropertySet createSdbcxDescriptor( Connection _forConnection ) { - XTablesSupplier suppTables = (XTablesSupplier)UnoRuntime.queryInterface( - XTablesSupplier.class, _forConnection ); - XDataDescriptorFactory tableDescFac = (XDataDescriptorFactory)UnoRuntime.queryInterface( - XDataDescriptorFactory.class, suppTables.getTables() ); + XTablesSupplier suppTables = UnoRuntime.queryInterface( XTablesSupplier.class, _forConnection.getXConnection() ); + XDataDescriptorFactory tableDescFac = UnoRuntime.queryInterface( XDataDescriptorFactory.class, suppTables.getTables() ); XPropertySet tableDesc = tableDescFac.createDataDescriptor(); try @@ -81,12 +79,10 @@ public class HsqlTableDescriptor } catch ( Exception e ) { e.printStackTrace( System.err ); } - XColumnsSupplier suppDescCols = (XColumnsSupplier)UnoRuntime.queryInterface( - XColumnsSupplier.class, tableDesc ); + XColumnsSupplier suppDescCols = UnoRuntime.queryInterface( XColumnsSupplier.class, tableDesc ); XNameAccess descColumns = suppDescCols.getColumns(); - XDataDescriptorFactory columnDescFac = (XDataDescriptorFactory)UnoRuntime.queryInterface( - XDataDescriptorFactory.class, descColumns ); + XDataDescriptorFactory columnDescFac = UnoRuntime.queryInterface( XDataDescriptorFactory.class, descColumns ); HsqlColumnDescriptor[] myColumns = getColumns(); for ( int i = 0; i < myColumns.length; ++i ) diff --git a/connectivity/qa/connectivity/tools/makefile.mk b/connectivity/qa/connectivity/tools/makefile.mk index 589a85ea38..32aa94c773 100644 --- a/connectivity/qa/connectivity/tools/makefile.mk +++ b/connectivity/qa/connectivity/tools/makefile.mk @@ -29,10 +29,10 @@ # #************************************************************************* -PRJ = ..$/..$/.. +PRJ = ../../.. TARGET = ConnectivityTools PRJNAME = connectivity -PACKAGE = connectivity$/tools +PACKAGE = connectivity/tools # --- Settings ----------------------------------------------------- .INCLUDE: settings.mk @@ -46,14 +46,8 @@ all: #----- compile .java files ----------------------------------------- JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunnerLight.jar -# Do not use $/ with the $(FIND) command as for W32-4nt this leads to a backslash -# in a posix command. In this special case use / instead of $/ -.IF "$(GUI)"=="OS2" -JAVAFILES := $(shell @ls ./*.java) -.ELSE -JAVAFILES := $(shell @$(FIND) ./*.java) -.ENDIF -JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) +JAVAFILES := $(shell @$(FIND) . -name "*.java") +JAVACLASSFILES := $(foreach,i,$(JAVAFILES) $(CLASSDIR)/$(PACKAGE)/$(i:d)$(i:b).class) #----- make a jar from compiled files ------------------------------ diff --git a/connectivity/qa/connectivity/tools/sdb/Connection.java b/connectivity/qa/connectivity/tools/sdb/Connection.java new file mode 100644 index 0000000000..aac120fb1e --- /dev/null +++ b/connectivity/qa/connectivity/tools/sdb/Connection.java @@ -0,0 +1,93 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package connectivity.tools.sdb; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.sdb.XSingleSelectQueryComposer; +import com.sun.star.sdbc.SQLException; +import com.sun.star.sdbc.XConnection; +import com.sun.star.sdbc.XDatabaseMetaData; +import com.sun.star.sdbc.XPreparedStatement; +import com.sun.star.sdbc.XResultSet; +import com.sun.star.sdbc.XStatement; +import com.sun.star.sdbcx.XTablesSupplier; +import com.sun.star.uno.Exception; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.util.XRefreshable; + +/** + * is a convenience wrapper around a SDB-level connection object + */ +public class Connection +{ + private final XConnection m_connection; + + public Connection( final XConnection _connection ) + { + m_connection = _connection; + } + + public XConnection getXConnection() + { + return m_connection; + } + + public boolean execute( final String _sql ) throws SQLException + { + XStatement statement = createStatement(); + return statement.execute( _sql ); + } + + public XResultSet executeQuery( final String _sql ) throws SQLException + { + XStatement statement = createStatement(); + return statement.executeQuery( _sql ); + } + + public int executeUpdate( final String _sql ) throws SQLException + { + XStatement statement = createStatement(); + return statement.executeUpdate( _sql ); + } + + public void refreshTables() + { + final XTablesSupplier suppTables = UnoRuntime.queryInterface(XTablesSupplier.class, m_connection); + final XRefreshable refresh = UnoRuntime.queryInterface( XRefreshable.class, suppTables.getTables() ); + refresh.refresh(); + } + + public XSingleSelectQueryComposer createSingleSelectQueryComposer() throws Exception + { + final XMultiServiceFactory connectionFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class, m_connection ); + return UnoRuntime.queryInterface( + XSingleSelectQueryComposer.class, connectionFactory.createInstance( "com.sun.star.sdb.SingleSelectQueryComposer" ) ); + } + + public + XStatement createStatement() throws SQLException + { + return m_connection.createStatement(); + } + + public + XPreparedStatement prepareStatement( String _sql ) throws SQLException + { + return m_connection.prepareStatement( _sql ); + } + + public + XDatabaseMetaData getMetaData() throws SQLException + { + return m_connection.getMetaData(); + } + + public + void close() throws SQLException + { + m_connection.close(); + } +} diff --git a/connectivity/source/commontools/BlobHelper.cxx b/connectivity/source/commontools/BlobHelper.cxx new file mode 100644 index 0000000000..ba6aaf2715 --- /dev/null +++ b/connectivity/source/commontools/BlobHelper.cxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FValue.cxx,v $ + * $Revision: 1.34 $ + * + * 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/FValue.cxx b/connectivity/source/commontools/FValue.cxx index 3068acde8b..9b5a21ff60 100644 --- a/connectivity/source/commontools/FValue.cxx +++ b/connectivity/source/commontools/FValue.cxx @@ -257,6 +257,7 @@ void ORowSetValue::setTypeKind(sal_Int32 _eType) case DataType::BLOB: case DataType::CLOB: case DataType::OBJECT: + case DataType::OTHER: (*this) = getAny(); break; default: @@ -847,6 +848,7 @@ bool ORowSetValue::operator==(const ORowSetValue& _rRH) const case DataType::BLOB: case DataType::CLOB: case DataType::OBJECT: + case DataType::OTHER: bRet = false; break; default: @@ -913,6 +915,7 @@ Any ORowSetValue::makeAny() const case DataType::BLOB: case DataType::CLOB: case DataType::OBJECT: + case DataType::OTHER: rValue = getAny(); break; case DataType::BIT: @@ -1019,6 +1022,19 @@ Any ORowSetValue::makeAny() const 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; } } return aRet; @@ -1090,6 +1106,9 @@ sal_Bool ORowSetValue::getBool() const case DataType::INTEGER: bRet = m_bSigned ? (m_aValue.m_nInt32 != 0) : (*static_cast<sal_Int64*>(m_aValue.m_pValue) != sal_Int64(0)); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return bRet; @@ -1131,6 +1150,8 @@ sal_Int8 ORowSetValue::getInt8() const 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: @@ -1155,6 +1176,9 @@ sal_Int8 ORowSetValue::getInt8() const else nRet = static_cast<sal_Int8>(*static_cast<sal_Int64*>(m_aValue.m_pValue)); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return nRet; @@ -1196,6 +1220,8 @@ sal_Int16 ORowSetValue::getInt16() const 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: @@ -1220,6 +1246,9 @@ sal_Int16 ORowSetValue::getInt16() const else nRet = static_cast<sal_Int16>(*static_cast<sal_Int64*>(m_aValue.m_pValue)); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return nRet; @@ -1261,6 +1290,8 @@ sal_Int32 ORowSetValue::getInt32() const 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: @@ -1285,6 +1316,9 @@ sal_Int32 ORowSetValue::getInt32() const else nRet = static_cast<sal_Int32>(*static_cast<sal_Int64*>(m_aValue.m_pValue)); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return nRet; @@ -1326,6 +1360,8 @@ sal_Int64 ORowSetValue::getLong() const 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: @@ -1350,6 +1386,9 @@ sal_Int64 ORowSetValue::getLong() const else nRet = *(sal_Int64*)m_aValue.m_pValue; break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return nRet; @@ -1395,6 +1434,8 @@ float ORowSetValue::getFloat() const 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: @@ -1419,6 +1460,9 @@ float ORowSetValue::getFloat() const else nRet = float(*(sal_Int64*)m_aValue.m_pValue); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return nRet; @@ -1466,6 +1510,8 @@ double ORowSetValue::getDouble() const 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: @@ -1490,6 +1536,9 @@ double ORowSetValue::getDouble() const else nRet = double(*(sal_Int64*)m_aValue.m_pValue); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return nRet; @@ -1551,6 +1600,8 @@ void ORowSetValue::setFromDouble(const double& _rVal,sal_Int32 _nDatatype) 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: @@ -1595,12 +1646,39 @@ Sequence<sal_Int8> ORowSetValue::getSequence() const case DataType::BLOB: { Reference<XInputStream> xStream; - Any aValue = getAny(); + const Any aValue = makeAny(); if(aValue.hasValue()) { - aValue >>= xStream; + 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()) - xStream->readBytes(aSeq,xStream->available()); + { + 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; @@ -1658,6 +1736,9 @@ Sequence<sal_Int8> ORowSetValue::getSequence() const aValue.Year = pDateTime->Year; } break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return aValue; @@ -1696,6 +1777,10 @@ Sequence<sal_Int8> ORowSetValue::getSequence() const break; case DataType::TIME: aValue = *static_cast< ::com::sun::star::util::Time*>(m_aValue.m_pValue); + break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return aValue; @@ -1743,6 +1828,9 @@ Sequence<sal_Int8> ORowSetValue::getSequence() const case DataType::TIMESTAMP: aValue = *static_cast< ::com::sun::star::util::DateTime*>(m_aValue.m_pValue); break; + default: + OSL_ENSURE(0,"Illegal conversion!"); + break; } } return aValue; @@ -1833,6 +1921,9 @@ namespace detail 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() { } @@ -1862,6 +1953,9 @@ namespace detail 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: @@ -1892,7 +1986,10 @@ namespace detail 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 sal_Bool wasNull() const { return m_xColumn->wasNull( ); }; + 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; @@ -1987,13 +2084,17 @@ void ORowSetValue::impl_fill( const sal_Int32 _nType, sal_Bool _bNullable, const (*this) = _rValueSource.getLong(); break; case DataType::CLOB: - (*this) = ::com::sun::star::uno::makeAny(_rValueSource.getCharacterStream()); + (*this) = ::com::sun::star::uno::makeAny(_rValueSource.getClob()); setTypeKind(DataType::CLOB); break; case DataType::BLOB: - (*this) = ::com::sun::star::uno::makeAny(_rValueSource.getBinaryStream()); + (*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!" ); bReadData = false; @@ -2139,6 +2240,29 @@ void ORowSetValue::fill(const Any& _rValue) 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"); diff --git a/connectivity/source/commontools/TIndexes.cxx b/connectivity/source/commontools/TIndexes.cxx index b4ae00b603..d0fb9289ac 100644 --- a/connectivity/source/commontools/TIndexes.cxx +++ b/connectivity/source/commontools/TIndexes.cxx @@ -143,73 +143,80 @@ sdbcx::ObjectType OIndexesHelper::appendObject( const ::rtl::OUString& _rForName if ( m_pTable->isNew() ) return cloneDescriptor( descriptor ); - ::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 ( 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 "); + 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) + + ::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() ) { - 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.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.appendAscii(","); + aSql.setCharAt(aSql.getLength()-1,')'); } - aSql.setCharAt(aSql.getLength()-1,')'); - } - else - { - aSql.append(aComposedName); + 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(); + 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; + xColumns->getByIndex(0) >>= xColProp; - aSql.append(aDot); - aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))); - } + 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); + Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); + if ( xStmt.is() ) + { + ::rtl::OUString sSql = aSql.makeStringAndClear(); + xStmt->execute(sSql); + ::comphelper::disposeComponent(xStmt); + } } return createObject( _rForName ); @@ -221,27 +228,34 @@ void OIndexesHelper::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString _sElem Reference< XConnection> xConnection = m_pTable->getConnection(); if( xConnection.is() && !m_pTable->isNew()) { - ::rtl::OUString aName,aSchema; - sal_Int32 nLen = _sElementName.indexOf('.'); - if(nLen != -1) - aSchema = _sElementName.copy(0,nLen); - aName = _sElementName.copy(nLen+1); + 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 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 ); + ::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; + 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); + Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); + if ( xStmt.is() ) + { + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } } } } diff --git a/connectivity/source/commontools/TKeys.cxx b/connectivity/source/commontools/TKeys.cxx index 1875c3e283..ae7e8d6df9 100644 --- a/connectivity/source/commontools/TKeys.cxx +++ b/connectivity/source/commontools/TKeys.cxx @@ -150,69 +150,80 @@ sdbcx::ObjectType OKeysHelper::appendObject( const ::rtl::OUString& _rForName, c return xNewDescriptor; } - // 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. - 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; - ::rtl::OUString aSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ALTER TABLE ")); - ::rtl::OUString aQuote = m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString( ); - ::rtl::OUString aDot = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".")); - - aSql += composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable, ::dbtools::eInTableDefinitions, false, false, true ); - aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ADD ")); - - if ( nKeyType == KeyType::PRIMARY ) + if ( nKeyType == KeyType::FOREIGN ) { - aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" PRIMARY KEY (")); + descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE)) >>= sReferencedName; + descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_UPDATERULE)) >>= nUpdateRule; + descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE)) >>= nDeleteRule; } - else if ( nKeyType == KeyType::FOREIGN ) + + if ( m_pTable->getKeyService().is() ) { - aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FOREIGN KEY (")); + m_pTable->getKeyService()->addKey(m_pTable,descriptor); } 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) { - ::cppu::extractInterface(xColProp,xColumns->getByIndex(i)); - aSql += ::dbtools::quoteName( aQuote,getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))) - + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")); - } - aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"))); + // 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(".")); - sal_Int32 nUpdateRule = 0, nDeleteRule = 0; - ::rtl::OUString sReferencedName; + aSql.append(composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable, ::dbtools::eInTableDefinitions, false, false, true )); + aSql.appendAscii(" ADD "); - if ( nKeyType == KeyType::FOREIGN ) - { - descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE)) >>= sReferencedName; - - aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" REFERENCES ")) - + ::dbtools::quoteTableName(m_pTable->getConnection()->getMetaData(),sReferencedName,::dbtools::eInTableDefinitions); - aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (")); + if ( nKeyType == KeyType::PRIMARY ) + { + aSql.appendAscii(" PRIMARY KEY ("); + } + else if ( nKeyType == KeyType::FOREIGN ) + { + aSql.appendAscii(" FOREIGN KEY ("); + } + else + throw SQLException(); - for(sal_Int32 i=0;i<xColumns->getCount();++i) + 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) { - xColumns->getByIndex(i) >>= xColProp; - aSql += ::dbtools::quoteName( aQuote,getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_RELATEDCOLUMN)))) - + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")); + 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 = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"))); + aSql.appendAscii(")"); - descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_UPDATERULE)) >>= nUpdateRule; - descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE)) >>= nDeleteRule; + if ( nKeyType == KeyType::FOREIGN ) + { + aSql.appendAscii(" REFERENCES "); + aSql.append(::dbtools::quoteTableName(m_pTable->getConnection()->getMetaData(),sReferencedName,::dbtools::eInTableDefinitions)); + aSql.appendAscii(" ("); - aSql += getKeyRuleString(sal_True ,nUpdateRule); - aSql += getKeyRuleString(sal_False ,nDeleteRule); - } + 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); + 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 @@ -269,34 +280,41 @@ void OKeysHelper::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName Reference< XConnection> xConnection = m_pTable->getConnection(); if ( xConnection.is() && !m_pTable->isNew() ) { - ::rtl::OUString aSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ALTER TABLE ")); - - aSql += composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable,::dbtools::eInTableDefinitions, false, false, true ); - Reference<XPropertySet> xKey(getObject(_nPos),UNO_QUERY); - - sal_Int32 nKeyType = KeyType::PRIMARY; - if ( xKey.is() ) + if ( m_pTable->getKeyService().is() ) { - ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); - xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nKeyType; - } - if ( KeyType::PRIMARY == nKeyType ) - { - aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DROP PRIMARY KEY")); + m_pTable->getKeyService()->dropKey(m_pTable,xKey); } else { - aSql += getDropForeignKey(); - const ::rtl::OUString aQuote = m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString(); - aSql += ::dbtools::quoteName( aQuote,_sElementName); - } + ::rtl::OUStringBuffer aSql; + aSql.appendAscii("ALTER TABLE "); - Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); - if ( xStmt.is() ) - { - xStmt->execute(aSql); - ::comphelper::disposeComponent(xStmt); + 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); + } } } } diff --git a/connectivity/source/commontools/TTableHelper.cxx b/connectivity/source/commontools/TTableHelper.cxx index 9a150d4694..f8a43fd237 100644 --- a/connectivity/source/commontools/TTableHelper.cxx +++ b/connectivity/source/commontools/TTableHelper.cxx @@ -101,11 +101,40 @@ namespace connectivity struct OTableHelperImpl { TKeyMap m_aKeys; - Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData; + // 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(s_sTableRename),UNO_QUERY); + static const ::rtl::OUString s_sTableAlteration(RTL_CONSTASCII_USTRINGPARAM("TableAlterationServiceName")); + m_xAlter.set(xFac->createInstance(s_sTableAlteration),UNO_QUERY); + static const ::rtl::OUString s_sKeyAlteration(RTL_CONSTASCII_USTRINGPARAM("KeyAlterationServiceName")); + m_xKeyAlter.set(xFac->createInstance(s_sKeyAlteration),UNO_QUERY); + static const ::rtl::OUString s_sIndexAlteration(RTL_CONSTASCII_USTRINGPARAM("IndexAlterationServiceName")); + m_xIndexAlter.set(xFac->createInstance(s_sIndexAlteration),UNO_QUERY); + } + } + catch(const Exception&) + { + } + } }; } @@ -113,16 +142,8 @@ OTableHelper::OTableHelper( sdbcx::OCollection* _pTables, const Reference< XConnection >& _xConnection, sal_Bool _bCase) :OTable_TYPEDEF(_pTables,_bCase) - ,m_pImpl(new OTableHelperImpl) -{ - try - { - m_pImpl->m_xConnection = _xConnection; - m_pImpl->m_xMetaData = m_pImpl->m_xConnection->getMetaData(); - } - catch(const Exception&) - { - } + ,m_pImpl(new OTableHelperImpl(_xConnection)) +{ } // ------------------------------------------------------------------------- OTableHelper::OTableHelper( sdbcx::OCollection* _pTables, @@ -140,16 +161,8 @@ OTableHelper::OTableHelper( sdbcx::OCollection* _pTables, _Description, _SchemaName, _CatalogName) - ,m_pImpl(new OTableHelperImpl) + ,m_pImpl(new OTableHelperImpl(_xConnection)) { - try - { - m_pImpl->m_xConnection = _xConnection; - m_pImpl->m_xMetaData = m_pImpl->m_xConnection->getMetaData(); - } - catch(const Exception&) - { - } } // ----------------------------------------------------------------------------- OTableHelper::~OTableHelper() @@ -483,24 +496,31 @@ void SAL_CALL OTableHelper::rename( const ::rtl::OUString& newName ) throw(SQLEx if(!isNew()) { - ::rtl::OUString sSql = getRenameStart(); - ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); + 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 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; + ::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); + Reference< XStatement > xStmt = m_pImpl->m_xConnection->createStatement( ); + if ( xStmt.is() ) + { + xStmt->execute(sSql); + ::comphelper::disposeComponent(xStmt); + } } OTable_TYPEDEF::rename(newName); @@ -579,3 +599,24 @@ 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/dbmetadata.cxx b/connectivity/source/commontools/dbmetadata.cxx index 5e07514624..13ff267071 100644 --- a/connectivity/source/commontools/dbmetadata.cxx +++ b/connectivity/source/commontools/dbmetadata.cxx @@ -257,6 +257,27 @@ namespace dbtools } //-------------------------------------------------------------------- + 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 ); diff --git a/connectivity/source/commontools/dbtools.cxx b/connectivity/source/commontools/dbtools.cxx index eaf1d6fe8e..d4b485ca75 100644 --- a/connectivity/source/commontools/dbtools.cxx +++ b/connectivity/source/commontools/dbtools.cxx @@ -213,6 +213,7 @@ sal_Int32 getDefaultNumberFormat(sal_Int32 _nDataType, case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: + case DataType::CLOB: nFormat = _xTypes->getStandardFormat(NumberFormat::TEXT, _rLocale); break; case DataType::DATE: @@ -234,10 +235,10 @@ sal_Int32 getDefaultNumberFormat(sal_Int32 _nDataType, case DataType::STRUCT: case DataType::ARRAY: case DataType::BLOB: - case DataType::CLOB: case DataType::REF: default: - nFormat = NumberFormat::UNDEFINED; + nFormat = _xTypes->getStandardFormat(NumberFormat::UNDEFINED, _rLocale); + //nFormat = NumberFormat::UNDEFINED; } return nFormat; } @@ -1387,16 +1388,18 @@ namespace ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); Reference< XPropertySetInfo > xInfo = _xTable->getPropertySetInfo(); if ( xInfo.is() - && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)) - && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) ) { ::rtl::OUString aCatalog; ::rtl::OUString aSchema; ::rtl::OUString aTable; - _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)) >>= _out_rCatalog; - _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= _out_rSchema; + 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 @@ -1778,15 +1781,31 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>(); Reference<XNameAccess> xParamsAsNames(xParamsAsIndicies, UNO_QUERY); sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0; - if ( (nParamCount && _aParametersSet.empty()) || ::std::count(_aParametersSet.begin(),_aParametersSet.end(),true) != nParamCount ) + ::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(_aParametersSet,xParamsAsIndicies); + Reference<XIndexAccess> xWrappedParameters = new OParameterWrapper(aNewParameterSet,xParamsAsIndicies); aRequest.Parameters = xWrappedParameters; aRequest.Connection = _xConnection; OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest)); @@ -1814,11 +1833,10 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, Reference< XPropertySet > xParamColumn(xWrappedParameters->getByIndex(i),UNO_QUERY); if (xParamColumn.is()) { -#ifdef DBG_UTIL ::rtl::OUString sName; - xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sName; + xParamColumn->getPropertyValue(PROPERTY_NAME) >>= sName; OSL_ENSURE(sName.equals(pFinalValues->Name), "::dbaui::askForParameters: inconsistent parameter names!"); -#endif + // determine the field type and ... sal_Int32 nParamType = 0; xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nParamType; @@ -1826,21 +1844,17 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, sal_Int32 nScale = 0; if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE), xParamColumn)) xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale; - // and set the value - ::std::bit_vector::const_iterator aIter = _aParametersSet.begin(); - ::std::bit_vector::const_iterator aEnd = _aParametersSet.end(); - sal_Int32 j = 0; - sal_Int32 nParamPos = -1; - for(; aIter != aEnd && j <= i; ++aIter) - { - ++nParamPos; - if ( !*aIter ) + // (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] ) { - ++j; + _xParameters->setObjectWithInfo(*aIterPos, pFinalValues->Value, nParamType, nScale); } } - _xParameters->setObjectWithInfo(nParamPos + 1, pFinalValues->Value, nParamType, nScale); - // (the index of the parameters is one-based) } } } @@ -1850,9 +1864,20 @@ void setObjectWithInfo(const Reference<XParameters>& _xParams, sal_Int32 parameterIndex, const Any& x, sal_Int32 sqlType, - sal_Int32 /*scale*/) throw(SQLException, RuntimeException) + 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(!x.hasValue()) + if ( _rValue.isNull() ) _xParams->setNull(parameterIndex,sqlType); else { @@ -1860,65 +1885,62 @@ void setObjectWithInfo(const Reference<XParameters>& _xParams, { case DataType::DECIMAL: case DataType::NUMERIC: - _xParams->setObjectWithInfo(parameterIndex,x,sqlType,0); + _xParams->setObjectWithInfo(parameterIndex,_rValue.makeAny(),sqlType,scale); break; case DataType::CHAR: case DataType::VARCHAR: - //case DataType::DECIMAL: - //case DataType::NUMERIC: case DataType::LONGVARCHAR: - _xParams->setString(parameterIndex,::comphelper::getString(x)); + _xParams->setString(parameterIndex,_rValue); break; - case DataType::BIGINT: + case DataType::CLOB: { - sal_Int64 nValue = 0; - if(x >>= nValue) + Any x(_rValue.makeAny()); + ::rtl::OUString sValue; + if ( x >>= sValue ) + _xParams->setString(parameterIndex,sValue); + else { - _xParams->setLong(parameterIndex,nValue); - break; + 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: - { - float nValue = 0; - if(x >>= nValue) - { - _xParams->setFloat(parameterIndex,nValue); - break; - } - } - // run through if we couldn't set a float value case DataType::DOUBLE: - _xParams->setDouble(parameterIndex,::comphelper::getDouble(x)); + _xParams->setDouble(parameterIndex,_rValue); break; case DataType::DATE: - { - ::com::sun::star::util::Date aValue; - if(x >>= aValue) - _xParams->setDate(parameterIndex,aValue); - } + _xParams->setDate(parameterIndex,_rValue); break; case DataType::TIME: - { - ::com::sun::star::util::Time aValue; - if(x >>= aValue) - _xParams->setTime(parameterIndex,aValue); - } + _xParams->setTime(parameterIndex,_rValue); break; case DataType::TIMESTAMP: - { - ::com::sun::star::util::DateTime aValue; - if(x >>= aValue) - _xParams->setTimestamp(parameterIndex,aValue); - } + _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); @@ -1944,16 +1966,25 @@ void setObjectWithInfo(const Reference<XParameters>& _xParams, break; case DataType::BIT: case DataType::BOOLEAN: - _xParams->setBoolean(parameterIndex,::cppu::any2bool(x)); + _xParams->setBoolean(parameterIndex,_rValue); break; case DataType::TINYINT: - _xParams->setByte(parameterIndex,(sal_Int8)::comphelper::getINT32(x)); + if ( _rValue.isSigned() ) + _xParams->setByte(parameterIndex,_rValue); + else + _xParams->setShort(parameterIndex,_rValue); break; case DataType::SMALLINT: - _xParams->setShort(parameterIndex,(sal_Int16)::comphelper::getINT32(x)); + if ( _rValue.isSigned() ) + _xParams->setShort(parameterIndex,_rValue); + else + _xParams->setInt(parameterIndex,_rValue); break; case DataType::INTEGER: - _xParams->setInt(parameterIndex,::comphelper::getINT32(x)); + if ( _rValue.isSigned() ) + _xParams->setInt(parameterIndex,_rValue); + else + _xParams->setLong(parameterIndex,_rValue); break; default: { diff --git a/connectivity/source/commontools/dbtools2.cxx b/connectivity/source/commontools/dbtools2.cxx index 86a7f1e601..6c798efdf6 100644 --- a/connectivity/source/commontools/dbtools2.cxx +++ b/connectivity/source/commontools/dbtools2.cxx @@ -596,7 +596,39 @@ bool getBooleanDataSourceSetting( const Reference< XConnection >& _rxConnection, } 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) { diff --git a/connectivity/source/commontools/formattedcolumnvalue.cxx b/connectivity/source/commontools/formattedcolumnvalue.cxx index 58811abc5e..a0874572e2 100644 --- a/connectivity/source/commontools/formattedcolumnvalue.cxx +++ b/connectivity/source/commontools/formattedcolumnvalue.cxx @@ -45,13 +45,11 @@ /** === 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 @@ -62,6 +60,7 @@ namespace dbtools 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; @@ -116,21 +115,7 @@ namespace dbtools //................................................................ void lcl_clear_nothrow( FormattedColumnValue_Data& _rData ) { - if ( _rData.m_xFormatter.is() ) - { - try - { - Reference< XComponent > xFormatterComp( _rData.m_xFormatter, UNO_QUERY ); - if ( xFormatterComp.is() ) - xFormatterComp->dispose(); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - _rData.m_xFormatter.clear(); - } - + _rData.m_xFormatter.clear(); _rData.m_nFormatKey = 0; _rData.m_nFieldType = DataType::OTHER; _rData.m_nKeyType = NumberFormat::UNDEFINED; @@ -141,21 +126,24 @@ namespace dbtools } //................................................................ - void lcl_initColumnDataValue_nothrow( const ::comphelper::ComponentContext& _rContext, FormattedColumnValue_Data& _rData, - const Reference< XRowSet >& _rxRowSet, const Reference< XPropertySet >& _rxColumn ) + void lcl_initColumnDataValue_nothrow( FormattedColumnValue_Data& _rData, + const Reference< XNumberFormatter >& i_rNumberFormatter, const Reference< XPropertySet >& _rxColumn ) { lcl_clear_nothrow( _rData ); - OSL_PRECOND( _rxRowSet.is(), "lcl_initColumnDataValue_nothrow: no row set!" ); - OSL_PRECOND( _rxColumn.is(), "lcl_initColumnDataValue_nothrow: no column!" ); - if ( !_rxRowSet.is() || !_rxColumn.is() ) + 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 ) @@ -180,10 +168,6 @@ namespace dbtools break; } - // get the number formats supplier of the connection of the form - Reference< XConnection > xConnection( getConnection( _rxRowSet ), UNO_QUERY_THROW ); - Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( xConnection, sal_False, _rContext.getLegacyServiceFactory() ), UNO_QUERY_THROW ); - // get the format key of our bound field Reference< XPropertySetInfo > xPSI( _rxColumn->getPropertySetInfo(), UNO_QUERY_THROW ); bool bHaveFieldFormat = false; @@ -197,23 +181,49 @@ namespace dbtools // fall back to a format key as indicated by the field type Locale aSystemLocale; MsLangId::convertLanguageToLocale( MsLangId::getSystemLanguage(), aSystemLocale ); - Reference< XNumberFormatTypes > xNumTypes( xSupplier->getNumberFormats(), UNO_QUERY_THROW ); + Reference< XNumberFormatTypes > xNumTypes( xNumberFormatsSupp->getNumberFormats(), UNO_QUERY_THROW ); _rData.m_nFormatKey = getDefaultNumberFormat( _rxColumn, xNumTypes, aSystemLocale ); } // some more formatter settings - _rData.m_nKeyType = ::comphelper::getNumberFormatType( xSupplier->getNumberFormats(), _rData.m_nFormatKey ); - Reference< XPropertySet > xFormatSettings( xSupplier->getNumberFormatSettings(), UNO_QUERY_THROW ); + _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 ); - // create a formatter working with the connection's number format supplier - _rData.m_xFormatter.set( _rContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW ); - _rData.m_xFormatter->attachNumberFormatsSupplier( xSupplier ); + // 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 ); } } @@ -221,11 +231,19 @@ namespace dbtools //= FormattedColumnValue //==================================================================== //-------------------------------------------------------------------- - FormattedColumnValue::FormattedColumnValue( const ::comphelper::ComponentContext& _rContext, - const Reference< XRowSet >& _rxRowSet, const Reference< XPropertySet >& _rxColumn ) + 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( _rContext, *m_pData, _rxRowSet, _rxColumn ); + lcl_initColumnDataValue_nothrow( *m_pData, i_rNumberFormatter, _rxColumn ); } //-------------------------------------------------------------------- diff --git a/connectivity/source/commontools/makefile.mk b/connectivity/source/commontools/makefile.mk index cb5a4ad3f7..1cc6cf4949 100644 --- a/connectivity/source/commontools/makefile.mk +++ b/connectivity/source/commontools/makefile.mk @@ -89,6 +89,7 @@ EXCEPTIONSFILES=\ $(SLO)$/ParamterSubstitution.obj \ $(SLO)$/DriversConfig.obj \ $(SLO)$/formattedcolumnvalue.obj \ + $(SLO)$/BlobHelper.obj \ $(SLO)$/warningscontainer.obj SLOFILES=\ diff --git a/connectivity/source/commontools/predicateinput.cxx b/connectivity/source/commontools/predicateinput.cxx index 94d269955b..8bb6b79974 100644 --- a/connectivity/source/commontools/predicateinput.cxx +++ b/connectivity/source/commontools/predicateinput.cxx @@ -148,9 +148,10 @@ namespace dbtools sal_Int32 nType = DataType::OTHER; _rxField->getPropertyValue( ::rtl::OUString::createFromAscii( "Type" ) ) >>= nType; - if ( ( DataType::CHAR == nType ) - || ( DataType::VARCHAR == 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 ); diff --git a/connectivity/source/drivers/ado/AResultSet.cxx b/connectivity/source/drivers/ado/AResultSet.cxx index 10295db9a4..142286adca 100644 --- a/connectivity/source/drivers/ado/AResultSet.cxx +++ b/connectivity/source/drivers/ado/AResultSet.cxx @@ -334,11 +334,9 @@ Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw } // ------------------------------------------------------------------------- -Any SAL_CALL OResultSet::getObject( sal_Int32 /*columnIndex*/, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException) +Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException) { - - ::dbtools::throwFeatureNotImplementedException( "XRow::getObject", *this ); - return Any(); + return getValue(columnIndex).makeAny(); } // ------------------------------------------------------------------------- @@ -786,14 +784,24 @@ void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const ::com::s } // ------------------------------------------------------------------------- -void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 /*columnIndex*/, const Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(SQLException, RuntimeException) +void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) { - ::dbtools::throwFeatureNotImplementedException( "XRowUpdate::updateBinaryStream", *this ); + if(!x.is()) + ::dbtools::throwFunctionSequenceException(*this); + + Sequence<sal_Int8> aSeq; + x->readBytes(aSeq,length); + updateBytes(columnIndex,aSeq); } // ------------------------------------------------------------------------- -void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 /*columnIndex*/, const Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(SQLException, RuntimeException) +void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) { - ::dbtools::throwFeatureNotImplementedException( "XRowUpdate::updateCharacterStream", *this ); + if(!x.is()) + ::dbtools::throwFunctionSequenceException(*this); + + Sequence<sal_Int8> aSeq; + x->readBytes(aSeq,length); + updateBytes(columnIndex,aSeq); } // ------------------------------------------------------------------------- void SAL_CALL OResultSet::refreshRow( ) throw(SQLException, RuntimeException) diff --git a/connectivity/source/drivers/ado/Aolevariant.cxx b/connectivity/source/drivers/ado/Aolevariant.cxx index 650c77a244..b98cf943f5 100644 --- a/connectivity/source/drivers/ado/Aolevariant.cxx +++ b/connectivity/source/drivers/ado/Aolevariant.cxx @@ -39,8 +39,17 @@ #include "diagnose_ex.h" #include "resource/sharedresources.hxx" #include "resource/ado_res.hrc" - +#include "com/sun/star/bridge/oleautomation/Date.hpp" +#include "com/sun/star/bridge/oleautomation/Currency.hpp" +#include "com/sun/star/bridge/oleautomation/SCode.hpp" +#include "com/sun/star/bridge/oleautomation/Decimal.hpp" + +using namespace com::sun::star::beans; +using namespace com::sun::star::uno; +using namespace com::sun::star::bridge::oleautomation; using namespace connectivity::ado; +using ::rtl::OUString; + OLEString::OLEString() :m_sStr(NULL) { @@ -698,6 +707,88 @@ SAFEARRAY* OLEVariant::getUI1SAFEARRAYPtr() const return V_ARRAY(&varDest); } // ----------------------------------------------------------------------------- +::com::sun::star::uno::Any OLEVariant::makeAny() const +{ + ::com::sun::star::uno::Any aValue; + switch (V_VT(this)) + { + case VT_EMPTY: + case VT_NULL: + aValue.setValue(NULL, Type()); + break; + case VT_I2: + aValue.setValue( & iVal, getCppuType( (sal_Int16*)0)); + break; + case VT_I4: + aValue.setValue( & lVal, getCppuType( (sal_Int32*)0)); + break; + case VT_R4: + aValue.setValue( & fltVal, getCppuType( (float*)0)); + break; + case VT_R8: + aValue.setValue(& dblVal, getCppuType( (double*)0)); + break; + case VT_CY: + { + Currency cy(cyVal.int64); + aValue <<= cy; + break; + } + case VT_DATE: + { + aValue <<= (::com::sun::star::util::Date)*this; + break; + } + case VT_BSTR: + { + OUString b(reinterpret_cast<const sal_Unicode*>(bstrVal)); + aValue.setValue( &b, getCppuType( &b)); + break; + } + case VT_BOOL: + { + sal_Bool b= boolVal == VARIANT_TRUE; + aValue.setValue( &b, getCppuType( &b)); + break; + } + case VT_I1: + aValue.setValue( & cVal, getCppuType((sal_Int8*)0)); + break; + case VT_UI1: // there is no unsigned char in UNO + aValue.setValue( & bVal, getCppuType( (sal_Int8*)0)); + break; + case VT_UI2: + aValue.setValue( & uiVal, getCppuType( (sal_uInt16*)0)); + break; + case VT_UI4: + aValue.setValue( & ulVal, getCppuType( (sal_uInt32*)0)); + break; + case VT_INT: + aValue.setValue( & intVal, getCppuType( (sal_Int32*)0)); + break; + case VT_UINT: + aValue.setValue( & uintVal, getCppuType( (sal_uInt32*)0)); + break; + case VT_VOID: + aValue.setValue( NULL, Type()); + break; + case VT_DECIMAL: + { + Decimal dec; + dec.Scale = decVal.scale; + dec.Sign = decVal.sign; + dec.LowValue = decVal.Lo32; + dec.MiddleValue = decVal.Mid32; + dec.HighValue = decVal.Hi32; + aValue <<= dec; + break; + } + + default: + break; + } + return aValue; +} // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/ado/ado.xcu b/connectivity/source/drivers/ado/ado.xcu index fe4596f19e..89ac9b1e5a 100755 --- a/connectivity/source/drivers/ado/ado.xcu +++ b/connectivity/source/drivers/ado/ado.xcu @@ -115,6 +115,11 @@ <value>true</value> </prop> </node> + <node oor:name="PrimaryKeySupport" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> </node> <node oor:name="MetaData"> <node oor:name="SupportsTableCreation" oor:op="replace"> @@ -152,6 +157,11 @@ <value>3</value> </prop> </node> + <node oor:name="ColumnAliasInOrderBy" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>false</value> + </prop> + </node> </node> <node oor:name="Features"> <node oor:name="UseSQL92NamingConstraints" oor:op="replace"> diff --git a/connectivity/source/drivers/ado/adoimp.cxx b/connectivity/source/drivers/ado/adoimp.cxx index cd89c61711..def609be32 100644 --- a/connectivity/source/drivers/ado/adoimp.cxx +++ b/connectivity/source/drivers/ado/adoimp.cxx @@ -157,8 +157,10 @@ DataTypeEnum ADOS::MapJdbc2ADOType(sal_Int32 _nType,sal_Int32 _nJetEngine) case DataType::BIT: return adBoolean; break; case DataType::BINARY: return adBinary; break; case DataType::VARCHAR: return adVarWChar; break; + case DataType::CLOB: case DataType::LONGVARCHAR: return adLongVarWChar; break; case DataType::VARBINARY: return adVarBinary; break; + case DataType::BLOB: case DataType::LONGVARBINARY: return adLongVarBinary; break; case DataType::CHAR: return adWChar; break; case DataType::TINYINT: return isJetEngine(_nJetEngine) ? adUnsignedTinyInt : adTinyInt;break; diff --git a/connectivity/source/drivers/file/FStatement.cxx b/connectivity/source/drivers/file/FStatement.cxx index 6d82486dae..652d41d886 100644 --- a/connectivity/source/drivers/file/FStatement.cxx +++ b/connectivity/source/drivers/file/FStatement.cxx @@ -497,13 +497,16 @@ void OStatement_Base::construct(const ::rtl::OUString& sql) throw(SQLException, // SELECT statement without columns -> error m_pConnection->throwGenericSQLException(STR_QUERY_NO_COLUMN,*this); - if ( m_aSQLIterator.getStatementType() == SQL_STATEMENT_CREATE_TABLE ) - // CREATE TABLE is not supported at all - m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,*this); - - if ( ( m_aSQLIterator.getStatementType() == SQL_STATEMENT_ODBC_CALL ) || ( m_aSQLIterator.getStatementType() == SQL_STATEMENT_UNKNOWN ) ) - // ODBC call or unknown statement type -> error - m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,*this); + switch(m_aSQLIterator.getStatementType()) + { + case SQL_STATEMENT_CREATE_TABLE: + case SQL_STATEMENT_ODBC_CALL: + case SQL_STATEMENT_UNKNOWN: + m_pConnection->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,*this); + break; + default: + break; + } // at this moment we support only one table per select statement Reference< ::com::sun::star::lang::XUnoTunnel> xTunnel(xTabs.begin()->second,UNO_QUERY); diff --git a/connectivity/source/drivers/hsqldb/HTable.cxx b/connectivity/source/drivers/hsqldb/HTable.cxx index 8e6fc34b2c..baed33e43c 100644 --- a/connectivity/source/drivers/hsqldb/HTable.cxx +++ b/connectivity/source/drivers/hsqldb/HTable.cxx @@ -214,7 +214,7 @@ void SAL_CALL OHSQLTable::alterColumnByName( const ::rtl::OUString& colName, con // now we should look if the name of the column changed ::rtl::OUString sNewColumnName; descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_NAME)) >>= sNewColumnName; - if ( !sNewColumnName.equalsIgnoreAsciiCase(colName) ) + if ( !sNewColumnName.equals(colName) ) { const ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); diff --git a/connectivity/source/drivers/jdbc/Boolean.cxx b/connectivity/source/drivers/jdbc/Boolean.cxx index 4e17033cee..c9f222827b 100644 --- a/connectivity/source/drivers/jdbc/Boolean.cxx +++ b/connectivity/source/drivers/jdbc/Boolean.cxx @@ -40,17 +40,19 @@ jclass java_lang_Boolean::theClass = 0; java_lang_Boolean::~java_lang_Boolean() {} - -jclass java_lang_Boolean::getMyClass() const +jclass java_lang_Boolean::st_getMyClass() { // die Klasse muss nur einmal geholt werden, daher statisch if( !theClass ) - { theClass = findMyClass("java/lang/Boolean"); - } return theClass; } +jclass java_lang_Boolean::getMyClass() const +{ + return st_getMyClass(); +} + java_lang_Boolean::java_lang_Boolean( sal_Bool _par0 ): java_lang_Object( NULL, (jobject)NULL ) { SDBThreadAttach t; diff --git a/connectivity/source/drivers/jdbc/CallableStatement.cxx b/connectivity/source/drivers/jdbc/CallableStatement.cxx index 8167c0ee8a..94cf7f58ea 100644 --- a/connectivity/source/drivers/jdbc/CallableStatement.cxx +++ b/connectivity/source/drivers/jdbc/CallableStatement.cxx @@ -227,9 +227,8 @@ void SAL_CALL java_sql_CallableStatement::registerOutParameter( sal_Int32 parame static jmethodID mID(NULL); obtainMethodId(t.pEnv, cMethodName,cSignature, mID); // Parameter konvertieren - jstring str = convertwchar_tToJavaString(t.pEnv,typeName); - t.pEnv->CallVoidMethod( object, mID, parameterIndex,sqlType,str); - t.pEnv->DeleteLocalRef(str); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,typeName)); + t.pEnv->CallVoidMethod( object, mID, parameterIndex,sqlType,str.get()); ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); } } @@ -336,23 +335,22 @@ void java_sql_CallableStatement::createStatement(JNIEnv* /*_pEnv*/) // Java-Call absetzen jobject out = NULL; // Parameter konvertieren - jstring str = convertwchar_tToJavaString(t.pEnv,m_sSqlStatement); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,m_sSqlStatement)); static jmethodID mID(NULL); if ( !mID ) mID = t.pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature ); if( mID ){ - out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID, str ,m_nResultSetType,m_nResultSetConcurrency); + out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID, str.get() ,m_nResultSetType,m_nResultSetConcurrency); } //mID else { static const char * cSignature2 = "(Ljava/lang/String;)Ljava/sql/CallableStatement;"; static jmethodID mID2 = t.pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature2 );OSL_ENSURE(mID2,"Unknown method id!"); if( mID2 ){ - out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID2, str ); + out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID2, str.get() ); } //mID } - t.pEnv->DeleteLocalRef(str); ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); if ( out ) diff --git a/connectivity/source/drivers/jdbc/Clob.cxx b/connectivity/source/drivers/jdbc/Clob.cxx index c3c53d5809..a1bbc0710a 100644 --- a/connectivity/source/drivers/jdbc/Clob.cxx +++ b/connectivity/source/drivers/jdbc/Clob.cxx @@ -34,6 +34,8 @@ #include "java/tools.hxx" #include "java/io/Reader.hxx" #include <connectivity/dbexception.hxx> +#include <rtl/logfile.hxx> + using namespace connectivity; //************************************************************** //************ Class: java.sql.Clob @@ -61,6 +63,7 @@ jclass java_sql_Clob::getMyClass() const sal_Int64 SAL_CALL java_sql_Clob::length( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_Clob::length" ); jlong out(0); SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); @@ -79,6 +82,7 @@ sal_Int64 SAL_CALL java_sql_Clob::length( ) throw(::com::sun::star::sdbc::SQLEx ::rtl::OUString SAL_CALL java_sql_Clob::getSubString( sal_Int64 pos, sal_Int32 subStringLength ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_Clob::getSubString" ); SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); ::rtl::OUString aStr; { @@ -98,6 +102,7 @@ sal_Int64 SAL_CALL java_sql_Clob::length( ) throw(::com::sun::star::sdbc::SQLEx ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL java_sql_Clob::getCharacterStream( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_Clob::getCharacterStream" ); SDBThreadAttach t; static jmethodID mID(NULL); jobject out = callObjectMethod(t.pEnv,"getCharacterStream","()Ljava/io/Reader;", mID); @@ -108,6 +113,7 @@ sal_Int64 SAL_CALL java_sql_Clob::length( ) throw(::com::sun::star::sdbc::SQLEx sal_Int64 SAL_CALL java_sql_Clob::position( const ::rtl::OUString& searchstr, sal_Int32 start ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_Clob::position" ); jlong out(0); SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); @@ -130,6 +136,7 @@ sal_Int64 SAL_CALL java_sql_Clob::position( const ::rtl::OUString& searchstr, sa sal_Int64 SAL_CALL java_sql_Clob::positionOfClob( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob >& /*pattern*/, sal_Int64 /*start*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_Clob::positionOfClob" ); ::dbtools::throwFeatureNotImplementedException( "XClob::positionOfClob", *this ); // this was put here in CWS warnings01. The previous implementation was defective, as it did ignore // the pattern parameter. Since the effort for proper implementation is rather high - we would need diff --git a/connectivity/source/drivers/jdbc/InputStream.cxx b/connectivity/source/drivers/jdbc/InputStream.cxx index 0236c7f350..17c9b54152 100644 --- a/connectivity/source/drivers/jdbc/InputStream.cxx +++ b/connectivity/source/drivers/jdbc/InputStream.cxx @@ -84,8 +84,9 @@ void SAL_CALL java_io_InputStream::closeInput( ) throw(::com::sun::star::io::No // ----------------------------------------------------- sal_Int32 SAL_CALL java_io_InputStream::readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { - if ( aData.getLength() < nBytesToRead ) - throw ::com::sun::star::io::BufferSizeExceededException(); + if (nBytesToRead < 0) + throw ::com::sun::star::io::BufferSizeExceededException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), *this ); + jint out(0); SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); @@ -102,7 +103,8 @@ sal_Int32 SAL_CALL java_io_InputStream::readBytes( ::com::sun::star::uno::Sequen if(out > 0) { jboolean p = sal_False; - memcpy(aData.getArray(),t.pEnv->GetByteArrayElements(pByteArray,&p),out); + aData.realloc ( out ); + rtl_copyMemory(aData.getArray(),t.pEnv->GetByteArrayElements(pByteArray,&p),out); } t.pEnv->DeleteLocalRef((jbyteArray)pByteArray); } //t.pEnv diff --git a/connectivity/source/drivers/jdbc/JConnection.cxx b/connectivity/source/drivers/jdbc/JConnection.cxx index e2f1afcb77..17e8d2dbbe 100644 --- a/connectivity/source/drivers/jdbc/JConnection.cxx +++ b/connectivity/source/drivers/jdbc/JConnection.cxx @@ -56,6 +56,7 @@ #include <rtl/ustrbuf.hxx> #include <jni.h> #include "resource/common_res.hrc" +#include <unotools/confignode.hxx> #include <list> #include <memory> @@ -553,10 +554,9 @@ Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareCall( const static jmethodID mID(NULL); obtainMethodId(t.pEnv, cMethodName,cSignature, mID); // Parameter konvertieren - jstring str = convertwchar_tToJavaString(t.pEnv,sql); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,sql)); - jobject out = t.pEnv->CallObjectMethod( object, mID, str ); - t.pEnv->DeleteLocalRef(str); + jobject out = t.pEnv->CallObjectMethod( object, mID, str.get() ); aStr = JavaString2String(t.pEnv, (jstring)out ); ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); } //t.pEnv @@ -767,7 +767,20 @@ void java_sql_Connection::loadDriverFromProperties( const ::rtl::OUString& _sDri enableAutoRetrievingEnabled( bAutoRetrievingEnabled ); setAutoRetrievingStatement( sGeneratedValueStatement ); } - +// ----------------------------------------------------------------------------- +::rtl::OUString java_sql_Connection::impl_getJavaDriverClassPath_nothrow(const ::rtl::OUString& _sDriverClass) +{ + static const ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/JDBC/DriverClassPaths")); + ::utl::OConfigurationTreeRoot aNamesRoot = ::utl::OConfigurationTreeRoot::createWithServiceFactory( + m_pDriver->getContext().getLegacyServiceFactory(), s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY); + ::rtl::OUString sURL; + if ( aNamesRoot.isValid() && aNamesRoot.hasByName( _sDriverClass ) ) + { + ::utl::OConfigurationNode aRegisterObj = aNamesRoot.openNode( _sDriverClass ); + OSL_VERIFY( aRegisterObj.getNodeValue( "Path" ) >>= sURL ); + } + return sURL; +} // ----------------------------------------------------------------------------- sal_Bool java_sql_Connection::construct(const ::rtl::OUString& url, const Sequence< PropertyValue >& info) @@ -790,6 +803,8 @@ sal_Bool java_sql_Connection::construct(const ::rtl::OUString& url, ::comphelper::NamedValueCollection aSettings( info ); sDriverClass = aSettings.getOrDefault( "JavaDriverClass", sDriverClass ); sDriverClassPath = aSettings.getOrDefault( "JavaDriverClassPath", sDriverClassPath); + if ( !sDriverClassPath.getLength() ) + sDriverClassPath = impl_getJavaDriverClassPath_nothrow(sDriverClass); bAutoRetrievingEnabled = aSettings.getOrDefault( "IsAutoRetrievingEnabled", bAutoRetrievingEnabled ); sGeneratedValueStatement = aSettings.getOrDefault( "AutoRetrievingStatement", sGeneratedValueStatement ); m_bParameterSubstitution = aSettings.getOrDefault( "ParameterNameSubstitution", m_bParameterSubstitution ); @@ -810,8 +825,8 @@ sal_Bool java_sql_Connection::construct(const ::rtl::OUString& url, static const char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;"; static const char * cMethodName = "connect"; // Java-Call absetzen - jmethodID mID = NULL; - if ( !mID )
+ static jmethodID mID = NULL; + if ( !mID ) mID = t.pEnv->GetMethodID( m_Driver_theClass, cMethodName, cSignature ); if ( mID ) { diff --git a/connectivity/source/drivers/jdbc/JStatement.cxx b/connectivity/source/drivers/jdbc/JStatement.cxx index 7aa1750bb6..049274c489 100644 --- a/connectivity/source/drivers/jdbc/JStatement.cxx +++ b/connectivity/source/drivers/jdbc/JStatement.cxx @@ -712,38 +712,44 @@ void java_sql_Statement_Base::getFastPropertyValue( ) const { java_sql_Statement_Base* THIS = const_cast<java_sql_Statement_Base*>(this); - switch(nHandle) + try + { + switch(nHandle) + { + case PROPERTY_ID_QUERYTIMEOUT: + rValue <<= THIS->getQueryTimeOut(); + break; + case PROPERTY_ID_MAXFIELDSIZE: + rValue <<= THIS->getMaxFieldSize(); + break; + case PROPERTY_ID_MAXROWS: + rValue <<= THIS->getMaxRows(); + break; + case PROPERTY_ID_CURSORNAME: + rValue <<= THIS->getCursorName(); + break; + case PROPERTY_ID_RESULTSETCONCURRENCY: + rValue <<= THIS->getResultSetConcurrency(); + break; + case PROPERTY_ID_RESULTSETTYPE: + rValue <<= THIS->getResultSetType(); + break; + case PROPERTY_ID_FETCHDIRECTION: + rValue <<= THIS->getFetchDirection(); + break; + case PROPERTY_ID_FETCHSIZE: + rValue <<= THIS->getFetchSize(); + break; + case PROPERTY_ID_ESCAPEPROCESSING: + rValue <<= (sal_Bool)m_bEscapeProcessing; + break; + case PROPERTY_ID_USEBOOKMARKS: + default: + ; + } + } + catch(const Exception&) { - case PROPERTY_ID_QUERYTIMEOUT: - rValue <<= THIS->getQueryTimeOut(); - break; - case PROPERTY_ID_MAXFIELDSIZE: - rValue <<= THIS->getMaxFieldSize(); - break; - case PROPERTY_ID_MAXROWS: - rValue <<= THIS->getMaxRows(); - break; - case PROPERTY_ID_CURSORNAME: - rValue <<= THIS->getCursorName(); - break; - case PROPERTY_ID_RESULTSETCONCURRENCY: - rValue <<= THIS->getResultSetConcurrency(); - break; - case PROPERTY_ID_RESULTSETTYPE: - rValue <<= THIS->getResultSetType(); - break; - case PROPERTY_ID_FETCHDIRECTION: - rValue <<= THIS->getFetchDirection(); - break; - case PROPERTY_ID_FETCHSIZE: - rValue <<= THIS->getFetchSize(); - break; - case PROPERTY_ID_ESCAPEPROCESSING: - rValue <<= (sal_Bool)m_bEscapeProcessing; - break; - case PROPERTY_ID_USEBOOKMARKS: - default: - ; } } // ------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/jdbc/Object.cxx b/connectivity/source/drivers/jdbc/Object.cxx index b8e8c87954..72f3731f5a 100644 --- a/connectivity/source/drivers/jdbc/Object.cxx +++ b/connectivity/source/drivers/jdbc/Object.cxx @@ -43,7 +43,7 @@ #include <vos/mutex.hxx> #include <osl/thread.h> #include <com/sun/star/uno/Sequence.hxx> - +#include "java/LocalRef.hxx" #include "resource/jdbc_log.hrc" #include <rtl/logfile.hxx> #include <comphelper/logging.hxx> @@ -395,10 +395,9 @@ void java_lang_Object::callVoidMethodWithStringArg( const char* _pMethodName, jm OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" ); obtainMethodId(t.pEnv, _pMethodName,"(Ljava/lang/String;)V", _inout_MethodID); - jstring str = convertwchar_tToJavaString(t.pEnv,_nArgument); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument)); // call method - t.pEnv->CallVoidMethod( object, _inout_MethodID , str); - t.pEnv->DeleteLocalRef(str); + t.pEnv->CallVoidMethod( object, _inout_MethodID , str.get()); ThrowSQLException( t.pEnv, NULL ); } // ------------------------------------------------------------------------- @@ -417,10 +416,9 @@ sal_Int32 java_lang_Object::callIntMethodWithStringArg( const char* _pMethodName // *this // ); - jstring str = convertwchar_tToJavaString(t.pEnv,_nArgument); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument)); // call method - jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str); - t.pEnv->DeleteLocalRef(str); + jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str.get()); ThrowSQLException( t.pEnv, NULL ); return (sal_Int32)out; } diff --git a/connectivity/source/drivers/jdbc/PreparedStatement.cxx b/connectivity/source/drivers/jdbc/PreparedStatement.cxx index 62e12c42a5..7639357a41 100644 --- a/connectivity/source/drivers/jdbc/PreparedStatement.cxx +++ b/connectivity/source/drivers/jdbc/PreparedStatement.cxx @@ -45,7 +45,7 @@ #include "resource/jdbc_log.hrc" #include "resource/common_res.hrc" #include "resource/sharedresources.hxx" - +#include "java/LocalRef.hxx" #include <string.h> using namespace connectivity; @@ -138,10 +138,9 @@ void SAL_CALL java_sql_PreparedStatement::setString( sal_Int32 parameterIndex, c // Java-Call absetzen static jmethodID mID(NULL); obtainMethodId(t.pEnv, cMethodName,cSignature, mID); - jstring str = convertwchar_tToJavaString(t.pEnv,x); - t.pEnv->CallVoidMethod( object, mID, parameterIndex,str); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,x)); + t.pEnv->CallVoidMethod( object, mID, parameterIndex,str.get()); // und aufraeumen - t.pEnv->DeleteLocalRef(str); ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); } //t.pEnv } diff --git a/connectivity/source/drivers/jdbc/ResultSet.cxx b/connectivity/source/drivers/jdbc/ResultSet.cxx index 8a5a9a22a0..144ee27c7c 100644 --- a/connectivity/source/drivers/jdbc/ResultSet.cxx +++ b/connectivity/source/drivers/jdbc/ResultSet.cxx @@ -30,10 +30,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" +#include "java/lang/String.hxx" +#include "java/lang/Boolean.hxx" #include "java/sql/ResultSet.hxx" #include "java/math/BigDecimal.hxx" #include "java/sql/JStatement.hxx" #include "java/sql/SQLWarning.hxx" +#include "java/sql/Timestamp.hxx" #include "java/sql/Array.hxx" #include "java/sql/Ref.hxx" #include "java/sql/Clob.hxx" @@ -54,6 +57,7 @@ #include "connectivity/dbexception.hxx" #include "resource/common_res.hrc" #include "resource/sharedresources.hxx" +#include "java/LocalRef.hxx" #include <rtl/logfile.hxx> #include <string.h> @@ -324,6 +328,7 @@ Any SAL_CALL java_sql_ResultSet::getObject( sal_Int32 columnIndex, const Referen { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_ResultSet::getObject" ); jobject out(0); + Any aRet; SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); { jvalue args[2]; @@ -341,15 +346,43 @@ Any SAL_CALL java_sql_ResultSet::getObject( sal_Int32 columnIndex, const Referen obtainMethodId(t.pEnv, cMethodName,cSignature, mID); } - out = t.pEnv->CallObjectMethodA( object, mID, args); - t.pEnv->DeleteLocalRef((jstring)args[1].l); - ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); - // und aufraeumen - + out = t.pEnv->CallObjectMethodA( object, mID, args); + t.pEnv->DeleteLocalRef((jstring)args[1].l); + ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); + // und aufraeumen + if ( out ) + { + if ( t.pEnv->IsInstanceOf(out,java_lang_String::st_getMyClass()) ) + { + java_lang_String aVal(t.pEnv,out); + aRet <<= (::rtl::OUString)aVal; + } + else if ( t.pEnv->IsInstanceOf(out,java_lang_Boolean::st_getMyClass()) ) + { + java_lang_Boolean aVal(t.pEnv,out); + static jmethodID methodID = NULL; + aRet <<= aVal.callBooleanMethod("booleanValue",methodID); + } + else if ( t.pEnv->IsInstanceOf(out,java_sql_Date::st_getMyClass()) ) + { + java_sql_Date aVal(t.pEnv,out); + aRet <<= (::com::sun::star::util::Date)aVal; + } + else if ( t.pEnv->IsInstanceOf(out,java_sql_Time::st_getMyClass()) ) + { + java_sql_Time aVal(t.pEnv,out); + aRet <<= (::com::sun::star::util::Time)aVal; + } + else if ( t.pEnv->IsInstanceOf(out,java_sql_Timestamp::st_getMyClass()) ) + { + java_sql_Timestamp aVal(t.pEnv,out); + aRet <<= (::com::sun::star::util::DateTime)aVal; + } + else + t.pEnv->DeleteLocalRef(out); + } } //t.pEnv - // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! - ::dbtools::throwFunctionNotSupportedException( "XRow::getObject", *this ); - return out==0 ? Any() : Any();//new java_lang_Object( t.pEnv, out ); + return aRet; } // ------------------------------------------------------------------------- @@ -689,9 +722,8 @@ void SAL_CALL java_sql_ResultSet::updateString( sal_Int32 columnIndex, const ::r { // Parameter konvertieren - jstring str = convertwchar_tToJavaString(t.pEnv,x); - t.pEnv->CallVoidMethod( object, mID,columnIndex,str); - t.pEnv->DeleteLocalRef(str); + jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,x)); + t.pEnv->CallVoidMethod( object, mID,columnIndex,str.get()); ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); } } @@ -754,16 +786,68 @@ void SAL_CALL java_sql_ResultSet::updateTimestamp( sal_Int32 columnIndex, const } // ------------------------------------------------------------------------- -void SAL_CALL java_sql_ResultSet::updateBinaryStream( sal_Int32 /*columnIndex*/, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +void SAL_CALL java_sql_ResultSet::updateBinaryStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_ResultSet::updateBinaryStream" ); - ::dbtools::throwFeatureNotImplementedException( "XParameters::updateBinaryStream", *this ); + try + { + SDBThreadAttach t; + { + + // temporaere Variable initialisieren + // Java-Call absetzen + static jmethodID mID(NULL); + if ( !mID ) + { + static const char * cSignature = "(ILjava/io/InputStream;I)V"; + static const char * cMethodName = "updateBinaryStream"; + obtainMethodId(t.pEnv, cMethodName,cSignature, mID); + } + + { + // Parameter konvertieren + jobject obj = createByteInputStream(x,length); + t.pEnv->CallVoidMethod( object, mID, columnIndex,obj,length); + ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); + } + } + } + catch(Exception) + { + ::dbtools::throwFeatureNotImplementedException( "XRowUpdate::updateBinaryStream", *this ); + } } // ------------------------------------------------------------------------- -void SAL_CALL java_sql_ResultSet::updateCharacterStream( sal_Int32 /*columnIndex*/, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& /*x*/, sal_Int32 /*length*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) +void SAL_CALL java_sql_ResultSet::updateCharacterStream( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "jdbc", "Ocke.Janssen@sun.com", "java_sql_ResultSet::updateCharacterStream" ); - ::dbtools::throwFeatureNotImplementedException( "XRowUpdate::updateCharacterStream", *this ); + try + { + SDBThreadAttach t; + { + + // temporaere Variable initialisieren + // Java-Call absetzen + static jmethodID mID(NULL); + if ( !mID ) + { + static const char * cSignature = "(ILjava/io/Reader;I)V"; + static const char * cMethodName = "updateCharacterStream"; + obtainMethodId(t.pEnv, cMethodName,cSignature, mID); + } + + { + // Parameter konvertieren + jobject obj = createCharArrayReader(x,length); + t.pEnv->CallVoidMethod( object, mID, columnIndex,obj,length); + ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); + } + } + } + catch(Exception) + { + ::dbtools::throwFeatureNotImplementedException( "XRowUpdate::updateCharacterStream", *this ); + } } // ------------------------------------------------------------------------- void SAL_CALL java_sql_ResultSet::updateObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Any& x ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) diff --git a/connectivity/source/drivers/jdbc/Timestamp.cxx b/connectivity/source/drivers/jdbc/Timestamp.cxx index 5a014d12a5..fe66e881a7 100644 --- a/connectivity/source/drivers/jdbc/Timestamp.cxx +++ b/connectivity/source/drivers/jdbc/Timestamp.cxx @@ -71,6 +71,10 @@ java_sql_Date::~java_sql_Date() jclass java_sql_Date::getMyClass() const { + return st_getMyClass(); +} +jclass java_sql_Date::st_getMyClass() +{ // die Klasse muss nur einmal geholt werden, daher statisch if( !theClass ) theClass = findMyClass("java/sql/Date"); @@ -94,12 +98,15 @@ java_sql_Time::~java_sql_Time() jclass java_sql_Time::getMyClass() const { + return st_getMyClass(); +} +jclass java_sql_Time::st_getMyClass() +{ // die Klasse muss nur einmal geholt werden, daher statisch if( !theClass ) theClass = findMyClass("java/sql/Time"); return theClass; } - java_sql_Time::java_sql_Time( const ::com::sun::star::util::Time& _rOut ): java_util_Date( NULL, (jobject)NULL ) { SDBThreadAttach t; @@ -140,12 +147,15 @@ java_sql_Timestamp::~java_sql_Timestamp() jclass java_sql_Timestamp::getMyClass() const { + return st_getMyClass(); +} +jclass java_sql_Timestamp::st_getMyClass() +{ // die Klasse muss nur einmal geholt werden, daher statisch if( !theClass ) theClass = findMyClass("java/sql/Timestamp"); return theClass; } - java_sql_Timestamp::java_sql_Timestamp(const ::com::sun::star::util::DateTime& _rOut) :java_util_Date( NULL, (jobject)NULL ) { diff --git a/connectivity/source/drivers/jdbc/jdbc.xcu b/connectivity/source/drivers/jdbc/jdbc.xcu index 7a64519e48..56dfcbc8cb 100755 --- a/connectivity/source/drivers/jdbc/jdbc.xcu +++ b/connectivity/source/drivers/jdbc/jdbc.xcu @@ -145,6 +145,11 @@ <value>true</value> </prop> </node> + <node oor:name="PrimaryKeySupport" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> </node> <node oor:name="MetaData"> <node oor:name="SupportsTableCreation" oor:op="replace"> diff --git a/connectivity/source/drivers/jdbc/makefile.mk b/connectivity/source/drivers/jdbc/makefile.mk index 831a6755af..fb37a30777 100644 --- a/connectivity/source/drivers/jdbc/makefile.mk +++ b/connectivity/source/drivers/jdbc/makefile.mk @@ -95,6 +95,7 @@ SHL1STDLIBS=\ $(SALLIB) \ $(JVMACCESSLIB) \ $(DBTOOLSLIB) \ + $(UNOTOOLSLIB) \ $(JVMFWKLIB) \ $(COMPHELPERLIB) diff --git a/connectivity/source/drivers/jdbc/tools.cxx b/connectivity/source/drivers/jdbc/tools.cxx index 8a3ca446dc..e4a79817f3 100644 --- a/connectivity/source/drivers/jdbc/tools.cxx +++ b/connectivity/source/drivers/jdbc/tools.cxx @@ -153,6 +153,8 @@ java_util_Properties* connectivity::createStringPropertyArray(const Sequence< Pr && pBegin->Name.compareToAscii( "SupportsTableCreation" ) && pBegin->Name.compareToAscii( "UseJava" ) && pBegin->Name.compareToAscii( "Authentication" ) + && pBegin->Name.compareToAscii( "PreferDosLikeLineEnds" ) + && pBegin->Name.compareToAscii( "PrimaryKeySupport" ) ) { ::rtl::OUString aStr; @@ -218,5 +220,58 @@ sal_Bool connectivity::isExceptionOccured(JNIEnv *pEnv,sal_Bool _bClear) return bRet; } - - +// ----------------------------------------------------------------------------- +jobject connectivity::createByteInputStream(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x,sal_Int32 length) +{ + SDBThreadAttach t; + if( !t.pEnv || !x.is() ) + return NULL; + // Java-Call fuer den Konstruktor absetzen + // temporaere Variable initialisieren + jclass clazz = java_lang_Object::findMyClass("java/io/ByteArrayInputStream"); + static jmethodID mID(NULL); + if ( !mID ) + { + static const char * cSignature = "([B)V"; + mID = t.pEnv->GetMethodID( clazz, "<init>", cSignature ); + OSL_ENSURE( mID, cSignature ); + if ( !mID ) + throw SQLException(); + } // if ( !_inout_MethodID ) + jbyteArray pByteArray = t.pEnv->NewByteArray(length); + Sequence< sal_Int8 > aData; + x->readBytes(aData,length); + jboolean p = sal_False; + rtl_copyMemory(t.pEnv->GetByteArrayElements(pByteArray,&p),aData.getArray(),aData.getLength()); + jobject out = t.pEnv->NewObject( clazz, mID,pByteArray); + t.pEnv->DeleteLocalRef((jbyteArray)pByteArray); + return out; +} +// ----------------------------------------------------------------------------- +jobject connectivity::createCharArrayReader(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x,sal_Int32 length) +{ + SDBThreadAttach t; + if( !t.pEnv || !x.is() ) + return NULL; + // Java-Call fuer den Konstruktor absetzen + // temporaere Variable initialisieren + jclass clazz = java_lang_Object::findMyClass("java/io/CharArrayReader"); + static jmethodID mID(NULL); + if ( !mID ) + { + static const char * cSignature = "([C)V"; + mID = t.pEnv->GetMethodID( clazz, "<init>", cSignature ); + OSL_ENSURE( mID, cSignature ); + if ( !mID ) + throw SQLException(); + } // if ( !_inout_MethodID ) + jcharArray pCharArray = t.pEnv->NewCharArray(length); + Sequence< sal_Int8 > aData; + x->readBytes(aData,length); + jboolean p = sal_False; + rtl_copyMemory(t.pEnv->GetCharArrayElements(pCharArray,&p),aData.getArray(),aData.getLength()); + jobject out = t.pEnv->NewObject( clazz, mID,pCharArray); + t.pEnv->DeleteLocalRef((jcharArray)pCharArray); + return out; +} +// ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.cxx b/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.cxx index dc422f3cfa..bd4bfddb5f 100644 --- a/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.cxx +++ b/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.cxx @@ -33,12 +33,6 @@ #include <MNSINIParser.hxx> #include <rtl/byteseq.hxx> -ini_Section * IniParser::getSection(OUString const & secName) -{ - if (mAllSection.find(secName) != mAllSection.end()) - return &mAllSection[secName]; - return NULL; -} IniParser::IniParser(OUString const & rIniName) throw(com::sun::star::io::IOException ) { OUString iniUrl; diff --git a/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.hxx b/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.hxx index 7a556d9a1e..13cc611350 100644 --- a/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.hxx +++ b/connectivity/source/drivers/mozab/bootstrap/MNSINIParser.hxx @@ -75,7 +75,6 @@ class IniParser IniSectionMap mAllSection; public: IniSectionMap * getAllSection(){return &mAllSection;}; - ini_Section * getSection(OUString const & secName); IniParser(OUString const & rIniName) throw(com::sun::star::io::IOException ); #if OSL_DEBUG_LEVEL > 0 void Dump(); diff --git a/connectivity/source/drivers/mysql/YTable.cxx b/connectivity/source/drivers/mysql/YTable.cxx index 8680ac2079..5e4cff3459 100644 --- a/connectivity/source/drivers/mysql/YTable.cxx +++ b/connectivity/source/drivers/mysql/YTable.cxx @@ -284,7 +284,7 @@ void SAL_CALL OMySQLTable::alterColumnByName( const ::rtl::OUString& colName, co const ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); sSql += ::dbtools::quoteName(sQuote,colName); sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ")); - sSql += ::dbtools::createStandardColumnPart(descriptor,getConnection(),getTypeCreatePattern()); + sSql += OTables::adjustSQL(::dbtools::createStandardColumnPart(descriptor,getConnection(),getTypeCreatePattern())); executeStatement(sSql); } m_pColumns->refresh(); @@ -313,7 +313,7 @@ void OMySQLTable::alterColumnType(sal_Int32 nNewType,const ::rtl::OUString& _rCo ::comphelper::copyProperties(_xDescriptor,xProp); xProp->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),makeAny(nNewType)); - sSql += ::dbtools::createStandardColumnPart(xProp,getConnection(),getTypeCreatePattern()); + sSql += OTables::adjustSQL(::dbtools::createStandardColumnPart(xProp,getConnection(),getTypeCreatePattern())); executeStatement(sSql); } // ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/mysql/YTables.cxx b/connectivity/source/drivers/mysql/YTables.cxx index 8b2626d612..9af4b9f630 100644 --- a/connectivity/source/drivers/mysql/YTables.cxx +++ b/connectivity/source/drivers/mysql/YTables.cxx @@ -187,12 +187,27 @@ void OTables::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName) } } // ------------------------------------------------------------------------- +::rtl::OUString OTables::adjustSQL(const ::rtl::OUString& _sSql) +{ + ::rtl::OUString sSQL = _sSql; + static const ::rtl::OUString s_sUNSIGNED(RTL_CONSTASCII_USTRINGPARAM("UNSIGNED")); + sal_Int32 nIndex = sSQL.indexOf(s_sUNSIGNED); + while(nIndex != -1 ) + { + sal_Int32 nParen = sSQL.indexOf(')',nIndex); + sal_Int32 nPos = nIndex + s_sUNSIGNED.getLength(); + ::rtl::OUString sNewUnsigned( sSQL.copy(nPos,nParen - nPos + 1)); + sSQL = sSQL.replaceAt(nIndex,s_sUNSIGNED.getLength()+sNewUnsigned.getLength(),sNewUnsigned + s_sUNSIGNED); + nIndex = sSQL.indexOf(s_sUNSIGNED,nIndex + s_sUNSIGNED.getLength()+sNewUnsigned.getLength()); + } + return sSQL; +} +// ------------------------------------------------------------------------- void OTables::createTable( const Reference< XPropertySet >& descriptor ) { const Reference< XConnection > xConnection = static_cast<OMySQLCatalog&>(m_rParent).getConnection(); static const ::rtl::OUString s_sCreatePattern(RTL_CONSTASCII_USTRINGPARAM("(M,D)")); - const ::rtl::OUString aSql = ::dbtools::createSqlCreateTableStatement(descriptor,xConnection,s_sCreatePattern); - + const ::rtl::OUString aSql = adjustSQL(::dbtools::createSqlCreateTableStatement(descriptor,xConnection,s_sCreatePattern)); Reference< XStatement > xStmt = xConnection->createStatement( ); if ( xStmt.is() ) { diff --git a/connectivity/source/drivers/odbc/odbc.xcu b/connectivity/source/drivers/odbc/odbc.xcu index f906d08bdd..5c8d8c07d5 100755 --- a/connectivity/source/drivers/odbc/odbc.xcu +++ b/connectivity/source/drivers/odbc/odbc.xcu @@ -150,6 +150,11 @@ <value>true</value> </prop> </node> + <node oor:name="PrimaryKeySupport" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> </node> <node oor:name="MetaData"> <node oor:name="SupportsTableCreation" oor:op="replace"> diff --git a/connectivity/source/drivers/odbcbase/ODatabaseMetaData.cxx b/connectivity/source/drivers/odbcbase/ODatabaseMetaData.cxx index 97edeeffeb..6874e4e69f 100644 --- a/connectivity/source/drivers/odbcbase/ODatabaseMetaData.cxx +++ b/connectivity/source/drivers/odbcbase/ODatabaseMetaData.cxx @@ -921,6 +921,7 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_In OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CONVERT_VARCHAR,nValue,*this); break; case DataType::LONGVARCHAR: + case DataType::CLOB: OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CONVERT_LONGVARCHAR,nValue,*this); break; case DataType::DATE: @@ -939,6 +940,7 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_In OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CONVERT_VARBINARY,nValue,*this); break; case DataType::LONGVARBINARY: + case DataType::BLOB: OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CONVERT_LONGVARBINARY,nValue,*this); break; case DataType::SQLNULL: @@ -959,12 +961,6 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_In case DataType::ARRAY: // OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CORRELATION_NAME,nValue,*this); break; - case DataType::BLOB: - // OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CORRELATION_NAME,nValue,*this); - break; - case DataType::CLOB: - // OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CORRELATION_NAME,nValue,*this); - break; case DataType::REF: // OTools::GetInfo(m_pConnection,m_aConnectionHandle,SQL_CORRELATION_NAME,nValue,*this); break; @@ -1009,6 +1005,7 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_In bConvert = (nValue & SQL_CVT_VARCHAR) == SQL_CVT_VARCHAR; break; case DataType::LONGVARCHAR: + case DataType::CLOB: bConvert = (nValue & SQL_CVT_LONGVARCHAR) == SQL_CVT_LONGVARCHAR; break; case DataType::DATE: @@ -1027,6 +1024,7 @@ sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_In bConvert = (nValue & SQL_CVT_VARBINARY) == SQL_CVT_VARBINARY; break; case DataType::LONGVARBINARY: + case DataType::BLOB: bConvert = (nValue & SQL_CVT_LONGVARBINARY) == SQL_CVT_LONGVARBINARY; break; } diff --git a/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx b/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx index 773b9c0293..20e705ba0e 100644 --- a/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx +++ b/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx @@ -283,7 +283,7 @@ Sequence< sal_Int8 > SAL_CALL ODatabaseMetaDataResultSet::getBytes( sal_Int32 co aDate.day = 0; aDate.month = 0; aDate.year = 0; - OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_DATE,m_bWasNull,**this,&aDate,sizeof aDate); + OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,m_pConnection->useOldDateFormat() ? SQL_C_DATE : SQL_C_TYPE_DATE,m_bWasNull,**this,&aDate,sizeof aDate); return Date(aDate.day,aDate.month,aDate.year); } else @@ -434,7 +434,7 @@ sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) columnIndex = mapColumn(columnIndex); ::rtl::OUString aVal; if(columnIndex <= m_nDriverColumnCount) - aVal = OTools::getStringValue(m_pConnection,m_aStatementHandle,columnIndex,(SWORD)SQL_C_WCHAR,m_bWasNull,**this,m_nTextEncoding); + aVal = OTools::getStringValue(m_pConnection,m_aStatementHandle,columnIndex,impl_getColumnType_nothrow(columnIndex),m_bWasNull,**this,m_nTextEncoding); else m_bWasNull = sal_True; @@ -454,7 +454,7 @@ sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) columnIndex = mapColumn(columnIndex); TIME_STRUCT aTime={0,0,0}; if(columnIndex <= m_nDriverColumnCount) - OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_TIME,m_bWasNull,**this,&aTime,sizeof aTime); + OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,m_pConnection->useOldDateFormat() ? SQL_C_TIME : SQL_C_TYPE_TIME,m_bWasNull,**this,&aTime,sizeof aTime); else m_bWasNull = sal_True; return Time(0,aTime.second,aTime.minute,aTime.hour); @@ -472,7 +472,7 @@ sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) columnIndex = mapColumn(columnIndex); TIMESTAMP_STRUCT aTime={0,0,0,0,0,0,0}; if(columnIndex <= m_nDriverColumnCount) - OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_TIMESTAMP,m_bWasNull,**this,&aTime,sizeof aTime); + OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,m_pConnection->useOldDateFormat() ? SQL_C_TIMESTAMP : SQL_C_TYPE_TIMESTAMP,m_bWasNull,**this,&aTime,sizeof aTime); else m_bWasNull = sal_True; return DateTime((sal_uInt16)aTime.fraction*1000,aTime.second,aTime.minute,aTime.hour,aTime.day,aTime.month,aTime.year); @@ -1316,5 +1316,11 @@ void ODatabaseMetaDataResultSet::checkColumnCount() } // ----------------------------------------------------------------------------- - +SWORD ODatabaseMetaDataResultSet::impl_getColumnType_nothrow(sal_Int32 columnIndex) +{ + ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex); + if ( aFind == m_aODBCColumnTypes.end() ) + aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pConnection,m_aStatementHandle,*this,columnIndex))).first; + return aFind->second; +} diff --git a/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx b/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx index 187808bdbd..1fe1e3525e 100644 --- a/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx +++ b/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx @@ -321,16 +321,6 @@ void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool setInt (parameterIndex, value); } // ------------------------------------------------------------------------- -#define PREP_BIND_PARAM(_ty,_jt) \ - OTools::bindParameter(m_pConnection, \ - m_aStatementHandle, \ - parameterIndex, \ - bindBuf, \ - getLengthBuf(parameterIndex), \ - (SWORD)_jt, \ - sal_False,m_pConnection->useOldDateFormat(),_pData,(Reference <XInterface>)*this,getOwnConnection()->getTextEncoding()) - - void OPreparedStatement::setParameter(sal_Int32 parameterIndex,sal_Int32 _nType,sal_Int32 _nSize,void* _pData) { ::osl::MutexGuard aGuard( m_aMutex ); @@ -353,6 +343,10 @@ void OPreparedStatement::setParameter(sal_Int32 parameterIndex,sal_Int32 _nType, case SQL_NUMERIC: ++nRealSize; break; + case SQL_BINARY: + case SQL_VARBINARY: + nRealSize=1; //dummy buffer, binary data isn't copied + break; default: break; } @@ -480,15 +474,17 @@ void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 s } // ------------------------------------------------------------------------- -void SAL_CALL OPreparedStatement::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) throw(SQLException, RuntimeException) +void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException) { - ::dbtools::throwFunctionNotSupportedException( "XParameters::setClob", *this ); + if ( x.is() ) + setStream(parameterIndex, x->getCharacterStream(), (SQLLEN)x->length(), DataType::LONGVARCHAR); } // ------------------------------------------------------------------------- -void SAL_CALL OPreparedStatement::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) throw(SQLException, RuntimeException) +void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException) { - ::dbtools::throwFunctionNotSupportedException( "XParameters::setBlob", *this ); + if ( x.is() ) + setStream(parameterIndex, x->getBinaryStream(), (SQLLEN)x->length(), DataType::LONGVARCHAR); } // ------------------------------------------------------------------------- @@ -503,7 +499,12 @@ void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Re ::dbtools::throwFunctionNotSupportedException( "XParameters::setRef", *this ); } // ------------------------------------------------------------------------- - +void OPreparedStatement::setDecimal( sal_Int32 parameterIndex, const ::rtl::OUString& x ) +{ + ::rtl::OString aString(::rtl::OUStringToOString(x,getOwnConnection()->getTextEncoding())); + setParameter(parameterIndex,DataType::DECIMAL,aString.getLength(),(void*)&x); +} +// ------------------------------------------------------------------------- void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 sqlType, sal_Int32 scale ) throw(SQLException, RuntimeException) { checkDisposed(OStatement_BASE::rBHelper.bDisposed); @@ -528,6 +529,12 @@ void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, c setNull(parameterIndex,sqlType); break; case DataType::DECIMAL: + { + ORowSetValue aValue; + aValue.fill(x); + setDecimal(parameterIndex,aValue); + } + break; case DataType::NUMERIC: { ORowSetValue aValue; @@ -568,19 +575,20 @@ void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException) { setParameter(parameterIndex,DataType::BINARY,x.getLength(),(void*)&x); + boundParams[parameterIndex-1].setSequence(x); // this assures that the sequence stays alive } // ------------------------------------------------------------------------- void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) { - setStream (parameterIndex, x, length, DataType::LONGVARCHAR); + setStream(parameterIndex, x, length, DataType::LONGVARCHAR); } // ------------------------------------------------------------------------- void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) { - setStream (parameterIndex, x, length, DataType::LONGVARBINARY); + setStream(parameterIndex, x, length, DataType::LONGVARBINARY); } // ------------------------------------------------------------------------- @@ -839,10 +847,10 @@ sal_Int32 OPreparedStatement::getPrecision ( sal_Int32 sqlType) // Sets an input stream as a parameter, using the given SQL type //-------------------------------------------------------------------- -void OPreparedStatement::setStream ( +void OPreparedStatement::setStream( sal_Int32 ParameterIndex, const Reference< XInputStream>& x, - sal_Int32 length, + SQLLEN length, sal_Int32 SQLtype) throw(SQLException) { diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx index e48cfe0259..2544d08b8f 100644 --- a/connectivity/source/drivers/odbcbase/OResultSet.cxx +++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx @@ -223,9 +223,11 @@ SQLRETURN OResultSet::unbind(sal_Bool _bUnbindHandle) delete static_cast< double* >(reinterpret_cast< void * >(pValue->first)); break; case DataType::LONGVARCHAR: + case DataType::CLOB: delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first)); break; case DataType::LONGVARBINARY: + case DataType::BLOB: delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first)); break; case DataType::DATE: @@ -284,9 +286,11 @@ TVoidPtr OResultSet::allocBindColumn(sal_Int32 _nType,sal_Int32 _nColumnIndex) aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new double(0.0)),_nType); break; case DataType::LONGVARCHAR: + case DataType::CLOB: aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType); // dient nur zum auffinden break; case DataType::LONGVARBINARY: + case DataType::BLOB: aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType); // dient nur zum auffinden break; case DataType::DATE: @@ -465,11 +469,9 @@ Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) thro return nRet; } - ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex); - if ( aFind == m_aODBCColumnTypes.end() ) - aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,columnIndex))).first; + const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex); - switch(aFind->second) + switch(nColumnType) { case SQL_WVARCHAR: case SQL_WCHAR: @@ -478,7 +480,7 @@ Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) thro case SQL_CHAR: case SQL_LONGVARCHAR: { - ::rtl::OUString aRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,aFind->second,m_bWasNull,**this,m_nTextEncoding); + ::rtl::OUString aRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding); return Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),sizeof(sal_Unicode)*aRet.getLength()); } default: @@ -623,10 +625,8 @@ sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLExcept else { checkDisposed(OResultSet_BASE::rBHelper.bDisposed); - ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex); - if ( aFind == m_aODBCColumnTypes.end() ) - aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,columnIndex))).first; - nRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,aFind->second,m_bWasNull,**this,m_nTextEncoding); + const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex); + nRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding); } return nRet; } @@ -1499,11 +1499,10 @@ void OResultSet::fillRow(sal_Int32 _nToColumn) case DataType::DECIMAL: case DataType::NUMERIC: case DataType::LONGVARCHAR: + case DataType::CLOB: { - ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(nColumn); - if ( aFind == m_aODBCColumnTypes.end() ) - aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(nColumn,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,nColumn))).first; - *pColumn = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,nColumn,aFind->second,m_bWasNull,**this,m_nTextEncoding); + const SWORD nColumnType = impl_getColumnType_nothrow(nColumn); + *pColumn = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,nColumn,nColumnType,m_bWasNull,**this,m_nTextEncoding); } break; case DataType::BIGINT: @@ -1514,6 +1513,7 @@ void OResultSet::fillRow(sal_Int32 _nToColumn) *pColumn = getDouble(nColumn); break; case DataType::LONGVARBINARY: + case DataType::BLOB: *pColumn = getBytes(nColumn); break; case DataType::DATE: @@ -1719,6 +1719,7 @@ void OResultSet::fillNeededData(SQLRETURN _nRet) case DataType::BINARY: case DataType::VARBINARY: case DataType::LONGVARBINARY: + case DataType::BLOB: aSeq = m_aRow[nColumnIndex]; N3SQLPutData (m_aStatementHandle, aSeq.getArray(), aSeq.getLength()); break; @@ -1730,6 +1731,7 @@ void OResultSet::fillNeededData(SQLRETURN _nRet) break; } case DataType::LONGVARCHAR: + case DataType::CLOB: { ::rtl::OUString sRet; sRet = m_aRow[nColumnIndex].getString(); @@ -1745,4 +1747,12 @@ void OResultSet::fillNeededData(SQLRETURN _nRet) while (nRet == SQL_NEED_DATA); } } +// ----------------------------------------------------------------------------- +SWORD OResultSet::impl_getColumnType_nothrow(sal_Int32 columnIndex) +{ + ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex); + if ( aFind == m_aODBCColumnTypes.end() ) + aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,columnIndex))).first; + return aFind->second; +} diff --git a/connectivity/source/drivers/odbcbase/OTools.cxx b/connectivity/source/drivers/odbcbase/OTools.cxx index 9d8873c0d1..c5506533ae 100644 --- a/connectivity/source/drivers/odbcbase/OTools.cxx +++ b/connectivity/source/drivers/odbcbase/OTools.cxx @@ -135,6 +135,7 @@ void OTools::bindData( SQLSMALLINT _nOdbcType, { case SQL_CHAR: case SQL_VARCHAR: + case SQL_DECIMAL: if(_bUseWChar) { *pLen = SQL_NTS; @@ -160,7 +161,7 @@ void OTools::bindData( SQLSMALLINT _nOdbcType, *pLen = sizeof(sal_Int64); _nColumnSize = *pLen; break; - case SQL_DECIMAL: + case SQL_NUMERIC: if(_bUseWChar) { @@ -210,12 +211,9 @@ void OTools::bindData( SQLSMALLINT _nOdbcType, if(pSeq) { - // memcpy(_pData,pSeq->getConstArray(),pSeq->getLength()); - _pData = (sal_Int8*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray(); + _pData = (sal_Int8*)pSeq->getConstArray(); *pLen = pSeq->getLength(); } - // _pData = (sal_Int8*)((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getConstArray(); - // *pLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength(); } break; case SQL_LONGVARBINARY: diff --git a/connectivity/source/inc/ado/Aolevariant.hxx b/connectivity/source/inc/ado/Aolevariant.hxx index ddacefec17..f53985d007 100644 --- a/connectivity/source/inc/ado/Aolevariant.hxx +++ b/connectivity/source/inc/ado/Aolevariant.hxx @@ -161,6 +161,7 @@ namespace connectivity double getDate() const; CY getCurrency() const; SAFEARRAY* getUI1SAFEARRAYPtr() const; + ::com::sun::star::uno::Any makeAny() const; static VARIANT_BOOL VariantBool(sal_Bool bEinBoolean); diff --git a/connectivity/source/inc/java/lang/Boolean.hxx b/connectivity/source/inc/java/lang/Boolean.hxx index 9bc7dc7d61..8a4cacdc63 100644 --- a/connectivity/source/inc/java/lang/Boolean.hxx +++ b/connectivity/source/inc/java/lang/Boolean.hxx @@ -48,6 +48,7 @@ namespace connectivity java_lang_Boolean( JNIEnv * pEnv, jobject myObj ) : java_lang_Object( pEnv, myObj ){} java_lang_Boolean( sal_Bool _par0 ); + static jclass st_getMyClass(); }; } diff --git a/connectivity/source/inc/java/sql/Connection.hxx b/connectivity/source/inc/java/sql/Connection.hxx index 55244525da..713433d842 100644 --- a/connectivity/source/inc/java/sql/Connection.hxx +++ b/connectivity/source/inc/java/sql/Connection.hxx @@ -80,6 +80,11 @@ namespace connectivity const ::rtl::OUString& _sDriverClassPath, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rSystemProperties ); + /** load driver class path from system configuration. + @param _sDriverClass + The driver class name to look for in the configuration. + */ + ::rtl::OUString impl_getJavaDriverClassPath_nothrow(const ::rtl::OUString& _sDriverClass); protected: // statische Daten fuer die Klasse diff --git a/connectivity/source/inc/java/sql/Timestamp.hxx b/connectivity/source/inc/java/sql/Timestamp.hxx index 2af09c2f02..83e6a728f9 100644 --- a/connectivity/source/inc/java/sql/Timestamp.hxx +++ b/connectivity/source/inc/java/sql/Timestamp.hxx @@ -54,6 +54,7 @@ namespace connectivity java_sql_Date( const ::com::sun::star::util::Date& _rOut ); operator ::com::sun::star::util::Date(); + static jclass st_getMyClass(); }; @@ -73,6 +74,7 @@ namespace connectivity java_sql_Time( JNIEnv * pEnv, jobject myObj ) : java_util_Date( pEnv, myObj ){} java_sql_Time( const ::com::sun::star::util::Time& _rOut ); operator ::com::sun::star::util::Time(); + static jclass st_getMyClass(); }; //************************************************************** @@ -93,6 +95,7 @@ namespace connectivity sal_Int32 getNanos(); void setNanos(sal_Int32 n); + static jclass st_getMyClass(); }; } #endif // _CONNECTIVITY_JAVA_SQL_TIMESTAMP_HXX_ diff --git a/connectivity/source/inc/java/tools.hxx b/connectivity/source/inc/java/tools.hxx index 098126895a..897a5ac572 100644 --- a/connectivity/source/inc/java/tools.hxx +++ b/connectivity/source/inc/java/tools.hxx @@ -41,6 +41,7 @@ #include <comphelper/uno3.hxx> #include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/util/Time.hpp> #include <com/sun/star/util/Date.hpp> #include <com/sun/star/util/DateTime.hpp> @@ -85,6 +86,9 @@ namespace connectivity <TRUE/> if an exception is occured */ sal_Bool isExceptionOccured(JNIEnv *pEnv,sal_Bool _bClear); + + jobject createByteInputStream(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x,sal_Int32 length); + jobject createCharArrayReader(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& x,sal_Int32 length); } #endif // _CONNECTIVITY_JAVA_TOOLS_HXX_ diff --git a/connectivity/source/inc/mysql/YTables.hxx b/connectivity/source/inc/mysql/YTables.hxx index 981dcccc1f..c17358dd4a 100644 --- a/connectivity/source/inc/mysql/YTables.hxx +++ b/connectivity/source/inc/mysql/YTables.hxx @@ -74,6 +74,11 @@ namespace connectivity can contain () which have to filled with values */ static ::rtl::OUString getTypeString(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxColProp); + + /** convert the sql statement to fit MySQL notation + @param _sSql in/out + */ + static ::rtl::OUString adjustSQL(const ::rtl::OUString& _sSql); }; } } diff --git a/connectivity/source/inc/odbc/OBoundParam.hxx b/connectivity/source/inc/odbc/OBoundParam.hxx index 31d3dde82b..a2b5a4cceb 100644 --- a/connectivity/source/inc/odbc/OBoundParam.hxx +++ b/connectivity/source/inc/odbc/OBoundParam.hxx @@ -119,6 +119,11 @@ namespace connectivity paramInputStreamLen = len; } + void setSequence(const ::com::sun::star::uno::Sequence< sal_Int8 >& _aSequence) + { + aSequence = _aSequence; + } + //-------------------------------------------------------------------- // getInputStream // Gets the input stream for the bound parameter @@ -191,6 +196,7 @@ namespace connectivity // data is in native format. ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream> paramInputStream; + ::com::sun::star::uno::Sequence< sal_Int8 > aSequence; // When an input stream is // bound to a parameter, the // input stream is saved diff --git a/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx b/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx index 5078eb3ac5..596ebaad9d 100644 --- a/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx +++ b/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx @@ -100,6 +100,7 @@ namespace connectivity sal_Int32 getFetchDirection() const throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); sal_Int32 getFetchSize() const throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); ::rtl::OUString getCursorName() const throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); + SWORD impl_getColumnType_nothrow(sal_Int32 columnIndex); sal_Int32 mapColumn (sal_Int32 column); diff --git a/connectivity/source/inc/odbc/OPreparedStatement.hxx b/connectivity/source/inc/odbc/OPreparedStatement.hxx index dfd2a62830..e3b3592773 100644 --- a/connectivity/source/inc/odbc/OPreparedStatement.hxx +++ b/connectivity/source/inc/odbc/OPreparedStatement.hxx @@ -89,7 +89,7 @@ namespace connectivity void FreeParams(); void putParamData (sal_Int32 index) throw(::com::sun::star::sdbc::SQLException); void setStream (sal_Int32 ParameterIndex,const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, - sal_Int32 length,sal_Int32 SQLtype) throw(::com::sun::star::sdbc::SQLException); + SQLLEN length,sal_Int32 SQLtype) throw(::com::sun::star::sdbc::SQLException); sal_Int32 getParamLength ( sal_Int32 index); sal_Int8* getLengthBuf (sal_Int32 index); sal_Int8* getDataBuf (sal_Int32 index); @@ -102,6 +102,7 @@ namespace connectivity sal_Bool isPrepared() const { return m_bPrepared;} void prepareStatement(); void checkParameterIndex(sal_Int32 _parameterIndex); + void setDecimal( sal_Int32 parameterIndex, const ::rtl::OUString& x ); /** creates the driver specific resultset (factory) diff --git a/connectivity/source/inc/odbc/OResultSet.hxx b/connectivity/source/inc/odbc/OResultSet.hxx index 194bb50987..b5b41aeb14 100644 --- a/connectivity/source/inc/odbc/OResultSet.hxx +++ b/connectivity/source/inc/odbc/OResultSet.hxx @@ -176,6 +176,7 @@ namespace connectivity sal_Bool moveImpl(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData); TVoidPtr allocBindColumn(sal_Int32 _nType,sal_Int32 _nColumnIndex); SQLRETURN unbind(sal_Bool _bUnbindHandle = sal_True); + SWORD impl_getColumnType_nothrow(sal_Int32 columnIndex); // OPropertyArrayUsageHelper virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; diff --git a/connectivity/source/parse/PColumn.cxx b/connectivity/source/parse/PColumn.cxx index 34b3f3a582..8eca29dfb5 100644 --- a/connectivity/source/parse/PColumn.cxx +++ b/connectivity/source/parse/PColumn.cxx @@ -116,7 +116,7 @@ OParseColumn* OParseColumn::createColumnForResultSet( const Reference< XResultSe const Reference< XDatabaseMetaData >& _rxDBMetaData, sal_Int32 _nColumnPos ) { OParseColumn* pColumn = new OParseColumn( - _rxResMetaData->getColumnName( _nColumnPos ), + _rxResMetaData->getColumnLabel( _nColumnPos ), _rxResMetaData->getColumnTypeName( _nColumnPos ), ::rtl::OUString(), _rxResMetaData->isNullable( _nColumnPos ), @@ -135,6 +135,7 @@ OParseColumn* OParseColumn::createColumnForResultSet( const Reference< XResultSe eComplete ) ); pColumn->setIsSearchable( _rxResMetaData->isSearchable( _nColumnPos ) ); + pColumn->setRealName(_rxResMetaData->getColumnName( _nColumnPos )); return pColumn; } diff --git a/connectivity/source/parse/sqlbison.y b/connectivity/source/parse/sqlbison.y index 97875dfd4d..1680516e8d 100644 --- a/connectivity/source/parse/sqlbison.y +++ b/connectivity/source/parse/sqlbison.y @@ -107,7 +107,6 @@ static connectivity::OSQLInternalNode* newNode(const sal_Char* pNewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0) { - OSL_TRACE("connectivity: Rule Number: %d,%d",eNodeType,nNodeID); return new connectivity::OSQLInternalNode(pNewValue, eNodeType, nNodeID); } @@ -115,7 +114,6 @@ static connectivity::OSQLInternalNode* newNode(const ::rtl::OString& _NewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0) { - OSL_TRACE("connectivity: Rule Number: %d,%d",eNodeType,nNodeID); return new connectivity::OSQLInternalNode(_NewValue, eNodeType, nNodeID); } @@ -123,7 +121,6 @@ static connectivity::OSQLInternalNode* newNode(const ::rtl::OUString& _NewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0) { - OSL_TRACE("connectivity: Rule Number: %d,%d",eNodeType,nNodeID); return new connectivity::OSQLInternalNode(_NewValue, eNodeType, nNodeID); } @@ -2043,7 +2040,8 @@ join_spec: | named_columns_join ; join_type: - SQL_TOKEN_INNER + /* empty */ {$$ = SQL_NEW_RULE;} + | SQL_TOKEN_INNER { $$ = SQL_NEW_RULE; $$->append($1); diff --git a/connectivity/source/parse/sqliterator.cxx b/connectivity/source/parse/sqliterator.cxx index c92fc9b709..3cb4b821cd 100644 --- a/connectivity/source/parse/sqliterator.cxx +++ b/connectivity/source/parse/sqliterator.cxx @@ -952,21 +952,7 @@ bool OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode* pSele if ( pColumnRef->isRule() ) { bFkt = sal_True; - if ( SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term) || SQL_ISRULE(pColumnRef,factor) ) - { - nType = DataType::DOUBLE; - } - else - { - ::rtl::OUString sFunctionName; - if ( SQL_ISRULE(pColumnRef,length_exp) ) - pColumnRef->getChild(0)->getChild(0)->parseNodeToStr( - sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); - else - pColumnRef->getChild(0)->parseNodeToStr( - sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); - nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); - } + nType = getFunctionReturnType(pColumnRef); } } /* @@ -1601,7 +1587,6 @@ void OSQLParseTreeIterator::impl_traverse( sal_uInt32 _nIncludeMask ) case SQL_STATEMENT_INSERT: break; default: - OSL_ENSURE( false, "OSQLParseTreeIterator::traverseAll: not yet implemented for this statement type!" ); break; } } @@ -2104,3 +2089,84 @@ void OSQLParseTreeIterator::impl_appendError( const SQLException& _rError ) m_aErrors = _rError; } // ----------------------------------------------------------------------------- +sal_Int32 OSQLParseTreeIterator::getFunctionReturnType(const OSQLParseNode* _pNode ) +{ + sal_Int32 nType = DataType::OTHER; + ::rtl::OUString sFunctionName; + if ( SQL_ISRULE(_pNode,length_exp) ) + { + _pNode->getChild(0)->getChild(0)->parseNodeToStr(sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); + nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); + } + else if ( SQL_ISRULE(_pNode,num_value_exp) || SQL_ISRULE(_pNode,term) || SQL_ISRULE(_pNode,factor) ) + { + nType = DataType::DOUBLE; + } + else + { + _pNode->getChild(0)->parseNodeToStr(sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); + + // MIN and MAX have another return type, we have to check the expression itself. + // @see http://qa.openoffice.org/issues/show_bug.cgi?id=99566 + if ( SQL_ISRULE(_pNode,general_set_fct) && (SQL_ISTOKEN(_pNode->getChild(0),MIN) || SQL_ISTOKEN(_pNode->getChild(0),MAX) )) + { + const OSQLParseNode* pValueExp = _pNode->getChild(3); + if (SQL_ISRULE(pValueExp,column_ref)) + { + ::rtl::OUString sColumnName; + ::rtl::OUString aTableRange; + getColumnRange(pValueExp,sColumnName,aTableRange); + OSL_ENSURE(sColumnName.getLength(),"Columnname darf nicht leer sein"); + Reference<XPropertySet> xColumn = findColumn( sColumnName, aTableRange, true ); + + if ( xColumn.is() ) + { + xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TYPE)) >>= nType; + } + } + else + { + if ( SQL_ISRULE(pValueExp,num_value_exp) || SQL_ISRULE(pValueExp,term) || SQL_ISRULE(pValueExp,factor) ) + { + nType = DataType::DOUBLE; + } + else if ( SQL_ISRULE(pValueExp,datetime_primary) ) + { + switch(pValueExp->getChild(0)->getTokenID() ) + { + case SQL_TOKEN_CURRENT_DATE: + nType = DataType::DATE; + break; + case SQL_TOKEN_CURRENT_TIME: + nType = DataType::TIME; + break; + case SQL_TOKEN_CURRENT_TIMESTAMP: + nType = DataType::TIMESTAMP; + break; + } + } + else if ( SQL_ISRULE(pValueExp,value_exp_primary) ) + { + nType = getFunctionReturnType(pValueExp->getChild(1)); + } + else if ( SQL_ISRULE(pValueExp,concatenation) + || SQL_ISRULE(pValueExp,char_factor) + || SQL_ISRULE(pValueExp,bit_value_fct) + || SQL_ISRULE(pValueExp,char_value_fct) + || SQL_ISRULE(pValueExp,char_substring_fct) + || SQL_ISRULE(pValueExp,fold) + || SQL_ISTOKEN(pValueExp,STRING) ) + { + nType = DataType::VARCHAR; + } + } + if ( nType == DataType::OTHER ) + nType = DataType::DOUBLE; + } + else + nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); + } + + return nType; +} + diff --git a/connectivity/source/parse/sqlnode.cxx b/connectivity/source/parse/sqlnode.cxx index a359c64df1..568b8bd78c 100644 --- a/connectivity/source/parse/sqlnode.cxx +++ b/connectivity/source/parse/sqlnode.cxx @@ -813,8 +813,9 @@ OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral) case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: - if ( !SQL_ISRULE(pReturn,char_value_exp) && !buildStringNodes(pReturn) ) - pReturn = NULL; + case DataType::CLOB: + if ( !SQL_ISRULE(pReturn,char_value_exp) && !buildStringNodes(pReturn) ) + pReturn = NULL; default: break; } @@ -829,6 +830,7 @@ OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral) case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: + case DataType::CLOB: break; case DataType::DATE: case DataType::TIME: @@ -872,12 +874,13 @@ OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral) case DataType::REAL: case DataType::DOUBLE: // kill thousand seperators if any - killThousandSeparator(pReturn); + killThousandSeparator(pReturn); break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: - pReturn = buildNode_STR_NUM(pReturn); + case DataType::CLOB: + pReturn = buildNode_STR_NUM(pReturn); break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_INT_COMPARE); @@ -893,12 +896,13 @@ OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral) case DataType::REAL: case DataType::DOUBLE: // kill thousand seperators if any - killThousandSeparator(pReturn); + killThousandSeparator(pReturn); break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: - pReturn = buildNode_STR_NUM(pReturn); + case DataType::CLOB: + pReturn = buildNode_STR_NUM(pReturn); break; case DataType::INTEGER: default: @@ -907,7 +911,7 @@ OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral) } break; default: - OSL_ENSURE(0,"Not handled!"); + ; } } return pReturn; @@ -967,6 +971,7 @@ sal_Int16 OSQLParser::buildLikeRule(OSQLParseNode*& pAppend, OSQLParseNode*& pLi case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: + case DataType::CLOB: if(pLiteral->isRule()) { pAppend->append(pLiteral); @@ -1228,6 +1233,7 @@ OSQLParseNode* OSQLParser::predicateTree(::rtl::OUString& rErrorMessage, const : case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: + case DataType::CLOB: s_pScanner->SetRule(s_pScanner->GetSTRINGRule()); break; default: @@ -1415,7 +1421,11 @@ OSQLParser::OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star: { OSQLParseNode::table_node, "table_node" }, { OSQLParseNode::as, "as" }, { OSQLParseNode::op_column_commalist, "op_column_commalist" }, - { OSQLParseNode::table_primary_as_range_column, "table_primary_as_range_column" } + { OSQLParseNode::table_primary_as_range_column, "table_primary_as_range_column" }, + { OSQLParseNode::datetime_primary, "datetime_primary" }, + { OSQLParseNode::concatenation, "concatenation" }, + { OSQLParseNode::char_factor, "char_factor" }, + { OSQLParseNode::bit_value_fct, "bit_value_fct" } }; size_t nRuleMapCount = sizeof( aRuleDescriptions ) / sizeof( aRuleDescriptions[0] ); OSL_ENSURE( nRuleMapCount == size_t( OSQLParseNode::rule_count ), "OSQLParser::OSQLParser: added a new rule? Adjust this map!" ); |