summaryrefslogtreecommitdiffstats
path: root/connectivity/qa
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /connectivity/qa
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'connectivity/qa')
-rw-r--r--connectivity/qa/complex/connectivity/DBaseDriverTest.java70
-rw-r--r--connectivity/qa/complex/connectivity/FlatFileAccess.java245
-rw-r--r--connectivity/qa/complex/connectivity/HsqlDriverTest.java145
-rw-r--r--connectivity/qa/complex/connectivity/JdbcLongVarCharTest.java125
-rw-r--r--connectivity/qa/complex/connectivity/SubTestCase.java41
-rw-r--r--connectivity/qa/complex/connectivity/TestCase.java27
-rw-r--r--connectivity/qa/complex/connectivity/dbase/DBaseDateFunctions.java296
-rw-r--r--connectivity/qa/complex/connectivity/dbase/DBaseNumericFunctions.java388
-rw-r--r--connectivity/qa/complex/connectivity/dbase/DBaseSqlTests.java80
-rw-r--r--connectivity/qa/complex/connectivity/dbase/DBaseStringFunctions.java310
-rw-r--r--connectivity/qa/complex/connectivity/hsqldb/TestCacheSize.java591
-rw-r--r--connectivity/qa/connectivity/ado/DriverTest.cxx141
-rw-r--r--connectivity/qa/connectivity/ado/TS001018407.mdbbin0 -> 2789376 bytes
-rw-r--r--connectivity/qa/connectivity/commontools/FValue_test.cxx366
-rw-r--r--connectivity/qa/connectivity/mork/DriverTest.cxx199
-rw-r--r--connectivity/qa/connectivity/mork/abook_10_john_does.mab159
-rw-r--r--connectivity/qa/connectivity/mysql/mysql.cxx501
-rw-r--r--connectivity/qa/connectivity/resource/sharedresources_test.cxx107
-rw-r--r--connectivity/qa/connectivity/tools/AbstractDatabase.java208
-rw-r--r--connectivity/qa/connectivity/tools/CRMDatabase.java277
-rw-r--r--connectivity/qa/connectivity/tools/CsvDatabase.java31
-rw-r--r--connectivity/qa/connectivity/tools/DataSource.java150
-rw-r--r--connectivity/qa/connectivity/tools/DatabaseAccess.java50
-rw-r--r--connectivity/qa/connectivity/tools/DbaseDatabase.java32
-rw-r--r--connectivity/qa/connectivity/tools/FlatFileDatabase.java74
-rw-r--r--connectivity/qa/connectivity/tools/HsqlColumnDescriptor.java75
-rw-r--r--connectivity/qa/connectivity/tools/HsqlDatabase.java202
-rw-r--r--connectivity/qa/connectivity/tools/HsqlTableDescriptor.java93
-rw-r--r--connectivity/qa/connectivity/tools/QueryDefinition.java49
-rw-r--r--connectivity/qa/connectivity/tools/RowSet.java288
-rw-r--r--connectivity/qa/connectivity/tools/sdb/Connection.java80
-rw-r--r--connectivity/qa/scenarios.sce21
32 files changed, 5421 insertions, 0 deletions
diff --git a/connectivity/qa/complex/connectivity/DBaseDriverTest.java b/connectivity/qa/complex/connectivity/DBaseDriverTest.java
new file mode 100644
index 000000000..f1c89dc70
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/DBaseDriverTest.java
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package complex.connectivity;
+
+import complex.connectivity.dbase.DBaseDateFunctions;
+import complex.connectivity.dbase.DBaseStringFunctions;
+import complex.connectivity.dbase.DBaseSqlTests;
+import complex.connectivity.dbase.DBaseNumericFunctions;
+import complexlib.ComplexTestCase;
+import share.LogWriter;
+
+public class DBaseDriverTest extends ComplexTestCase implements TestCase
+{
+ @Override
+ public String[] getTestMethodNames()
+ {
+ return new String[]
+ {
+ "Functions"
+ };
+ }
+
+ @Override
+ public String getTestObjectName()
+ {
+ return "DBaseDriverTest";
+ }
+
+ @Override
+ public void assure( final String i_message, final boolean i_condition )
+ {
+ super.assure( i_message, i_condition );
+ }
+
+ public LogWriter getLog()
+ {
+ return log;
+ }
+
+ public void Functions() throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ DBaseStringFunctions aStringTest = new DBaseStringFunctions(param.getMSF(), this);
+ aStringTest.testFunctions();
+
+ DBaseNumericFunctions aNumericTest = new DBaseNumericFunctions(param.getMSF(), this);
+ aNumericTest.testFunctions();
+
+ DBaseDateFunctions aDateTest = new DBaseDateFunctions(param.getMSF(), this);
+ aDateTest.testFunctions();
+
+ DBaseSqlTests aSqlTest = new DBaseSqlTests(param.getMSF(), this);
+ aSqlTest.testFunctions();
+ }
+}
diff --git a/connectivity/qa/complex/connectivity/FlatFileAccess.java b/connectivity/qa/complex/connectivity/FlatFileAccess.java
new file mode 100644
index 000000000..43d0eabef
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/FlatFileAccess.java
@@ -0,0 +1,245 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package complex.connectivity;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.sdb.CommandType;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.util.Date;
+import complexlib.ComplexTestCase;
+import connectivity.tools.CsvDatabase;
+import connectivity.tools.RowSet;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlatFileAccess extends ComplexTestCase
+{
+ @Override
+ public String[] getTestMethodNames()
+ {
+ return new String[] {
+ "testBasicAccess",
+ "testCalendarFunctions",
+ "testSortingByFunction"
+ };
+ }
+
+ @Override
+ public String getTestObjectName()
+ {
+ return "FlatFileAccess";
+ }
+
+ public void before() throws Exception
+ {
+ m_database = new CsvDatabase( param.getMSF() );
+
+ // proper settings
+ final XPropertySet dataSourceSettings = m_database.getDataSource().geSettings();
+ dataSourceSettings.setPropertyValue( "Extension", "csv" );
+ dataSourceSettings.setPropertyValue( "HeaderLine", Boolean.TRUE );
+ dataSourceSettings.setPropertyValue( "FieldDelimiter", " " );
+ m_database.store();
+
+ // write the table(s) for our test
+ final String tableLocation = m_database.getTableFileLocation().getAbsolutePath();
+ final PrintWriter tableWriter = new PrintWriter( new FileOutputStream( tableLocation + File.separatorChar + "dates.csv", false ) );
+ tableWriter.println( "ID date" );
+ tableWriter.println( "1 2013-01-01" );
+ tableWriter.println( "2 2012-02-02" );
+ tableWriter.println( "3 2011-03-03" );
+ tableWriter.close();
+ }
+
+ public void after()
+ {
+ }
+
+ private static class EqualityDate extends Date
+ {
+ EqualityDate( short i_day, short i_month, short i_year )
+ {
+ super( i_day, i_month, i_year );
+ }
+
+ @Override
+ public boolean equals( Object i_compare )
+ {
+ if ( !( i_compare instanceof Date ) )
+ return false;
+ return Day == ((Date)i_compare).Day
+ && Month == ((Date)i_compare).Month
+ && Year == ((Date)i_compare).Year;
+ }
+ }
+
+ /**
+ * ensures simple SELECTs from our table(s) work, and deliver the expected results
+ */
+ public void testBasicAccess()
+ {
+ testRowSetResults(
+ "SELECT * FROM \"dates\"",
+ new RowSetIntGetter(1),
+ new Integer[] { 1, 2, 3 },
+ "simple select", "wrong IDs"
+ );
+
+ testRowSetResults(
+ "SELECT * FROM \"dates\"",
+ new RowSetDateGetter( 2 ),
+ new EqualityDate[] { new EqualityDate( (short)1, (short)1, (short)2013 ),
+ new EqualityDate( (short)2, (short)2, (short)2012 ),
+ new EqualityDate( (short)3, (short)3, (short)2011 )
+ },
+ "simple select", "wrong dates"
+ );
+ testRowSetResults(
+ "SELECT \"date\", \"ID\" FROM \"dates\" ORDER BY \"ID\" DESC",
+ new RowSetIntGetter( 2 ),
+ new Integer[] { 3, 2, 1 },
+ "explicit column selection, sorted by IDs", "wrong IDs"
+ );
+ testRowSetResults(
+ "SELECT * FROM \"dates\" ORDER BY \"date\"",
+ new RowSetIntGetter( 1 ),
+ new Integer[] { 3, 2, 1 },
+ "sorted by date", "wrong IDs"
+ );
+ }
+
+ /**
+ * ensures the basic functionality for selecting calendar functions from a CSV table - this is a prerequisite for
+ * later tests.
+ */
+ public void testCalendarFunctions()
+ {
+ // simple check for proper results of the calendar functions (DATE/MONTH)
+ // The * at the first position is crucial here - there was code which wrongly calculated
+ // column positions of function columns when * was present in the statement
+ testRowSetResults(
+ "SELECT \"dates\".*, YEAR( \"date\" ) FROM \"dates\"",
+ new RowSetIntGetter( 3 ),
+ new Integer[] { 2013, 2012, 2011 },
+ "YEAR function", "wrong calculated years"
+ );
+ testRowSetResults(
+ "SELECT \"dates\".*, MONTH( \"date\" ) FROM \"dates\"",
+ new RowSetIntGetter( 3 ),
+ new Integer[] { 1, 2, 3 },
+ "MONTH function", "wrong calculated months"
+ );
+ }
+
+ /**
+ * ensures that sorting by a function column works
+ */
+ public void testSortingByFunction()
+ {
+ // most simple case: select a function, and sort by it
+ testRowSetResults(
+ "SELECT YEAR( \"date\" ) AS \"year\" FROM \"dates\" ORDER BY \"year\"",
+ new RowSetIntGetter(1),
+ new Integer[] { 2011, 2012, 2013 },
+ "single YEAR selection, sorted by years", "wrong calculated years"
+ );
+ // somewhat more "difficult" (this used to crash): Select all columns, plus a function, so the calculated
+ // column has a position greater than column count
+ testRowSetResults(
+ "SELECT \"dates\".*, YEAR( \"date\" ) AS \"year\" FROM \"dates\" ORDER BY \"year\" DESC",
+ new RowSetIntGetter(3),
+ new Integer[] { 2013, 2012, 2011 },
+ "extended YEAR selection, sorted by years", "wrong calculated years"
+ );
+ }
+
+ private interface RowSetValueGetter
+ {
+ Object getValue( final RowSet i_rowSet ) throws SQLException;
+ }
+
+ private static abstract class RowSetColumnValueGetter implements RowSetValueGetter
+ {
+ RowSetColumnValueGetter( final int i_columnIndex )
+ {
+ m_columnIndex = i_columnIndex;
+ }
+
+ protected final int m_columnIndex;
+ }
+
+ private static class RowSetIntGetter extends RowSetColumnValueGetter
+ {
+ RowSetIntGetter( final int i_columnIndex )
+ {
+ super( i_columnIndex );
+ }
+
+ public Object getValue( final RowSet i_rowSet ) throws SQLException
+ {
+ return i_rowSet.getInt( m_columnIndex );
+ }
+ }
+
+ private static class RowSetDateGetter extends RowSetColumnValueGetter
+ {
+ RowSetDateGetter( final int i_columnIndex )
+ {
+ super( i_columnIndex );
+ }
+
+ public Object getValue( final RowSet i_rowSet ) throws SQLException
+ {
+ return i_rowSet.getDate( m_columnIndex );
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> void testRowSetResults( String i_command, RowSetValueGetter i_getter,
+ T[] i_expectedValues, String i_context, String i_failureDesc )
+ {
+ RowSet rowSet = null;
+ try
+ {
+ rowSet = m_database.createRowSet( CommandType.COMMAND, i_command );
+ rowSet.execute();
+
+ List< T > values = new ArrayList< T >();
+ while ( rowSet.next() )
+ {
+ values.add( (T)i_getter.getValue( rowSet ) );
+ }
+ assureEquals( i_context + ": " + i_failureDesc, i_expectedValues, values.toArray(), ContinueWithTest.YES );
+ }
+ catch( final SQLException e )
+ {
+ failed( i_context + ": caught an exception: " + e.toString(), ContinueWithTest.NO );
+ }
+ finally
+ {
+ if ( rowSet != null )
+ rowSet.dispose();
+ }
+ }
+
+ private CsvDatabase m_database = null;
+}
diff --git a/connectivity/qa/complex/connectivity/HsqlDriverTest.java b/connectivity/qa/complex/connectivity/HsqlDriverTest.java
new file mode 100644
index 000000000..aba01fad9
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/HsqlDriverTest.java
@@ -0,0 +1,145 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package complex.connectivity;
+
+import complex.connectivity.hsqldb.TestCacheSize;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XStorable;
+
+import com.sun.star.lang.*;
+import com.sun.star.document.XDocumentSubStorageSupplier;
+import complexlib.ComplexTestCase;
+
+
+import org.hsqldb.lib.StopWatch;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.beans.PropertyState;
+import com.sun.star.embed.XStorage;
+import com.sun.star.sdbc.XDataSource;
+import com.sun.star.sdbc.XDriver;
+import connectivity.tools.HsqlDatabase;
+
+public class HsqlDriverTest extends ComplexTestCase {
+
+
+ @Override
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ @Override
+ public String getTestObjectName() {
+ return "DriverTest";
+ }
+
+ public void assurePublic(String sMessage,boolean check){
+ super.assure(sMessage,check);
+ }
+
+ public void test(){
+ XDataSource ds = null;
+ System.gc();
+ try {
+ HsqlDatabase database = new HsqlDatabase( param.getMSF() );
+ ds = database.getDataSource().getXDataSource();
+ } catch(Exception ex) {
+ throw new RuntimeException("factory: unable to construct data source", ex );
+ }
+
+ try{
+ XDocumentSubStorageSupplier doc = UnoRuntime.queryInterface(XDocumentSubStorageSupplier.class,ds);
+ XStorage stor = doc.getDocumentSubStorage("database",4);
+ try{
+ if ( stor.isStreamElement("db.log") )
+ stor.removeElement("db.log");
+ } catch(Exception e){}
+ try{
+ if ( stor.isStreamElement("db.properties") )
+ stor.removeElement("db.properties");
+ } catch(Exception e){}
+ try{
+ if ( stor.isStreamElement("db.script") )
+ stor.removeElement("db.script");
+ } catch(Exception e){}
+ try{
+ if ( stor.isStreamElement("db.script.new") )
+ stor.removeElement("db.script.new");
+ } catch(Exception e){}
+ XStorable mod = UnoRuntime.queryInterface(XStorable.class,ds);
+ mod.store();
+ XComponent xComp = UnoRuntime.queryInterface(XComponent.class,stor);
+ if ( xComp != null )
+ xComp.dispose();
+ } catch(Exception e){}
+
+ try{
+ XDocumentSubStorageSupplier doc = UnoRuntime.queryInterface(XDocumentSubStorageSupplier.class,ds);
+ XModel mod = UnoRuntime.queryInterface(XModel.class,ds);
+ XStorage stor = doc.getDocumentSubStorage("database",4);
+ com.sun.star.beans.PropertyValue[] info = new com.sun.star.beans.PropertyValue[]{
+ new com.sun.star.beans.PropertyValue("Storage",0,stor,PropertyState.DIRECT_VALUE)
+ ,new com.sun.star.beans.PropertyValue("URL",0,mod.getURL(),PropertyState.DIRECT_VALUE)
+ };
+ XDriver drv = UnoRuntime.queryInterface(XDriver.class,param.getMSF().createInstance("com.sun.star.sdbcx.comp.hsqldb.Driver"));
+
+
+ TestCacheSize test = new TestCacheSize(info,drv);
+
+ StopWatch sw = new StopWatch();
+
+ try{
+ test.setUp();
+ test.testFillUp();
+ test.checkResults();
+ test.tearDown();
+ System.out.println("Total Test Time: " + sw.elapsedTime());
+ } catch(Exception e){}
+
+ try{
+ XStorable mod2 = UnoRuntime.queryInterface(XStorable.class,ds);
+ mod2.store();
+ } catch(Exception e){}
+ }catch(Exception e){}
+ }
+
+ public void test2(){
+ System.gc();
+
+ try{
+ com.sun.star.beans.PropertyValue[] info = new com.sun.star.beans.PropertyValue[]{
+ new com.sun.star.beans.PropertyValue("JavaDriverClass",0,"org.hsqldb.jdbcDriver",PropertyState.DIRECT_VALUE)
+ ,new com.sun.star.beans.PropertyValue("ParameterNameSubstitution",0, false,PropertyState.DIRECT_VALUE)
+ };
+ XDriver drv = UnoRuntime.queryInterface(XDriver.class,param.getMSF().createInstance("com.sun.star.comp.sdbc.JDBCDriver"));
+ TestCacheSize test = new TestCacheSize(info,drv);
+ test.setURL("jdbc:hsqldb:g:\\hsql\\db");
+
+
+ StopWatch sw = new StopWatch();
+
+ try{
+ test.setUp();
+ test.testFillUp();
+ test.checkResults();
+ test.tearDown();
+ System.out.println("Total Test Time: " + sw.elapsedTime());
+ } catch(Exception e){}
+ }catch(Exception e){}
+ }
+}
diff --git a/connectivity/qa/complex/connectivity/JdbcLongVarCharTest.java b/connectivity/qa/complex/connectivity/JdbcLongVarCharTest.java
new file mode 100644
index 000000000..3817add48
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/JdbcLongVarCharTest.java
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package complex.connectivity;
+
+import com.sun.star.beans.PropertyState;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.sdbc.XResultSet;
+import com.sun.star.sdbc.XClob;
+import com.sun.star.sdbc.XDriverAccess;
+import com.sun.star.sdbc.XParameters;
+import com.sun.star.sdbc.XPreparedStatement;
+import com.sun.star.sdbc.XResultSetMetaData;
+import com.sun.star.sdbc.XResultSetMetaDataSupplier;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.uno.UnoRuntime;
+import complexlib.ComplexTestCase;
+
+public class JdbcLongVarCharTest extends ComplexTestCase
+{
+
+ @Override
+ public String[] getTestMethodNames()
+ {
+ return new String[]
+ {
+ "testLongVarChar"
+ };
+ }
+
+ @Override
+ public String getTestObjectName()
+ {
+ return "LongVarCharTest";
+ }
+
+ public void testLongVarChar()
+ {
+
+ try
+ {
+ System.out.println("== Start testing ==");
+
+ /* Get URL from environment variable.
+ *
+ * Example URL:
+ * jdbc:mysql://localhost:3306/mysql?user=username&password=password
+ */
+ String url = System.getenv("CONNECTIVITY_TEST_MYSQL_DRIVER_JDBC");
+ com.sun.star.beans.PropertyValue prop[] = new PropertyValue[1];
+ prop[0] = new PropertyValue("JavaDriverClass", 0, "com.mysql.jdbc.Driver", PropertyState.DIRECT_VALUE);
+
+ // get the remote office component context
+ XMultiServiceFactory xServiceManager = param.getMSF();
+ Object x = xServiceManager.createInstance("com.sun.star.sdbc.DriverManager");
+ com.sun.star.sdbc.XDriverAccess xDriverAccess = UnoRuntime.queryInterface(XDriverAccess.class, x);
+ com.sun.star.sdbc.XDriver xDriver = xDriverAccess.getDriverByURL(url);
+ com.sun.star.sdbc.XConnection xConnection = xDriver.connect(url, prop);
+
+ Object prepStmnt = xConnection.prepareStatement("SELECT * FROM i90114 WHERE i90114.c1 = ?");
+ UnoRuntime.queryInterface(XParameters.class, prepStmnt).clearParameters();
+ UnoRuntime.queryInterface(XParameters.class, prepStmnt).setInt(1, 1);
+ XResultSet xResultSet = ((XPreparedStatement) prepStmnt).executeQuery();
+ XRow xRow = UnoRuntime.queryInterface(XRow.class, xResultSet);
+
+ XResultSetMetaDataSupplier xRsMetaSup = UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, xResultSet);
+ XResultSetMetaData xRsMetaData = xRsMetaSup.getMetaData();
+ int nColumnCount = xRsMetaData.getColumnCount();
+
+ System.out.println("== MetaData ==");
+ for (int i = 1; i <= nColumnCount; ++i)
+ {
+ System.out.println("Name: " + xRsMetaData.getColumnName(i) + " Type: " +
+ xRsMetaData.getColumnType(i));
+ }
+
+ System.out.println("== Result ==");
+ while (xResultSet.next())
+ {
+ String str = "not set";
+
+ XClob xClob = xRow.getClob(2);
+ if (xClob != null)
+ {
+ System.out.println("xClob != null");
+ int len = (int) xClob.length();
+ str = xClob.getSubString(1, len);
+ }
+ else
+ {
+ System.out.println("xClob == null");
+ }
+
+ System.out.println("c1 (Int): " + xRow.getInt(1) + " c2 (String): " + xRow.getString(2) + " c3 (Clob): " + str);
+ }
+
+ xConnection.close();
+ }
+ catch (java.lang.Exception e)
+ {
+ System.out.println("== Exception occurred while testing ==");
+ e.printStackTrace();
+ } finally
+ {
+ System.out.println("== End testing ==");
+ System.exit(0);
+ }
+ }
+}
diff --git a/connectivity/qa/complex/connectivity/SubTestCase.java b/connectivity/qa/complex/connectivity/SubTestCase.java
new file mode 100644
index 000000000..7abffa844
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/SubTestCase.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package complex.connectivity;
+
+import share.LogWriter;
+
+public class SubTestCase implements TestCase
+{
+ protected SubTestCase( final TestCase i_parentTestCase )
+ {
+ m_parentTestCase = i_parentTestCase;
+ }
+
+ public void assure( String i_message, boolean i_condition )
+ {
+ m_parentTestCase.assure( i_message, i_condition );
+ }
+
+ public LogWriter getLog()
+ {
+ return m_parentTestCase.getLog();
+ }
+
+ private final TestCase m_parentTestCase;
+}
diff --git a/connectivity/qa/complex/connectivity/TestCase.java b/connectivity/qa/complex/connectivity/TestCase.java
new file mode 100644
index 000000000..9261499af
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/TestCase.java
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package complex.connectivity;
+
+import share.LogWriter;
+
+public interface TestCase
+{
+ void assure( final String i_message, final boolean i_condition );
+ LogWriter getLog();
+}
diff --git a/connectivity/qa/complex/connectivity/dbase/DBaseDateFunctions.java b/connectivity/qa/complex/connectivity/dbase/DBaseDateFunctions.java
new file mode 100644
index 000000000..85975b481
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/dbase/DBaseDateFunctions.java
@@ -0,0 +1,296 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package complex.connectivity.dbase;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.sdbc.*;
+import com.sun.star.beans.XPropertySet;
+
+import com.sun.star.lang.XMultiServiceFactory;
+import complex.connectivity.TestCase;
+import complex.connectivity.SubTestCase;
+
+public class DBaseDateFunctions extends SubTestCase
+{
+
+ private static final String where = "FROM \"biblio\" \"biblio\" where \"Identifier\" = 'BOR00'";
+ private final XMultiServiceFactory m_xORB;
+
+ public DBaseDateFunctions(final XMultiServiceFactory _xORB, final TestCase i_testCase)
+ {
+ super( i_testCase );
+ m_xORB = _xORB;
+ }
+
+ public void testFunctions() throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRowSet xRowRes = UnoRuntime.queryInterface(XRowSet.class,
+ m_xORB.createInstance("com.sun.star.sdb.RowSet"));
+
+ getLog().println("starting DateTime function test!");
+ // set the properties needed to connect to a database
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("DataSourceName", "Bibliography");
+
+ xProp.setPropertyValue("CommandType", Integer.valueOf(com.sun.star.sdb.CommandType.COMMAND));
+
+ try
+ {
+ curdate(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("upper " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ curtime(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("lower " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ dayname(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("ascii " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ dayofmonth(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("char_len " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ dayofweek(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("concat " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ dayofyear(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("locate " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ hour(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("substr " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ minute(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("ltrim " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ month(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("rtrim " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ monthname(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("space " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ now(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("replace " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ quarter(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("repeat " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ second(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("insert " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ week(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("left " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ year(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("right " + ex.getMessage(), false);
+ throw ex;
+ }
+ }
+
+ private XRow execute(final XRowSet xRowRes, final String sql) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("Command", "SELECT " + sql + where);
+ xRowRes.execute();
+ final XResultSet xRes = UnoRuntime.queryInterface(XResultSet.class, xRowRes);
+ assure("No valid row! ", xRes.next());
+
+ return UnoRuntime.queryInterface(XRow.class, xRes);
+ }
+
+ private void dayofweek(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "DAYOFWEEK('1998-02-03') ");
+ assure("DAYOFWEEK('1998-02-03') failed!", row.getInt(1) == 3);
+ }
+
+ private void dayofmonth(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "DAYOFMONTH('1998-02-03') ");
+ assure("DAYOFMONTH('1998-02-03') failed!", row.getInt(1) == 3);
+ }
+
+ private void dayofyear(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "DAYOFYEAR('1998-02-03') ");
+ assure("DAYOFYEAR('1998-02-03') failed!", row.getInt(1) == 34);
+ }
+
+ private void month(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "month('1998-02-03') ");
+ assure("month('1998-02-03') failed!", row.getInt(1) == 2);
+ }
+
+ private void dayname(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "DAYNAME('1998-02-05') ");
+ assure("DAYNAME('1998-02-05') failed!", row.getString(1).equals("Thursday"));
+ }
+
+ private void monthname(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "MONTHNAME('1998-02-05') ");
+ assure("MONTHNAME('1998-02-05') failed!", row.getString(1).equals("February"));
+ }
+
+ private void quarter(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "QUARTER('98-01-01'),QUARTER('98-04-01'),QUARTER('98-07-01'),QUARTER('98-10-01') ");
+ assure("QUARTER('98-01-01') failed!", row.getInt(1) == 1);
+ assure("QUARTER('98-04-01') failed!", row.getInt(2) == 2);
+ assure("QUARTER('98-07-01') failed!", row.getInt(3) == 3);
+ assure("QUARTER('98-10-01') failed!", row.getInt(4) == 4);
+ }
+
+ private void week(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "WEEK('1998-02-20') ");
+ assure("WEEK('1998-02-20') failed!", row.getInt(1) == 7);
+ }
+
+ private void year(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "YEAR('98-02-03') ");
+ assure("YEAR('98-02-03') failed!", row.getInt(1) == 98);
+ }
+
+ private void hour(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "HOUR('10:05:03') ");
+ assure("HOUR('10:05:03') failed!", row.getInt(1) == 10);
+ }
+
+ private void minute(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "MINUTE('98-02-03 10:05:03') ");
+ assure("MINUTE('98-02-03 10:05:03') failed!", row.getInt(1) == 5);
+ }
+
+ private void second(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "SECOND('10:05:03') ");
+ assure("SECOND('10:05:03') failed!", row.getInt(1) == 3);
+ }
+
+ private void curdate(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "CURDATE() ");
+ final com.sun.star.util.Date aDate = row.getDate(1);
+ getLog().println("CURDATE() is '" + aDate.Year + "-" + aDate.Month + "-" + aDate.Day + "'");
+ }
+
+ private void curtime(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "CURTIME() ");
+ final com.sun.star.util.Time aTime = row.getTime(1);
+ getLog().println("CURTIME() is '" + aTime.Hours + ":" + aTime.Minutes + ":" + aTime.Seconds + "'");
+ }
+
+ private void now(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "NOW() ");
+ final com.sun.star.util.DateTime aTime = row.getTimestamp(1);
+ getLog().println("NOW() is '" + aTime.Year + "-" + aTime.Month + "-" + aTime.Day + "'");
+ getLog().println("'" + aTime.Hours + ":" + aTime.Minutes + ":" + aTime.Seconds + "'");
+ }
+}
diff --git a/connectivity/qa/complex/connectivity/dbase/DBaseNumericFunctions.java b/connectivity/qa/complex/connectivity/dbase/DBaseNumericFunctions.java
new file mode 100644
index 000000000..218f02b0a
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/dbase/DBaseNumericFunctions.java
@@ -0,0 +1,388 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package complex.connectivity.dbase;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.sdbc.*;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.XMultiServiceFactory;
+import complex.connectivity.SubTestCase;
+import complex.connectivity.TestCase;
+
+
+public class DBaseNumericFunctions extends SubTestCase
+{
+ private static final String where = "FROM \"biblio\" \"biblio\" where \"Identifier\" = 'BOR00'";
+ private final XMultiServiceFactory m_xORB;
+
+ public DBaseNumericFunctions(final XMultiServiceFactory _xORB, final TestCase i_testCase)
+ {
+ super( i_testCase );
+ m_xORB = _xORB;
+ }
+
+ public void testFunctions() throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRowSet xRowRes = UnoRuntime.queryInterface(XRowSet.class,
+ m_xORB.createInstance("com.sun.star.sdb.RowSet"));
+
+ getLog().println("starting Numeric function test");
+ // set the properties needed to connect to a database
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("DataSourceName", "Bibliography");
+
+ xProp.setPropertyValue("CommandType", Integer.valueOf(com.sun.star.sdb.CommandType.COMMAND));
+
+ try
+ {
+ abs(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("abs " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ acos(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("acos " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ asin(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("asin " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ atan(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("atan " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ atan2(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("atan2 " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ ceiling(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("ceiling " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ cos(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("cos " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ degrees(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("degrees " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ exp(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("exp " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ floor(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("floor " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ log(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("log " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ log10(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("log10 " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ mod(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("mod " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ pi(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("pi " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ pow(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("pow " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ radians(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("radians " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ round(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("round " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ sign(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("sign " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ sin(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("sin " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ sqrt(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("sqrt " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ tan(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("tan " + ex.getMessage(), false);
+ throw ex;
+ }
+
+ }
+
+ private XRow execute(final XRowSet xRowRes,final String sql) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("Command", "SELECT " + sql + where);
+ xRowRes.execute();
+ final XResultSet xRes = UnoRuntime.queryInterface(XResultSet.class, xRowRes);
+ assure("No valid row! ", xRes.next());
+
+ return UnoRuntime.queryInterface(XRow.class, xRes);
+ }
+
+ private void abs(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ABS(2),ABS(-32) ");
+ assure("ABS(2) failed!", row.getInt(1) == 2);
+ assure("ABS(-32) failed!", row.getInt(2) == 32);
+ }
+
+ private void sign(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "SIGN(-32),SIGN(0),SIGN(234) ");
+ assure("SIGN(-32)failed!", row.getInt(1) == -1);
+ assure("SIGN(0) failed!", row.getInt(2) == 0);
+ assure("SIGN(234) failed!", row.getInt(3) == 1);
+ }
+
+ private void mod(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "MOD(234, 10) ");
+ assure("MOD(234, 10) failed!", row.getInt(1) == 4);
+ }
+
+ private void floor(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "FLOOR(1.23),FLOOR(-1.23) ");
+ assure("FLOOR(1.23) failed!", row.getInt(1) == 1);
+ assure("FLOOR(-1.23) failed!", row.getInt(2) == -2);
+ }
+
+ private void ceiling(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "CEILING(1.23),CEILING(-1.23) ");
+ assure("CEILING(1.23) failed!", row.getInt(1) == 2);
+ assure("CEILING(-1.23) failed!", row.getInt(2) == -1);
+ }
+
+ private void round(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ROUND(-1.23),ROUND(1.298, 1) ");
+ assure("ROUND(-1.23) failed!", row.getInt(1) == -1);
+ assure("ROUND(1.298, 1) failed!", row.getDouble(2) == 1.3);
+ }
+
+ private void exp(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "EXP(2),EXP(-2) ");
+ assure("EXP(2) failed!", (float) row.getDouble(1) == (float) Math.exp(2));
+ assure("EXP(-2) failed!", (float) row.getDouble(2) == (float) Math.exp(-2));
+ }
+
+ private void log(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "LOG(2),LOG(-2) ");
+ assure("LOG(2) failed!", (float) row.getDouble(1) == (float) Math.log(2));
+ row.getDouble(2);
+ assure("LOG(-2) failed!", row.wasNull());
+ }
+
+ private void log10(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "LOG10(100) ");
+ assure("LOG10(100) failed!", row.getDouble(1) == 2.0);
+ }
+
+ private void pow(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "POWER(2,2) ");
+ assure("POWER(2,2) failed!", row.getDouble(1) == 4.0);
+ }
+
+ private void sqrt(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "SQRT(4) ");
+ assure("SQRT(4) failed!", row.getDouble(1) == 2.0);
+ }
+
+ private void pi(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "PI() ");
+ assure("PI() failed!", (float) row.getDouble(1) == (float) Math.PI);
+ }
+
+ private void cos(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "COS(PI()) ");
+ assure("COS(PI()) failed!", row.getDouble(1) == -1.0);
+ }
+
+ private void sin(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "SIN(2) ");
+ assure("SIN(PI()) failed!", (float) row.getDouble(1) == (float) Math.sin(2));
+ }
+
+ private void tan(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "TAN(PI()+1) ");
+ assure("TAN(PI()+1) failed!", (float) row.getDouble(1) == (float) Math.tan(Math.PI + 1.0));
+ }
+
+ private void acos(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ACOS(1) ");
+ assure("ACOS(1) failed!", (float) row.getDouble(1) == 0.0);
+ }
+
+ private void asin(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ASIN(0) ");
+ assure("ASIN(0) failed!", (float) row.getDouble(1) == 0.0);
+ }
+
+ private void atan(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ATAN(0) ");
+ assure("ATAN(0) failed!", row.getDouble(1) == 0.0);
+ }
+
+ private void atan2(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ATAN2(0,2) ");
+ assure("ATAN2(0,2) failed!", (float) row.getDouble(1) == 0.0);
+ }
+
+ private void degrees(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "DEGREES(PI()) ");
+ assure("DEGREES(PI()) failed!", row.getDouble(1) == 180.0);
+ }
+
+ private void radians(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "RADIANS(90) ");
+ assure("RADIANS(90) failed!", (float) row.getDouble(1) == (float) (Math.PI / 2.0));
+ }
+}
diff --git a/connectivity/qa/complex/connectivity/dbase/DBaseSqlTests.java b/connectivity/qa/complex/connectivity/dbase/DBaseSqlTests.java
new file mode 100644
index 000000000..09f7cac22
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/dbase/DBaseSqlTests.java
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package complex.connectivity.dbase;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.sdbc.*;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.XMultiServiceFactory;
+import complex.connectivity.TestCase;
+import complex.connectivity.SubTestCase;
+
+public class DBaseSqlTests extends SubTestCase
+{
+ private final XMultiServiceFactory m_xORB;
+
+ public DBaseSqlTests(final XMultiServiceFactory _xORB,final TestCase i_testCase)
+ {
+ super( i_testCase );
+ m_xORB = _xORB;
+ }
+
+ public void testFunctions() throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRowSet xRowRes = UnoRuntime.queryInterface(XRowSet.class,
+ m_xORB.createInstance("com.sun.star.sdb.RowSet"));
+
+ getLog().println("starting SQL test");
+ // set the properties needed to connect to a database
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("DataSourceName", "Bibliography");
+ xProp.setPropertyValue("CommandType", Integer.valueOf(com.sun.star.sdb.CommandType.COMMAND));
+
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where \"Identifier\" like 'B%'");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where not \"Identifier\" like 'B%'");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where not \"Identifier\" not like 'B%'");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where not(0 = 1)");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where 0 = 0");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where (0 = 0)");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where 0 <> 1");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where 0 < 1");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where 2 > 1");
+ execute(xRowRes,"1,1+1,'a' + 'b' FROM \"biblio\" \"biblio\" where 2 > 1");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where not \"Identifier\" is NULL");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where \"Identifier\" is not NULL");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where \"Identifier\" = \"Identifier\"");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where not(not(\"Identifier\" = \"Identifier\"))");
+ execute(xRowRes,"1 FROM \"biblio\" \"biblio\" where (1 = 1 and 2 = 1) or 3 = 33 or 4 = 44 or ('a' = 'a' and 'b' = 'b')");
+ }
+
+ private void execute(final XRowSet xRowRes, String sql) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ try
+ {
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("Command", "SELECT " + sql);
+ xRowRes.execute();
+ }
+ catch(SQLException e)
+ {
+ getLog().println(sql + " Error: " + e.getMessage());
+ }
+ }
+
+
+}
diff --git a/connectivity/qa/complex/connectivity/dbase/DBaseStringFunctions.java b/connectivity/qa/complex/connectivity/dbase/DBaseStringFunctions.java
new file mode 100644
index 000000000..4d5dc2dd6
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/dbase/DBaseStringFunctions.java
@@ -0,0 +1,310 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package complex.connectivity.dbase;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.sdbc.*;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.XMultiServiceFactory;
+import complex.connectivity.SubTestCase;
+import complex.connectivity.TestCase;
+
+public class DBaseStringFunctions extends SubTestCase
+{
+ private String where = "FROM \"biblio\" \"biblio\" where \"Identifier\" = 'BOR00'";
+ private final XMultiServiceFactory m_xORB;
+
+ public DBaseStringFunctions(final XMultiServiceFactory _xORB,final TestCase i_testCase)
+ {
+ super( i_testCase );
+ m_xORB = _xORB;
+ }
+
+ public void testFunctions() throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRowSet xRowRes = UnoRuntime.queryInterface(XRowSet.class,
+ m_xORB.createInstance("com.sun.star.sdb.RowSet"));
+
+ getLog().println("starting String function test");
+ // set the properties needed to connect to a database
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("DataSourceName", "Bibliography");
+
+ xProp.setPropertyValue("CommandType", Integer.valueOf(com.sun.star.sdb.CommandType.COMMAND));
+
+ try
+ {
+ upper(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("upper " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ lower(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("lower " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ ascii(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("ascii " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ char_length(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("char_len " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ concat(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("concat " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ chartest(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("char " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ locate(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("locate " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ substring(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("substr " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ ltrim(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("ltrim " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ rtrim(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("rtrim " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ space(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("space " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ replace(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("replace " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ repeat(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("repeat " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ insert(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("insert " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ left(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("left " + ex.getMessage(), false);
+ throw ex;
+ }
+ try
+ {
+ right(xRowRes);
+ }
+ catch (SQLException ex)
+ {
+ assure("right " + ex.getMessage(), false);
+ throw ex;
+ }
+ }
+
+ private XRow execute(final XRowSet xRowRes, String sql) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XPropertySet xProp = UnoRuntime.queryInterface(XPropertySet.class, xRowRes);
+ xProp.setPropertyValue("Command", "SELECT " + sql + where);
+ xRowRes.execute();
+ final XResultSet xRes = UnoRuntime.queryInterface(XResultSet.class, xRowRes);
+ assure("No valid row! ", xRes.next());
+
+ return UnoRuntime.queryInterface(XRow.class, xRes);
+ }
+
+ private void upper(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "upper('test'),UCASE('test') ");
+ assure("upper('test') failed!", row.getString(1).equals("TEST"));
+ assure("ucase('test') failed!", row.getString(2).equals("TEST"));
+ }
+
+ private void lower(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "lower('TEST'),LCASE('TEST') ");
+ assure("lower('TEST') failed!", row.getString(1).equals("test"));
+ assure("lcase('TEST') failed!", row.getString(2).equals("test"));
+ final String temp = where;
+ where = "FROM \"biblio\" \"biblio\" where LOWER(\"Identifier\") like 'bor%'";
+ execute(xRowRes, "lower('TEST'),LCASE('TEST') ");
+ where = temp;
+ }
+
+ private void ascii(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "ASCII('2') ");
+ assure("ascii('2') failed!", row.getInt(1) == 50);
+ }
+
+ private void char_length(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "char_length('test'),character_length('test'),OCTET_LENGTH('test') ");
+ assure("char_length('test') failed!", row.getInt(1) == 4);
+ assure("character_length('test') failed!", row.getInt(2) == 4);
+ assure("OCTET_LENGTH('test') failed!", row.getInt(3) == 4);
+ }
+
+ private void concat(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "CONCAT('Hello',' ','World') ");
+ assure("CONCAT('Hello',' ',,'World') failed!", row.getString(1).equals("Hello World"));
+ }
+
+ private void locate(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "LOCATE('bar', 'foobarbar') ");
+ assure("LOCATE('bar', 'foobarbar') failed!", row.getInt(1) == 4);
+ }
+
+ private void substring(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "SUBSTRING('Quadratically',5) ");
+ assure("SUBSTRING('Quadratically',5) failed!", row.getString(1).equals("ratically"));
+ }
+
+ private void ltrim(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "LTRIM(' barbar') ");
+ assure("LTRIM(' barbar') failed!", row.getString(1).equals("barbar"));
+ }
+
+ private void rtrim(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "RTRIM('barbar ') ");
+ assure("RTRIM('barbar ') failed!", row.getString(1).equals("barbar"));
+ }
+
+ private void space(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "space(6) ");
+ assure("space(6) failed!", row.getString(1).equals(" "));
+ }
+
+ private void replace(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "REPLACE('www.OOo.com', 'w', 'Ww') ");
+ assure("REPLACE('www.OOo.com', 'w', 'Ww') failed!", row.getString(1).equals("WwWwWw.OOo.com"));
+ }
+
+ private void repeat(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "REPEAT('OOo', 3) ");
+ assure("REPEAT('OOo', 3) failed!", row.getString(1).equals("OOoOOoOOo"));
+ }
+
+ private void insert(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "INSERT('Quadratic', 3, 4, 'What') ");
+ assure("INSERT('Quadratic', 3, 4, 'What') failed!", row.getString(1).equals("QuWhattic"));
+ }
+
+ private void left(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "LEFT('foobarbar', 5) ");
+ assure("LEFT('foobarbar', 5) failed!", row.getString(1).equals("fooba"));
+ }
+
+ private void right(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "RIGHT('foobarbar', 4) ");
+ assure("RIGHT('foobarbar', 4) failed!", row.getString(1).equals("rbar"));
+ }
+
+ private void chartest(final XRowSet xRowRes) throws com.sun.star.uno.Exception, com.sun.star.beans.UnknownPropertyException
+ {
+ final XRow row = execute(xRowRes, "CHAR(ascii('t'),ascii('e'),ascii('s'),ascii('t')) ");
+ assure("CHAR(ascii('t'),ascii('e'),ascii('s'),ascii('t')) failed!", row.getString(1).equals("test"));
+ }
+}
diff --git a/connectivity/qa/complex/connectivity/hsqldb/TestCacheSize.java b/connectivity/qa/complex/connectivity/hsqldb/TestCacheSize.java
new file mode 100644
index 000000000..d3c802e15
--- /dev/null
+++ b/connectivity/qa/complex/connectivity/hsqldb/TestCacheSize.java
@@ -0,0 +1,591 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * Copyright (c) 2001-2004, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package complex.connectivity.hsqldb;
+
+
+
+import org.hsqldb.lib.StopWatch;
+
+import java.util.Random;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.sdbc.*;
+
+/**
+ * Test large cached tables by setting up a cached table of 100000 records
+ * or more and a much smaller memory table with about 1/100th rows used.
+ * Populate both tables so that an indexed column of the cached table has a
+ * foreign key reference to the main table.
+ *
+ * This database can be used to demonstrate efficient queries to retrieve
+ * the data from the cached table.
+ *
+ * 1.7.1 insert timings for 100000 rows, cache scale 12:
+ * simple table, no extra index: 52 s
+ * with index on lastname only: 56 s
+ * with index on zip only: 211 s
+ * foreign key, referential_integrity true: 216 s
+ *
+ * The above have improved a lot in 1.7.2
+ *
+ * This test now incorporates the defunct TestTextTables
+ *
+ * @version 1.7.2
+ * @since 1.7.0
+ */
+public class TestCacheSize {
+
+ // program can edit the *.properties file to set cache_size
+ private boolean filedb = true;
+
+ // shutdown performed mid operation - not for mem: or hsql: URL's
+ private boolean shutdown = true;
+
+ // fixed
+ private String url = "sdbc:embedded:hsqldb";
+
+ // frequent reporting of progress
+ private boolean reportProgress = false;
+
+ // type of the big table {MEMORY | CACHED | TEXT}
+ private String tableType = "CACHED";
+ private int cacheScale = 17;
+
+ // script format {TEXT, BINARY, COMPRESSED}
+ private String logType = "TEXT";
+ private int writeDelay = 60;
+ private boolean indexZip = true;
+ private boolean indexLastName = false;
+ private boolean addForeignKey = false;
+ private boolean refIntegrity = true;
+
+ // speeds up inserts when tableType=="CACHED"
+ private boolean createTempTable = false;
+
+ // introduces fragmentation to the .data file during insert
+ private boolean deleteWhileInsert = false;
+ private int deleteWhileInsertInterval = 10000;
+
+ // size of the tables used in test
+ private int bigrows = 10000;
+ private int smallrows = 0xfff;
+
+ // if the extra table needs to be created and filled up
+ private boolean multikeytable = false;
+
+
+ private XStatement sStatement;
+ private XConnection cConnection;
+ private XDriver drv;
+ private com.sun.star.beans.PropertyValue[] info;
+
+ public TestCacheSize(com.sun.star.beans.PropertyValue[] _info,XDriver _drv){
+ drv = _drv;
+ info = _info;
+ }
+
+ public void setURL(String _url){
+ url = _url;
+ }
+
+ public void setUp() {
+
+ try {
+ sStatement = null;
+ cConnection = null;
+
+ if (filedb) {
+
+ cConnection = drv.connect(url,info);
+ sStatement = cConnection.createStatement();
+
+ sStatement.execute("SET SCRIPTFORMAT " + logType);
+ sStatement.execute("SET LOGSIZE " + 0);
+ sStatement.execute("SHUTDOWN");
+ cConnection.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("TestSql.setUp() error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Fill up the cache
+ *
+ *
+ */
+ public void testFillUp() {
+
+ StopWatch sw = new StopWatch();
+ String ddl1 = "DROP TABLE test IF EXISTS;"
+ + "DROP TABLE zip IF EXISTS;";
+ String ddl2 = "CREATE CACHED TABLE zip( zip INT IDENTITY );";
+ String ddl3 = "CREATE " + tableType + " TABLE test( id INT IDENTITY,"
+ + " firstname VARCHAR, " + " lastname VARCHAR, "
+ + " zip INTEGER, " + " filler VARCHAR); ";
+ String ddl31 = "SET TABLE test SOURCE \"test.csv;cache_scale="
+ + cacheScale + "\";";
+
+ // adding extra index will slow down inserts a bit
+ String ddl4 = "CREATE INDEX idx1 ON TEST (lastname);";
+
+ // adding this index will slow down inserts a lot
+ String ddl5 = "CREATE INDEX idx2 ON TEST (zip);";
+
+ // referential integrity checks will slow down inserts a bit
+ String ddl6 =
+ "ALTER TABLE test add constraint c1 FOREIGN KEY (zip) REFERENCES zip(zip);";
+ String ddl7 = "CREATE TEMP TABLE temptest( id INT,"
+ + " firstname VARCHAR, " + " lastname VARCHAR, "
+ + " zip INTEGER, " + " filler VARCHAR); ";
+ String filler =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ String mddl1 = "DROP TABLE test2 IF EXISTS;";
+ String mddl2 = "CREATE " + tableType
+ + " TABLE test2( id1 INT, id2 INT,"
+ + " firstname VARCHAR, " + " lastname VARCHAR, "
+ + " zip INTEGER, " + " filler VARCHAR, "
+ + " PRIMARY KEY (id1,id2) ); ";
+ String mdd13 = "SET TABLE test2 SOURCE \"test2.csv;cache_scale="
+ + cacheScale + "\";";
+
+ try {
+ System.out.println("Connecting");
+ sw.zero();
+
+ cConnection = null;
+ sStatement = null;
+ cConnection = drv.connect(url,info);
+
+ System.out.println("connected: " + sw.elapsedTime());
+ sw.zero();
+
+ sStatement = cConnection.createStatement();
+
+ java.util.Random randomgen = new java.util.Random();
+
+ sStatement.execute("SET WRITE_DELAY " + writeDelay);
+ sStatement.execute(ddl1);
+ sStatement.execute(ddl2);
+ sStatement.execute(ddl3);
+
+ if (tableType.equals("TEXT")) {
+ sStatement.execute(ddl31);
+ }
+
+ System.out.println("test table with no index");
+
+ if (indexLastName) {
+ sStatement.execute(ddl4);
+ System.out.println("create index on lastname");
+ }
+
+ if (indexZip) {
+ sStatement.execute(ddl5);
+ System.out.println("create index on zip");
+ }
+
+ if (addForeignKey) {
+ sStatement.execute(ddl6);
+ System.out.println("add foreign key");
+ }
+
+ if (createTempTable) {
+ sStatement.execute(ddl7);
+ System.out.println("temp table");
+ }
+
+ if (multikeytable) {
+ sStatement.execute(mddl1);
+ sStatement.execute(mddl2);
+
+ if (tableType.equals("TEXT")) {
+ sStatement.execute(mdd13);
+ }
+
+ System.out.println("multi key table");
+ }
+
+ System.out.println("Setup time: " + sw.elapsedTime());
+ fillUpBigTable(filler, randomgen);
+
+ if (multikeytable) {
+ fillUpMultiTable(filler, randomgen);
+ }
+
+ sw.zero();
+
+ if (shutdown) {
+ sStatement.execute("SHUTDOWN");
+ System.out.println("Shutdown Time: " + sw.elapsedTime());
+ }
+
+ cConnection.close();
+ } catch (SQLException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ private void fillUpBigTable(String filler,
+ Random randomgen) throws SQLException {
+
+ StopWatch sw = new StopWatch();
+ int i;
+
+ for (i = 0; i <= smallrows; i++) {
+ sStatement.execute("INSERT INTO zip VALUES(null);");
+ }
+
+ sStatement.execute("SET REFERENTIAL_INTEGRITY " + this.refIntegrity
+ + ";");
+
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "INSERT INTO test (firstname,lastname,zip,filler) VALUES (?,?,?,?)");
+
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+ para.setString(1, "Julia");
+ para.setString(2, "Clancy");
+
+ for (i = 0; i < bigrows; i++) {
+ para.setInt(3, randomgen.nextInt(smallrows));
+
+ long nextrandom = randomgen.nextLong();
+ int randomlength = (int) nextrandom & 0x7f;
+
+ if (randomlength > filler.length()) {
+ randomlength = filler.length();
+ }
+
+ String varfiller = filler.substring(0, randomlength);
+
+ para.setString(4, nextrandom + varfiller);
+ ps.execute();
+
+ if (reportProgress && (i + 1) % 10000 == 0) {
+ System.out.println("Insert " + (i + 1) + " : "
+ + sw.elapsedTime());
+ }
+
+ // delete and add 4000 rows to introduce fragmentation
+ if (deleteWhileInsert && i != 0
+ && i % deleteWhileInsertInterval == 0) {
+ sStatement.execute("CALL IDENTITY();");
+
+ XMultipleResults mrs = UnoRuntime.queryInterface(XMultipleResults.class,sStatement);
+ XResultSet rs = mrs.getResultSet();
+
+ rs.next();
+
+ XRow row = UnoRuntime.queryInterface(XRow.class,rs);
+ int lastId = row.getInt(1);
+
+ sStatement.execute(
+ "SELECT * INTO TEMP tempt FROM test WHERE id > "
+ + (lastId - 4000) + " ;");
+ sStatement.execute("DELETE FROM test WHERE id > "
+ + (lastId - 4000) + " ;");
+ sStatement.execute("INSERT INTO test SELECT * FROM tempt;");
+ sStatement.execute("DROP TABLE tempt;");
+ }
+ }
+
+ System.out.println("Total insert: " + i);
+ System.out.println("Insert time: " + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ }
+
+ private void fillUpMultiTable(String filler,
+ Random randomgen) throws SQLException {
+
+ StopWatch sw = new StopWatch();
+ int i;
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "INSERT INTO test2 (id1, id2, firstname,lastname,zip,filler) VALUES (?,?,?,?,?,?)");
+
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+ para.setString(3, "Julia");
+ para.setString(4, "Clancy");
+
+ int id1 = 0;
+
+ for (i = 0; i < bigrows; i++) {
+ int id2 = randomgen.nextInt(Integer.MAX_VALUE);
+
+ if (i % 1000 == 0) {
+ id1 = randomgen.nextInt(Integer.MAX_VALUE);
+ }
+
+ para.setInt(1, id1);
+ para.setInt(2, id2);
+ para.setInt(5, randomgen.nextInt(smallrows));
+
+ long nextrandom = randomgen.nextLong();
+ int randomlength = (int) nextrandom & 0x7f;
+
+ if (randomlength > filler.length()) {
+ randomlength = filler.length();
+ }
+
+ String varfiller = filler.substring(0, randomlength);
+
+ para.setString(6, nextrandom + varfiller);
+
+ try {
+ ps.execute();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ if (reportProgress && (i + 1) % 10000 == 0) {
+ System.out.println("Insert " + (i + 1) + " : "
+ + sw.elapsedTime());
+ }
+ }
+
+ System.out.println("Multi Key Total insert: " + i);
+ System.out.println("Insert time: " + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ }
+
+ public void tearDown() {}
+
+ public void checkResults() {
+
+ try {
+ StopWatch sw = new StopWatch();
+ XResultSet rs;
+
+ cConnection = drv.connect(url,info);
+
+ System.out.println("Reopened database: " + sw.elapsedTime());
+ sw.zero();
+
+ sStatement = cConnection.createStatement();
+
+ sStatement.execute("SET WRITE_DELAY " + writeDelay);
+
+ // the tests use different indexes
+ // use primary index
+ sStatement.execute("SELECT count(*) from TEST");
+
+ XMultipleResults mrs = UnoRuntime.queryInterface(XMultipleResults.class,sStatement);
+ rs = mrs.getResultSet();
+ XRow row = UnoRuntime.queryInterface(XRow.class,rs);
+
+ rs.next();
+ System.out.println("Row Count: " + row.getInt(1));
+ System.out.println("Time to count: " + sw.elapsedTime());
+
+ // use index on zip
+ sw.zero();
+ sStatement.execute("SELECT count(*) from TEST where zip > -1");
+
+ rs = mrs.getResultSet();
+
+ rs.next();
+ System.out.println("Row Count: " + row.getInt(1));
+ System.out.println("Time to count: " + sw.elapsedTime());
+ checkSelects();
+ checkUpdates();
+ checkSelects();
+ sw.zero();
+ sStatement.execute("SELECT count(*) from TEST where zip > -1");
+
+ rs = mrs.getResultSet();
+
+ rs.next();
+ System.out.println("Row Count: " + row.getInt(1));
+ System.out.println("Time to count: " + sw.elapsedTime());
+ sw.zero();
+
+ if (shutdown) {
+ sStatement.execute("SHUTDOWN");
+ System.out.println("Shutdown Time: " + sw.elapsedTime());
+ }
+
+ cConnection.close();
+ System.out.println("Closed database: " + sw.elapsedTime());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void checkSelects() {
+
+ StopWatch sw = new StopWatch();
+ java.util.Random randomgen = new java.util.Random();
+ int i = 0;
+ boolean slow = false;
+
+ try {
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "SELECT TOP 1 firstname,lastname,zip,filler FROM test WHERE zip = ?");
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+
+ for (; i < bigrows; i++) {
+ para.setInt(1, randomgen.nextInt(smallrows));
+ ps.execute();
+
+ if ((i + 1) == 100 && sw.elapsedTime() > 5000) {
+ slow = true;
+ }
+
+ if (reportProgress && (i + 1) % 10000 == 0
+ || (slow && (i + 1) % 100 == 0)) {
+ System.out.println("Select " + (i + 1) + " : "
+ + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("Select random zip " + i + " rows : "
+ + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ sw.zero();
+
+ try {
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "SELECT firstname,lastname,zip,filler FROM test WHERE id = ?");
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+
+ for (i = 0; i < bigrows; i++) {
+ para.setInt(1, randomgen.nextInt(bigrows - 1));
+ ps.execute();
+
+ if (reportProgress && (i + 1) % 10000 == 0
+ || (slow && (i + 1) % 100 == 0)) {
+ System.out.println("Select " + (i + 1) + " : "
+ + (sw.elapsedTime() + 1));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("Select random id " + i + " rows : "
+ + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ sw.zero();
+
+ try {
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "SELECT zip FROM zip WHERE zip = ?");
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+
+ for (i = 0; i < bigrows; i++) {
+ para.setInt(1, randomgen.nextInt(smallrows - 1));
+ ps.execute();
+
+ if (reportProgress && (i + 1) % 10000 == 0
+ || (slow && (i + 1) % 100 == 0)) {
+ System.out.println("Select " + (i + 1) + " : "
+ + (sw.elapsedTime() + 1));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("Select random zip from zip table " + i
+ + " rows : " + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ }
+
+ private void checkUpdates() {
+
+ StopWatch sw = new StopWatch();
+ java.util.Random randomgen = new java.util.Random();
+ int i = 0;
+ boolean slow = false;
+ int count = 0;
+
+ try {
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "UPDATE test SET filler = filler || zip WHERE zip = ?");
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+
+ for (; i < smallrows; i++) {
+ int random = randomgen.nextInt(smallrows - 1);
+
+ para.setInt(1, random);
+
+ count += ps.executeUpdate();
+
+ if (reportProgress && count % 10000 < 20) {
+ System.out.println("Update " + count + " : "
+ + (sw.elapsedTime() + 1));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("Update with random zip " + i
+ + " UPDATE commands, " + count + " rows : "
+ + sw.elapsedTime() + " rps: "
+ + (1000L * count / (sw.elapsedTime() + 1)));
+ sw.zero();
+
+ try {
+ XPreparedStatement ps = cConnection.prepareStatement(
+ "UPDATE test SET zip = zip + 1 WHERE id = ?");
+ XParameters para = UnoRuntime.queryInterface(XParameters.class,ps);
+
+ for (i = 0; i < bigrows; i++) {
+ int random = randomgen.nextInt(bigrows - 1);
+
+ para.setInt(1, random);
+ ps.execute();
+
+ if (reportProgress && (i + 1) % 10000 == 0
+ || (slow && (i + 1) % 100 == 0)) {
+ System.out.println("Update " + (i + 1) + " : "
+ + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("Update with random id " + i + " rows : "
+ + sw.elapsedTime() + " rps: "
+ + (1000L * i / (sw.elapsedTime() + 1)));
+ }
+}
diff --git a/connectivity/qa/connectivity/ado/DriverTest.cxx b/connectivity/qa/connectivity/ado/DriverTest.cxx
new file mode 100644
index 000000000..f4dd0ebc2
--- /dev/null
+++ b/connectivity/qa/connectivity/ado/DriverTest.cxx
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include "ado/AConnection.hxx"
+#include "ado/ADatabaseMetaData.hxx"
+#include "ado/ADriver.hxx"
+#include "ado/AStatement.hxx"
+#include "ado/ACallableStatement.hxx"
+#include "ado/APreparedStatement.hxx"
+#include "ado/ACatalog.hxx"
+#include <com/sun/star/sdbc/ColumnValue.hpp>
+#include <com/sun/star/sdbc/TransactionIsolation.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <connectivity/dbexception.hxx>
+#include <osl/file.hxx>
+#include "strings.hrc"
+
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+namespace connectivity::ado {
+
+
+class AdoDriverTest: public test::BootstrapFixture
+{
+public:
+ AdoDriverTest() : test::BootstrapFixture(false, false) {};
+
+ void test_metadata();
+ void test_select_default_all();
+
+ virtual void setUp();
+ virtual void tearDown();
+
+ CPPUNIT_TEST_SUITE(AdoDriverTest);
+
+ CPPUNIT_TEST(test_metadata);
+ CPPUNIT_TEST(test_select_default_all);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ Reference<XInterface> m_xAdoComponent;
+ Reference<XConnection> m_xConnection;
+};
+
+void AdoDriverTest::setUp()
+{
+ test::BootstrapFixture::setUp();
+ m_xAdoComponent = getMultiServiceFactory()->createInstance("com.sun.star.comp.sdbc.ado.ODriver");
+ CPPUNIT_ASSERT_MESSAGE("no ado component!", m_xAdoComponent.is());
+
+ OUString url = "sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" +
+ m_directories.getPathFromWorkdir("/CppunitTest/TS001018407.mdb");
+
+ Sequence< PropertyValue > info;
+ Reference< XDriver> xDriver(m_xAdoComponent, UNO_QUERY);
+ if (!xDriver.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to ado driver!", xDriver.is());
+ }
+
+ m_xConnection = xDriver->connect(url, info);
+ if (!m_xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to students data source!", m_xConnection.is());
+ }
+}
+
+void AdoDriverTest::tearDown()
+{
+ m_xAdoComponent = 0;
+ test::BootstrapFixture::tearDown();
+}
+
+void AdoDriverTest::test_metadata()
+{
+ Reference< XDatabaseMetaData > xDatabaseMetaData = m_xConnection->getMetaData();
+ if (!xDatabaseMetaData.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot retrieve meta data!", xDatabaseMetaData.is());
+ }
+
+ const Any catalog;
+ const OUString schemaPattern = "%";
+ const OUString tableNamePattern = "%";
+ const Sequence< OUString > types;
+
+ Reference< XResultSet > xResultSet =
+ xDatabaseMetaData->getTables(catalog, schemaPattern, tableNamePattern, types);
+ if (!xResultSet.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot retrieve tables!", xResultSet.is());
+ }
+}
+
+void AdoDriverTest::test_select_default_all()
+{
+ const OUString sql = "select \"FirstName\" from \"Students\" ORDER BY \"FirstName\"";
+ Reference< XPreparedStatement > xStatement = m_xConnection->prepareStatement(sql);
+ if (!xStatement.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot create prepared statement!", xStatement.is());
+ }
+
+ Reference< XResultSet > xResultSet = xStatement->executeQuery();
+ if (!xResultSet.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot execute sql statement!", xResultSet.is());
+ }
+
+ Reference< XRow > xDelegatorRow(xResultSet, UNO_QUERY);
+ if (!xDelegatorRow.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xDelegatorRow.is());
+ }
+
+ sal_Bool result = xResultSet->first();
+ CPPUNIT_ASSERT_MESSAGE("fetch first row failed!", result);
+/*
+ OUString mail = xDelegatorRow->getString(1);
+ CPPUNIT_ASSERT_MESSAGE("first row is not john@doe.org!", mail.equalsAscii("john@doe.org"));
+*/
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(AdoDriverTest);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/connectivity/qa/connectivity/ado/TS001018407.mdb b/connectivity/qa/connectivity/ado/TS001018407.mdb
new file mode 100644
index 000000000..abe9f5ee3
--- /dev/null
+++ b/connectivity/qa/connectivity/ado/TS001018407.mdb
Binary files differ
diff --git a/connectivity/qa/connectivity/commontools/FValue_test.cxx b/connectivity/qa/connectivity/commontools/FValue_test.cxx
new file mode 100644
index 000000000..b6f0e3658
--- /dev/null
+++ b/connectivity/qa/connectivity/commontools/FValue_test.cxx
@@ -0,0 +1,366 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include <connectivity/FValue.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+namespace connectivity::commontools {
+
+class FValueTest: public test::BootstrapFixture
+{
+public:
+ FValueTest() : test::BootstrapFixture(false, false) {};
+
+ void test_Bool();
+
+ void test_Int8();
+
+ void test_Int16();
+ void test_uInt16();
+
+ void test_Int32();
+ void test_uInt32();
+
+ void test_Int64();
+ void test_uInt64();
+
+ void test_float();
+ void test_double();
+
+ void test_bool_getString();
+ void test_bit_getString();
+
+ void test_bool_creation();
+
+ CPPUNIT_TEST_SUITE(FValueTest);
+
+ CPPUNIT_TEST(test_Bool);
+
+ CPPUNIT_TEST(test_Int8);
+
+ CPPUNIT_TEST(test_Int16);
+ CPPUNIT_TEST(test_uInt16);
+
+ CPPUNIT_TEST(test_Int32);
+ CPPUNIT_TEST(test_uInt32);
+
+ CPPUNIT_TEST(test_Int64);
+ CPPUNIT_TEST(test_uInt64);
+
+ CPPUNIT_TEST(test_float);
+ CPPUNIT_TEST(test_double);
+
+ CPPUNIT_TEST(test_bool_getString);
+ CPPUNIT_TEST(test_bit_getString);
+ CPPUNIT_TEST(test_bool_creation);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void FValueTest::test_Bool()
+{
+ bool src_Bool = true;
+ ORowSetValue v(src_Bool);
+ bool trg_Bool = v.getBool();
+
+ std::cerr << "src_Bool: " << src_Bool << std::endl;
+ std::cerr << "trg_Bool: " << trg_Bool << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("bool conversion to ORowSetValue didn't work", trg_Bool, src_Bool);
+
+ Any any_Bool = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_Bool);
+ trg_Bool = t.getBool();
+
+ std::cerr << "trg_Bool: " << trg_Bool << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("bool conversion from Any didn't work", trg_Bool, src_Bool);
+}
+
+void FValueTest::test_Int8()
+{
+ sal_Int8 src_salInt8 = 127;
+ ORowSetValue v(src_salInt8);
+ sal_Int8 trg_salInt8 = v.getInt8();
+
+ std::cerr << "src_salInt8: " << static_cast<short>(src_salInt8) << std::endl;
+ std::cerr << "trg_salInt8: " << static_cast<short>(trg_salInt8) << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int8 conversion to ORowSetValue didn't work", trg_salInt8, src_salInt8);
+
+ Any any_Int8 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_Int8);
+ trg_salInt8 = t.getInt8();
+
+ std::cerr << "trg_salInt8: " << static_cast<short>(trg_salInt8) << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int8 conversion from Any didn't work", trg_salInt8, src_salInt8);
+}
+
+void FValueTest::test_Int16()
+{
+ sal_Int16 src_salInt16 = -10001;
+ ORowSetValue v(src_salInt16);
+ sal_Int16 trg_salInt16 = v.getInt16();
+
+ std::cerr << "src_salInt16: " << src_salInt16 << std::endl;
+ std::cerr << "trg_salInt16: " << trg_salInt16 << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int16 conversion to ORowSetValue didn't work", trg_salInt16, src_salInt16);
+
+ Any any_Int16 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_Int16);
+ trg_salInt16 = t.getInt16();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int16 conversion from Any didn't work", trg_salInt16, src_salInt16);
+}
+
+void FValueTest::test_uInt16()
+{
+ sal_uInt16 src_saluInt16 = 10001;
+ ORowSetValue v(src_saluInt16);
+ sal_uInt16 trg_saluInt16 = v.getUInt16();
+
+ std::cerr << "src_saluInt16: " << src_saluInt16 << std::endl;
+ std::cerr << "trg_saluInt16: " << trg_saluInt16 << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_uInt16 conversion to ORowSetValue didn't work", trg_saluInt16, src_saluInt16);
+
+ Any any_uInt16 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_uInt16);
+ trg_saluInt16 = t.getUInt16();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_uInt16 conversion from Any didn't work", trg_saluInt16, src_saluInt16);
+}
+
+void FValueTest::test_Int32()
+{
+ sal_Int32 src_salInt32 = -10000001;
+ ORowSetValue v(src_salInt32);
+ sal_Int32 trg_salInt32 = v.getInt32();
+
+ std::cerr << "src_salInt32: " << src_salInt32 << std::endl;
+ std::cerr << "trg_salInt32: " << trg_salInt32 << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int32 conversion to ORowSetValue didn't work", trg_salInt32, src_salInt32);
+
+ Any any_Int32 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_Int32);
+ trg_salInt32 = t.getInt32();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int32 conversion from Any didn't work", trg_salInt32, src_salInt32);
+}
+
+void FValueTest::test_uInt32()
+{
+ sal_uInt32 src_saluInt32 = 100000001;
+ ORowSetValue v(src_saluInt32);
+ sal_uInt32 trg_saluInt32 = v.getUInt32();
+
+ std::cerr << "src_saluInt32: " << src_saluInt32 << std::endl;
+ std::cerr << "trg_saluInt32: " << trg_saluInt32 << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_uInt32 conversion to ORowSetValue didn't work", trg_saluInt32, src_saluInt32);
+
+ Any any_uInt32 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_uInt32);
+ trg_saluInt32 = t.getUInt32();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_uInt32 conversion from Any didn't work", trg_saluInt32, src_saluInt32);
+}
+
+void FValueTest::test_Int64()
+{
+ sal_Int64 src_salInt64 = -1000000000000000001LL;
+ ORowSetValue v(src_salInt64);
+ sal_Int64 trg_salInt64 = v.getLong();
+
+ std::cerr << "src_salInt64: " << src_salInt64 << std::endl;
+ std::cerr << "trg_salInt64: " << trg_salInt64 << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int64 conversion to ORowSetValue didn't work", trg_salInt64, src_salInt64);
+
+ Any any_Int64 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_Int64);
+ trg_salInt64 = t.getLong();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_Int64 conversion from Any didn't work", trg_salInt64, src_salInt64);
+}
+
+void FValueTest::test_uInt64()
+{
+ sal_uInt64 src_saluInt64 = 10000000000000000001ULL;
+ ORowSetValue v(src_saluInt64);
+ sal_uInt64 trg_saluInt64 = v.getULong();
+
+ std::cerr << "src_saluInt64: " << src_saluInt64 << std::endl;
+ std::cerr << "trg_saluInt64: " << trg_saluInt64 << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_uInt64 conversion to ORowSetValue didn't work", trg_saluInt64, src_saluInt64);
+
+ Any any_uInt64 = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_uInt64);
+ trg_saluInt64 = t.getULong();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("sal_uInt64 conversion from Any didn't work", trg_saluInt64, src_saluInt64);
+}
+
+void FValueTest::test_float()
+{
+ float src_float = 1.234f;
+ ORowSetValue v(src_float);
+ float trg_float = v.getFloat();
+
+ std::cerr << "src_float: " << src_float << std::endl;
+ std::cerr << "trg_float: " << trg_float << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("float conversion to ORowSetValue didn't work", trg_float, src_float);
+
+ Any any_float = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_float);
+ trg_float = t.getFloat();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("float conversion from Any didn't work", trg_float, src_float);
+}
+
+void FValueTest::test_double()
+{
+ double src_double = 1.23456789;
+ ORowSetValue v(src_double);
+ double trg_double = v.getDouble();
+
+ std::cerr << "src_double: " << src_double << std::endl;
+ std::cerr << "trg_double: " << trg_double << std::endl;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("double conversion to ORowSetValue didn't work", trg_double, src_double);
+
+ Any any_double = v.makeAny();
+ ORowSetValue t;
+ t.fill(any_double);
+ trg_double = t.getDouble();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("double conversion from Any didn't work", trg_double, src_double);
+}
+
+void FValueTest::test_bool_getString()
+{
+ bool src_bool_1 = true;
+ ORowSetValue v_1(src_bool_1);
+ OUString trg_bool_1 = v_1.getString();
+
+ std::cerr << "src_bool_1: " << src_bool_1 << std::endl;
+ std::cerr << "trg_bool_1: " << trg_bool_1 << std::endl;
+
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool to string conversion didn't work", bool(trg_bool_1 == "true"));
+
+ bool src_bool_0 = false;
+ ORowSetValue v_0(src_bool_0);
+ OUString trg_bool_0 = v_0.getString();
+
+ std::cerr << "src_bool_0: " << src_bool_0 << std::endl;
+ std::cerr << "trg_bool_0: " << trg_bool_0 << std::endl;
+
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool to string conversion didn't work", bool(trg_bool_0 == "false"));
+}
+
+void FValueTest::test_bit_getString()
+{
+ bool src_bool_1 = true;
+ ORowSetValue v_1(src_bool_1);
+ v_1.setTypeKind(DataType::BIT);
+ OUString trg_bool_1 = v_1.getString();
+
+ std::cerr << "src_bit_1: " << src_bool_1 << std::endl;
+ std::cerr << "trg_bit_1: " << trg_bool_1 << std::endl;
+
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bit to string conversion didn't work", bool(trg_bool_1 == "1"));
+
+ bool src_bool_0 = false;
+ ORowSetValue v_0(src_bool_0);
+ v_0.setTypeKind(DataType::BIT);
+ OUString trg_bool_0 = v_0.getString();
+
+ std::cerr << "src_bit_0: " << src_bool_0 << std::endl;
+ std::cerr << "trg_bit_0: " << trg_bool_0 << std::endl;
+
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bit to string conversion didn't work", bool(trg_bool_0 == "0"));
+}
+
+void FValueTest::test_bool_creation()
+{
+ ORowSetValue vTrue(true);
+ ORowSetValue vFalse(false);
+
+ {
+ ORowSetValue v(OUString("1"));
+ v.setTypeKind(DataType::BOOLEAN);
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool creation from string didn't work", bool(v == vTrue));
+ }
+
+ {
+ ORowSetValue v(OUString("0"));
+ v.setTypeKind(DataType::BOOLEAN);
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool creation from string didn't work", bool(v == vFalse));
+ }
+
+ {
+ ORowSetValue v(OUString("true"));
+ v.setTypeKind(DataType::BOOLEAN);
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool creation from string didn't work", bool(v == vTrue));
+ }
+
+ {
+ ORowSetValue v(OUString("tRuE"));
+ v.setTypeKind(DataType::BOOLEAN);
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool creation from string didn't work", bool(v == vTrue));
+ }
+
+ {
+ ORowSetValue v(OUString("false"));
+ v.setTypeKind(DataType::BOOLEAN);
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool creation from string didn't work", bool(v == vFalse));
+ }
+
+ {
+ ORowSetValue v(OUString("0"));
+ v.setTypeKind(DataType::BOOLEAN);
+ CPPUNIT_ASSERT_MESSAGE("ORowSetValue bool creation from string didn't work", bool(v == vFalse));
+ }
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(FValueTest);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/qa/connectivity/mork/DriverTest.cxx b/connectivity/qa/connectivity/mork/DriverTest.cxx
new file mode 100644
index 000000000..e2f2849ff
--- /dev/null
+++ b/connectivity/qa/connectivity/mork/DriverTest.cxx
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include <com/sun/star/sdbc/XDriver.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+namespace connectivity::mork {
+
+
+class MorkDriverTest: public test::BootstrapFixture
+{
+public:
+ MorkDriverTest() : test::BootstrapFixture(false, false) {};
+
+ void checkAcceptsURL(Reference< XDriver> const & xDriver, const char* url, bool expected);
+ void test_metadata();
+ void test_select_default_all();
+ void test_select_list_table_joe_doe_5();
+
+ virtual void setUp() override;
+ virtual void tearDown() override;
+
+ CPPUNIT_TEST_SUITE(MorkDriverTest);
+
+ CPPUNIT_TEST(test_metadata);
+ CPPUNIT_TEST(test_select_default_all);
+ CPPUNIT_TEST(test_select_list_table_joe_doe_5);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ Reference<XInterface> m_xMorkComponent;
+ Reference<XConnection> m_xConnection;
+};
+
+void MorkDriverTest::checkAcceptsURL(Reference< XDriver> const & xDriver, const char* url, bool expected)
+{
+ bool res = xDriver->acceptsURL(OUString::createFromAscii(url));
+ if (res != expected)
+ {
+ CPPUNIT_ASSERT_MESSAGE("wrong URL outcome!", true);
+ }
+}
+
+void MorkDriverTest::setUp()
+{
+ test::BootstrapFixture::setUp();
+ m_xMorkComponent = getMultiServiceFactory()->createInstance("com.sun.star.comp.sdbc.MorkDriver");
+ CPPUNIT_ASSERT_MESSAGE("no mork component!", m_xMorkComponent.is());
+
+ // is this the best way to pass test file through URL?
+ // may be take a custom Sequence< PropertyValue > route?
+ OUString url = "sdbc:address:thunderbird:unittest:" +
+ m_directories.getPathFromSrc("/connectivity/qa/connectivity/mork/abook_10_john_does.mab");
+
+ Sequence< PropertyValue > info;
+ Reference< XDriver> xDriver(m_xMorkComponent, UNO_QUERY);
+ if (!xDriver.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to mork driver!", xDriver.is());
+ }
+
+ // bad
+ checkAcceptsURL(xDriver, "sdbc:address:macab", false);
+ checkAcceptsURL(xDriver, "sdbc:mozab:ldap:", false);
+ checkAcceptsURL(xDriver, "sdbc:mozab:outlook:", false);
+ checkAcceptsURL(xDriver, "sdbc:mozab:outlookexp:", false);
+
+ // good
+ checkAcceptsURL(xDriver, "sdbc:mozab:mozilla:", true);
+ checkAcceptsURL(xDriver, "sdbc:mozab:thunderbird:", true);
+ checkAcceptsURL(xDriver, "sdbc:address:mozilla:", true);
+ checkAcceptsURL(xDriver, "sdbc:address:thunderbird:", true);
+
+ m_xConnection = xDriver->connect(url, info);
+ if (!m_xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to address book data source!", m_xConnection.is());
+ }
+}
+
+void MorkDriverTest::tearDown()
+{
+// how to make dispose() work?
+// Reference< css::lang::XComponent >( m_xMorkComponent, UNO_QUERY_THROW )->dispose();
+ m_xConnection->close();
+ test::BootstrapFixture::tearDown();
+}
+
+void MorkDriverTest::test_metadata()
+{
+ Reference< XDatabaseMetaData > xDatabaseMetaData = m_xConnection->getMetaData();
+ if (!xDatabaseMetaData.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot retrieve meta data!", xDatabaseMetaData.is());
+ }
+
+ const Any catalog;
+ const OUString schemaPattern = "%";
+ const OUString tableNamePattern = "%";
+ const Sequence< OUString > types;
+
+ Reference< XResultSet > xResultSet =
+ xDatabaseMetaData->getTables(catalog, schemaPattern, tableNamePattern, types);
+ if (!xResultSet.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot retrieve tables!", xResultSet.is());
+ }
+
+ // TODO: how to access that result set and check the tables?
+ // it should be 3 tables inside: AddressBook, does_5 and does_10
+}
+
+void MorkDriverTest::test_select_default_all()
+{
+ const OUString sql = "select \"E-mail\" from \"AddressBook\" ORDER BY \"E-mail\"";
+ Reference< XPreparedStatement > xStatement = m_xConnection->prepareStatement(sql);
+ if (!xStatement.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot create prepared statement!", xStatement.is());
+ }
+
+ Reference< XResultSet > xResultSet = xStatement->executeQuery();
+ if (!xResultSet.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot execute sql statement!", xResultSet.is());
+ }
+
+ Reference< XRow > xDelegatorRow(xResultSet, UNO_QUERY);
+ if (!xDelegatorRow.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xDelegatorRow.is());
+ }
+
+ bool result = xResultSet->first();
+ CPPUNIT_ASSERT_MESSAGE("fetch first row failed!", result);
+ OUString mail = xDelegatorRow->getString(1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("first row is not john@doe.org!", OUString("john@doe.org"), mail);
+
+ result = xResultSet->next();
+ CPPUNIT_ASSERT_MESSAGE("fetch second row failed!", result);
+ mail = xDelegatorRow->getString(1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("second row is not john@doe10.org!", OUString("john@doe10.org"), mail);
+
+ result = xResultSet->last();
+ CPPUNIT_ASSERT_MESSAGE("fetch last row failed!", result);
+ mail = xDelegatorRow->getString(1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("last row is not john@doe9.org!", OUString("john@doe9.org"), mail);
+
+ css::uno::Reference<css::sdbc::XCloseable>(
+ xStatement, css::uno::UNO_QUERY_THROW)->close();
+}
+
+void MorkDriverTest::test_select_list_table_joe_doe_5()
+{
+ const OUString sql = "select \"E-mail\" from \"does_5\" where \"E-mail\" LIKE '%doe5.org' ";
+ Reference< XPreparedStatement > xStatement = m_xConnection->prepareStatement(sql);
+ if (!xStatement.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot create prepared statement!", xStatement.is());
+ }
+
+ Reference< XResultSet > xResultSet = xStatement->executeQuery();
+ if (!xResultSet.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot execute sql statement!", xResultSet.is());
+ }
+
+ Reference< XRow > xDelegatorRow(xResultSet, UNO_QUERY);
+ if (!xDelegatorRow.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xDelegatorRow.is());
+ }
+
+ bool result = xResultSet->first();
+ CPPUNIT_ASSERT_MESSAGE("fetch first row failed!", result);
+ OUString mail = xDelegatorRow->getString(1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("last row is not john@doe5.org!", OUString("john@doe5.org"), mail);
+
+ css::uno::Reference<css::sdbc::XCloseable>(
+ xStatement, css::uno::UNO_QUERY_THROW)->close();
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(MorkDriverTest);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/connectivity/qa/connectivity/mork/abook_10_john_does.mab b/connectivity/qa/connectivity/mork/abook_10_john_does.mab
new file mode 100644
index 000000000..41aac4c3e
--- /dev/null
+++ b/connectivity/qa/connectivity/mork/abook_10_john_does.mab
@@ -0,0 +1,159 @@
+// <!-- <mdb:mork:z v="1.4"/> -->
+< <(a=c)> // (f=iso-8859-1)
+ (B8=LastModifiedDate)(B9=RecordKey)(BA=AddrCharSet)(BB=LastRecordKey)
+ (BC=ns:addrbk:db:table:kind:pab)(BD=ListName)(BE=ListNickName)
+ (BF=ListDescription)(C0=ListTotalAddresses)(C1=LowercaseListName)
+ (C2=ns:addrbk:db:table:kind:deleted)(C3=_Yahoo)(C4=_MSN)
+ (C5=_GoogleTalk)(C6=_Skype)(C7=_JabberId)(C8=PreferDisplayName)
+ (C9=PhotoURI)(CA=PhotoType)(CB=PhotoName)(CC=DbRowID)(CD=_QQ)(CE=_ICQ)
+ (80=ns:addrbk:db:row:scope:card:all)
+ (81=ns:addrbk:db:row:scope:list:all)
+ (82=ns:addrbk:db:row:scope:data:all)(83=FirstName)(84=LastName)
+ (85=PhoneticFirstName)(86=PhoneticLastName)(87=DisplayName)
+ (88=NickName)(89=PrimaryEmail)(8A=LowercasePrimaryEmail)
+ (8B=SecondEmail)(8C=PreferMailFormat)(8D=PopularityIndex)
+ (8E=AllowRemoteContent)(8F=WorkPhone)(90=HomePhone)(91=FaxNumber)
+ (92=PagerNumber)(93=CellularNumber)(94=WorkPhoneType)(95=HomePhoneType)
+ (96=FaxNumberType)(97=PagerNumberType)(98=CellularNumberType)
+ (99=HomeAddress)(9A=HomeAddress2)(9B=HomeCity)(9C=HomeState)
+ (9D=HomeZipCode)(9E=HomeCountry)(9F=WorkAddress)(A0=WorkAddress2)
+ (A1=WorkCity)(A2=WorkState)(A3=WorkZipCode)(A4=WorkCountry)
+ (A5=JobTitle)(A6=Department)(A7=Company)(A8=_AimScreenName)
+ (A9=AnniversaryYear)(AA=AnniversaryMonth)(AB=AnniversaryDay)
+ (AC=SpouseName)(AD=FamilyName)(AE=WebPage1)(AF=WebPage2)(B0=BirthYear)
+ (B1=BirthMonth)(B2=BirthDay)(B3=Custom1)(B4=Custom2)(B5=Custom3)
+ (B6=Custom4)(B7=Notes)>
+
+<(AF=b)(81=John Doe)(82=)(80=0)(83=John)(84=1)(85=Doe)(86=john@doe.org)
+ (87=generic)(88=John Doe2)(89=Doe2)(8A=john@doe2.org)(8B=2)(8C=John Doe3)
+ (8D=Doe3)(8E=john@doe3.org)(8F=3)(90=John Doe4)(91=Doe4)(92
+ =john@doe4.org)(93=4)(94=John Doe5)(95=Doe5)(96=john@doe5.org)(97=5)
+ (98=John Doe6)(99=Doe6)(9A=john@doe6.org)(9B=6)(9C=John Doe7)(9D=Doe7)
+ (9E=john@doe7.org)(9F=7)(A0=John Doe8)(A1=Doe8)(A2=john@doe8.org)
+ (A3=8)(A4=John Doe9)(A5=Doe9)(A6=john@doe9.org)(A7=9)(A8=John Doe10)
+ (A9=Doe10)(AA=john@doe10.org)(AB=10)(AC=a)(AD=Does_5)(AE=does_5)>
+{1:^80 {(k^BC:c)(s=9)}
+ [1:^82(^BB=b)]
+ [1(^87^81)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^85)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^86)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=1)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^86)(^B9=1)]
+ [2(^87^88)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^89)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^8A)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=2)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^8A)(^B9=2)]
+ [3(^87^8C)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^8D)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^8E)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=3)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^8E)(^B9=3)]
+ [4(^87^90)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^91)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^92)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=4)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^92)(^B9=4)]
+ [5(^87^94)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^95)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^96)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=5)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^96)(^B9=5)]
+ [6(^87^98)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^99)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^9A)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=6)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^9A)(^B9=6)]
+ [7(^87^9C)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^9D)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^9E)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=7)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^9E)(^B9=7)]
+ [8(^87^A0)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^A1)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^A2)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=8)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^A2)(^B9=8)]
+ [9(^87^A4)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^A5)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^A6)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=9)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^A6)(^B9=9)]
+ [A(^87^A8)(^86=)(^C3=)(^A1=)(^AE=)(^C4=)(^C5=)(^B2=)(^A7=)(^9A=)(^B3=)
+ (^C6=)(^A6=)(^A4=)(^A5=)(^A3=)(^9E=)(^85=)(^B0=)(^8D=0)(^C7=)(^A0=)
+ (^A2=)(^B7=)(^8C=0)(^B8=0)(^83^83)(^A8=)(^C8=1)(^84^A9)(^92=)(^C9=)
+ (^B6=)(^9D=)(^89^AA)(^8E=0)(^AF=)(^CA^87)(^8F=)(^CB=)(^8B=)(^93=)
+ (^90=)(^CC=10)(^B1=)(^CD=)(^9B=)(^9C=)(^91=)(^B4=)(^9F=)(^99=)(^88=)
+ (^CE=)(^B5=)(^8A^AA)(^B9=a)]
+ [1:^81(^BD^AD)(^C1^AE)(^BE=)(^BF=)(^C0=0)(^B9=b)]}
+
+@$${9{@
+
+<(B2=c)(B0=Does_10)(B1=does_10)>
+{1:^80 {(k^BC:c)(s=9)}
+ [-2:^81(^BD^B0)(^C1^B1)(^BE=)(^BF=)(^C0=0)(^B9=c)]}
+[1:^82(^BB=c)]
+@$$}9}@
+
+@$${A{@
+< <(a=c)> // (f=iso-8859-1)
+ (CF=Address1)>
+[-1:^81(^BD^AD)(^C1^AE)(^BE=)(^BF=)(^C0=1)(^B9=b)(^CF=1)]
+@$$}A}@
+
+@$${B{@
+< <(a=c)> // (f=iso-8859-1)
+ (D0=Address2)>
+[-1:^81(^BD^AD)(^C1^AE)(^BE=)(^BF=)(^C0=2)(^B9=b)(^CF=1)(^D0=2)]
+@$$}B}@
+
+@$${C{@
+< <(a=c)> // (f=iso-8859-1)
+ (D1=Address3)>
+[-1:^81(^BD^AD)(^C1^AE)(^BE=)(^BF=)(^C0=3)(^B9=b)(^CF=1)(^D0=2)(^D1=3)]
+@$$}C}@
+
+@$${D{@
+< <(a=c)> // (f=iso-8859-1)
+ (D2=Address4)>
+[-1:^81(^BD^AD)(^C1^AE)(^BE=)(^BF=)(^C0=4)(^B9=b)(^CF=1)(^D0=2)(^D1=3)
+ (^D2=4)]
+@$$}D}@
+
+@$${E{@
+< <(a=c)> // (f=iso-8859-1)
+ (D3=Address5)>
+[-1:^81(^BD^AD)(^C1^AE)(^BE=)(^BF=)(^C0=5)(^B9=b)(^CF=1)(^D0=2)(^D1=3)
+ (^D2=4)(^D3=5)]
+@$$}E}@
+
+@$${F{@
+[-2:^81(^BD^B0)(^C1^B1)(^BE=)(^BF=)(^C0=1)(^B9=c)(^CF=a)]
+@$$}F}@
+
+@$${10{@
+[-2:^81(^BD^B0)(^C1^B1)(^BE=)(^BF=)(^C0=2)(^B9=c)(^CF=a)(^D0=6)]
+@$$}10}@
+
+@$${11{@
+[-2:^81(^BD^B0)(^C1^B1)(^BE=)(^BF=)(^C0=3)(^B9=c)(^CF=a)(^D0=6)(^D1=7)]
+@$$}11}@
+
+@$${12{@
+[-2:^81(^BD^B0)(^C1^B1)(^BE=)(^BF=)(^C0=4)(^B9=c)(^CF=a)(^D0=6)(^D1=7)
+ (^D2=8)]
+@$$}12}@
+
+@$${13{@
+[-2:^81(^BD^B0)(^C1^B1)(^BE=)(^BF=)(^C0=5)(^B9=c)(^CF=a)(^D0=6)(^D1=7)
+ (^D2=8)(^D3=9)]
+@$$}13}@
diff --git a/connectivity/qa/connectivity/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx
new file mode 100644
index 000000000..7291c9f44
--- /dev/null
+++ b/connectivity/qa/connectivity/mysql/mysql.cxx
@@ -0,0 +1,501 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+#include <com/sun/star/sdbc/XColumnLocate.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/sdbc/XStatement.hpp>
+#include <com/sun/star/sdbc/XDriver.hpp>
+
+#include <com/sun/star/util/DateTime.hpp>
+#include <svtools/miscopt.hxx>
+#include <osl/process.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+class MysqlTestDriver : public test::BootstrapFixture
+{
+private:
+ OUString m_sUrl;
+ Reference<XInterface> m_xMysqlcComponent;
+ Reference<XDriver> m_xDriver;
+ Sequence<PropertyValue> m_infos;
+
+public:
+ MysqlTestDriver()
+ : test::BootstrapFixture(false, false)
+ {
+ }
+ virtual void setUp() override;
+ virtual void tearDown() override;
+ void testDBConnection();
+ void testCreateAndDropTable();
+ void testIntegerInsertAndQuery();
+ void testDBPositionChange();
+ void testMultipleResultsets();
+ void testDBMetaData();
+ void testTimestampField();
+ void testNumericConversionPrepared();
+ void testPreparedStmtIsAfterLast();
+ void testGetStringFromBloColumnb();
+
+ CPPUNIT_TEST_SUITE(MysqlTestDriver);
+ CPPUNIT_TEST(testDBConnection);
+ CPPUNIT_TEST(testCreateAndDropTable);
+ CPPUNIT_TEST(testIntegerInsertAndQuery);
+ CPPUNIT_TEST(testMultipleResultsets);
+ CPPUNIT_TEST(testDBMetaData);
+ CPPUNIT_TEST(testTimestampField);
+ CPPUNIT_TEST(testNumericConversionPrepared);
+ CPPUNIT_TEST(testPreparedStmtIsAfterLast);
+ CPPUNIT_TEST(testGetStringFromBloColumnb);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void MysqlTestDriver::tearDown()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ }
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+ xStatement->executeUpdate("DROP TABLE IF EXISTS otherTable");
+ test::BootstrapFixture::tearDown();
+}
+
+void MysqlTestDriver::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ /* Get URL from environment variable. This test suite should run only when
+ * there is a URL given. This is because it can be used for testing connection to
+ * external databases as well.
+ *
+ * Example URL:
+ * username/password@sdbc:mysql:mysqlc:localhost:3306/testdatabase
+ */
+ osl_getEnvironment(OUString("CONNECTIVITY_TEST_MYSQL_DRIVER").pData, &m_sUrl.pData);
+ m_xMysqlcComponent
+ = getMultiServiceFactory()->createInstance("com.sun.star.comp.sdbc.mysqlc.MysqlCDriver");
+ CPPUNIT_ASSERT_MESSAGE("no mysqlc component!", m_xMysqlcComponent.is());
+
+ // set user name and password
+ m_infos = Sequence<PropertyValue>{ 2 };
+ m_infos[0].Name = OUString{ "user" };
+ sal_Int32 nPer = m_sUrl.indexOf("/");
+ m_infos[0].Value = makeAny(m_sUrl.copy(0, nPer));
+ m_sUrl = m_sUrl.copy(nPer + 1);
+ m_infos[1].Name = OUString{ "password" };
+ sal_Int32 nAt = m_sUrl.indexOf("@");
+ m_infos[1].Value = makeAny(m_sUrl.copy(0, nAt));
+ m_sUrl = m_sUrl.copy(nAt + 1);
+
+ m_xDriver.set(m_xMysqlcComponent, UNO_QUERY);
+ if (!m_xDriver.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to mysqlc driver!", m_xDriver.is());
+ }
+}
+
+/**
+ * Test database connection. It is assumed that the given URL is correct and
+ * there is a server running at the location.
+ */
+void MysqlTestDriver::testDBConnection()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ }
+
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+
+ Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT 1");
+ CPPUNIT_ASSERT(xResultSet.is());
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is());
+
+ sal_Bool result = xResultSet->first();
+ CPPUNIT_ASSERT_MESSAGE("fetch first row failed!", result);
+}
+
+/**
+ * Test creation and removal of a table
+ */
+void MysqlTestDriver::testCreateAndDropTable()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ }
+
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ auto nUpdateCount
+ = xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)");
+ CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
+
+ // we can use the same xStatement instance here
+ nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable");
+ CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
+}
+
+void MysqlTestDriver::testIntegerInsertAndQuery()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ }
+
+ Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ auto nUpdateCount
+ = xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)");
+ CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
+
+ Reference<XPreparedStatement> xPrepared
+ = xConnection->prepareStatement(OUString{ "INSERT INTO myTestTable VALUES (?)" });
+ Reference<XParameters> xParams(xPrepared, UNO_QUERY);
+ constexpr int ROW_COUNT = 3;
+ for (int i = 0; i < ROW_COUNT; ++i)
+ {
+ xParams->setLong(1, i); // first and only column
+ nUpdateCount = xPrepared->executeUpdate();
+ CPPUNIT_ASSERT_EQUAL(1, nUpdateCount); // one row is inserted at a time
+ }
+
+ // now let's query the existing data
+ Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT id from myTestTable");
+ CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is());
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ Reference<XColumnLocate> xColumnLocate(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is());
+
+ for (long i = 0; i < ROW_COUNT; ++i)
+ {
+ bool hasRow = xResultSet->next();
+ CPPUNIT_ASSERT_MESSAGE("not enough result after query", hasRow);
+ CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(1)); // first and only column
+ CPPUNIT_ASSERT_EQUAL(i, xRow->getLong(xColumnLocate->findColumn("id"))); // test findColumn
+ }
+ CPPUNIT_ASSERT_MESSAGE("Cursor is not on last position.",
+ xResultSet->isLast()); // cursor is on last position
+ CPPUNIT_ASSERT_EQUAL(ROW_COUNT, xResultSet->getRow()); // which is the last position
+
+ bool hasRow = xResultSet->next(); // go to afterlast
+ // no more rows, next should return false
+ CPPUNIT_ASSERT_MESSAGE("next returns true after last row", !hasRow);
+ // cursor should be in afterlast position
+ CPPUNIT_ASSERT_EQUAL(ROW_COUNT + 1, xResultSet->getRow());
+ CPPUNIT_ASSERT_MESSAGE("Cursor is not on after-last position.", xResultSet->isAfterLast());
+
+ nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable");
+ CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
+}
+
+void MysqlTestDriver::testDBPositionChange()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ {
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ }
+
+ Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ auto nUpdateCount
+ = xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)");
+ CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
+ Reference<XPreparedStatement> xPrepared
+ = xConnection->prepareStatement(OUString{ "INSERT INTO myTestTable VALUES (?)" });
+ Reference<XParameters> xParams(xPrepared, UNO_QUERY);
+ constexpr int ROW_COUNT = 3;
+ for (int i = 1; i <= ROW_COUNT; ++i)
+ {
+ xParams->setLong(1, i); // first and only column
+ nUpdateCount = xPrepared->executeUpdate();
+ CPPUNIT_ASSERT_EQUAL(1, nUpdateCount); // one row is inserted at a time
+ }
+ Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT id from myTestTable");
+ CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is());
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is());
+
+ xResultSet->afterLast();
+ CPPUNIT_ASSERT_EQUAL(ROW_COUNT + 1, xResultSet->getRow());
+ xResultSet->last();
+ CPPUNIT_ASSERT_EQUAL(ROW_COUNT, nUpdateCount);
+ CPPUNIT_ASSERT_EQUAL(ROW_COUNT, xResultSet->getRow());
+ bool successPrevious = xResultSet->previous();
+ CPPUNIT_ASSERT(successPrevious);
+ CPPUNIT_ASSERT_EQUAL(ROW_COUNT - 1, nUpdateCount);
+ xResultSet->beforeFirst();
+ xResultSet->next();
+ CPPUNIT_ASSERT_EQUAL(1, xResultSet->getRow());
+ xResultSet->first();
+ CPPUNIT_ASSERT_EQUAL(1, xResultSet->getRow());
+
+ // Now previous should put the cursor to before-first position, but it
+ // should return with false.
+ successPrevious = xResultSet->previous();
+ CPPUNIT_ASSERT(!successPrevious);
+ CPPUNIT_ASSERT_EQUAL(0, xResultSet->getRow());
+
+ nUpdateCount = xStatement->executeUpdate("DROP TABLE myTestTable");
+ CPPUNIT_ASSERT_EQUAL(0, nUpdateCount); // it's a DDL statement
+}
+
+void MysqlTestDriver::testMultipleResultsets()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ CPPUNIT_ASSERT(xConnection.is());
+ Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ // create two tables
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+ xStatement->executeUpdate("DROP TABLE IF EXISTS otherTable");
+ xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)");
+ xStatement->executeUpdate("INSERT INTO myTestTable VALUES (1)");
+ xStatement->executeUpdate("CREATE TABLE otherTable (id INTEGER PRIMARY KEY)");
+ xStatement->executeUpdate("INSERT INTO otherTable VALUES (2)");
+
+ // create first result set
+ Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT id from myTestTable");
+ CPPUNIT_ASSERT_MESSAGE("result set cannot be instantiated after query", xResultSet.is());
+ // use it
+ xResultSet->next();
+ Reference<XRow> xRowFirst(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(1l, xRowFirst->getLong(1));
+ // create second result set
+ Reference<XResultSet> xResultSet2 = xStatement->executeQuery("SELECT id from otherTable");
+ // use second result set
+ xResultSet2->next();
+ Reference<XRow> xRowSecond(xResultSet2, UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(2l, xRowSecond->getLong(1));
+ // now use the first result set again
+#if 0
+ // FIXME this was broken by 86c86719782243275b65f1f7f2cfdcc0e56c8cd4 adding closeResultSet() in execute()
+ CPPUNIT_ASSERT_EQUAL(1l, xRowFirst->getLong(1));
+#endif
+
+ xStatement->executeUpdate("DROP TABLE myTestTable");
+ xStatement->executeUpdate("DROP TABLE otherTable");
+}
+
+void MysqlTestDriver::testDBMetaData()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ xStatement->executeUpdate(
+ "CREATE TABLE myTestTable (id INTEGER PRIMARY KEY, name VARCHAR(20))");
+ Reference<XPreparedStatement> xPrepared
+ = xConnection->prepareStatement(OUString{ "INSERT INTO myTestTable VALUES (?, ?)" });
+ Reference<XParameters> xParams(xPrepared, UNO_QUERY);
+ constexpr int ROW_COUNT = 3;
+ for (int i = 0; i < ROW_COUNT; ++i)
+ {
+ xParams->setLong(1, i);
+ xParams->setString(2, "lorem");
+ xPrepared->executeUpdate();
+ }
+
+ Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT * from myTestTable");
+ Reference<XResultSetMetaDataSupplier> xMetaDataSupplier(xResultSet, UNO_QUERY);
+ Reference<XResultSetMetaData> xMetaData = xMetaDataSupplier->getMetaData();
+ CPPUNIT_ASSERT_EQUAL(OUString{ "id" }, xMetaData->getColumnName(1));
+ CPPUNIT_ASSERT_EQUAL(OUString{ "name" }, xMetaData->getColumnName(2));
+ CPPUNIT_ASSERT(!xMetaData->isAutoIncrement(1));
+ CPPUNIT_ASSERT(!xMetaData->isCaseSensitive(2)); // default collation should be case insensitive
+ xResultSet->next(); // use it
+ // test that meta data is usable even after fetching result set
+ CPPUNIT_ASSERT_EQUAL(OUString{ "name" }, xMetaData->getColumnName(2));
+ CPPUNIT_ASSERT_THROW_MESSAGE("exception expected when indexing out of range",
+ xMetaData->getColumnName(3), sdbc::SQLException);
+ xStatement->executeUpdate("DROP TABLE myTestTable");
+}
+
+void MysqlTestDriver::testTimestampField()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ xStatement->executeUpdate(
+ "CREATE TABLE myTestTable (id INTEGER PRIMARY KEY, mytimestamp timestamp)");
+ xStatement->executeUpdate("INSERT INTO myTestTable VALUES (1, '2008-02-16 20:15:03')");
+
+ // now let's query
+ Reference<XResultSet> xResultSet
+ = xStatement->executeQuery("SELECT mytimestamp from myTestTable");
+
+ xResultSet->next(); // use it
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("cannot extract row from result set!", xRow.is());
+ util::DateTime dt = xRow->getTimestamp(1);
+ CPPUNIT_ASSERT_EQUAL(static_cast<short>(2008), dt.Year);
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(2), dt.Month);
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(16), dt.Day);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(20), dt.Hours);
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(15), dt.Minutes);
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(3), dt.Seconds);
+
+ xStatement->executeUpdate("DROP TABLE myTestTable");
+}
+
+/**
+ * Test getting value from a decimal type column from a result set of a
+ * prepared statement, getting as a tinyint, string, short, int, long.
+ */
+void MysqlTestDriver::testNumericConversionPrepared()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ xStatement->executeUpdate("CREATE TABLE myTestTable (myDecimal DECIMAL(4,2))");
+ xStatement->executeUpdate("INSERT INTO myTestTable VALUES (11.22)");
+ Reference<XPreparedStatement> xPrepared
+ = xConnection->prepareStatement("SELECT * from myTestTable");
+ Reference<XResultSet> xResultSet = xPrepared->executeQuery();
+ xResultSet->next(); // use it
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("11.22"), xRow->getString(1));
+ // converting to integer types results in rounding down the number
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int8>(11), xRow->getByte(1));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(11), xRow->getShort(1));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11), xRow->getInt(1));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int64>(11), xRow->getLong(1));
+
+ xStatement->executeUpdate("DROP TABLE myTestTable");
+}
+
+/**
+ * Test cursor positioning method isAfterLast in case of using prepared
+ * statement.
+ */
+void MysqlTestDriver::testPreparedStmtIsAfterLast()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ // create test table
+ xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY)");
+ Reference<XPreparedStatement> xPrepared
+ = xConnection->prepareStatement(OUString{ "INSERT INTO myTestTable VALUES (?)" });
+ Reference<XParameters> xParams(xPrepared, UNO_QUERY);
+ constexpr int ROW_COUNT = 6;
+ for (int i = 0; i < ROW_COUNT; ++i)
+ {
+ xParams->setShort(1, i);
+ xPrepared->executeUpdate();
+ }
+
+ // query test table
+ xPrepared = xConnection->prepareStatement("SELECT id from myTestTable where id = 3");
+ Reference<XResultSet> xResultSet = xPrepared->executeQuery();
+
+ // There should be exactly one row, therefore IsAfterLast is false at first.
+ xResultSet->next();
+ CPPUNIT_ASSERT(!xResultSet->isAfterLast());
+
+ // attempt to fetch more data
+ bool hasData = xResultSet->next();
+ CPPUNIT_ASSERT(!hasData); // now we are on "AfterLast"
+ CPPUNIT_ASSERT(xResultSet->isAfterLast());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+}
+
+void MysqlTestDriver::testGetStringFromBloColumnb()
+{
+ Reference<XConnection> xConnection = m_xDriver->connect(m_sUrl, m_infos);
+ if (!xConnection.is())
+ CPPUNIT_ASSERT_MESSAGE("cannot connect to data source!", xConnection.is());
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+
+ // create test table
+ xStatement->executeUpdate("CREATE TABLE myTestTable (id INTEGER PRIMARY KEY, tinytexty "
+ "TINYTEXT, texty TEXT, mediumTexty MEDIUMTEXT, longtexty LONGTEXT)");
+ Reference<XPreparedStatement> xPrepared = xConnection->prepareStatement(
+ OUString{ "INSERT INTO myTestTable VALUES (?, ?, ?, ?, ?)" });
+ Reference<XParameters> xParams(xPrepared, UNO_QUERY);
+ constexpr int ROW_COUNT = 6;
+ for (int i = 0; i < ROW_COUNT; ++i)
+ {
+ xParams->setShort(1, i);
+ xParams->setString(2, OUString::number(i));
+ xParams->setString(3, OUString::number(i));
+ xParams->setString(4, OUString::number(i));
+ xParams->setString(5, OUString::number(i));
+ xPrepared->executeUpdate();
+ }
+
+ // query test table
+ xPrepared = xConnection->prepareStatement(
+ "SELECT tinytexty, texty, mediumtexty, longtexty from myTestTable where texty LIKE '3'");
+ Reference<XResultSet> xResultSet = xPrepared->executeQuery();
+ xResultSet->next();
+ Reference<XRow> xRow(xResultSet, UNO_QUERY);
+
+ // all the textual blob types should be able to be queried via getString().
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), xRow->getString(1));
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), xRow->getString(2));
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), xRow->getString(3));
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), xRow->getString(4));
+
+ xStatement->executeUpdate("DROP TABLE IF EXISTS myTestTable");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(MysqlTestDriver);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/qa/connectivity/resource/sharedresources_test.cxx b/connectivity/qa/connectivity/resource/sharedresources_test.cxx
new file mode 100644
index 000000000..a6bf22fba
--- /dev/null
+++ b/connectivity/qa/connectivity/resource/sharedresources_test.cxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+#include <resource/sharedresources.hxx>
+#include <strings.hrc>
+
+#include <utility>
+#include <vector>
+
+using namespace css;
+
+namespace connectivity_test
+{
+#define TEST_SOURCE_STRING NC_("TEST_SOURCE_STRING", "UnitTest")
+#define TEST_SOURCE_ONE_SUBSTITUTION NC_("TEST_SOURCE_ONE_SUBSTITUTION", "One substitution $sub$")
+#define TEST_SOURCE_TWO_SUBSTITUTION \
+ NC_("TEST_SOURCE_TWO_SUBSTITUTION", "Two substitution $sub0$ $sub1$")
+#define TEST_SOURCE_THREE_SUBSTITUTION \
+ NC_("TEST_SOURCE_THREE_SUBSTITUTION", "Three substitution $sub0$ $sub1$ $sub2$")
+
+class SharedResourcesTest : public test::BootstrapFixture
+{
+public:
+ SharedResourcesTest();
+
+ void testGetSourceString();
+ void testGetSourceStringWithSubstitutionOne();
+ void testGetSourceStringWithSubstitutionTwo();
+ void testGetSourceStringWithSubstitutionThree();
+ void testGetSourceStringWithSubstitutionVector();
+
+ CPPUNIT_TEST_SUITE(SharedResourcesTest);
+
+ CPPUNIT_TEST(testGetSourceString);
+ CPPUNIT_TEST(testGetSourceStringWithSubstitutionOne);
+ CPPUNIT_TEST(testGetSourceStringWithSubstitutionTwo);
+ CPPUNIT_TEST(testGetSourceStringWithSubstitutionThree);
+ CPPUNIT_TEST(testGetSourceStringWithSubstitutionVector);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ ::connectivity::SharedResources m_aResource;
+};
+
+SharedResourcesTest::SharedResourcesTest()
+ : test::BootstrapFixture(false, false)
+{
+}
+
+void SharedResourcesTest::testGetSourceString()
+{
+ CPPUNIT_ASSERT_EQUAL(OUString("UnitTest"), m_aResource.getResourceString(TEST_SOURCE_STRING));
+}
+
+void SharedResourcesTest::testGetSourceStringWithSubstitutionOne()
+{
+ CPPUNIT_ASSERT_EQUAL(OUString("One substitution UnitTest"),
+ m_aResource.getResourceStringWithSubstitution(TEST_SOURCE_ONE_SUBSTITUTION,
+ "$sub$", "UnitTest"));
+}
+
+void SharedResourcesTest::testGetSourceStringWithSubstitutionTwo()
+{
+ CPPUNIT_ASSERT_EQUAL(OUString("Two substitution UnitTest1 UnitTest2"),
+ m_aResource.getResourceStringWithSubstitution(TEST_SOURCE_TWO_SUBSTITUTION,
+ "$sub0$", "UnitTest1",
+ "$sub1$", "UnitTest2"));
+}
+
+void SharedResourcesTest::testGetSourceStringWithSubstitutionThree()
+{
+ CPPUNIT_ASSERT_EQUAL(OUString("Three substitution UnitTest1 UnitTest2 UnitTest3"),
+ m_aResource.getResourceStringWithSubstitution(
+ TEST_SOURCE_THREE_SUBSTITUTION, "$sub0$", "UnitTest1", "$sub1$",
+ "UnitTest2", "$sub2$", "UnitTest3"));
+}
+
+void SharedResourcesTest::testGetSourceStringWithSubstitutionVector()
+{
+ std::vector<std::pair<const char*, OUString>> aStringToSubstitutes;
+ aStringToSubstitutes.push_back(std::pair<const char*, OUString>("$sub0$", "vector0"));
+ aStringToSubstitutes.push_back(std::pair<const char*, OUString>("$sub1$", "vector1"));
+ aStringToSubstitutes.push_back(std::pair<const char*, OUString>("$sub2$", "vector2"));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Three substitution vector0 vector1 vector2"),
+ m_aResource.getResourceStringWithSubstitution(
+ TEST_SOURCE_THREE_SUBSTITUTION, aStringToSubstitutes));
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SharedResourcesTest);
+
+} // namespace connectivity_test
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/connectivity/qa/connectivity/tools/AbstractDatabase.java b/connectivity/qa/connectivity/tools/AbstractDatabase.java
new file mode 100644
index 000000000..601b36e23
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/AbstractDatabase.java
@@ -0,0 +1,208 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package connectivity.tools;
+
+import com.sun.star.container.XNameAccess;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XStorable;
+import com.sun.star.io.IOException;
+import com.sun.star.lang.XMultiServiceFactory;
+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.XStatement;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.CloseVetoException;
+import connectivity.tools.sdb.Connection;
+import java.io.File;
+import static org.junit.Assert.*;
+
+public abstract class AbstractDatabase implements DatabaseAccess
+{
+ public AbstractDatabase(final XMultiServiceFactory orb) throws Exception
+ {
+ m_orb = orb;
+ }
+
+
+ public AbstractDatabase(final XMultiServiceFactory orb, final String _existingDocumentURL ) throws Exception
+ {
+ m_orb = orb;
+ createDBDocument( _existingDocumentURL );
+ }
+
+ /** returns a connection to the database
+ *
+ * Multiple calls to this method return the same connection. The DbaseDatabase object keeps
+ * the ownership of the connection, so you don't need to (and should not) dispose/close it.
+ */
+ public Connection defaultConnection() throws SQLException
+ {
+ if ( m_connection == null )
+ m_connection = new Connection( m_databaseDocument.getDataSource().getConnection("", "") );
+
+ return m_connection;
+ }
+
+ /** executes the given SQL statement via the defaultConnection
+ */
+ public void executeSQL(final String statementString) throws SQLException
+ {
+ final XStatement statement = defaultConnection().createStatement();
+ statement.execute(statementString);
+ }
+
+ /** stores the database document
+ */
+ public void store() throws IOException
+ {
+ if (m_databaseDocument != null)
+ {
+ final XStorable storeDoc = UnoRuntime.queryInterface(XStorable.class, m_databaseDocument);
+ storeDoc.store();
+ }
+ }
+
+ /** closes the database document
+ *
+ * Any CloseVetoExceptions fired by third parties are ignored, and any reference to the
+ * database document is released.
+ */
+ public void close()
+ {
+ // close connection
+ final XCloseable closeConn = UnoRuntime.queryInterface( XCloseable.class,
+ m_connection != null ? m_connection.getXConnection() : null );
+ if (closeConn != null)
+ {
+ try
+ {
+ closeConn.close();
+ }
+ catch (SQLException e)
+ {
+ }
+ }
+ m_connection = null;
+
+ // close document
+ final com.sun.star.util.XCloseable closeDoc = UnoRuntime.queryInterface( com.sun.star.util.XCloseable.class, m_databaseDocument );
+ if (closeDoc != null)
+ {
+ try
+ {
+ closeDoc.close(true);
+ }
+ catch (CloseVetoException e)
+ {
+ }
+ }
+ m_databaseDocument = null;
+ }
+
+ /** closes the document, and deletes the underlying file
+ */
+ public void closeAndDelete()
+ {
+ close();
+ delete();
+ }
+
+ protected void delete() {}
+
+ /** returns the underlying database document
+ */
+ public XOfficeDatabaseDocument getDatabaseDocument()
+ {
+ return m_databaseDocument;
+ }
+
+ /** returns the model interface of the underlying database document
+ */
+ public XModel getModel()
+ {
+ return UnoRuntime.queryInterface( XModel.class, m_databaseDocument );
+ }
+
+ public XMultiServiceFactory getORB()
+ {
+ return m_orb;
+ }
+
+
+ final private void createDBDocument(final String _docURL) throws Exception
+ {
+ m_databaseDocumentFile = _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_databaseDocument.getDataSource());
+ }
+
+ /** returns the URL of the ODB document represented by this instance
+ */
+ public String getDocumentURL()
+ {
+ return m_databaseDocumentFile;
+ }
+
+ /** returns the data source belonging to this database
+ */
+ public DataSource getDataSource()
+ {
+ return m_dataSource;
+ }
+
+ /** creates a row set operating the database, with a given command/type
+ */
+ public RowSet createRowSet(final int _commandType, final String _command)
+ {
+ return new RowSet(m_orb, getDocumentURL(), _commandType, _command);
+ }
+
+ @Override
+ protected void finalize() throws Throwable
+ {
+ // Cannot call close() here, as it accesses UNO objects (that may
+ // already have been finalized):
+ assertNull(
+ "missing call to connectivity.tools.AbstractDatabase.close",
+ m_connection);
+ assertNull(
+ "missing call to connectivity.tools.AbstractDatabase.close",
+ m_databaseDocument);
+
+ delete();
+ super.finalize();
+ }
+
+ // the service factory
+ protected final XMultiServiceFactory m_orb;
+ // the URL of the temporary file used for the database document
+ protected String m_databaseDocumentFile;
+ // the database document
+ protected XOfficeDatabaseDocument m_databaseDocument;
+ // the data source belonging to the database document
+ protected DataSource m_dataSource;
+ // the default connection
+ private Connection m_connection;
+}
diff --git a/connectivity/qa/connectivity/tools/CRMDatabase.java b/connectivity/qa/connectivity/tools/CRMDatabase.java
new file mode 100644
index 000000000..3d3392628
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/CRMDatabase.java
@@ -0,0 +1,277 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+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.application.XDatabaseDocumentUI;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.uno.UnoRuntime;
+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 Connection m_connection;
+
+ /** constructs the CRM database
+ */
+ public CRMDatabase( XMultiServiceFactory _orb, boolean _withUI ) throws Exception
+ {
+ m_orb = _orb;
+
+ m_database = new HsqlDatabase( m_orb );
+
+ 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
+ */
+ public CRMDatabase( XMultiServiceFactory _orb, final String _existingDocumentURL ) throws Exception
+ {
+ m_orb = _orb;
+
+ m_database = new HsqlDatabase( m_orb, _existingDocumentURL );
+ 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 IOException
+ {
+ XDatabaseDocumentUI ui = getDocumentUI();
+ if ( ui != null )
+ ui.closeSubComponents();
+ m_database.store();
+ m_database.closeAndDelete();
+ }
+
+
+ private 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','Preferred') " );
+ 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 {fn DAYOFMONTH ('2001-01-01')} AS \"ID_VARCHAR\" FROM \"products\"", false );
+*/
+ validateUnparseable();
+ }
+}
diff --git a/connectivity/qa/connectivity/tools/CsvDatabase.java b/connectivity/qa/connectivity/tools/CsvDatabase.java
new file mode 100644
index 000000000..abb016c90
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/CsvDatabase.java
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package connectivity.tools;
+
+import com.sun.star.lang.XMultiServiceFactory;
+
+public class CsvDatabase extends FlatFileDatabase
+{
+
+ public CsvDatabase( final XMultiServiceFactory i_orb ) throws Exception
+ {
+ super( i_orb, "flat" );
+ }
+
+}
diff --git a/connectivity/qa/connectivity/tools/DataSource.java b/connectivity/qa/connectivity/tools/DataSource.java
new file mode 100644
index 000000000..844c4488f
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/DataSource.java
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package connectivity.tools;
+
+import com.sun.star.container.ElementExistException;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.XNameContainer;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.XSingleServiceFactory;
+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.uno.Exception;
+import com.sun.star.uno.UnoRuntime;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class DataSource
+{
+ // the service factory
+
+ private final XDataSource m_dataSource;
+
+ public DataSource(final XMultiServiceFactory _orb, final String _registeredName) throws Exception
+ {
+ final XNameAccess dbContext = UnoRuntime.queryInterface(
+ XNameAccess.class, _orb.createInstance( "com.sun.star.sdb.DatabaseContext" ) );
+
+ m_dataSource = UnoRuntime.queryInterface( XDataSource.class, dbContext.getByName( _registeredName ) );
+ }
+
+ public DataSource(final XDataSource _dataSource)
+ {
+ m_dataSource = _dataSource;
+ }
+
+ final public XDataSource getXDataSource()
+ {
+ return m_dataSource;
+ }
+
+ /**
+ * retrieves the data source's settings
+ */
+ public XPropertySet geSettings()
+ {
+ return UnoRuntime.queryInterface( XPropertySet.class, impl_getPropertyValue( "Settings" ) );
+ }
+
+ /** creates a query with a given name and SQL command
+ */
+ public void createQuery(final String _name, final String _sqlCommand) throws ElementExistException, WrappedTargetException, com.sun.star.lang.IllegalArgumentException
+ {
+ createQuery(_name, _sqlCommand, true);
+ }
+
+ /** creates a query with a given name, SQL command, and EscapeProcessing flag
+ */
+ public void createQuery(final String _name, final String _sqlCommand, final boolean _escapeProcessing) throws ElementExistException, WrappedTargetException, com.sun.star.lang.IllegalArgumentException
+ {
+ final XSingleServiceFactory queryDefsFac = UnoRuntime.queryInterface( XSingleServiceFactory.class, getQueryDefinitions() );
+ XPropertySet queryDef = null;
+ try
+ {
+ queryDef = UnoRuntime.queryInterface( XPropertySet.class, queryDefsFac.createInstance() );
+ queryDef.setPropertyValue("Command", _sqlCommand);
+ queryDef.setPropertyValue("EscapeProcessing", Boolean.valueOf(_escapeProcessing));
+ }
+ catch (com.sun.star.uno.Exception e)
+ {
+ e.printStackTrace(System.err);
+ }
+
+ final XNameContainer queryDefsContainer = UnoRuntime.queryInterface( XNameContainer.class, getQueryDefinitions() );
+ queryDefsContainer.insertByName(_name, queryDef);
+ }
+
+ /** provides the query definition with the given name
+ */
+ public QueryDefinition getQueryDefinition(final String _name) throws NoSuchElementException
+ {
+ final XNameAccess allDefs = getQueryDefinitions();
+ try
+ {
+ return new QueryDefinition( UnoRuntime.queryInterface( XPropertySet.class, allDefs.getByName( _name) ) );
+ }
+ catch (WrappedTargetException e)
+ {
+ }
+ throw new NoSuchElementException();
+ }
+
+ /** provides the container of query definitions of the data source
+ */
+ private XNameAccess getQueryDefinitions()
+ {
+ final XQueryDefinitionsSupplier suppQueries = UnoRuntime.queryInterface(
+ XQueryDefinitionsSupplier.class, m_dataSource);
+ return suppQueries.getQueryDefinitions();
+ }
+
+ /**
+ * retrieves a property value from the data source
+ * @param i_propertyName
+ * the name of the property whose value is to be returned.
+ */
+ private Object impl_getPropertyValue( final String i_propertyName )
+ {
+ Object propertyValue = null;
+ try
+ {
+ final XPropertySet dataSourceProps = UnoRuntime.queryInterface( XPropertySet.class, m_dataSource );
+ propertyValue = dataSourceProps.getPropertyValue( i_propertyName );
+ }
+ catch (Exception ex)
+ {
+ Logger.getLogger(DataSource.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return propertyValue;
+ }
+
+ /** returns the name of the data source
+ *
+ * If a data source is registered at the database context, the name is the registration
+ * name. Otherwise, it's the URL which the respective database document is based on.
+ *
+ * Note that the above definition is from the UNO API, not from this wrapper here.
+ */
+ public String getName()
+ {
+ return (String)impl_getPropertyValue( "Name" );
+ }
+}
diff --git a/connectivity/qa/connectivity/tools/DatabaseAccess.java b/connectivity/qa/connectivity/tools/DatabaseAccess.java
new file mode 100644
index 000000000..347faa46e
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/DatabaseAccess.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package connectivity.tools;
+
+import com.sun.star.frame.XModel;
+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 connectivity.tools.sdb.Connection;
+
+public interface DatabaseAccess
+{
+ Connection defaultConnection() throws SQLException;
+
+ void executeSQL(final String statementString) throws SQLException;
+
+ void store() throws IOException;
+
+ void close();
+
+ void closeAndDelete();
+
+ XOfficeDatabaseDocument getDatabaseDocument();
+
+ XModel getModel();
+
+ String getDocumentURL();
+
+ DataSource getDataSource();
+
+ RowSet createRowSet(final int _commandType, final String _command);
+
+ XMultiServiceFactory getORB();
+}
diff --git a/connectivity/qa/connectivity/tools/DbaseDatabase.java b/connectivity/qa/connectivity/tools/DbaseDatabase.java
new file mode 100644
index 000000000..9a1dc8448
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/DbaseDatabase.java
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package connectivity.tools;
+
+import com.sun.star.lang.XMultiServiceFactory;
+
+public class DbaseDatabase extends FlatFileDatabase
+{
+
+ public DbaseDatabase( final XMultiServiceFactory i_orb ) throws Exception
+ {
+ super( i_orb, "dbase" );
+ }
+
+
+}
diff --git a/connectivity/qa/connectivity/tools/FlatFileDatabase.java b/connectivity/qa/connectivity/tools/FlatFileDatabase.java
new file mode 100644
index 000000000..5351ba953
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/FlatFileDatabase.java
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package connectivity.tools;
+
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.frame.XStorable;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.sdb.XOfficeDatabaseDocument;
+import com.sun.star.uno.UnoRuntime;
+
+import helper.URLHelper;
+import java.io.File;
+
+class FlatFileDatabase extends AbstractDatabase
+{
+
+ protected FlatFileDatabase( final XMultiServiceFactory i_orb, final String i_urlSubScheme ) throws Exception
+ {
+ super(i_orb);
+ m_urlSubScheme = i_urlSubScheme;
+ createDBDocument();
+ }
+
+
+ /**
+ * returns a {@link File} which represents the folder where the database's table files reside.
+ */
+ public File getTableFileLocation()
+ {
+ return m_tableFileLocation;
+ }
+
+ /** creates an empty database document in a temporary location
+ */
+ private void createDBDocument() throws Exception
+ {
+ final File documentFile = File.createTempFile( m_urlSubScheme, ".odb" );
+ if ( documentFile.exists() )
+ documentFile.delete();
+ m_tableFileLocation = new File(documentFile.getParent() + File.separator + documentFile.getName().replace(".odb", "") + File.separator );
+ m_tableFileLocation.mkdir();
+ m_databaseDocumentFile = URLHelper.getFileURLFromSystemPath(documentFile);
+ final String path = URLHelper.getFileURLFromSystemPath( m_tableFileLocation.getPath() );
+
+ m_databaseDocument = UnoRuntime.queryInterface( XOfficeDatabaseDocument.class,
+ m_orb.createInstance("com.sun.star.sdb.OfficeDatabaseDocument"));
+ m_dataSource = new DataSource(m_databaseDocument.getDataSource());
+
+ final XPropertySet dsProperties = UnoRuntime.queryInterface(XPropertySet.class, m_databaseDocument.getDataSource());
+ dsProperties.setPropertyValue("URL", "sdbc:" + m_urlSubScheme + ":" + path);
+
+ final XStorable storable = UnoRuntime.queryInterface( XStorable.class, m_databaseDocument );
+ storable.storeAsURL( m_databaseDocumentFile, new PropertyValue[] { } );
+ }
+
+ private final String m_urlSubScheme;
+ private File m_tableFileLocation = null;
+}
diff --git a/connectivity/qa/connectivity/tools/HsqlColumnDescriptor.java b/connectivity/qa/connectivity/tools/HsqlColumnDescriptor.java
new file mode 100644
index 000000000..12330ff70
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/HsqlColumnDescriptor.java
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package connectivity.tools;
+
+/** is a very simply and rudimentary descriptor of table columns, for creating HSQLDB tables
+ */
+public class HsqlColumnDescriptor
+{
+ private final String Name;
+ private final String TypeName;
+ private final boolean Required;
+ private final boolean PrimaryKey;
+ private final String ForeignTable;
+ private final String ForeignColumn;
+
+ public final String getName() { return Name; }
+ public final String getTypeName() { return TypeName; }
+ public final boolean isRequired() { return Required; }
+ public final boolean isPrimaryKey() { return PrimaryKey; }
+
+ public final boolean isForeignKey() { return ( ForeignTable.length() != 0 ) && ( ForeignColumn.length() != 0 ); }
+ public final String getForeignTable() { return ForeignTable; }
+ public final String getForeignColumn() { return ForeignColumn; }
+
+ /// determines that a column is required, i.e. not nullable
+ public static final int REQUIRED = 1;
+ /// determines that a column is part of the primary key of its table
+ public static final int PRIMARY = 2;
+
+ public HsqlColumnDescriptor( String _Name, String _TypeName )
+ {
+ Name = _Name;
+ TypeName = _TypeName;
+ Required = false;
+ PrimaryKey = false;
+ ForeignTable = "";
+ ForeignColumn = "";
+ }
+
+ public HsqlColumnDescriptor( String _Name, String _TypeName, int _Flags )
+ {
+ Name = _Name;
+ TypeName = _TypeName;
+ Required = ( _Flags & REQUIRED ) != 0;
+ PrimaryKey = ( _Flags & PRIMARY ) != 0;
+ ForeignTable = "";
+ ForeignColumn = "";
+ }
+
+ public HsqlColumnDescriptor( String _Name, String _TypeName, int _Flags, String _ForeignTable, String _ForeignColumn )
+ {
+ Name = _Name;
+ TypeName = _TypeName;
+ Required = ( _Flags & REQUIRED ) != 0;
+ PrimaryKey = ( _Flags & PRIMARY ) != 0;
+ ForeignTable = _ForeignTable;
+ ForeignColumn = _ForeignColumn;
+ }
+}
diff --git a/connectivity/qa/connectivity/tools/HsqlDatabase.java b/connectivity/qa/connectivity/tools/HsqlDatabase.java
new file mode 100644
index 000000000..0d2ab4af9
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/HsqlDatabase.java
@@ -0,0 +1,202 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+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;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.sdb.XOfficeDatabaseDocument;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbcx.XAppend;
+import com.sun.star.sdbcx.XTablesSupplier;
+import com.sun.star.uno.UnoRuntime;
+
+import helper.URLHelper;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Assert;
+
+public class HsqlDatabase extends AbstractDatabase
+{
+
+
+ public HsqlDatabase(final XMultiServiceFactory orb) throws Exception
+ {
+ super(orb);
+ createDBDocument();
+ }
+
+
+ public HsqlDatabase(final XMultiServiceFactory orb, final String _existingDocumentURL) throws Exception
+ {
+ super(orb, _existingDocumentURL);
+ }
+
+ /** creates an empty database document in a temporary location
+ */
+ private void createDBDocument() throws Exception
+ {
+ Assert.assertNull(m_documentFile);
+ m_documentFile = File.createTempFile("testdb", ".odb");
+ if ( m_documentFile.exists() )
+ m_documentFile.delete();
+ m_databaseDocumentFile = URLHelper.getFileURLFromSystemPath(m_documentFile);
+
+ m_databaseDocument = UnoRuntime.queryInterface(
+ XOfficeDatabaseDocument.class, m_orb.createInstance("com.sun.star.sdb.OfficeDatabaseDocument"));
+ m_dataSource = new DataSource(m_databaseDocument.getDataSource());
+
+ final XPropertySet dsProperties = UnoRuntime.queryInterface(XPropertySet.class, m_databaseDocument.getDataSource());
+ dsProperties.setPropertyValue("URL", "sdbc:embedded:hsqldb");
+
+ final XStorable storable = UnoRuntime.queryInterface(XStorable.class, m_databaseDocument);
+ storable.storeAsURL( m_databaseDocumentFile, new PropertyValue[]
+ { new PropertyValue( "PickListEntry", 0, false, PropertyState.DIRECT_VALUE )
+ } );
+ }
+
+ @Override protected final void delete() {
+ if (m_documentFile != null) {
+ boolean ok = m_documentFile.delete();
+ //TODO: fails on Windows: Assert.assertTrue("delete " + m_documentFile.getPath(), ok);
+ }
+ }
+
+ /** drops the table with a given name
+
+ @param _name
+ the name of the table to drop
+ */
+ private void dropTable(final String _name) throws SQLException
+ {
+ final StringBuffer dropStatement = new StringBuffer("DROP TABLE \"");
+ dropStatement.append(_name);
+ dropStatement.append("\" IF EXISTS");
+ executeSQL(dropStatement.toString());
+ }
+
+ public void createTable(final HsqlTableDescriptor _tableDesc, final boolean _dropIfExists) throws SQLException
+ {
+ if (_dropIfExists)
+ {
+ dropTable(_tableDesc.getName());
+ }
+ createTable(_tableDesc);
+ }
+
+ /** creates a table
+ */
+ public void createTable(final HsqlTableDescriptor _tableDesc) throws SQLException
+ {
+ StringBuffer createStatement = new StringBuffer("CREATE CACHED TABLE \"");
+ createStatement.append(_tableDesc.getName());
+ createStatement.append("\" ( ");
+
+ String primaryKeyList = "";
+
+ final HashMap<String, String> foreignKeys = new HashMap<String, String>();
+ final HashMap<String, String> foreignKeyRefs = new HashMap<String, String>();
+
+ final HsqlColumnDescriptor[] columns = _tableDesc.getColumns();
+ for (int i = 0; i < columns.length; ++i)
+ {
+ if (i > 0)
+ {
+ createStatement.append(", ");
+ }
+
+ createStatement.append("\"").append(columns[i].getName());
+ createStatement.append("\" ").append(columns[i].getTypeName());
+
+ if (columns[i].isRequired())
+ {
+ createStatement.append(" NOT NULL");
+ }
+
+ if (columns[i].isPrimaryKey())
+ {
+ if (primaryKeyList.length() > 0)
+ {
+ primaryKeyList += ", ";
+ }
+ primaryKeyList += "\"" + columns[i].getName() + "\"";
+ }
+
+ if (columns[i].isForeignKey())
+ {
+ final String foreignTable = columns[i].getForeignTable();
+
+ String foreignKeysForTable = foreignKeys.containsKey(foreignTable) ? foreignKeys.get(foreignTable) : "";
+ if (foreignKeysForTable.length() > 0)
+ {
+ foreignKeysForTable += ", ";
+ }
+ foreignKeysForTable += "\"" + columns[i].getName() + "\"";
+ foreignKeys.put(foreignTable, foreignKeysForTable);
+
+ final StringBuffer foreignKeyRefsForTable = new StringBuffer(foreignKeyRefs.containsKey(foreignTable) ? foreignKeyRefs.get(foreignTable) : "");
+ if (foreignKeyRefsForTable.length() > 0)
+ {
+ foreignKeyRefsForTable.append(", ");
+ }
+ foreignKeyRefsForTable.append("\"").append(columns[i].getForeignColumn()).append("\"");
+ foreignKeyRefs.put(foreignTable, foreignKeyRefsForTable.toString());
+ }
+ }
+
+ if (primaryKeyList.length() > 0)
+ {
+ createStatement.append(", PRIMARY KEY (");
+ createStatement.append(primaryKeyList);
+ createStatement.append(')');
+ }
+
+ for (Map.Entry<String, String> foreignKey : foreignKeys.entrySet())
+ {
+ final String foreignTable = foreignKey.getKey();
+
+ createStatement.append(", FOREIGN KEY (");
+ createStatement.append(foreignKey.getValue());
+ createStatement.append(") REFERENCES \"");
+ createStatement.append(foreignTable);
+ createStatement.append("\"(");
+ createStatement.append(foreignKeyRefs.get(foreignTable));
+ createStatement.append(')');
+ }
+
+ createStatement.append(')');
+
+ executeSQL(createStatement.toString());
+ }
+
+ /** creates a table in the database. using the SDBCX-API
+ */
+ public void createTableInSDBCX(final HsqlTableDescriptor _tableDesc) throws SQLException, ElementExistException
+ {
+ final XPropertySet sdbcxDescriptor = _tableDesc.createSdbcxDescriptor(defaultConnection());
+ final XTablesSupplier suppTables = UnoRuntime.queryInterface( XTablesSupplier.class, defaultConnection().getXConnection() );
+ final XAppend appendTable = UnoRuntime.queryInterface( XAppend.class, suppTables.getTables() );
+ appendTable.appendByDescriptor(sdbcxDescriptor);
+ }
+
+ private File m_documentFile;
+}
diff --git a/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java b/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java
new file mode 100644
index 000000000..626f62eb8
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/HsqlTableDescriptor.java
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+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.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
+ */
+public class HsqlTableDescriptor
+{
+ private final String m_name;
+ private final HsqlColumnDescriptor[] m_columns;
+
+ /** Creates a new instance of HsqlTableDescriptor */
+ public HsqlTableDescriptor( String _name, HsqlColumnDescriptor[] _columns )
+ {
+ m_name = _name;
+ m_columns = _columns;
+ }
+
+ /** returns the name of the table
+ */
+ public String getName()
+ {
+ return m_name;
+ }
+
+ /** returns the set of column descriptors for the table
+ */
+ public HsqlColumnDescriptor[] getColumns()
+ {
+ return m_columns;
+ }
+
+ public XPropertySet createSdbcxDescriptor( Connection _forConnection )
+ {
+ XTablesSupplier suppTables = UnoRuntime.queryInterface( XTablesSupplier.class, _forConnection.getXConnection() );
+ XDataDescriptorFactory tableDescFac = UnoRuntime.queryInterface( XDataDescriptorFactory.class, suppTables.getTables() );
+ XPropertySet tableDesc = tableDescFac.createDataDescriptor();
+
+ try
+ {
+ tableDesc.setPropertyValue( "Name", getName() );
+ }
+ catch ( Exception e ) { e.printStackTrace( System.err ); }
+
+ XColumnsSupplier suppDescCols = UnoRuntime.queryInterface( XColumnsSupplier.class, tableDesc );
+
+ XNameAccess descColumns = suppDescCols.getColumns();
+ XDataDescriptorFactory columnDescFac = UnoRuntime.queryInterface( XDataDescriptorFactory.class, descColumns );
+
+ HsqlColumnDescriptor[] myColumns = getColumns();
+ for ( int i = 0; i < myColumns.length; ++i )
+ {
+ XPropertySet columnDesc = columnDescFac.createDataDescriptor();
+ try
+ {
+ columnDesc.setPropertyValue( "Name", myColumns[i].getName() );
+ columnDesc.setPropertyValue( "IsNullable", Integer.valueOf( myColumns[i].isRequired() ? ColumnValue.NO_NULLS : ColumnValue.NULLABLE) );
+ columnDesc.setPropertyValue( "TypeName", myColumns[i].getTypeName() );
+ if ( myColumns[i].isPrimaryKey() || myColumns[i].isForeignKey() )
+ // not yet implemented
+ throw new java.lang.UnsupportedOperationException("creating a primary or foreign key via SDBCX not yet implemented" );
+ }
+ catch( com.sun.star.uno.Exception e ) { e.printStackTrace( System.err ); }
+ }
+
+ return tableDesc;
+ }
+}
diff --git a/connectivity/qa/connectivity/tools/QueryDefinition.java b/connectivity/qa/connectivity/tools/QueryDefinition.java
new file mode 100644
index 000000000..fc3cba382
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/QueryDefinition.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package connectivity.tools;
+
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.WrappedTargetException;
+
+public class QueryDefinition
+{
+ private final XPropertySet m_queryDef;
+
+ public QueryDefinition( XPropertySet _queryDef )
+ {
+ m_queryDef = _queryDef;
+ }
+
+ /** retrieves the command underlying the query definition
+ *
+ * This method is a mere wrapped around the <code>getPropertyValue( "Command" )</code> call
+ */
+ public final String getCommand() throws WrappedTargetException
+ {
+ String command = null;
+ try {
+ command = (String)m_queryDef.getPropertyValue( "Command" );
+ }
+ catch (UnknownPropertyException e) { }
+
+ return command;
+ }
+
+}
diff --git a/connectivity/qa/connectivity/tools/RowSet.java b/connectivity/qa/connectivity/tools/RowSet.java
new file mode 100644
index 000000000..22b52156f
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/RowSet.java
@@ -0,0 +1,288 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package connectivity.tools;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.io.XInputStream;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.sdbc.SQLException;
+import com.sun.star.sdbc.XArray;
+import com.sun.star.sdbc.XBlob;
+import com.sun.star.sdbc.XClob;
+import com.sun.star.sdbc.XRef;
+import com.sun.star.sdbc.XRow;
+import com.sun.star.sdbc.XRowSet;
+import com.sun.star.sdbc.XRowSetListener;
+import com.sun.star.sdbcx.XColumnsSupplier;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.util.Date;
+import com.sun.star.util.DateTime;
+import com.sun.star.util.Time;
+
+public class RowSet implements XRowSet, XRow
+{
+ private XRowSet m_rowSet;
+ private XRow m_row;
+
+ public RowSet( XMultiServiceFactory _orb, String _dataSource, int _commandType, String _command )
+ {
+ try
+ {
+ XPropertySet rowSetProps = UnoRuntime.queryInterface( XPropertySet.class, _orb.createInstance( "com.sun.star.sdb.RowSet" ) );
+ rowSetProps.setPropertyValue( "DataSourceName", _dataSource );
+ rowSetProps.setPropertyValue( "CommandType", Integer.valueOf( _commandType ) );
+ rowSetProps.setPropertyValue( "Command", _command );
+
+ m_rowSet = UnoRuntime.queryInterface( XRowSet.class, rowSetProps );
+ m_row = UnoRuntime.queryInterface( XRow.class, rowSetProps );
+ }
+ catch ( Exception e )
+ {
+ throw new java.lang.RuntimeException(e);
+ }
+ }
+
+ // misc
+ public int getColumnCount()
+ {
+ XColumnsSupplier suppCols = UnoRuntime.queryInterface(
+ XColumnsSupplier.class, m_rowSet );
+ XIndexAccess columns = UnoRuntime.queryInterface(
+ XIndexAccess.class, suppCols.getColumns() );
+ return columns.getCount();
+ }
+
+ // XRowSet
+ public void execute() throws SQLException
+ {
+ m_rowSet.execute();
+ }
+
+ public void addRowSetListener( XRowSetListener _listener )
+ {
+ m_rowSet.addRowSetListener( _listener );
+ }
+
+ public void removeRowSetListener( XRowSetListener _listener )
+ {
+ m_rowSet.removeRowSetListener( _listener );
+ }
+
+ public boolean next() throws SQLException
+ {
+ return m_rowSet.next();
+ }
+
+ public boolean isBeforeFirst() throws SQLException
+ {
+ return m_rowSet.isBeforeFirst();
+ }
+
+ public boolean isAfterLast() throws SQLException
+ {
+ return m_rowSet.isAfterLast();
+ }
+
+ public boolean isFirst() throws SQLException
+ {
+ return m_rowSet.isFirst();
+ }
+
+ public boolean isLast() throws SQLException
+ {
+ return m_rowSet.isLast();
+ }
+
+ public void beforeFirst() throws SQLException
+ {
+ m_rowSet.beforeFirst();
+ }
+
+ public void afterLast() throws SQLException
+ {
+ m_rowSet.afterLast();
+ }
+
+ public boolean first() throws SQLException
+ {
+ return m_rowSet.first();
+ }
+
+ public boolean last() throws SQLException
+ {
+ return m_rowSet.last();
+ }
+
+ public int getRow() throws SQLException
+ {
+ return m_rowSet.getRow();
+ }
+
+ public boolean absolute(int i) throws SQLException
+ {
+ return m_rowSet.absolute(i);
+ }
+
+ public boolean relative(int i) throws SQLException
+ {
+ return m_rowSet.relative(i);
+ }
+
+ public boolean previous() throws SQLException
+ {
+ return m_rowSet.previous();
+ }
+
+ public void refreshRow() throws SQLException
+ {
+ m_rowSet.refreshRow();
+ }
+
+ public boolean rowUpdated() throws SQLException
+ {
+ return m_rowSet.rowUpdated();
+ }
+
+ public boolean rowInserted() throws SQLException
+ {
+ return m_rowSet.rowInserted();
+ }
+
+ public boolean rowDeleted() throws SQLException
+ {
+ return m_rowSet.rowDeleted();
+ }
+
+ // XRow
+ public Object getStatement() throws SQLException
+ {
+ return m_rowSet.getStatement();
+ }
+
+ public boolean wasNull() throws SQLException
+ {
+ return m_row.wasNull();
+ }
+
+ public String getString(int i) throws SQLException
+ {
+ return m_row.getString(i);
+ }
+
+ public boolean getBoolean(int i) throws SQLException
+ {
+ return m_row.getBoolean(i);
+ }
+
+ public byte getByte(int i) throws SQLException
+ {
+ return m_row.getByte(i);
+ }
+
+ public short getShort(int i) throws SQLException
+ {
+ return m_row.getShort(i);
+ }
+
+ public int getInt(int i) throws SQLException
+ {
+ return m_row.getInt(i);
+ }
+
+ public long getLong(int i) throws SQLException
+ {
+ return m_row.getLong(i);
+ }
+
+ public float getFloat(int i) throws SQLException
+ {
+ return m_row.getFloat(i);
+ }
+
+ public double getDouble(int i) throws SQLException
+ {
+ return m_row.getDouble(i);
+ }
+
+ public byte[] getBytes(int i) throws SQLException
+ {
+ return m_row.getBytes(i);
+ }
+
+ public Date getDate(int i) throws SQLException
+ {
+ return m_row.getDate(i);
+ }
+
+ public Time getTime(int i) throws SQLException
+ {
+ return m_row.getTime(i);
+ }
+
+ public DateTime getTimestamp(int i) throws SQLException
+ {
+ return m_row.getTimestamp(i);
+ }
+
+ public XInputStream getBinaryStream(int i) throws SQLException
+ {
+ return m_row.getBinaryStream(i);
+ }
+
+ public XInputStream getCharacterStream(int i) throws SQLException
+ {
+ return m_row.getCharacterStream(i);
+ }
+
+ public Object getObject(int i, XNameAccess xNameAccess) throws SQLException
+ {
+ return m_row.getObject(i, xNameAccess);
+ }
+
+ public XRef getRef(int i) throws SQLException
+ {
+ return m_row.getRef(i);
+ }
+
+ public XBlob getBlob(int i) throws SQLException
+ {
+ return m_row.getBlob(i);
+ }
+
+ public XClob getClob(int i) throws SQLException
+ {
+ return m_row.getClob(i);
+ }
+
+ public XArray getArray(int i) throws SQLException
+ {
+ return m_row.getArray(i);
+ }
+
+ public void dispose()
+ {
+ if ( m_rowSet == null )
+ return;
+ XComponent rowSetComp = UnoRuntime.queryInterface( XComponent.class, m_rowSet );
+ rowSetComp.dispose();
+ }
+}
diff --git a/connectivity/qa/connectivity/tools/sdb/Connection.java b/connectivity/qa/connectivity/tools/sdb/Connection.java
new file mode 100644
index 000000000..d713de379
--- /dev/null
+++ b/connectivity/qa/connectivity/tools/sdb/Connection.java
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+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.XPreparedStatement;
+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 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
+ void close() throws SQLException
+ {
+ m_connection.close();
+ }
+}
diff --git a/connectivity/qa/scenarios.sce b/connectivity/qa/scenarios.sce
new file mode 100644
index 000000000..4f366945e
--- /dev/null
+++ b/connectivity/qa/scenarios.sce
@@ -0,0 +1,21 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+-o complex.connectivity.DBaseDriverTest
+-o complex.connectivity.HsqlDriverTest
+#-o complex.connectivity.JdbcLongVarCharTest
+-o complex.connectivity.FlatFileAccess