summaryrefslogtreecommitdiffstats
path: root/dbaccess/qa/unit
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /dbaccess/qa/unit
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dbaccess/qa/unit')
-rw-r--r--dbaccess/qa/unit/data/dbaccess-dialogs-test.txt111
-rw-r--r--dbaccess/qa/unit/data/firebird_empty.odbbin0 -> 2148 bytes
-rw-r--r--dbaccess/qa/unit/data/firebird_integer_ods12.odbbin0 -> 77617 bytes
-rw-r--r--dbaccess/qa/unit/data/hsqldb_empty.odbbin0 -> 2345 bytes
-rw-r--r--dbaccess/qa/unit/data/hsqldb_migration_test.odbbin0 -> 3949 bytes
-rw-r--r--dbaccess/qa/unit/data/tdf119625.odbbin0 -> 6350 bytes
-rw-r--r--dbaccess/qa/unit/data/tdf126268.odbbin0 -> 5015 bytes
-rw-r--r--dbaccess/qa/unit/data/tdf132924.odbbin0 -> 3148 bytes
-rw-r--r--dbaccess/qa/unit/dbaccess-dialogs-test.cxx61
-rw-r--r--dbaccess/qa/unit/dbtest_base.cxx58
-rw-r--r--dbaccess/qa/unit/embeddeddb_performancetest.cxx357
-rw-r--r--dbaccess/qa/unit/firebird.cxx130
-rw-r--r--dbaccess/qa/unit/hsql_binary_import.cxx101
-rw-r--r--dbaccess/qa/unit/hsqldb.cxx45
-rw-r--r--dbaccess/qa/unit/tdf119625.cxx121
-rw-r--r--dbaccess/qa/unit/tdf126268.cxx97
16 files changed, 1081 insertions, 0 deletions
diff --git a/dbaccess/qa/unit/data/dbaccess-dialogs-test.txt b/dbaccess/qa/unit/data/dbaccess-dialogs-test.txt
new file mode 100644
index 0000000000..3d02708890
--- /dev/null
+++ b/dbaccess/qa/unit/data/dbaccess-dialogs-test.txt
@@ -0,0 +1,111 @@
+# -*- 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 contains all dialogs that the unit tests in the module
+# will work on if it is in script mode. It will read one-by-one,
+# try to open it and create a screenshot that will be saved in
+# workdir/screenshots using the pattern of the ui-file name.
+#
+# Syntax:
+# - empty lines are allowed
+# - lines starting with '#' are treated as comment
+# - all other lines should contain a *.ui filename in the same
+# notation as in the dialog constructors (see code)
+
+#
+# The 'known' dialogs which have a hard-coded representation
+# in registerKnownDialogsByID/createDialogByID
+#
+
+# No known dialogs in dbaccess for now
+
+#
+# Dialogs without a hard-coded representation. These will
+# be visualized using a fallback based on weld::Builder
+#
+
+# currently deactivated, leads to problems and the test to not work
+# This is typically a hint that these should be hard-coded in the
+# test case since they need some document and model data to work
+# dbaccess/ui/joindialog.ui <- not calling ORelationControl::lateInit for
+# DlgQryJoin::m_xTableControl member OTableListBoxControl::m_pRC_Tables leaves its
+# BrowseBox::mvCols empty, causing "implicit conversion from type 'int' of value -1 (32-bit,
+# signed) to type 'sal_uInt16' (aka 'unsigned short') changed the value to 65535 (16-bit,
+# unsigned)" when calling
+# GetColumnId( static_cast<sal_uInt16>(mvCols.size()) - 1 );
+# in BrowseBox::AutoSizeLastColumn (svtools/source/brwbox/brwbox1.cxx) with Clang
+# -fsanitize=implicit-signed-integer-truncation
+# dbaccess/ui/relationdialog.ui <- not calling ORelationControl::lateInit for
+# ORelationDialog::m_xTableControl member OTableListBoxControl::m_pRC_Tables leaves its
+# BrowseBox::mvCols empty, causing "implicit conversion from type 'int' of value -1 (32-bit,
+# signed) to type 'sal_uInt16' (aka 'unsigned short') changed the value to 65535 (16-bit,
+# unsigned)" when calling
+# GetColumnId( static_cast<sal_uInt16>(mvCols.size()) - 1 );
+# in BrowseBox::AutoSizeLastColumn (svtools/source/brwbox/brwbox1.cxx) with Clang
+# -fsanitize=implicit-signed-integer-truncation
+
+dbaccess/ui/advancedsettingsdialog.ui
+dbaccess/ui/admindialog.ui
+dbaccess/ui/fielddialog.ui
+dbaccess/ui/useradmindialog.ui
+dbaccess/ui/mysqlnativesettings.ui
+dbaccess/ui/textpage.ui
+dbaccess/ui/applycolpage.ui
+dbaccess/ui/copytablepage.ui
+dbaccess/ui/namematchingpage.ui
+dbaccess/ui/typeselectpage.ui
+dbaccess/ui/specialsettingspage.ui
+dbaccess/ui/generatedvaluespage.ui
+dbaccess/ui/ldapconnectionpage.ui
+dbaccess/ui/dbwizmysqlintropage.ui
+dbaccess/ui/dbwizmysqlnativepage.ui
+dbaccess/ui/specialjdbcconnectionpage.ui
+dbaccess/ui/authentificationpage.ui
+dbaccess/ui/finalpagewizard.ui
+dbaccess/ui/tablesfilterpage.ui
+dbaccess/ui/useradminpage.ui
+dbaccess/ui/connectionpage.ui
+dbaccess/ui/dbwizconnectionpage.ui
+dbaccess/ui/dbwiztextpage.ui
+dbaccess/ui/jdbcconnectionpage.ui
+dbaccess/ui/dbwizspreadsheetpage.ui
+dbaccess/ui/dbasepage.ui
+dbaccess/ui/autocharsetpage.ui
+dbaccess/ui/odbcpage.ui
+dbaccess/ui/userdetailspage.ui
+dbaccess/ui/autocharsetpage.ui
+dbaccess/ui/generalspecialjdbcdetailspage.ui
+dbaccess/ui/mysqlnativepage.ui
+dbaccess/ui/ldappage.ui
+dbaccess/ui/emptypage.ui
+dbaccess/ui/generalpagedialog.ui
+dbaccess/ui/generalpagewizard.ui
+dbaccess/ui/collectionviewdialog.ui
+dbaccess/ui/dbaseindexdialog.ui
+dbaccess/ui/directsqldialog.ui
+dbaccess/ui/savedialog.ui
+dbaccess/ui/savedialog.ui
+dbaccess/ui/rowheightdialog.ui
+dbaccess/ui/colwidthdialog.ui
+dbaccess/ui/choosedatasourcedialog.ui
+dbaccess/ui/indexdesigndialog.ui
+dbaccess/ui/parametersdialog.ui
+dbaccess/ui/queryfilterdialog.ui
+dbaccess/ui/sortdialog.ui
+dbaccess/ui/querypropertiesdialog.ui
+dbaccess/ui/sqlexception.ui
+dbaccess/ui/textconnectionsettings.ui
+dbaccess/ui/password.ui
+dbaccess/ui/tablesfilterdialog.ui
+dbaccess/ui/tablesjoindialog.ui
+dbaccess/ui/savemodifieddialog.ui
+dbaccess/ui/saveindexdialog.ui
+dbaccess/ui/designsavemodifieddialog.ui
+dbaccess/ui/tabledesignsavemodifieddialog.ui
+dbaccess/ui/deleteallrowsdialog.ui
diff --git a/dbaccess/qa/unit/data/firebird_empty.odb b/dbaccess/qa/unit/data/firebird_empty.odb
new file mode 100644
index 0000000000..9aabfd47b0
--- /dev/null
+++ b/dbaccess/qa/unit/data/firebird_empty.odb
Binary files differ
diff --git a/dbaccess/qa/unit/data/firebird_integer_ods12.odb b/dbaccess/qa/unit/data/firebird_integer_ods12.odb
new file mode 100644
index 0000000000..642b038dd7
--- /dev/null
+++ b/dbaccess/qa/unit/data/firebird_integer_ods12.odb
Binary files differ
diff --git a/dbaccess/qa/unit/data/hsqldb_empty.odb b/dbaccess/qa/unit/data/hsqldb_empty.odb
new file mode 100644
index 0000000000..087c261131
--- /dev/null
+++ b/dbaccess/qa/unit/data/hsqldb_empty.odb
Binary files differ
diff --git a/dbaccess/qa/unit/data/hsqldb_migration_test.odb b/dbaccess/qa/unit/data/hsqldb_migration_test.odb
new file mode 100644
index 0000000000..99b6b5d9a6
--- /dev/null
+++ b/dbaccess/qa/unit/data/hsqldb_migration_test.odb
Binary files differ
diff --git a/dbaccess/qa/unit/data/tdf119625.odb b/dbaccess/qa/unit/data/tdf119625.odb
new file mode 100644
index 0000000000..e7bd69d60b
--- /dev/null
+++ b/dbaccess/qa/unit/data/tdf119625.odb
Binary files differ
diff --git a/dbaccess/qa/unit/data/tdf126268.odb b/dbaccess/qa/unit/data/tdf126268.odb
new file mode 100644
index 0000000000..434a4238ba
--- /dev/null
+++ b/dbaccess/qa/unit/data/tdf126268.odb
Binary files differ
diff --git a/dbaccess/qa/unit/data/tdf132924.odb b/dbaccess/qa/unit/data/tdf132924.odb
new file mode 100644
index 0000000000..8cee7bcbab
--- /dev/null
+++ b/dbaccess/qa/unit/data/tdf132924.odb
Binary files differ
diff --git a/dbaccess/qa/unit/dbaccess-dialogs-test.cxx b/dbaccess/qa/unit/dbaccess-dialogs-test.cxx
new file mode 100644
index 0000000000..0551b31187
--- /dev/null
+++ b/dbaccess/qa/unit/dbaccess-dialogs-test.cxx
@@ -0,0 +1,61 @@
+/* -*- 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 <sal/config.h>
+#include <test/screenshot_test.hxx>
+#include <vcl/abstdlg.hxx>
+
+using namespace ::com::sun::star;
+
+/// Test opening a dialog in dbaccess
+class DbaccessDialogsTest : public ScreenshotTest
+{
+private:
+ /// helper method to populate KnownDialogs, called in setUp(). Needs to be
+ /// written and has to add entries to KnownDialogs
+ virtual void registerKnownDialogsByID(mapType& rKnownDialogs) override;
+
+ /// dialog creation for known dialogs by ID. Has to be implemented for
+ /// each registered known dialog
+ virtual VclPtr<VclAbstractDialog> createDialogByID(sal_uInt32 nID) override;
+
+public:
+ DbaccessDialogsTest();
+
+ // try to open a dialog
+ void openAnyDialog();
+
+ CPPUNIT_TEST_SUITE(DbaccessDialogsTest);
+ CPPUNIT_TEST(openAnyDialog);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+DbaccessDialogsTest::DbaccessDialogsTest() {}
+
+void DbaccessDialogsTest::registerKnownDialogsByID(mapType& /*rKnownDialogs*/)
+{
+ // fill map of known dialogs
+}
+
+VclPtr<VclAbstractDialog> DbaccessDialogsTest::createDialogByID(sal_uInt32 /*nID*/)
+{
+ return nullptr;
+}
+
+void DbaccessDialogsTest::openAnyDialog()
+{
+ /// process input file containing the UXMLDescriptions of the dialogs to dump
+ processDialogBatchFile(u"dbaccess/qa/unit/data/dbaccess-dialogs-test.txt");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DbaccessDialogsTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/qa/unit/dbtest_base.cxx b/dbaccess/qa/unit/dbtest_base.cxx
new file mode 100644
index 0000000000..88da4b4697
--- /dev/null
+++ b/dbaccess/qa/unit/dbtest_base.cxx
@@ -0,0 +1,58 @@
+/* -*- 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 <sal/config.h>
+
+#include <string_view>
+
+#include <cppunit/TestAssert.h>
+
+#include <test/unoapi_test.hxx>
+#include <unotools/tempfile.hxx>
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+class DBTestBase
+ : public UnoApiTest
+{
+public:
+ DBTestBase() : UnoApiTest("dbaccess/qa/unit/data") {};
+
+ uno::Reference<XOfficeDatabaseDocument> getDocumentForUrl(OUString const & url);
+
+ uno::Reference< XConnection >
+ getConnectionForDocument(
+ uno::Reference< XOfficeDatabaseDocument > const & xDocument);
+};
+
+uno::Reference<XOfficeDatabaseDocument> DBTestBase::getDocumentForUrl(OUString const & url) {
+ mxComponent = loadFromDesktop(url);
+ uno::Reference< XOfficeDatabaseDocument > xDocument(mxComponent, UNO_QUERY_THROW);
+ return xDocument;
+}
+
+uno::Reference< XConnection > DBTestBase::getConnectionForDocument(
+ uno::Reference< XOfficeDatabaseDocument > const & xDocument)
+{
+ uno::Reference< XDataSource > xDataSource = xDocument->getDataSource();
+ CPPUNIT_ASSERT(xDataSource.is());
+
+ uno::Reference< XConnection > xConnection = xDataSource->getConnection("","");
+ CPPUNIT_ASSERT(xConnection.is());
+
+ return xConnection;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/qa/unit/embeddeddb_performancetest.cxx b/dbaccess/qa/unit/embeddeddb_performancetest.cxx
new file mode 100644
index 0000000000..184ef0831a
--- /dev/null
+++ b/dbaccess/qa/unit/embeddeddb_performancetest.cxx
@@ -0,0 +1,357 @@
+/* -*- 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 "dbtest_base.cxx"
+
+#include <memory>
+#include <osl/process.h>
+#include <osl/time.h>
+#include <rtl/ustrbuf.hxx>
+#include <tools/stream.hxx>
+#include <unotools/tempfile.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/sdbc/XPreparedStatement.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XStatement.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+static void normaliseTimeValue(TimeValue* pVal)
+{
+ pVal->Seconds += pVal->Nanosec / 1000000000;
+ pVal->Nanosec %= 1000000000;
+}
+
+static void getTimeDifference(const TimeValue* pTimeStart,
+ const TimeValue* pTimeEnd,
+ TimeValue* pTimeDifference)
+{
+ // We add 1 second to the nanoseconds to ensure that we get a positive number
+ // We have to normalise anyway so this doesn't cause any harm.
+ // (Seconds/Nanosec are both unsigned)
+ pTimeDifference->Seconds = pTimeEnd->Seconds - pTimeStart->Seconds - 1;
+ pTimeDifference->Nanosec = 1000000000 + pTimeEnd->Nanosec - pTimeStart->Nanosec;
+ normaliseTimeValue(pTimeDifference);
+}
+
+static OUString getPrintableTimeValue(const TimeValue* pTimeValue)
+{
+ return OUString::number(
+ (sal_uInt64(pTimeValue->Seconds) * SAL_CONST_UINT64(1000000000)
+ + sal_uInt64(pTimeValue->Nanosec))/ 1000000
+ );
+}
+
+/*
+ * The recommended way to run this test is:
+ * 'SAL_LOG="" DBA_PERFTEST=YES make CppunitTest_dbaccess_embeddeddb_performancetest'
+ * This blocks the unnecessary exception output and show only the performance data.
+ *
+ * You also need to create the file dbaccess/qa/unit/data/wordlist, this list cannot
+ * contain any unescaped apostrophes (since the words are used directly to assemble
+ * sql statement), apostrophes are escaped using a double apostrophe, i.e. ''.
+ * one easy way of generating a list is using:
+ * 'for WORD in $(aspell dump master); do echo ${WORD//\'/\'\'}; done > dbaccess/qa/unit/data/wordlist'
+ *
+ * Note that wordlist cannot have more than 220580 lines, this is due to a hard
+ * limit in our hsqldb version.
+ *
+ * Also note that this unit test "fails" when doing performance testing, this is
+ * since by default unit test output is hidden, and thus there is no way of
+ * reading the results.
+ */
+class EmbeddedDBPerformanceTest
+ : public DBTestBase
+{
+private:
+ static constexpr OUString our_sEnableTestEnvVar = u"DBA_PERFTEST"_ustr;
+
+
+ // We store the results and print them at the end due to the amount of warning
+ // noise present which otherwise obscures the results.
+ OUStringBuffer m_aOutputBuffer;
+
+ void printTimes(const TimeValue* pTime1, const TimeValue* pTime2, const TimeValue* pTime3);
+
+ void doPerformanceTestOnODB(const OUString& rDriverURL,
+ std::u16string_view rDBName,
+ const bool bUsePreparedStatement);
+
+ void setupTestTable(uno::Reference< XConnection > const & xConnection);
+
+ SvFileStream *getWordListStream();
+
+ // Individual Tests
+ void performPreparedStatementInsertTest(
+ uno::Reference< XConnection > const & xConnection,
+ std::u16string_view rDBName);
+ void performStatementInsertTest(
+ uno::Reference< XConnection > const & xConnection,
+ std::u16string_view rDBName);
+ void performReadTest(
+ uno::Reference< XConnection > const & xConnection,
+ std::u16string_view rDBName);
+
+ // Perform all tests on a given DB.
+ void testFirebird();
+ void testHSQLDB();
+
+public:
+ void testPerformance();
+
+ CPPUNIT_TEST_SUITE(EmbeddedDBPerformanceTest);
+ CPPUNIT_TEST(testPerformance);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+SvFileStream* EmbeddedDBPerformanceTest::getWordListStream()
+{
+ OUString wlPath = createFileURL(u"wordlist");
+ return new SvFileStream(wlPath, StreamMode::READ);
+}
+
+void EmbeddedDBPerformanceTest::printTimes(
+ const TimeValue* pTime1,
+ const TimeValue* pTime2,
+ const TimeValue* pTime3)
+{
+ m_aOutputBuffer.append(
+ getPrintableTimeValue(pTime1) + "\t" +
+ getPrintableTimeValue(pTime2) + "\t" +
+ getPrintableTimeValue(pTime3) + "\t"
+ "\n");
+}
+
+// TODO: we probably should create a document from scratch instead?
+
+void EmbeddedDBPerformanceTest::testPerformance()
+{
+ OUString sEnabled;
+ osl_getEnvironment(our_sEnableTestEnvVar.pData, &sEnabled.pData);
+
+ if (sEnabled.isEmpty())
+ return;
+
+ m_aOutputBuffer.append("---------------------\n");
+ testFirebird();
+ m_aOutputBuffer.append("---------------------\n");
+ testHSQLDB();
+ m_aOutputBuffer.append("---------------------\n");
+
+ fprintf(stdout, "Performance Test Results:\n");
+ fprintf(stdout, "%s",
+ OUStringToOString(m_aOutputBuffer.makeStringAndClear(),
+ RTL_TEXTENCODING_UTF8)
+ .getStr()
+ );
+
+ // We want the results printed, but unit test output is only printed on failure
+ // Hence we deliberately fail the test.
+ CPPUNIT_ASSERT(false);
+}
+
+void EmbeddedDBPerformanceTest::testFirebird()
+{
+
+ m_aOutputBuffer.append("Standard Insert\n");
+ doPerformanceTestOnODB("sdbc:embedded:firebird", u"Firebird", false);
+ m_aOutputBuffer.append("PreparedStatement Insert\n");
+ doPerformanceTestOnODB("sdbc:embedded:firebird", u"Firebird", true);
+}
+
+void EmbeddedDBPerformanceTest::testHSQLDB()
+{
+ m_aOutputBuffer.append("Standard Insert\n");
+ doPerformanceTestOnODB("sdbc:embedded:hsqldb", u"HSQLDB", false);
+ m_aOutputBuffer.append("PreparedStatement Insert\n");
+ doPerformanceTestOnODB("sdbc:embedded:hsqldb", u"HSQLDB", true);
+}
+
+/**
+ * Use an existing .odb to do performance tests on. The database cannot have
+ * a table of the name PFTESTTABLE.
+ */
+void EmbeddedDBPerformanceTest::doPerformanceTestOnODB(
+ const OUString& rDriverURL,
+ std::u16string_view rDBName,
+ const bool bUsePreparedStatement)
+{
+ ::utl::TempFileNamed aFile;
+ aFile.EnableKillingFile();
+
+ {
+ uno::Reference< XOfficeDatabaseDocument > xDocument(
+ m_xSFactory->createInstance("com.sun.star.sdb.OfficeDatabaseDocument"),
+ UNO_QUERY_THROW);
+ uno::Reference< XStorable > xStorable(xDocument, UNO_QUERY_THROW);
+
+ uno::Reference< XDataSource > xDataSource = xDocument->getDataSource();
+ uno::Reference< XPropertySet > xPropertySet(xDataSource, UNO_QUERY_THROW);
+ xPropertySet->setPropertyValue("URL", Any(rDriverURL));
+
+ xStorable->storeAsURL(aFile.GetURL(), uno::Sequence< beans::PropertyValue >());
+ }
+
+ uno::Reference< XOfficeDatabaseDocument > xDocument(
+ loadFromDesktop(aFile.GetURL()), UNO_QUERY_THROW);
+
+ uno::Reference< XConnection > xConnection =
+ getConnectionForDocument(xDocument);
+
+ setupTestTable(xConnection);
+
+ if (bUsePreparedStatement)
+ performPreparedStatementInsertTest(xConnection, rDBName);
+ else
+ performStatementInsertTest(xConnection, rDBName);
+
+ performReadTest(xConnection, rDBName);
+}
+
+void EmbeddedDBPerformanceTest::setupTestTable(
+ uno::Reference< XConnection > const & xConnection)
+{
+ uno::Reference< XStatement > xStatement = xConnection->createStatement();
+
+ // Although not strictly necessary we use quoted identifiers to reflect
+ // the fact that Base always uses quoted identifiers.
+ xStatement->execute(
+ "CREATE TABLE \"PFTESTTABLE\" ( \"ID\" INTEGER NOT NULL PRIMARY KEY "
+ ", \"STRINGCOLUMNA\" VARCHAR (50) "
+ ")");
+
+ xConnection->commit();
+}
+
+void EmbeddedDBPerformanceTest::performPreparedStatementInsertTest(
+ uno::Reference< XConnection > const & xConnection,
+ std::u16string_view rDBName)
+{
+ uno::Reference< XPreparedStatement > xPreparedStatement =
+ xConnection->prepareStatement(
+ "INSERT INTO \"PFTESTTABLE\" ( \"ID\", "
+ "\"STRINGCOLUMNA\" "
+ ") VALUES ( ?, ? )"
+ );
+
+ uno::Reference< XParameters > xParameters(xPreparedStatement, UNO_QUERY_THROW);
+
+ std::unique_ptr< SvFileStream > pFile(getWordListStream());
+
+ OUString aWord;
+ sal_Int32 aID = 0;
+
+ TimeValue aStart, aMiddle, aEnd;
+ osl_getSystemTime(&aStart);
+
+ while (pFile->ReadByteStringLine(aWord, RTL_TEXTENCODING_UTF8))
+ {
+ xParameters->setInt(1, aID++);
+ xParameters->setString(2, aWord);
+ xPreparedStatement->execute();
+ }
+ osl_getSystemTime(&aMiddle);
+ xConnection->commit();
+ osl_getSystemTime(&aEnd);
+
+
+ TimeValue aTimeInsert, aTimeCommit, aTimeTotal;
+ getTimeDifference(&aStart, &aMiddle, &aTimeInsert);
+ getTimeDifference(&aMiddle, &aEnd, &aTimeCommit);
+ getTimeDifference(&aStart, &aEnd, &aTimeTotal);
+ m_aOutputBuffer.append(OUString::Concat("Insert: ") + rDBName + "\n");
+ printTimes(&aTimeInsert, &aTimeCommit, &aTimeTotal);
+
+ pFile->Close();
+}
+
+void EmbeddedDBPerformanceTest::performStatementInsertTest(
+ uno::Reference< XConnection > const & xConnection,
+ std::u16string_view rDBName)
+{
+ uno::Reference< XStatement > xStatement =
+ xConnection->createStatement();
+
+ std::unique_ptr< SvFileStream > pFile(getWordListStream());
+
+ OUString aWord;
+ sal_Int32 aID = 0;
+
+ TimeValue aStart, aMiddle, aEnd;
+ osl_getSystemTime(&aStart);
+
+ while (pFile->ReadByteStringLine(aWord, RTL_TEXTENCODING_UTF8))
+ {
+ xStatement->execute(
+ "INSERT INTO \"PFTESTTABLE\" ( \"ID\", "
+ "\"STRINGCOLUMNA\" "
+ ") VALUES ( "
+ + OUString::number(aID++) + ", '" + aWord + "' )"
+ );
+ }
+ osl_getSystemTime(&aMiddle);
+ xConnection->commit();
+ osl_getSystemTime(&aEnd);
+
+ TimeValue aTimeInsert, aTimeCommit, aTimeTotal;
+ getTimeDifference(&aStart, &aMiddle, &aTimeInsert);
+ getTimeDifference(&aMiddle, &aEnd, &aTimeCommit);
+ getTimeDifference(&aStart, &aEnd, &aTimeTotal);
+ m_aOutputBuffer.append(OUString::Concat("Insert: ") + rDBName + "\n");
+ printTimes(&aTimeInsert, &aTimeCommit, &aTimeTotal);
+
+ pFile->Close();
+}
+
+void EmbeddedDBPerformanceTest::performReadTest(
+ uno::Reference< XConnection > const & xConnection,
+ std::u16string_view rDBName)
+{
+ uno::Reference< XStatement > xStatement = xConnection->createStatement();
+
+ TimeValue aStart, aMiddle, aEnd;
+ osl_getSystemTime(&aStart);
+
+ uno::Reference< XResultSet > xResults = xStatement->executeQuery("SELECT * FROM PFTESTTABLE");
+
+ osl_getSystemTime(&aMiddle);
+
+ uno::Reference< XRow > xRow(xResults, UNO_QUERY_THROW);
+
+ while (xResults->next())
+ {
+ xRow->getString(2);
+ }
+ osl_getSystemTime(&aEnd);
+
+ TimeValue aTimeSelect, aTimeIterate, aTimeTotal;
+ getTimeDifference(&aStart, &aMiddle, &aTimeSelect);
+ getTimeDifference(&aMiddle, &aEnd, &aTimeIterate);
+ getTimeDifference(&aStart, &aEnd, &aTimeTotal);
+ m_aOutputBuffer.append(OUString::Concat("Read from: ") + rDBName + "\n");
+ printTimes(&aTimeSelect, &aTimeIterate, &aTimeTotal);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(EmbeddedDBPerformanceTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/qa/unit/firebird.cxx b/dbaccess/qa/unit/firebird.cxx
new file mode 100644
index 0000000000..1b6b7172fd
--- /dev/null
+++ b/dbaccess/qa/unit/firebird.cxx
@@ -0,0 +1,130 @@
+/* -*- 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 "dbtest_base.cxx"
+
+#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/XRow.hpp>
+#include <com/sun/star/sdbc/XStatement.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+class FirebirdTest
+ : public DBTestBase
+{
+public:
+ void testEmptyDBConnection();
+ void testIntegerDatabase();
+ void testTdf132924();
+
+ CPPUNIT_TEST_SUITE(FirebirdTest);
+ CPPUNIT_TEST(testEmptyDBConnection);
+ CPPUNIT_TEST(testIntegerDatabase);
+ CPPUNIT_TEST(testTdf132924);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+/**
+ * Test the loading of an "empty" file, i.e. the embedded database has not yet
+ * been initialised (as occurs when a new .odb is created and opened by base).
+ */
+void FirebirdTest::testEmptyDBConnection()
+{
+ createTempCopy(u"firebird_empty.odb");
+ uno::Reference< XOfficeDatabaseDocument > xDocument =
+ getDocumentForUrl(maTempFile.GetURL());
+
+ getConnectionForDocument(xDocument);
+
+ css::uno::Reference<util::XCloseable> xCloseable(mxComponent, css::uno::UNO_QUERY_THROW);
+ xCloseable->close(false);
+}
+
+/**
+ * Test reading of integers from a known .odb to verify that the data
+ * can still be read on all systems.
+ */
+void FirebirdTest::testIntegerDatabase()
+{
+ loadFromFile(u"firebird_integer_ods12.odb");
+ uno::Reference< XOfficeDatabaseDocument > xDocument(mxComponent, UNO_QUERY_THROW);
+
+ uno::Reference< XConnection > xConnection =
+ getConnectionForDocument(xDocument);
+
+ uno::Reference< XStatement > xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+
+ uno::Reference< XResultSet > xResultSet = xStatement->executeQuery(
+ "SELECT * FROM TESTTABLE");
+ CPPUNIT_ASSERT(xResultSet.is());
+ CPPUNIT_ASSERT(xResultSet->next());
+
+ uno::Reference< XRow > xRow(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT(xRow.is());
+ uno::Reference< XColumnLocate > xColumnLocate(xRow, UNO_QUERY);
+ CPPUNIT_ASSERT(xColumnLocate.is());
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(-30000),
+ xRow->getShort(xColumnLocate->findColumn("_SMALLINT")));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-2100000000),
+ xRow->getInt(xColumnLocate->findColumn("_INT")));
+ CPPUNIT_ASSERT_EQUAL(SAL_CONST_INT64(-9000000000000000000),
+ xRow->getLong(xColumnLocate->findColumn("_BIGINT")));
+ CPPUNIT_ASSERT_EQUAL(OUString("5"),
+ xRow->getString(xColumnLocate->findColumn("_CHAR")));
+ CPPUNIT_ASSERT_EQUAL(OUString("5"),
+ xRow->getString(xColumnLocate->findColumn("_VARCHAR")));
+
+ CPPUNIT_ASSERT(!xResultSet->next()); // Should only be one row
+
+ css::uno::Reference<util::XCloseable> xCloseable(mxComponent, css::uno::UNO_QUERY_THROW);
+ xCloseable->close(false);
+}
+
+void FirebirdTest::testTdf132924()
+{
+ loadFromFile(u"tdf132924.odb");
+ uno::Reference< XOfficeDatabaseDocument > xDocument(mxComponent, UNO_QUERY_THROW);
+ uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
+
+ uno::Reference<XStatement> xStatement = xConnection->createStatement();
+ CPPUNIT_ASSERT(xStatement.is());
+
+ uno::Reference<XResultSet> xResultSet = xStatement->executeQuery("SELECT * FROM AliasTest");
+ CPPUNIT_ASSERT(xResultSet.is());
+ CPPUNIT_ASSERT(xResultSet->next());
+
+ uno::Reference<XRow> xRow(xResultSet, UNO_QUERY);
+ CPPUNIT_ASSERT(xRow.is());
+ uno::Reference<XColumnLocate> xColumnLocate(xRow, UNO_QUERY);
+ CPPUNIT_ASSERT(xColumnLocate.is());
+
+ // Without the fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : The column name 'TestId' is not valid
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xRow->getShort(xColumnLocate->findColumn("TestId")));
+ CPPUNIT_ASSERT_EQUAL(OUString("TestName"), xRow->getString(xColumnLocate->findColumn("TestName")));
+
+ css::uno::Reference<util::XCloseable> xCloseable(mxComponent, css::uno::UNO_QUERY_THROW);
+ xCloseable->close(false);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(FirebirdTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/qa/unit/hsql_binary_import.cxx b/dbaccess/qa/unit/hsql_binary_import.cxx
new file mode 100644
index 0000000000..569463e7e4
--- /dev/null
+++ b/dbaccess/qa/unit/hsql_binary_import.cxx
@@ -0,0 +1,101 @@
+/* -*- 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 "dbtest_base.cxx"
+
+#include <osl/process.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <cppunit/extensions/HelperMacros.h>
+#include <officecfg/Office/Common.hxx>
+
+class HsqlBinaryImportTest : public DBTestBase
+{
+public:
+ void testBinaryImport();
+
+ virtual void setUp() override;
+
+ CPPUNIT_TEST_SUITE(HsqlBinaryImportTest);
+
+ CPPUNIT_TEST(testBinaryImport);
+
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void HsqlBinaryImportTest::setUp()
+{
+ DBTestBase::setUp();
+ osl_setEnvironment(OUString{ "DBACCESS_HSQL_MIGRATION" }.pData, OUString{ "1" }.pData);
+}
+
+void HsqlBinaryImportTest::testBinaryImport()
+{
+ bool oldValue = officecfg::Office::Common::Misc::ExperimentalMode::get();
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(true, xChanges);
+ xChanges->commit();
+ }
+
+ // the migration requires the file to be writable
+ createTempCopy(u"hsqldb_migration_test.odb");
+ uno::Reference<XOfficeDatabaseDocument> const xDocument
+ = getDocumentForUrl(maTempFile.GetURL());
+
+ uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
+ // at this point migration is already done
+
+ uno::Reference<XStatement> statement = xConnection->createStatement();
+
+ uno::Reference<XResultSet> xRes
+ = statement->executeQuery("SELECT \"ID\", \"Power_value\", \"Power_name\", \"Retired\", "
+ "\"Birth_date\" FROM \"TestTable\" ORDER BY \"ID\"");
+ uno::Reference<XRow> xRow(xRes, UNO_QUERY_THROW);
+
+ // assert first row
+ CPPUNIT_ASSERT(xRes->next());
+ constexpr sal_Int16 idExpected = 1;
+ CPPUNIT_ASSERT_EQUAL(idExpected, xRow->getShort(1));
+ CPPUNIT_ASSERT_EQUAL(OUString{ "45.32" }, xRow->getString(2)); // numeric
+ CPPUNIT_ASSERT_EQUAL(OUString{ "laser eye" }, xRow->getString(3)); // varchar
+ CPPUNIT_ASSERT(xRow->getBoolean(4)); // boolean
+
+ css::util::Date date = xRow->getDate(5);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16{ 15 }, date.Day);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16{ 1 }, date.Month);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16{ 1996 }, date.Year);
+
+ // assert second row
+ CPPUNIT_ASSERT(xRes->next());
+ constexpr sal_Int16 secondIdExpected = 2;
+ CPPUNIT_ASSERT_EQUAL(secondIdExpected, xRow->getShort(1)); // ID
+ CPPUNIT_ASSERT_EQUAL(OUString{ "54.12" }, xRow->getString(2)); // numeric
+ CPPUNIT_ASSERT_EQUAL(OUString{ "telekinesis" }, xRow->getString(3)); // varchar
+ CPPUNIT_ASSERT(!xRow->getBoolean(4)); // boolean
+
+ date = xRow->getDate(5);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16{ 26 }, date.Day);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16{ 2 }, date.Month);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16{ 1998 }, date.Year);
+
+ if (!oldValue)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(false, xChanges);
+ xChanges->commit();
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HsqlBinaryImportTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/dbaccess/qa/unit/hsqldb.cxx b/dbaccess/qa/unit/hsqldb.cxx
new file mode 100644
index 0000000000..eb553eac75
--- /dev/null
+++ b/dbaccess/qa/unit/hsqldb.cxx
@@ -0,0 +1,45 @@
+/* -*- 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 "dbtest_base.cxx"
+
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+
+class HSQLDBTest : public DBTestBase
+{
+public:
+ void testEmptyDBConnection();
+
+ CPPUNIT_TEST_SUITE(HSQLDBTest);
+ CPPUNIT_TEST(testEmptyDBConnection);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+/**
+ * Test the loading of an "empty" file, i.e. the embedded database has not yet
+ * been initialised (as occurs when a new .odb is created and opened by base).
+ */
+void HSQLDBTest::testEmptyDBConnection()
+{
+ createTempCopy(u"hsqldb_empty.odb");
+ uno::Reference<XOfficeDatabaseDocument> xDocument = getDocumentForUrl(maTempFile.GetURL());
+
+ getConnectionForDocument(xDocument);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HSQLDBTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/qa/unit/tdf119625.cxx b/dbaccess/qa/unit/tdf119625.cxx
new file mode 100644
index 0000000000..ba0c7b2ce3
--- /dev/null
+++ b/dbaccess/qa/unit/tdf119625.cxx
@@ -0,0 +1,121 @@
+/* -*- 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 "dbtest_base.cxx"
+
+#include <osl/process.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <cppunit/extensions/HelperMacros.h>
+#include <com/sun/star/util/Time.hpp>
+#include <officecfg/Office/Common.hxx>
+
+class Tdf119625Test : public DBTestBase
+{
+public:
+ void testTime();
+
+ virtual void setUp() override;
+
+ CPPUNIT_TEST_SUITE(Tdf119625Test);
+
+ CPPUNIT_TEST(testTime);
+
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Tdf119625Test::setUp()
+{
+ DBTestBase::setUp();
+ osl_setEnvironment(OUString{ "DBACCESS_HSQL_MIGRATION" }.pData, OUString{ "1" }.pData);
+}
+
+namespace
+{
+struct expect_t
+{
+ sal_Int16 id;
+ sal_Int16 h, m, s;
+};
+}
+
+/* The values here assume that our results are in UTC. However,
+ tdf#119675 "Firebird: Migration: User dialog to set treatment of
+ datetime and time values during migration" is going to change the
+ final result of migration. If that change is implemented below
+ the level we are testing, this test will have to allow for or set
+ the destination timezone.
+ */
+const expect_t expect[] = { { 0, 15, 10, 10 }, { 1, 23, 30, 30 }, { 2, 5, 0, 0 }, { 3, 4, 30, 0 },
+ { 4, 3, 15, 10 }, { 5, 5, 0, 0 }, { 6, 3, 22, 22 } };
+
+void Tdf119625Test::testTime()
+{
+ bool oldValue = officecfg::Office::Common::Misc::ExperimentalMode::get();
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(true, xChanges);
+ xChanges->commit();
+ }
+
+ // the migration requires the file to be writable
+ createTempCopy(u"tdf119625.odb");
+ uno::Reference<XOfficeDatabaseDocument> const xDocument
+ = getDocumentForUrl(maTempFile.GetURL());
+
+ uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
+ // at this point migration is already done
+ /* In the presence of tdf#119625, terminal already has messages
+
+ *value exceeds the range for a valid time
+ caused by
+ 'isc_dsql_execute'
+
+ warn:dbaccess:22435:22435:dbaccess/source/filter/hsqldb/hsqlimport.cxx:373: Error during migration
+
+ In this case, we do not expect anything good from the following
+ code, but I (tje, 2018-09-04) do not know how to detect this
+ situation. In particular, the migration has been observed to
+ create the destination table (but truncated after the first
+ row), and xConnection.is() returns true.
+ */
+
+ // select basically everything from the .odb
+ uno::Reference<XStatement> statement = xConnection->createStatement();
+
+ uno::Reference<XResultSet> xRes = statement->executeQuery(" SELECT id, tst_dt, tst_d, tst_t "
+ " FROM tst_data "
+ "ORDER BY id");
+ uno::Reference<XRow> xRow(xRes, UNO_QUERY_THROW);
+
+ // check result
+ for (auto& e : expect)
+ {
+ CPPUNIT_ASSERT(xRes->next());
+ CPPUNIT_ASSERT_EQUAL(xRow->getShort(1), e.id);
+ auto time_got = xRow->getTime(4);
+ auto time_expected = com::sun::star::util::Time(0, e.s, e.m, e.h, false);
+ auto equal_times = time_got == time_expected;
+ CPPUNIT_ASSERT(equal_times);
+ }
+ CPPUNIT_ASSERT(!xRes->next());
+
+ if (!oldValue)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(false, xChanges);
+ xChanges->commit();
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Tdf119625Test);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/dbaccess/qa/unit/tdf126268.cxx b/dbaccess/qa/unit/tdf126268.cxx
new file mode 100644
index 0000000000..c06fdead79
--- /dev/null
+++ b/dbaccess/qa/unit/tdf126268.cxx
@@ -0,0 +1,97 @@
+/* -*- 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 "dbtest_base.cxx"
+
+#include <osl/process.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <cppunit/extensions/HelperMacros.h>
+#include <officecfg/Office/Common.hxx>
+
+class Tdf126268Test : public DBTestBase
+{
+public:
+ void testNumbers();
+
+ virtual void setUp() override;
+
+ CPPUNIT_TEST_SUITE(Tdf126268Test);
+
+ CPPUNIT_TEST(testNumbers);
+
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Tdf126268Test::setUp()
+{
+ DBTestBase::setUp();
+ osl_setEnvironment(OUString{ "DBACCESS_HSQL_MIGRATION" }.pData, OUString{ "1" }.pData);
+}
+
+namespace
+{
+struct expect_t
+{
+ sal_Int16 id;
+ OUString number;
+};
+}
+
+const expect_t expect[] = {
+ { 1, "0.00" }, { 2, "25.00" }, { 3, "26.00" }, { 4, "30.4" }, { 5, "45.8" },
+ { 6, "-25.00" }, { 7, "-26.00" }, { 8, "-30.4" }, { 9, "-45.8" },
+};
+
+void Tdf126268Test::testNumbers()
+{
+ bool oldValue = officecfg::Office::Common::Misc::ExperimentalMode::get();
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(true, xChanges);
+ xChanges->commit();
+ }
+
+ // the migration requires the file to be writable
+ createTempCopy(u"tdf126268.odb");
+ uno::Reference<XOfficeDatabaseDocument> const xDocument
+ = getDocumentForUrl(maTempFile.GetURL());
+
+ uno::Reference<XConnection> xConnection = getConnectionForDocument(xDocument);
+
+ // select basically everything from the .odb
+ uno::Reference<XStatement> statement = xConnection->createStatement();
+
+ uno::Reference<XResultSet> xRes
+ = statement->executeQuery("SELECT ID, Column1, Column2 FROM tableTest ORDER BY ID");
+ uno::Reference<XRow> xRow(xRes, UNO_QUERY_THROW);
+
+ // check result
+ for (auto& e : expect)
+ {
+ CPPUNIT_ASSERT(xRes->next());
+ CPPUNIT_ASSERT_EQUAL(e.id, xRow->getShort(1));
+ CPPUNIT_ASSERT_EQUAL(e.number, xRow->getString(2)); //decimal
+ CPPUNIT_ASSERT_EQUAL(e.number, xRow->getString(3)); //numeric
+ }
+ CPPUNIT_ASSERT(!xRes->next());
+
+ if (!oldValue)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set(false, xChanges);
+ xChanges->commit();
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Tdf126268Test);
+
+CPPUNIT_PLUGIN_IMPLEMENT();