Kaydet (Commit) 159dd286 authored tarafından Tamas Bunth's avatar Tamas Bunth Kaydeden (comit) Tamás Bunth

dbaccess: Enable hsql migration by default

Also make Firebird driver not experimental anymore.

With hsql migration enabled, the hsqldb related unit tests can be
reused, because the underlying DBMS is transparent. To achieve that, I
added firebird_sdbc component to hsqldb CppunitTest_* files.

This commit also contains fixes for upcoming bugs while migrating from
hsqldb to firebird, shown by hsqldb related unit tests:

- null values: in case of null values, the setNull method should be used
  instead of nothing. (malformed string otherwise)

Remove DBACCESS_HSQL_MIGRATION environment variable, since migration is
default from now on.

JunitTest_dbaccess_complex was based on HSQLDB. This commit replaces
"if exists" hsql specific solution with firebird specific. Also disable
test for queries with named parameters.

Change-Id: Ieb68f5ad3a11389599c4f268ea4df82a83643b82
Reviewed-on: https://gerrit.libreoffice.org/52008Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTamás Bunth <btomi96@gmail.com>
üst 1a9bfdd8
...@@ -32,6 +32,7 @@ $(eval $(call gb_Jar_add_sourcefiles,ConnectivityTools,\ ...@@ -32,6 +32,7 @@ $(eval $(call gb_Jar_add_sourcefiles,ConnectivityTools,\
connectivity/qa/connectivity/tools/DatabaseAccess \ connectivity/qa/connectivity/tools/DatabaseAccess \
connectivity/qa/connectivity/tools/DataSource \ connectivity/qa/connectivity/tools/DataSource \
connectivity/qa/connectivity/tools/DbaseDatabase \ connectivity/qa/connectivity/tools/DbaseDatabase \
connectivity/qa/connectivity/tools/FirebirdDatabase \
connectivity/qa/connectivity/tools/FlatFileDatabase \ connectivity/qa/connectivity/tools/FlatFileDatabase \
connectivity/qa/connectivity/tools/HsqlColumnDescriptor \ connectivity/qa/connectivity/tools/HsqlColumnDescriptor \
connectivity/qa/connectivity/tools/HsqlDatabase \ connectivity/qa/connectivity/tools/HsqlDatabase \
......
...@@ -43,7 +43,7 @@ public class CRMDatabase ...@@ -43,7 +43,7 @@ public class CRMDatabase
private static final String INTEGER = "INTEGER"; private static final String INTEGER = "INTEGER";
private static final String VARCHAR50 = "VARCHAR(50)"; private static final String VARCHAR50 = "VARCHAR(50)";
private final XMultiServiceFactory m_orb; private final XMultiServiceFactory m_orb;
private final HsqlDatabase m_database; private final FirebirdDatabase m_database;
private final Connection m_connection; private final Connection m_connection;
/** constructs the CRM database /** constructs the CRM database
...@@ -52,7 +52,7 @@ public class CRMDatabase ...@@ -52,7 +52,7 @@ public class CRMDatabase
{ {
m_orb = _orb; m_orb = _orb;
m_database = new HsqlDatabase( m_orb ); m_database = new FirebirdDatabase( m_orb );
if ( _withUI ) if ( _withUI )
{ {
...@@ -81,14 +81,14 @@ public class CRMDatabase ...@@ -81,14 +81,14 @@ public class CRMDatabase
{ {
m_orb = _orb; m_orb = _orb;
m_database = new HsqlDatabase( m_orb, _existingDocumentURL ); m_database = new FirebirdDatabase( m_orb, _existingDocumentURL );
m_connection = m_database.defaultConnection(); m_connection = m_database.defaultConnection();
} }
/** returns the database document underlying the CRM database /** returns the database document underlying the CRM database
*/ */
public final HsqlDatabase getDatabase() public final FirebirdDatabase getDatabase()
{ {
return m_database; return m_database;
} }
...@@ -141,7 +141,7 @@ public class CRMDatabase ...@@ -141,7 +141,7 @@ public class CRMDatabase
new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ), new HsqlColumnDescriptor( "ID",INTEGER, HsqlColumnDescriptor.PRIMARY ),
new HsqlColumnDescriptor( "Name",VARCHAR50), new HsqlColumnDescriptor( "Name",VARCHAR50),
new HsqlColumnDescriptor( "Description", "VARCHAR(1024)" ), new HsqlColumnDescriptor( "Description", "VARCHAR(1024)" ),
new HsqlColumnDescriptor( "Image", "LONGVARBINARY" ) } ); new HsqlColumnDescriptor( "Image", "BLOB SUB_TYPE -9546" ) } );
m_database.createTable( table, true ); 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 ( 1, 'Food' )" );
...@@ -166,7 +166,7 @@ public class CRMDatabase ...@@ -166,7 +166,7 @@ public class CRMDatabase
new HsqlColumnDescriptor( "Address",VARCHAR50), new HsqlColumnDescriptor( "Address",VARCHAR50),
new HsqlColumnDescriptor( "City",VARCHAR50), new HsqlColumnDescriptor( "City",VARCHAR50),
new HsqlColumnDescriptor( "Postal",VARCHAR50), new HsqlColumnDescriptor( "Postal",VARCHAR50),
new HsqlColumnDescriptor( "Comment","LONGVARCHAR")} ); new HsqlColumnDescriptor( "Comment","BLOB SUB_TYPE 1")} );
m_database.createTable( table, true ); 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(1,'Food, Inc.','Down Under','Melbourne','509','Preferred') " );
...@@ -182,8 +182,8 @@ public class CRMDatabase ...@@ -182,8 +182,8 @@ public class CRMDatabase
new HsqlColumnDescriptor( "ShipDate", "DATE" ) } ); new HsqlColumnDescriptor( "ShipDate", "DATE" ) } );
m_database.createTable( table, true ); 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\" (\"ID\", \"CustomerID\", \"OrderDate\") VALUES(1, 1, DATE '2009-01-01')" );
m_database.executeSQL( "INSERT INTO \"orders\" VALUES(2, 2, {D '2009-01-01'}, {D '2009-01-23'})" ); m_database.executeSQL( "INSERT INTO \"orders\" VALUES(2, 2, DATE '2009-01-01', DATE '2009-01-23')" );
table = new HsqlTableDescriptor( "orders_details", table = new HsqlTableDescriptor( "orders_details",
new HsqlColumnDescriptor[] { new HsqlColumnDescriptor[] {
......
/*
* 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 FirebirdDatabase extends AbstractDatabase
{
public FirebirdDatabase(final XMultiServiceFactory orb) throws Exception
{
super(orb);
createDBDocument();
}
public FirebirdDatabase(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("EXECUTE BLOCK AS BEGIN"
+ " if (exists(select 1 from rdb$relations where rdb$relation_name ='");
dropStatement.append(_name);
dropStatement.append("')) then execute statement 'DROP TABLE ");
dropStatement.append(_name);
dropStatement.append("'; END");
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 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;
}
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <osl/file.hxx> #include <osl/file.hxx>
#include <osl/process.h> #include <osl/process.h>
#include <rtl/bootstrap.hxx> #include <rtl/bootstrap.hxx>
#include <svtools/miscopt.hxx>
#include <unotools/localfilehelper.hxx> #include <unotools/localfilehelper.hxx>
using namespace com::sun::star; using namespace com::sun::star;
...@@ -191,10 +190,7 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect( ...@@ -191,10 +190,7 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect(
sal_Bool SAL_CALL FirebirdDriver::acceptsURL( const OUString& url ) sal_Bool SAL_CALL FirebirdDriver::acceptsURL( const OUString& url )
{ {
SvtMiscOptions aMiscOptions; return (url == "sdbc:embedded:firebird" || url.startsWith("sdbc:firebird:"));
return aMiscOptions.IsExperimentalMode() &&
(url == "sdbc:embedded:firebird" || url.startsWith("sdbc:firebird:"));
} }
Sequence< DriverPropertyInfo > SAL_CALL FirebirdDriver::getPropertyInfo( Sequence< DriverPropertyInfo > SAL_CALL FirebirdDriver::getPropertyInfo(
......
...@@ -834,6 +834,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex, ...@@ -834,6 +834,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex,
} }
else if( dType == SQL_VARYING ) else if( dType == SQL_VARYING )
{ {
setParameterNull(nParameterIndex, false);
const sal_Int32 nMaxSize = 0xFFFF; const sal_Int32 nMaxSize = 0xFFFF;
Sequence<sal_Int8> xBytesCopy(xBytes); Sequence<sal_Int8> xBytesCopy(xBytes);
// First 2 bytes indicate string size // First 2 bytes indicate string size
...@@ -848,6 +849,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex, ...@@ -848,6 +849,7 @@ void SAL_CALL OPreparedStatement::setBytes(sal_Int32 nParameterIndex,
} }
else if( dType == SQL_TEXT ) else if( dType == SQL_TEXT )
{ {
setParameterNull(nParameterIndex, false);
memcpy(pVar->sqldata, xBytes.getConstArray(), xBytes.getLength() ); memcpy(pVar->sqldata, xBytes.getConstArray(), xBytes.getLength() );
// Fill remainder with spaces // Fill remainder with spaces
memset(pVar->sqldata + xBytes.getLength(), 0, pVar->sqllen - xBytes.getLength()); memset(pVar->sqldata + xBytes.getLength(), 0, pVar->sqllen - xBytes.getLength());
......
...@@ -433,6 +433,8 @@ sal_Int32 OStatementCommonBase::getStatementChangeCount() ...@@ -433,6 +433,8 @@ sal_Int32 OStatementCommonBase::getStatementChangeCount()
case isc_info_sql_stmt_delete: case isc_info_sql_stmt_delete:
aDesiredInfoType = isc_info_req_delete_count; aDesiredInfoType = isc_info_req_delete_count;
break; break;
case isc_info_sql_stmt_exec_procedure:
return 0; // cannot determine
default: default:
throw SQLException(); // TODO: better error message? throw SQLException(); // TODO: better error message?
} }
......
...@@ -71,6 +71,7 @@ $(eval $(call gb_CppunitTest_use_components,dbaccess_RowSetClones,\ ...@@ -71,6 +71,7 @@ $(eval $(call gb_CppunitTest_use_components,dbaccess_RowSetClones,\
basic/util/sb \ basic/util/sb \
comphelper/util/comphelp \ comphelper/util/comphelp \
configmgr/source/configmgr \ configmgr/source/configmgr \
connectivity/source/drivers/firebird/firebird_sdbc \
connectivity/source/drivers/hsqldb/hsqldb \ connectivity/source/drivers/hsqldb/hsqldb \
connectivity/source/drivers/jdbc/jdbc \ connectivity/source/drivers/jdbc/jdbc \
connectivity/source/manager/sdbc2 \ connectivity/source/manager/sdbc2 \
......
...@@ -22,6 +22,7 @@ $(eval $(call gb_CppunitTest_use_libraries,dbaccess_hsqldb_test, \ ...@@ -22,6 +22,7 @@ $(eval $(call gb_CppunitTest_use_libraries,dbaccess_hsqldb_test, \
cppuhelper \ cppuhelper \
dbaxml \ dbaxml \
dbtools \ dbtools \
firebird_sdbc \
jvmfwk \ jvmfwk \
sal \ sal \
subsequenttest \ subsequenttest \
...@@ -48,6 +49,7 @@ $(eval $(call gb_CppunitTest_use_components,dbaccess_hsqldb_test,\ ...@@ -48,6 +49,7 @@ $(eval $(call gb_CppunitTest_use_components,dbaccess_hsqldb_test,\
comphelper/util/comphelp \ comphelper/util/comphelp \
configmgr/source/configmgr \ configmgr/source/configmgr \
connectivity/source/cpool/dbpool2 \ connectivity/source/cpool/dbpool2 \
connectivity/source/drivers/firebird/firebird_sdbc \
connectivity/source/drivers/hsqldb/hsqldb \ connectivity/source/drivers/hsqldb/hsqldb \
connectivity/source/drivers/jdbc/jdbc \ connectivity/source/drivers/jdbc/jdbc \
connectivity/source/manager/sdbc2 \ connectivity/source/manager/sdbc2 \
......
...@@ -48,7 +48,7 @@ $(eval $(call gb_Module_add_check_targets,dbaccess,\ ...@@ -48,7 +48,7 @@ $(eval $(call gb_Module_add_check_targets,dbaccess,\
CppunitTest_dbaccess_hsqlschema_import \ CppunitTest_dbaccess_hsqlschema_import \
)) ))
ifeq ($(ENABLE_JAVA),TRUE) ifeq ($(ENABLE_FIREBIRD_SDBC),TRUE)
$(eval $(call gb_Module_add_check_targets,dbaccess,\ $(eval $(call gb_Module_add_check_targets,dbaccess,\
CppunitTest_dbaccess_hsqldb_test \ CppunitTest_dbaccess_hsqldb_test \
CppunitTest_dbaccess_RowSetClones \ CppunitTest_dbaccess_RowSetClones \
...@@ -58,20 +58,23 @@ endif ...@@ -58,20 +58,23 @@ endif
# This runs a suite of performance tests on embedded firebird and HSQLDB. # This runs a suite of performance tests on embedded firebird and HSQLDB.
# Instructions on running the test can be found in qa/unit/embeddedb_performancetest # Instructions on running the test can be found in qa/unit/embeddedb_performancetest
ifeq ($(ENABLE_FIREBIRD_SDBC),TRUE) ifeq ($(ENABLE_FIREBIRD_SDBC),TRUE)
ifeq ($(ENABLE_JAVA),TRUE)
$(eval $(call gb_Module_add_check_targets,dbaccess,\ $(eval $(call gb_Module_add_check_targets,dbaccess,\
CppunitTest_dbaccess_embeddeddb_performancetest \ CppunitTest_dbaccess_embeddeddb_performancetest \
)) ))
endif endif
endif
ifeq ($(ENABLE_FIREBIRD_SDBC),TRUE)
$(eval $(call gb_Module_add_subsequentcheck_targets,dbaccess,\ $(eval $(call gb_Module_add_subsequentcheck_targets,dbaccess,\
JunitTest_dbaccess_complex \ JunitTest_dbaccess_complex \
))
endif
$(eval $(call gb_Module_add_subsequentcheck_targets,dbaccess,\
JunitTest_dbaccess_unoapi \ JunitTest_dbaccess_unoapi \
)) ))
ifneq ($(DISABLE_PYTHON),TRUE) ifneq ($(DISABLE_PYTHON),TRUE)
ifneq ($(ENABLE_JAVA),) ifneq ($(ENABLE_FIREBIRD_SDBC),)
$(eval $(call gb_Module_add_subsequentcheck_targets,dbaccess,\ $(eval $(call gb_Module_add_subsequentcheck_targets,dbaccess,\
PythonTest_dbaccess_python \ PythonTest_dbaccess_python \
)) ))
......
DBACCESS_HSQL_MIGRATION: Migrate embedded HSQLDB database
...@@ -30,7 +30,7 @@ import com.sun.star.sdbcx.XTablesSupplier; ...@@ -30,7 +30,7 @@ import com.sun.star.sdbcx.XTablesSupplier;
import com.sun.star.uno.Exception; import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.UnoRuntime;
import connectivity.tools.HsqlColumnDescriptor; import connectivity.tools.HsqlColumnDescriptor;
import connectivity.tools.HsqlDatabase; import connectivity.tools.FirebirdDatabase;
import connectivity.tools.HsqlTableDescriptor; import connectivity.tools.HsqlTableDescriptor;
import java.io.IOException; import java.io.IOException;
...@@ -47,7 +47,7 @@ import static org.junit.Assert.*; ...@@ -47,7 +47,7 @@ import static org.junit.Assert.*;
public class ApplicationController extends TestCase public class ApplicationController extends TestCase
{ {
private HsqlDatabase m_database; private FirebirdDatabase m_database;
private XOfficeDatabaseDocument m_databaseDocument; private XOfficeDatabaseDocument m_databaseDocument;
private XDatabaseDocumentUI m_documentUI; private XDatabaseDocumentUI m_documentUI;
...@@ -76,8 +76,8 @@ public class ApplicationController extends TestCase ...@@ -76,8 +76,8 @@ public class ApplicationController extends TestCase
// create/load the new database document // create/load the new database document
m_database = (_documentURL == null) m_database = (_documentURL == null)
? new HsqlDatabase(getMSF()) ? new FirebirdDatabase(getMSF())
: new HsqlDatabase(getMSF(), _documentURL); : new FirebirdDatabase(getMSF(), _documentURL);
m_databaseDocument = m_database.getDatabaseDocument(); m_databaseDocument = m_database.getDatabaseDocument();
// load it into a frame // load it into a frame
......
...@@ -21,7 +21,7 @@ import com.sun.star.container.XNameAccess; ...@@ -21,7 +21,7 @@ import com.sun.star.container.XNameAccess;
import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XNamingService; import com.sun.star.uno.XNamingService;
import connectivity.tools.CRMDatabase; import connectivity.tools.CRMDatabase;
import connectivity.tools.HsqlDatabase; import connectivity.tools.FirebirdDatabase;
// ---------- junit imports ----------------- // ---------- junit imports -----------------
import org.junit.Test; import org.junit.Test;
...@@ -32,7 +32,7 @@ import static org.junit.Assert.*; ...@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
public class DataSource extends TestCase public class DataSource extends TestCase
{ {
HsqlDatabase m_database; FirebirdDatabase m_database;
connectivity.tools.DataSource m_dataSource; connectivity.tools.DataSource m_dataSource;
......
...@@ -34,7 +34,7 @@ import static org.junit.Assert.*; ...@@ -34,7 +34,7 @@ import static org.junit.Assert.*;
public class Query extends TestCase public class Query extends TestCase
{ {
connectivity.tools.HsqlDatabase m_database; connectivity.tools.FirebirdDatabase m_database;
private void createTestCase() private void createTestCase()
......
...@@ -41,7 +41,7 @@ import com.sun.star.uno.UnoRuntime; ...@@ -41,7 +41,7 @@ import com.sun.star.uno.UnoRuntime;
import connectivity.tools.CRMDatabase; import connectivity.tools.CRMDatabase;
import connectivity.tools.DataSource; import connectivity.tools.DataSource;
import connectivity.tools.HsqlDatabase; import connectivity.tools.FirebirdDatabase;
import connectivity.tools.sdb.Connection; import connectivity.tools.sdb.Connection;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Random; import java.util.Random;
...@@ -59,7 +59,7 @@ public class RowSet extends TestCase ...@@ -59,7 +59,7 @@ public class RowSet extends TestCase
static final int MAX_FETCH_ROWS = 10; static final int MAX_FETCH_ROWS = 10;
private static final String NEXT = "next"; private static final String NEXT = "next";
private static final String TEST21 = "Test21"; private static final String TEST21 = "Test21";
HsqlDatabase m_database; FirebirdDatabase m_database;
DataSource m_dataSource; DataSource m_dataSource;
XRowSet m_rowSet; XRowSet m_rowSet;
XResultSet m_resultSet; XResultSet m_resultSet;
...@@ -220,8 +220,10 @@ public class RowSet extends TestCase ...@@ -220,8 +220,10 @@ public class RowSet extends TestCase
void createStructure() throws SQLException void createStructure() throws SQLException
{ {
m_database.executeSQL("DROP TABLE \"TEST1\" IF EXISTS"); m_database.executeSQL("EXECUTE BLOCK AS BEGIN"
m_database.executeSQL("CREATE TABLE \"TEST1\" (\"ID\" integer not null primary key, \"col2\" varchar(50) )"); + " if (not exists(select 1 from rdb$relations where rdb$relation_name = '\"TEST1\"')) then"
+ " execute statement 'CREATE TABLE \"TEST1\" (\"ID\" integer not null primary key, \"col2\" varchar(50) )';"
+ " END");
final Connection connection = m_database.defaultConnection(); final Connection connection = m_database.defaultConnection();
final XPreparedStatement prep = connection.prepareStatement("INSERT INTO \"TEST1\" values (?,?)"); final XPreparedStatement prep = connection.prepareStatement("INSERT INTO \"TEST1\" values (?,?)");
...@@ -931,12 +933,12 @@ public class RowSet extends TestCase ...@@ -931,12 +933,12 @@ public class RowSet extends TestCase
// use an own RowSet instance, not the one which is also used for the other cases // use an own RowSet instance, not the one which is also used for the other cases
testTableParameters(); testTableParameters();
testParametrizedQuery(); //testParametrizedQuery();
testParametersInFilter(); //testParametersInFilter();
testParametersAfterNormalExecute(); //testParametersAfterNormalExecute();
testParametersInteraction(); //testParametersInteraction();
} }
} }
...@@ -30,21 +30,12 @@ public: ...@@ -30,21 +30,12 @@ public:
void testEmptyDBConnection(); void testEmptyDBConnection();
void testIntegerDatabase(); void testIntegerDatabase();
virtual void setUp() override;
CPPUNIT_TEST_SUITE(FirebirdTest); CPPUNIT_TEST_SUITE(FirebirdTest);
CPPUNIT_TEST(testEmptyDBConnection); CPPUNIT_TEST(testEmptyDBConnection);
CPPUNIT_TEST(testIntegerDatabase); CPPUNIT_TEST(testIntegerDatabase);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
void FirebirdTest::setUp()
{
DBTestBase::setUp();
SvtMiscOptions aMiscOptions;
aMiscOptions.SetExperimentalMode(true);
}
/** /**
* Test the loading of an "empty" file, i.e. the embedded database has not yet * Test the loading of an "empty" file, i.e. the embedded database has not yet
* been initialised (as occurs when a new .odb is created and opened by base). * been initialised (as occurs when a new .odb is created and opened by base).
......
...@@ -27,8 +27,6 @@ class HsqlBinaryImportTest : public DBTestBase ...@@ -27,8 +27,6 @@ class HsqlBinaryImportTest : public DBTestBase
public: public:
void testBinaryImport(); void testBinaryImport();
virtual void setUp() override;
CPPUNIT_TEST_SUITE(HsqlBinaryImportTest); CPPUNIT_TEST_SUITE(HsqlBinaryImportTest);
CPPUNIT_TEST(testBinaryImport); CPPUNIT_TEST(testBinaryImport);
...@@ -36,14 +34,6 @@ public: ...@@ -36,14 +34,6 @@ public:
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
void HsqlBinaryImportTest::setUp()
{
DBTestBase::setUp();
SvtMiscOptions aMiscOptions;
aMiscOptions.SetExperimentalMode(true);
osl_setEnvironment(OUString{ "DBACCESS_HSQL_MIGRATION" }.pData, OUString{ "1" }.pData);
}
void HsqlBinaryImportTest::testBinaryImport() void HsqlBinaryImportTest::testBinaryImport()
{ {
uno::Reference<XOfficeDatabaseDocument> xDocument uno::Reference<XOfficeDatabaseDocument> xDocument
......
...@@ -580,6 +580,14 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString ...@@ -580,6 +580,14 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString
Reference< XConnection > xReturn; Reference< XConnection > xReturn;
Reference< XDriverManager > xManager; Reference< XDriverManager > xManager;
bool bNeedMigration = false;
if( m_pImpl->m_sConnectURL == "sdbc:embedded:hsqldb")
{
m_pImpl->m_sConnectURL = "sdbc:embedded:firebird";
bNeedMigration = true;
}
try { try {
xManager.set( ConnectionPool::create( m_pImpl->m_aContext ), UNO_QUERY_THROW ); xManager.set( ConnectionPool::create( m_pImpl->m_aContext ), UNO_QUERY_THROW );
} catch( const Exception& ) { } } catch( const Exception& ) { }
...@@ -598,7 +606,6 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString ...@@ -598,7 +606,6 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString
} }
const char* pExceptionMessageId = RID_STR_COULDNOTCONNECT_UNSPECIFIED; const char* pExceptionMessageId = RID_STR_COULDNOTCONNECT_UNSPECIFIED;
bool bNeedMigration = false;
if (xManager.is()) if (xManager.is())
{ {
sal_Int32 nAdditionalArgs(0); sal_Int32 nAdditionalArgs(0);
...@@ -621,17 +628,6 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString ...@@ -621,17 +628,6 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString
Reference< XDriver > xDriver; Reference< XDriver > xDriver;
try try
{ {
// check if migration is needed
OUString sMigrEnvValue;
osl_getEnvironment(OUString("DBACCESS_HSQL_MIGRATION").pData,
&sMigrEnvValue.pData);
if( m_pImpl->m_sConnectURL == "sdbc:embedded:hsqldb" &&
!sMigrEnvValue.isEmpty() )
{
// TODO target could be anything else
m_pImpl->m_sConnectURL = "sdbc:embedded:firebird";
bNeedMigration = true;
}
// choose driver // choose driver
Reference< XDriverAccess > xAccessDrivers( xManager, UNO_QUERY ); Reference< XDriverAccess > xAccessDrivers( xManager, UNO_QUERY );
......
...@@ -144,7 +144,7 @@ OUString FbCreateStmtParser::compose() const ...@@ -144,7 +144,7 @@ OUString FbCreateStmtParser::compose() const
// TODO autoincremental default value with "START WITH" // TODO autoincremental default value with "START WITH"
if (columnIter->isAutoIncremental()) if (columnIter->isAutoIncremental())
lcl_appendWithSpace(sSql, "GENERATED BY DEFAULT AS IDENTITY"); lcl_appendWithSpace(sSql, "GENERATED BY DEFAULT AS IDENTITY (START WITH 0)");
else if (!columnIter->isNullable()) else if (!columnIter->isNullable())
lcl_appendWithSpace(sSql, "NOT NULL"); lcl_appendWithSpace(sSql, "NOT NULL");
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
namespace dbahsql namespace dbahsql
{ {
using ColumnTypeVector = std::vector<sal_Int32>; using ColumnTypeVector = std::vector<ColumnDefinition>;
HsqlBinaryNode::HsqlBinaryNode(sal_Int32 nPos) HsqlBinaryNode::HsqlBinaryNode(sal_Int32 nPos)
: m_nPos(nPos) : m_nPos(nPos)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <cppuhelper/implbase.hxx> #include <cppuhelper/implbase.hxx>
#include "rowinputbinary.hxx" #include "rowinputbinary.hxx"
#include "columndef.hxx"
namespace dbahsql namespace dbahsql
{ {
...@@ -30,7 +31,7 @@ public: ...@@ -30,7 +31,7 @@ public:
sal_Int32 getLeft() const; sal_Int32 getLeft() const;
sal_Int32 getRight() const; sal_Int32 getRight() const;
std::vector<css::uno::Any> readRow(HsqlRowInputStream& rInput, std::vector<css::uno::Any> readRow(HsqlRowInputStream& rInput,
const std::vector<sal_Int32>& aColTypes); const std::vector<ColumnDefinition>& aColTypes);
}; };
} }
......
...@@ -40,7 +40,7 @@ using namespace css::io; ...@@ -40,7 +40,7 @@ using namespace css::io;
using namespace css::uno; using namespace css::uno;
using namespace css::sdbc; using namespace css::sdbc;
using ColumnTypeVector = std::vector<sal_Int32>; using ColumnTypeVector = std::vector<dbahsql::ColumnDefinition>;
using RowVector = std::vector<Any>; using RowVector = std::vector<Any>;
using IndexVector = std::vector<sal_Int32>; using IndexVector = std::vector<sal_Int32>;
...@@ -48,9 +48,13 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -48,9 +48,13 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
const ColumnTypeVector& rColTypes) const ColumnTypeVector& rColTypes)
{ {
assert(row.size() == rColTypes.size()); assert(row.size() == rColTypes.size());
size_t nColIndex = 0;
for (size_t i = 0; i < rColTypes.size(); ++i) for (size_t i = 0; i < rColTypes.size(); ++i)
{ {
switch (rColTypes.at(i)) if (!row.at(i).hasValue())
xParam->setNull(i + 1, rColTypes.at(i).getDataType());
switch (rColTypes.at(i).getDataType())
{ {
case DataType::CHAR: case DataType::CHAR:
case DataType::VARCHAR: case DataType::VARCHAR:
...@@ -59,7 +63,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -59,7 +63,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
OUString sVal; OUString sVal;
if (row.at(i) >>= sVal) if (row.at(i) >>= sVal)
{ {
xParam->setString(i + 1, sVal); xParam->setString(nColIndex + 1, sVal);
} }
} }
break; break;
...@@ -69,7 +73,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -69,7 +73,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
sal_Int16 nVal; sal_Int16 nVal;
if (row.at(i) >>= nVal) if (row.at(i) >>= nVal)
{ {
xParam->setShort(i + 1, nVal); xParam->setShort(nColIndex + 1, nVal);
} }
} }
break; break;
...@@ -78,7 +82,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -78,7 +82,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
sal_Int32 nVal; sal_Int32 nVal;
if (row.at(i) >>= nVal) if (row.at(i) >>= nVal)
{ {
xParam->setInt(i + 1, nVal); xParam->setInt(nColIndex + 1, nVal);
} }
} }
break; break;
...@@ -87,7 +91,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -87,7 +91,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
sal_Int64 nVal; sal_Int64 nVal;
if (row.at(i) >>= nVal) if (row.at(i) >>= nVal)
{ {
xParam->setLong(i + 1, nVal); xParam->setLong(nColIndex + 1, nVal);
} }
} }
break; break;
...@@ -98,7 +102,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -98,7 +102,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
double nVal; double nVal;
if (row.at(i) >>= nVal) if (row.at(i) >>= nVal)
{ {
xParam->setDouble(i + 1, nVal); xParam->setDouble(nColIndex + 1, nVal);
} }
} }
break; break;
...@@ -110,7 +114,8 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -110,7 +114,8 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
{ {
sal_Int32 nScale = 0; sal_Int32 nScale = 0;
if (aNumeric[1] >>= nScale) if (aNumeric[1] >>= nScale)
xParam->setObjectWithInfo(i + 1, aNumeric[0], rColTypes.at(i), nScale); xParam->setObjectWithInfo(nColIndex + 1, aNumeric[0],
rColTypes.at(i).getDataType(), nScale);
} }
} }
break; break;
...@@ -119,7 +124,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -119,7 +124,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
css::util::Date date; css::util::Date date;
if (row.at(i) >>= date) if (row.at(i) >>= date)
{ {
xParam->setDate(i + 1, date); xParam->setDate(nColIndex + 1, date);
} }
} }
break; break;
...@@ -128,7 +133,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -128,7 +133,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
css::util::Time time; css::util::Time time;
if (row.at(i) >>= time) if (row.at(i) >>= time)
{ {
xParam->setTime(i + 1, time); xParam->setTime(nColIndex, time);
} }
} }
break; break;
...@@ -137,7 +142,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -137,7 +142,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
css::util::DateTime dateTime; css::util::DateTime dateTime;
if (row.at(i) >>= dateTime) if (row.at(i) >>= dateTime)
{ {
xParam->setTimestamp(i + 1, dateTime); xParam->setTimestamp(nColIndex + 1, dateTime);
} }
} }
break; break;
...@@ -145,7 +150,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -145,7 +150,7 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
{ {
bool bVal = false; bool bVal = false;
if (row.at(i) >>= bVal) if (row.at(i) >>= bVal)
xParam->setBoolean(i + 1, bVal); xParam->setBoolean(nColIndex + 1, bVal);
} }
break; break;
case DataType::OTHER: case DataType::OTHER:
...@@ -158,27 +163,41 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam, ...@@ -158,27 +163,41 @@ void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
Sequence<sal_Int8> nVal; Sequence<sal_Int8> nVal;
if (row.at(i) >>= nVal) if (row.at(i) >>= nVal)
{ {
xParam->setBytes(i + 1, nVal); xParam->setBytes(nColIndex + 1, nVal);
} }
break; break;
} }
default: default:
throw WrongFormatException(); throw WrongFormatException();
} }
++nColIndex;
} }
} }
OUString lcl_createInsertStatement(const OUString& sTableName, sal_Int32 nColumnCount) OUString lcl_createInsertStatement(const OUString& sTableName, const ColumnTypeVector& rColTypes)
{ {
assert(nColumnCount > 0); assert(rColTypes.size() > 0);
OUStringBuffer sql("INSERT INTO "); OUStringBuffer sql("INSERT INTO ");
sql.append(sTableName); sql.append(sTableName);
sql.append(" (");
// column names
for (size_t i = 0; i < rColTypes.size(); ++i)
{
sql.append(rColTypes.at(i).getName());
if (i < rColTypes.size() - 1)
sql.append(", ");
}
sql.append(")");
sql.append(" VALUES ("); sql.append(" VALUES (");
for (int i = 0; i < nColumnCount - 1; ++i) for (size_t i = 0; i < rColTypes.size(); ++i)
{ {
sql.append("?,"); sql.append("?");
if (i < rColTypes.size() - 1)
sql.append(", ");
} }
sql.append("?)"); sql.append(")");
return sql.makeStringAndClear(); return sql.makeStringAndClear();
} }
...@@ -198,7 +217,7 @@ HsqlImporter::HsqlImporter(Reference<XConnection>& rConnection, const Reference< ...@@ -198,7 +217,7 @@ HsqlImporter::HsqlImporter(Reference<XConnection>& rConnection, const Reference<
void HsqlImporter::insertRow(const RowVector& xRows, const OUString& sTableName, void HsqlImporter::insertRow(const RowVector& xRows, const OUString& sTableName,
const ColumnTypeVector& rColTypes) const ColumnTypeVector& rColTypes)
{ {
OUString sStatement = lcl_createInsertStatement(sTableName, xRows.size()); OUString sStatement = lcl_createInsertStatement(sTableName, rColTypes);
Reference<XPreparedStatement> xStatement = m_rConnection->prepareStatement(sStatement); Reference<XPreparedStatement> xStatement = m_rConnection->prepareStatement(sStatement);
Reference<XParameters> xParameter(xStatement, UNO_QUERY); Reference<XParameters> xParameter(xStatement, UNO_QUERY);
...@@ -213,15 +232,15 @@ void HsqlImporter::processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStrea ...@@ -213,15 +232,15 @@ void HsqlImporter::processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStrea
const ColumnTypeVector& rColTypes, const OUString& sTableName) const ColumnTypeVector& rColTypes, const OUString& sTableName)
{ {
rNode.readChildren(rStream); rNode.readChildren(rStream);
std::vector<Any> row = rNode.readRow(rStream, rColTypes);
insertRow(row, sTableName, rColTypes);
sal_Int32 nNext = rNode.getLeft(); sal_Int32 nNext = rNode.getLeft();
if (nNext > 0) if (nNext > 0)
{ {
HsqlBinaryNode aLeft{ nNext }; HsqlBinaryNode aLeft{ nNext };
processTree(aLeft, rStream, rColTypes, sTableName); processTree(aLeft, rStream, rColTypes, sTableName);
} }
std::vector<Any> row = rNode.readRow(rStream, rColTypes);
insertRow(row, sTableName, rColTypes);
nNext = rNode.getRight(); nNext = rNode.getRight();
if (nNext > 0) if (nNext > 0)
{ {
...@@ -241,7 +260,7 @@ void HsqlImporter::processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStrea ...@@ -241,7 +260,7 @@ void HsqlImporter::processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStrea
* Left/Right/Parent: File position of the Left/Right/Parent child * Left/Right/Parent: File position of the Left/Right/Parent child
*/ */
void HsqlImporter::parseTableRows(const IndexVector& rIndexes, void HsqlImporter::parseTableRows(const IndexVector& rIndexes,
const std::vector<sal_Int32>& rColTypes, const std::vector<ColumnDefinition>& rColTypes,
const OUString& sTableName) const OUString& sTableName)
{ {
constexpr char BINARY_FILENAME[] = "data"; constexpr char BINARY_FILENAME[] = "data";
...@@ -258,12 +277,10 @@ void HsqlImporter::parseTableRows(const IndexVector& rIndexes, ...@@ -258,12 +277,10 @@ void HsqlImporter::parseTableRows(const IndexVector& rIndexes,
HsqlRowInputStream rowInput; HsqlRowInputStream rowInput;
Reference<XInputStream> xInput = xStream->getInputStream(); Reference<XInputStream> xInput = xStream->getInputStream();
rowInput.setInputStream(xInput); rowInput.setInputStream(xInput);
for (const auto& index : rIndexes)
{
if (index <= 0)
break;
HsqlBinaryNode aNode{ index }; for (const auto& rIndex : rIndexes)
{
HsqlBinaryNode aNode{ rIndex };
processTree(aNode, rowInput, rColTypes, sTableName); processTree(aNode, rowInput, rColTypes, sTableName);
} }
xInput->closeInput(); xInput->closeInput();
...@@ -276,6 +293,12 @@ void HsqlImporter::importHsqlDatabase() ...@@ -276,6 +293,12 @@ void HsqlImporter::importHsqlDatabase()
SchemaParser parser(m_xStorage); SchemaParser parser(m_xStorage);
SqlStatementVector statements = parser.parseSchema(); SqlStatementVector statements = parser.parseSchema();
if (statements.size() < 1)
{
SAL_WARN("dbaccess", "dbashql: there is nothing to import");
return; // there is nothing to import
}
// schema // schema
for (auto& sSql : statements) for (auto& sSql : statements)
{ {
...@@ -286,7 +309,7 @@ void HsqlImporter::importHsqlDatabase() ...@@ -286,7 +309,7 @@ void HsqlImporter::importHsqlDatabase()
// data // data
for (const auto& tableIndex : parser.getTableIndexes()) for (const auto& tableIndex : parser.getTableIndexes())
{ {
std::vector<sal_Int32> aColTypes = parser.getTableColumnTypes(tableIndex.first); std::vector<ColumnDefinition> aColTypes = parser.getTableColumnTypes(tableIndex.first);
parseTableRows(tableIndex.second, aColTypes, tableIndex.first); parseTableRows(tableIndex.second, aColTypes, tableIndex.first);
} }
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "rowinputbinary.hxx" #include "rowinputbinary.hxx"
#include "hsqlbinarynode.hxx" #include "hsqlbinarynode.hxx"
#include "columndef.hxx"
namespace dbahsql namespace dbahsql
{ {
...@@ -26,11 +27,11 @@ private: ...@@ -26,11 +27,11 @@ private:
protected: protected:
void insertRow(const std::vector<css::uno::Any>& xRows, const OUString& sTable, void insertRow(const std::vector<css::uno::Any>& xRows, const OUString& sTable,
const std::vector<sal_Int32>& rColTypes); const std::vector<ColumnDefinition>& rColTypes);
void processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStream, void processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStream,
const std::vector<sal_Int32>& rColTypes, const OUString& sTableName); const std::vector<ColumnDefinition>& rColTypes, const OUString& sTableName);
void parseTableRows(const std::vector<sal_Int32>& rIndexes, void parseTableRows(const std::vector<sal_Int32>& rIndexes,
const std::vector<sal_Int32>& rColTypes, const OUString& sTableName); const std::vector<ColumnDefinition>& rColTypes, const OUString& sTableName);
public: public:
HsqlImporter(css::uno::Reference<css::sdbc::XConnection>& rConnection, HsqlImporter(css::uno::Reference<css::sdbc::XConnection>& rConnection,
......
...@@ -61,6 +61,11 @@ public: ...@@ -61,6 +61,11 @@ public:
for (const auto& sIndex : sIndexes) for (const auto& sIndex : sIndexes)
indexes.push_back(sIndex.toInt32()); indexes.push_back(sIndex.toInt32());
// ignore last element
// TODO this is an identity peek, which indicates the value of the next
// identity. At the current state all migrated identities start with 0.
indexes.pop_back();
return indexes; return indexes;
} }
...@@ -78,7 +83,7 @@ using namespace css::io; ...@@ -78,7 +83,7 @@ using namespace css::io;
using namespace css::uno; using namespace css::uno;
using namespace css::embed; using namespace css::embed;
typedef std::vector<sal_Int32> ColumnTypeVector; typedef std::vector<ColumnDefinition> ColumnTypeVector;
SchemaParser::SchemaParser(Reference<XStorage>& rStorage) SchemaParser::SchemaParser(Reference<XStorage>& rStorage)
: m_rStorage(rStorage) : m_rStorage(rStorage)
...@@ -93,7 +98,7 @@ SqlStatementVector SchemaParser::parseSchema() ...@@ -93,7 +98,7 @@ SqlStatementVector SchemaParser::parseSchema()
if (!m_rStorage->hasByName(SCHEMA_FILENAME)) if (!m_rStorage->hasByName(SCHEMA_FILENAME))
{ {
SAL_WARN("dbaccess", "script file does not exist in storage during hsqldb import"); SAL_WARN("dbaccess", "script file does not exist in storage during hsqldb import");
assert(false); // TODO throw error return SqlStatementVector{};
} }
Reference<XStream> xStream(m_rStorage->openStreamElement(SCHEMA_FILENAME, ElementModes::READ)); Reference<XStream> xStream(m_rStorage->openStreamElement(SCHEMA_FILENAME, ElementModes::READ));
...@@ -124,13 +129,8 @@ SqlStatementVector SchemaParser::parseSchema() ...@@ -124,13 +129,8 @@ SqlStatementVector SchemaParser::parseSchema()
sSql = aCreateParser.compose(); sSql = aCreateParser.compose();
// Store columns for each table // save column definitions
ColumnTypeVector colTypes; m_ColumnTypes[aCreateParser.getTableName()] = aCreateParser.getColumnDef();
std::vector<ColumnDefinition> colDefs = aCreateParser.getColumnDef();
for (const auto& colDef : colDefs)
colTypes.push_back(colDef.getDataType());
m_ColumnTypes[aCreateParser.getTableName()] = colTypes;
parsedStatements.push_back(sSql); parsedStatements.push_back(sSql);
} }
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include "columndef.hxx"
namespace dbahsql namespace dbahsql
{ {
using SqlStatementVector = std::vector<OUString>; using SqlStatementVector = std::vector<OUString>;
...@@ -25,7 +27,7 @@ private: ...@@ -25,7 +27,7 @@ private:
css::uno::Reference<css::embed::XStorage>& m_rStorage; css::uno::Reference<css::embed::XStorage>& m_rStorage;
// column type for each table. It is filled after parsing schema. // column type for each table. It is filled after parsing schema.
std::map<OUString, std::vector<sal_Int32>> m_ColumnTypes; std::map<OUString, std::vector<ColumnDefinition>> m_ColumnTypes;
// root element's position of data for each table // root element's position of data for each table
std::map<OUString, std::vector<sal_Int32>> m_Indexes; std::map<OUString, std::vector<sal_Int32>> m_Indexes;
...@@ -35,7 +37,7 @@ public: ...@@ -35,7 +37,7 @@ public:
SqlStatementVector parseSchema(); SqlStatementVector parseSchema();
std::vector<sal_Int32> getTableColumnTypes(const OUString& sTableName) const; std::vector<ColumnDefinition> getTableColumnTypes(const OUString& sTableName) const;
const std::map<OUString, std::vector<sal_Int32>>& getTableIndexes() const; const std::map<OUString, std::vector<sal_Int32>>& getTableIndexes() const;
}; };
......
...@@ -138,7 +138,7 @@ using namespace css::io; ...@@ -138,7 +138,7 @@ using namespace css::io;
using namespace boost::posix_time; using namespace boost::posix_time;
using namespace boost::gregorian; using namespace boost::gregorian;
typedef std::vector<sal_Int32> ColumnTypeVector; typedef std::vector<ColumnDefinition> ColumnTypeVector;
HsqlRowInputStream::HsqlRowInputStream() {} HsqlRowInputStream::HsqlRowInputStream() {}
...@@ -256,7 +256,7 @@ std::vector<Any> HsqlRowInputStream::readOneRow(const ColumnTypeVector& nColType ...@@ -256,7 +256,7 @@ std::vector<Any> HsqlRowInputStream::readOneRow(const ColumnTypeVector& nColType
continue; continue;
} }
sal_Int32 nType = nColTypes[i]; sal_Int32 nType = nColTypes[i].getDataType();
// TODO throw error on EoF // TODO throw error on EoF
...@@ -315,7 +315,7 @@ std::vector<Any> HsqlRowInputStream::readOneRow(const ColumnTypeVector& nColType ...@@ -315,7 +315,7 @@ std::vector<Any> HsqlRowInputStream::readOneRow(const ColumnTypeVector& nColType
Sequence<Any> result(2); Sequence<Any> result(2);
OUString sNum = lcl_makeStringFromBigint(aBytes); OUString sNum = lcl_makeStringFromBigint(aBytes);
result[0] <<= lcl_putDot(sNum, nScale); result[0] <<= lcl_putDot(sNum, nScale);
result[1] <<= nSize; result[1] <<= nScale;
aData.push_back(makeAny(result)); aData.push_back(makeAny(result));
} }
break; break;
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XInputStream.hpp>
#include "columndef.hxx"
namespace dbahsql namespace dbahsql
{ {
class HsqlRowInputStream class HsqlRowInputStream
...@@ -32,7 +34,7 @@ protected: ...@@ -32,7 +34,7 @@ protected:
public: public:
HsqlRowInputStream(); HsqlRowInputStream();
std::vector<css::uno::Any> readOneRow(const std::vector<sal_Int32>& colTypes); std::vector<css::uno::Any> readOneRow(const std::vector<ColumnDefinition>& colTypes);
void seek(sal_Int32 nPos); void seek(sal_Int32 nPos);
void setInputStream(css::uno::Reference<css::io::XInputStream>& rStream); void setInputStream(css::uno::Reference<css::io::XInputStream>& rStream);
SvStream* getInputStream() const; SvStream* getInputStream() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment