diff options
Diffstat (limited to 'connectivity/qa/connectivity')
18 files changed, 2723 insertions, 0 deletions
diff --git a/connectivity/qa/connectivity/ado/DriverTest.cxx b/connectivity/qa/connectivity/ado/DriverTest.cxx new file mode 100644 index 000000000..abe4da67b --- /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(u"/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; + static const OUStringLiteral schemaPattern = u"%"; + static const OUStringLiteral tableNamePattern = u"%"; + 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() +{ + static const OUStringLiteral sql = u"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 Binary files differnew file mode 100644 index 000000000..abe9f5ee3 --- /dev/null +++ b/connectivity/qa/connectivity/ado/TS001018407.mdb 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/mysql/mysql.cxx b/connectivity/qa/connectivity/mysql/mysql.cxx new file mode 100644 index 000000000..4b1a9a4e4 --- /dev/null +++ b/connectivity/qa/connectivity/mysql/mysql.cxx @@ -0,0 +1,502 @@ +/* -*- 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 <comphelper/propertysequence.hxx> +#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 + sal_Int32 nPer = m_sUrl.indexOf("/"); + OUString sUsername = m_sUrl.copy(0, nPer); + m_sUrl = m_sUrl.copy(nPer + 1); + sal_Int32 nAt = m_sUrl.indexOf("@"); + OUString sPassword = m_sUrl.copy(0, nAt); + m_sUrl = m_sUrl.copy(nAt + 1); + + m_infos = comphelper::InitPropertySequence( + { { "user", makeAny(sUsername) }, { "password", makeAny(sPassword) } }); + + 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 (tools::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..9c8f4e439 --- /dev/null +++ b/connectivity/qa/connectivity/resource/sharedresources_test.cxx @@ -0,0 +1,106 @@ +/* -*- 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{ { "$sub0$", "vector0" }, + { "$sub1$", "vector1" }, + { "$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..d34b39066 --- /dev/null +++ b/connectivity/qa/connectivity/tools/AbstractDatabase.java @@ -0,0 +1,207 @@ +/* + * 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 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(); + } +} |