From 4b870e7fcf2665274141611b28bbcba28c89da5d Mon Sep 17 00:00:00 2001 From: Xisco Fauli Date: Tue, 6 Oct 2026 16:21:29 +0200 Subject: [PATCH] dbaccess: port test from java to c++ I would like to turn this into an easyhack but first I want to revert commit 42190cd153d4061a8401acdb2c2f8edf9154a978 Author: Noel Grandin Date: Mon Mar 31 12:38:35 2025 +0200 Revert "Move SingleSelectQueryComposer.java tests to C++" This reverts commit d1ec7e90772421331bef31eb934180c7f992e42f. To avoid deadlocks on jenkins. and see where CI deadlocks Change-Id: I99a4b0ac035421cd255c51f69946b52d6ae6635f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211888 Tested-by: Jenkins Reviewed-by: Xisco Fauli --- dbaccess/CppunitTest_dbaccess_rowset_test.mk | 58 +++++++ dbaccess/Module_dbaccess.mk | 1 + dbaccess/qa/complex/dbaccess/RowSet.java | 126 -------------- dbaccess/qa/unit/CRMDatabase_test.cxx | 19 --- dbaccess/qa/unit/dbtest_base.cxx | 21 ++- dbaccess/qa/unit/rowset_test.cxx | 167 +++++++++++++++++++ 6 files changed, 245 insertions(+), 147 deletions(-) create mode 100644 dbaccess/CppunitTest_dbaccess_rowset_test.mk create mode 100644 dbaccess/qa/unit/rowset_test.cxx diff --git a/dbaccess/CppunitTest_dbaccess_rowset_test.mk b/dbaccess/CppunitTest_dbaccess_rowset_test.mk new file mode 100644 index 000000000000..6a70d07ed461 --- /dev/null +++ b/dbaccess/CppunitTest_dbaccess_rowset_test.mk @@ -0,0 +1,58 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,dbaccess_rowset_test)) + +$(eval $(call gb_CppunitTest_use_externals,dbaccess_rowset_test, \ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,dbaccess_rowset_test, \ + dbaccess/qa/unit/rowset_test \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,dbaccess_rowset_test, \ + comphelper \ + cppu \ + cppuhelper \ + dbaxml \ + dbtools \ + sal \ + subsequenttest \ + utl \ + test \ + tk \ + tl \ + unotest \ + xo \ +)) + +$(eval $(call gb_CppunitTest_use_api,dbaccess_rowset_test,\ + offapi \ + oovbaapi \ + udkapi \ +)) + +$(eval $(call gb_CppunitTest_use_ure,dbaccess_rowset_test)) +$(eval $(call gb_CppunitTest_use_vcl,dbaccess_rowset_test)) + +$(eval $(call gb_CppunitTest_use_rdb,dbaccess_rowset_test,services)) + +$(eval $(call gb_CppunitTest_use_configuration,dbaccess_rowset_test)) + +$(eval $(call gb_CppunitTest_use_uiconfigs,dbaccess_rowset_test, \ + dbaccess \ +)) + +$(eval $(call gb_CppunitTest_use_jars,dbaccess_rowset_test, \ + sdbc_hsqldb \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/dbaccess/Module_dbaccess.mk b/dbaccess/Module_dbaccess.mk index 8072063fb6ab..04c8cd9b9851 100644 --- a/dbaccess/Module_dbaccess.mk +++ b/dbaccess/Module_dbaccess.mk @@ -63,6 +63,7 @@ $(eval $(call gb_Module_add_check_targets,dbaccess,\ CppunitTest_dbaccess_hsqldb_test \ CppunitTest_dbaccess_RowSetClones \ CppunitTest_dbaccess_CRMDatabase_test \ + CppunitTest_dbaccess_rowset_test \ )) endif diff --git a/dbaccess/qa/complex/dbaccess/RowSet.java b/dbaccess/qa/complex/dbaccess/RowSet.java index ed42a271b46f..87a97e00d0de 100644 --- a/dbaccess/qa/complex/dbaccess/RowSet.java +++ b/dbaccess/qa/complex/dbaccess/RowSet.java @@ -812,131 +812,5 @@ public class RowSet extends TestCase testPosition(clone, cloneRow, 1, "mixed clone/rowset move/insertion: clone check"); testPosition(m_resultSet, m_row, 100, "mixed clone/rowset move/insertion: rowset check"); } - - - private void testTableParameters() throws com.sun.star.uno.Exception - { - // for a row set simply based on a table, there should be not parameters at all - createRowSet("products", CommandType.TABLE, false); - verifyParameters(new String[] - { - }, "testTableParameters"); - } - - - private void testParametersAfterNormalExecute() throws com.sun.star.uno.Exception - { - createRowSet("SELECT * FROM \"customers\"", CommandType.COMMAND, true); - m_rowSetProperties.setPropertyValue("Command", "SELECT * FROM \"customers\" WHERE \"City\" = :city"); - final XParameters rowsetParams = UnoRuntime.queryInterface( XParameters.class, m_rowSet ); - rowsetParams.setString(1, "London"); - m_rowSet.execute(); - } - - - private void verifyParameters(String[] _paramNames, String _context) throws com.sun.star.uno.Exception - { - final XIndexAccess params = m_paramsSupplier.getParameters(); - final int expected = _paramNames.length; - final int found = params != null ? params.getCount() : 0; - - assertTrue("wrong number of parameters (expected: " + expected + ", found: " + found + ") in " + _context, - found == expected); - - if (found == 0) - { - return; - } - - for (int i = 0; i < expected; ++i) - { - final XPropertySet parameter = UnoRuntime.queryInterface( XPropertySet.class, params.getByIndex( i ) ); - - final String expectedName = _paramNames[i]; - final String foundName = (String) parameter.getPropertyValue("Name"); - assertTrue("wrong parameter name (expected: " + expectedName + ", found: " + foundName + ") in" + _context, - expectedName.equals(foundName)); - } - } - - - private void testParametrizedQuery() throws com.sun.star.uno.Exception - { - // for a row set based on a parametrized query, those parameters should be properly - // recognized - m_dataSource.createQuery("products like", "SELECT * FROM \"products\" WHERE \"Name\" LIKE :product_name"); - createRowSet("products like", CommandType.QUERY, false); - verifyParameters(new String[] - { - "product_name" - }, "testParametrizedQuery"); - } - - - private void testParametersInteraction() throws com.sun.star.uno.Exception - { - createRowSet("products like", CommandType.QUERY, false); - - // let's fill in a parameter value via XParameters, and see whether it is respected by the parameters container - final XParameters rowsetParams = UnoRuntime.queryInterface(XParameters.class, m_rowSet); - rowsetParams.setString(1, "Apples"); - - XIndexAccess params = m_paramsSupplier.getParameters(); - XPropertySet firstParam = UnoRuntime.queryInterface( XPropertySet.class, params.getByIndex( 0 ) ); - Object firstParamValue = firstParam.getPropertyValue("Value"); - - assertTrue("XParameters and the parameters container do not properly interact", - "Apples".equals(firstParamValue)); - - // let's see whether this also survives an execute of the row set - rowsetParams.setString(1, "Oranges"); - m_rowSet.execute(); - { - // TODO: the following would not be necessary if the parameters container would *survive* - // the execution of the row set. It currently doesn't (though the values it represents do). - // It would be nice, but not strictly necessary, if it would. - params = m_paramsSupplier.getParameters(); - firstParam = UnoRuntime.queryInterface( XPropertySet.class, params.getByIndex( 0 ) ); - } - firstParamValue = firstParam.getPropertyValue("Value"); - assertTrue("XParameters and the parameters container do not properly interact, after the row set has been executed", - "Oranges".equals(firstParamValue)); - } - - - private void testParametersInFilter() throws com.sun.star.uno.Exception - { - createRowSet("SELECT * FROM \"customers\"", CommandType.COMMAND, false); - m_rowSetProperties.setPropertyValue("Filter", "\"City\" = :city"); - - m_rowSetProperties.setPropertyValue("ApplyFilter", Boolean.TRUE); - verifyParameters(new String[] - { - "city" - }, "testParametersInFilter"); - - m_rowSetProperties.setPropertyValue("ApplyFilter", Boolean.FALSE); - verifyParameters(new String[] - { - }, "testParametersInFilter"); - } - - - /** checks the XParametersSupplier functionality of a RowSet - */ - @Test - public void testParameters() throws Exception - { - createTestCase(false); - // use an own RowSet instance, not the one which is also used for the other cases - - testTableParameters(); - testParametrizedQuery(); - testParametersInFilter(); - - testParametersAfterNormalExecute(); - - testParametersInteraction(); - } } diff --git a/dbaccess/qa/unit/CRMDatabase_test.cxx b/dbaccess/qa/unit/CRMDatabase_test.cxx index 75dbc72f2fd4..995dc7d572aa 100644 --- a/dbaccess/qa/unit/CRMDatabase_test.cxx +++ b/dbaccess/qa/unit/CRMDatabase_test.cxx @@ -30,7 +30,6 @@ class CRMDBTest : public DBTestBase public: void testCRMDatabase(); void testRegistrationName(); - uno::Reference setUpDBConnection(); void testQueryColumns(); void testODBCEscapeQuery(); @@ -42,24 +41,9 @@ public: CPPUNIT_TEST_SUITE_END(); }; -uno::Reference CRMDBTest::setUpDBConnection() -{ - createDBDocument(u"sdbc:embedded:hsqldb"_ustr); - uno::Reference xDocument(mxComponent, UNO_QUERY_THROW); - uno::Reference xDataSource = xDocument->getDataSource(); - CPPUNIT_ASSERT(xDataSource.is()); - - // create queries before establishing connection to database - createQueries(xDataSource); - - uno::Reference xConnection = getConnectionForDocument(xDocument); - return xConnection; -} - void CRMDBTest::testCRMDatabase() { uno::Reference xConnection = setUpDBConnection(); - createTables(xConnection); // test selection Reference xStatement = xConnection->createStatement(); @@ -110,7 +94,6 @@ void CRMDBTest::testRegistrationName() // 2. register a newly created data source, and verify it has the proper name // Setup the CRMDatabase uno::Reference xConnection = setUpDBConnection(); - createTables(xConnection); uno::Reference xDocument(mxComponent, UNO_QUERY_THROW); uno::Reference xDataSource = xDocument->getDataSource(); @@ -142,7 +125,6 @@ void CRMDBTest::testQueryColumns() // Test prepared queries return the expected column names uno::Reference xConnection = setUpDBConnection(); - createTables(xConnection); uno::Reference xQuerySupplier(xConnection, UNO_QUERY_THROW); uno::Reference xQueryAccess = xQuerySupplier->getQueries(); @@ -175,7 +157,6 @@ void CRMDBTest::testQueryColumns() void CRMDBTest::testODBCEscapeQuery() { uno::Reference xConnection = setUpDBConnection(); - createTables(xConnection); uno::Reference xFactory(xConnection, UNO_QUERY); CPPUNIT_ASSERT(xFactory.is()); diff --git a/dbaccess/qa/unit/dbtest_base.cxx b/dbaccess/qa/unit/dbtest_base.cxx index bec6e6817ca1..dae7c3d5f74f 100644 --- a/dbaccess/qa/unit/dbtest_base.cxx +++ b/dbaccess/qa/unit/dbtest_base.cxx @@ -9,8 +9,6 @@ #include -#include - #include #include #include @@ -47,6 +45,8 @@ public: void createQuery(const OUString& sQuery, bool bEscapeProcessing, const OUString& sQueryName, const Reference & xDataSource); + uno::Reference setUpDBConnection(); + virtual void tearDown() override; }; @@ -182,6 +182,23 @@ void DBTestBase::createQuery(const OUString& sQuery, bool bEscapeProcessing, con xNameContainer->insertByName(sQueryName, Any(xQueryProp)); } +uno::Reference DBTestBase::setUpDBConnection() +{ + createDBDocument(u"sdbc:embedded:hsqldb"_ustr); + uno::Reference xDocument(mxComponent, UNO_QUERY_THROW); + uno::Reference xDataSource = xDocument->getDataSource(); + CPPUNIT_ASSERT(xDataSource.is()); + + // create queries before establishing connection to database + createQueries(xDataSource); + + uno::Reference xConnection = getConnectionForDocument(xDocument); + + createTables(xConnection); + + return xConnection; +} + void DBTestBase::tearDown() { if (mxComponent) diff --git a/dbaccess/qa/unit/rowset_test.cxx b/dbaccess/qa/unit/rowset_test.cxx new file mode 100644 index 000000000000..2f2dad4284f3 --- /dev/null +++ b/dbaccess/qa/unit/rowset_test.cxx @@ -0,0 +1,167 @@ +/* -*- 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +class RowSetTest : public DBTestBase +{ +}; + +CPPUNIT_TEST_FIXTURE(RowSetTest, testParameters) +{ + uno::Reference xConnection = setUpDBConnection(); + + Reference xStatement = xConnection->createStatement(); + CPPUNIT_ASSERT(xStatement.is()); + xStatement->execute(u"DROP TABLE \"TEST1\" IF EXISTS"_ustr); + xStatement->execute( + u"CREATE TABLE \"TEST1\" (\"ID\" INTEGER NOT NULL PRIMARY KEY, \"col2\" VARCHAR(50))"_ustr); + + xConnection->prepareStatement(u"INSERT INTO \"TEST1\" VALUES (?,?)"_ustr); + + Reference xPrepared + = xConnection->prepareStatement(u"INSERT INTO \"TEST1\" VALUES (?,?)"_ustr); + Reference xParams(xPrepared, UNO_QUERY); + constexpr int MAX_TABLE_ROWS = 100; + for (int i = 0; i < MAX_TABLE_ROWS; ++i) + { + xParams->setInt(1, i); + xParams->setString(2, u"Test"_ustr + OUString::number(i)); + xPrepared->executeUpdate(); + } + + uno::Reference xTablesSupplier(xConnection, UNO_QUERY_THROW); + uno::Reference xTablesRefresh(xTablesSupplier->getTables(), + UNO_QUERY_THROW); + xTablesRefresh->refresh(); + + uno::Reference xRowSet( + getMultiServiceFactory()->createInstance(u"com.sun.star.sdb.RowSet"_ustr), UNO_QUERY); + CPPUNIT_ASSERT(xRowSet.is()); + uno::Reference xRowSetProperties(xRowSet, UNO_QUERY); + CPPUNIT_ASSERT(xRowSetProperties.is()); + + // testTableParameters + // for a row set simply based on a table, there should be not parameters at all + xRowSetProperties->setPropertyValue(u"Command"_ustr, Any(u"PRODUCTS"_ustr)); + xRowSetProperties->setPropertyValue(u"CommandType"_ustr, Any(CommandType::TABLE)); + xRowSetProperties->setPropertyValue(u"ActiveConnection"_ustr, Any(xConnection)); + + uno::Reference xParametersSupplier(xRowSet, UNO_QUERY); + uno::Reference xIndex = xParametersSupplier->getParameters(); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndex->getCount()); + + // testParametrizedQuery + // for a row set based on a parametrized query, those parameters should be properly recognized + uno::Reference xDocument(mxComponent, UNO_QUERY_THROW); + createQuery(u"SELECT * FROM \"PRODUCTS\" WHERE \"NAME\" LIKE :product_name"_ustr, true, + u"products like"_ustr, xDocument->getDataSource()); + + xRowSetProperties->setPropertyValue(u"Command"_ustr, Any(u"products like"_ustr)); + xRowSetProperties->setPropertyValue(u"CommandType"_ustr, Any(CommandType::QUERY)); + xRowSetProperties->setPropertyValue(u"ActiveConnection"_ustr, Any(xConnection)); + + xIndex.set(xParametersSupplier->getParameters()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndex->getCount()); + uno::Reference xPropertySet(xIndex->getByIndex(0), UNO_QUERY_THROW); + + CPPUNIT_ASSERT_EQUAL(u"product_name"_ustr, + xPropertySet->getPropertyValue(u"Name"_ustr).get()); + + // testParametersInFilter + xRowSetProperties->setPropertyValue(u"Command"_ustr, Any(u"SELECT * FROM \"CUSTOMERS\""_ustr)); + xRowSetProperties->setPropertyValue(u"CommandType"_ustr, Any(CommandType::COMMAND)); + xRowSetProperties->setPropertyValue(u"ActiveConnection"_ustr, Any(xConnection)); + + xRowSetProperties->setPropertyValue(u"Filter"_ustr, Any(u"\"CITY\" = :city"_ustr)); + xRowSetProperties->setPropertyValue(u"ApplyFilter"_ustr, Any(true)); + + xIndex.set(xParametersSupplier->getParameters()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndex->getCount()); + xPropertySet.set(xIndex->getByIndex(0), UNO_QUERY_THROW); + + CPPUNIT_ASSERT_EQUAL(u"city"_ustr, + xPropertySet->getPropertyValue(u"Name"_ustr).get()); + + xRowSetProperties->setPropertyValue(u"ApplyFilter"_ustr, Any(false)); + + xIndex.set(xParametersSupplier->getParameters()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndex->getCount()); + + // testParametersAfterNormalExecute + xRowSetProperties->setPropertyValue(u"Command"_ustr, Any(u"SELECT * FROM \"CUSTOMERS\""_ustr)); + xRowSetProperties->setPropertyValue(u"CommandType"_ustr, Any(CommandType::COMMAND)); + xRowSetProperties->setPropertyValue(u"ActiveConnection"_ustr, Any(xConnection)); + + xRowSet->execute(); + + xIndex.set(xParametersSupplier->getParameters()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndex->getCount()); + + xRowSetProperties->setPropertyValue( + u"Command"_ustr, Any(u"SELECT * FROM \"CUSTOMERS\" WHERE \"CITY\" = :city"_ustr)); + xParams.set(xRowSet, UNO_QUERY); + xParams->setString(1, u"London"_ustr); + + xRowSet->execute(); + + xIndex.set(xParametersSupplier->getParameters()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndex->getCount()); + xPropertySet.set(xIndex->getByIndex(0), UNO_QUERY_THROW); + + CPPUNIT_ASSERT_EQUAL(u"city"_ustr, + xPropertySet->getPropertyValue(u"Name"_ustr).get()); + CPPUNIT_ASSERT_EQUAL(u"London"_ustr, + xPropertySet->getPropertyValue(u"Value"_ustr).get()); + + //testParametersInteraction + xRowSetProperties->setPropertyValue(u"Command"_ustr, Any(u"products like"_ustr)); + xRowSetProperties->setPropertyValue(u"CommandType"_ustr, Any(CommandType::QUERY)); + xRowSetProperties->setPropertyValue(u"ActiveConnection"_ustr, Any(xConnection)); + + // let's fill in a parameter value via XParameters, and see whether it is respected by the parameters container + xParams->setString(1, u"Apples"_ustr); + + xIndex.set(xParametersSupplier->getParameters()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndex->getCount()); + xPropertySet.set(xIndex->getByIndex(0), UNO_QUERY_THROW); + + CPPUNIT_ASSERT_EQUAL(u"product_name"_ustr, + xPropertySet->getPropertyValue(u"Name"_ustr).get()); + CPPUNIT_ASSERT_EQUAL(u"Apples"_ustr, + xPropertySet->getPropertyValue(u"Value"_ustr).get()); + + // let's fill in a parameter value via XParameters, and see whether it is respected by the parameters container + xParams->setString(1, u"Oranges"_ustr); + xRowSet->execute(); + + CPPUNIT_ASSERT_EQUAL(u"product_name"_ustr, + xPropertySet->getPropertyValue(u"Name"_ustr).get()); + CPPUNIT_ASSERT_EQUAL(u"Oranges"_ustr, + xPropertySet->getPropertyValue(u"Value"_ustr).get()); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */