summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbaccess/Library_dbahsql.mk5
-rw-r--r--dbaccess/source/filter/hsqldb/columndef.hxx10
-rw-r--r--dbaccess/source/filter/hsqldb/createparser.hxx10
-rw-r--r--dbaccess/source/filter/hsqldb/fbcreateparser.hxx10
-rw-r--r--dbaccess/source/filter/hsqldb/hsqlbinarynode.cxx61
-rw-r--r--dbaccess/source/filter/hsqldb/hsqlbinarynode.hxx39
-rw-r--r--dbaccess/source/filter/hsqldb/hsqlimport.cxx241
-rw-r--r--dbaccess/source/filter/hsqldb/hsqlimport.hxx20
-rw-r--r--dbaccess/source/filter/hsqldb/parseschema.cxx26
-rw-r--r--dbaccess/source/filter/hsqldb/parseschema.hxx17
-rw-r--r--dbaccess/source/filter/hsqldb/rowinputbinary.cxx246
-rw-r--r--dbaccess/source/filter/hsqldb/rowinputbinary.hxx46
12 files changed, 670 insertions, 61 deletions
diff --git a/dbaccess/Library_dbahsql.mk b/dbaccess/Library_dbahsql.mk
index f85660e6b3a8..bbcdea138a3e 100644
--- a/dbaccess/Library_dbahsql.mk
+++ b/dbaccess/Library_dbahsql.mk
@@ -27,6 +27,9 @@ $(eval $(call gb_Library_use_libraries,dbahsql,\
sal \
salhelper \
dbtools \
+ ucbhelper \
+ utl \
+ tl \
))
$(eval $(call gb_Library_add_exception_objects,dbahsql,\
@@ -35,6 +38,8 @@ $(eval $(call gb_Library_add_exception_objects,dbahsql,\
dbaccess/source/filter/hsqldb/createparser \
dbaccess/source/filter/hsqldb/columndef \
dbaccess/source/filter/hsqldb/fbcreateparser \
+ dbaccess/source/filter/hsqldb/rowinputbinary \
+ dbaccess/source/filter/hsqldb/hsqlbinarynode \
))
# vim: set noet sw=4 ts=4:
diff --git a/dbaccess/source/filter/hsqldb/columndef.hxx b/dbaccess/source/filter/hsqldb/columndef.hxx
index 4c46ac10a5ce..bded07bf5b4c 100644
--- a/dbaccess/source/filter/hsqldb/columndef.hxx
+++ b/dbaccess/source/filter/hsqldb/columndef.hxx
@@ -5,16 +5,6 @@
* 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 .
*/
#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_COLUMNDEF_HXX
diff --git a/dbaccess/source/filter/hsqldb/createparser.hxx b/dbaccess/source/filter/hsqldb/createparser.hxx
index 4bc4bd2343b6..03532a1d197f 100644
--- a/dbaccess/source/filter/hsqldb/createparser.hxx
+++ b/dbaccess/source/filter/hsqldb/createparser.hxx
@@ -5,16 +5,6 @@
* 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 .
*/
#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_CREATEPARSER_HXX
diff --git a/dbaccess/source/filter/hsqldb/fbcreateparser.hxx b/dbaccess/source/filter/hsqldb/fbcreateparser.hxx
index 02255089c1ca..fec8c6f9c34b 100644
--- a/dbaccess/source/filter/hsqldb/fbcreateparser.hxx
+++ b/dbaccess/source/filter/hsqldb/fbcreateparser.hxx
@@ -5,16 +5,6 @@
* 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 .
*/
#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_FBCREATEPARSER_HXX
diff --git a/dbaccess/source/filter/hsqldb/hsqlbinarynode.cxx b/dbaccess/source/filter/hsqldb/hsqlbinarynode.cxx
new file mode 100644
index 000000000000..8a8cf1a9a20b
--- /dev/null
+++ b/dbaccess/source/filter/hsqldb/hsqlbinarynode.cxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * 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 "hsqlbinarynode.hxx"
+#include "rowinputbinary.hxx"
+
+#include <cppuhelper/implbase.hxx>
+#include <vector>
+
+namespace dbahsql
+{
+using ColumnTypeVector = std::vector<sal_Int32>;
+
+HsqlBinaryNode::HsqlBinaryNode(sal_Int32 nPos)
+ : m_nPos(nPos)
+{
+}
+
+void HsqlBinaryNode::readChildren(HsqlRowInputStream& input)
+{
+ SvStream* pStream = input.getInputStream();
+ if (!pStream)
+ return;
+
+ pStream->Seek(m_nPos + 8); // skip size and balance
+ pStream->ReadInt32(m_nLeft);
+ if (m_nLeft <= 0)
+ m_nLeft = -1;
+ pStream->ReadInt32(m_nRight);
+ if (m_nRight <= 0)
+ m_nRight = -1;
+}
+
+std::vector<css::uno::Any> HsqlBinaryNode::readRow(HsqlRowInputStream& input,
+ const ColumnTypeVector& aColTypes)
+{
+ input.seek(m_nPos + 20); // go to data
+ return input.readOneRow(aColTypes);
+}
+
+sal_Int32 HsqlBinaryNode::getLeft() const { return m_nLeft; }
+sal_Int32 HsqlBinaryNode::getRight() const { return m_nRight; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/filter/hsqldb/hsqlbinarynode.hxx b/dbaccess/source/filter/hsqldb/hsqlbinarynode.hxx
new file mode 100644
index 000000000000..7c3631a6c8b2
--- /dev/null
+++ b/dbaccess/source/filter/hsqldb/hsqlbinarynode.hxx
@@ -0,0 +1,39 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_HSQLBINARYNODE_HXX
+#define INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_HSQLBINARYNODE_HXX
+
+#include <vector>
+#include <cppuhelper/implbase.hxx>
+
+#include "rowinputbinary.hxx"
+
+namespace dbahsql
+{
+class HsqlBinaryNode
+{
+private:
+ sal_Int32 m_nLeft = -1;
+ sal_Int32 m_nRight = -1;
+ sal_Int32 m_nPos = -1;
+
+public:
+ HsqlBinaryNode(sal_Int32 nPos);
+ void readChildren(HsqlRowInputStream& input);
+ sal_Int32 getLeft() const;
+ sal_Int32 getRight() const;
+ std::vector<css::uno::Any> readRow(HsqlRowInputStream& rInput,
+ const std::vector<sal_Int32>& aColTypes);
+};
+}
+
+#endif // INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_HSQLBINARYNODE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/filter/hsqldb/hsqlimport.cxx b/dbaccess/source/filter/hsqldb/hsqlimport.cxx
index be0e1df4a538..c2483e694a8d 100644
--- a/dbaccess/source/filter/hsqldb/hsqlimport.cxx
+++ b/dbaccess/source/filter/hsqldb/hsqlimport.cxx
@@ -18,15 +18,156 @@
*/
#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/WrongFormatException.hpp>
+
#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XParameters.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+
+#include <comphelper/string.hxx>
#include "hsqlimport.hxx"
#include "parseschema.hxx"
+#include "rowinputbinary.hxx"
-namespace dbahsql
+namespace
{
+using namespace ::comphelper;
+using namespace css::io;
using namespace css::uno;
using namespace css::sdbc;
+
+using ColumnTypeVector = std::vector<sal_Int32>;
+using RowVector = std::vector<Any>;
+using IndexVector = std::vector<sal_Int32>;
+
+class IndexStmtParser
+{
+private:
+ OUString m_sql;
+
+public:
+ IndexStmtParser(const OUString& sSql)
+ : m_sql(sSql)
+ {
+ }
+
+ bool isIndexStatement() const
+ {
+ return m_sql.startsWith("SET TABLE") && m_sql.indexOf("INDEX") >= 0;
+ }
+
+ IndexVector getIndexes() const
+ {
+ assert(isIndexStatement());
+
+ OUString sIndexPart = m_sql.copy(m_sql.indexOf("INDEX") + 5);
+ sal_Int32 nQuotePos = sIndexPart.indexOf("'") + 1;
+ OUString sIndexNums = sIndexPart.copy(nQuotePos, sIndexPart.lastIndexOf("'") - nQuotePos);
+
+ std::vector<OUString> sIndexes = string::split(sIndexNums, u' ');
+ IndexVector indexes;
+ for (const auto& sIndex : sIndexes)
+ indexes.push_back(sIndex.toInt32());
+
+ return indexes;
+ }
+
+ OUString getTableName() const
+ {
+ // SET TABLE <tableName>
+ return string::split(m_sql, u' ')[2];
+ }
+};
+
+void lcl_setParams(const RowVector& row, Reference<XParameters>& xParam,
+ const ColumnTypeVector& rColTypes)
+{
+ assert(row.size() == rColTypes.size());
+ for (size_t i = 0; i < rColTypes.size(); ++i)
+ {
+ switch (rColTypes.at(i))
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ {
+ OUString sVal;
+ if (row.at(i) >>= sVal)
+ {
+ xParam->setString(i + 1, sVal);
+ }
+ }
+ break;
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ {
+ sal_Int16 nVal;
+ if (row.at(i) >>= nVal)
+ {
+ xParam->setShort(i + 1, nVal);
+ }
+ }
+ break;
+ case DataType::INTEGER:
+ {
+ sal_Int32 nVal;
+ if (row.at(i) >>= nVal)
+ {
+ xParam->setInt(i + 1, nVal);
+ }
+ }
+ break;
+ case DataType::BIGINT:
+ break;
+ case DataType::REAL:
+ case DataType::FLOAT:
+ case DataType::DOUBLE:
+ break;
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ break;
+ case DataType::DATE:
+ break;
+ case DataType::TIME:
+ break;
+ case DataType::TIMESTAMP:
+ break;
+ case DataType::BOOLEAN:
+ break;
+ case DataType::OTHER:
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ break;
+ default:
+ throw WrongFormatException();
+ }
+ }
+}
+
+OUString lcl_createInsertStatement(const OUString& sTableName, sal_Int32 nColumnCount)
+{
+ assert(nColumnCount > 0);
+ OUStringBuffer sql("INSERT INTO ");
+ sql.append(sTableName);
+ sql.append(" VALUES (");
+ for (int i = 0; i < nColumnCount - 1; ++i)
+ {
+ sql.append("?,");
+ }
+ sql.append("?)");
+ return sql.makeStringAndClear();
+}
+
+} // unnamed namespace
+
+namespace dbahsql
+{
using namespace css::embed;
HsqlImporter::HsqlImporter(Reference<XConnection>& rConnection, const Reference<XStorage>& rStorage)
@@ -36,7 +177,81 @@ HsqlImporter::HsqlImporter(Reference<XConnection>& rConnection, const Reference<
m_xStorage.set(rStorage);
}
-void HsqlImporter::importSchema()
+void HsqlImporter::insertRow(const RowVector& xRows, const OUString& sTableName,
+ const ColumnTypeVector& rColTypes)
+{
+ OUString sStatement = lcl_createInsertStatement(sTableName, xRows.size());
+ Reference<XPreparedStatement> xStatement = m_rConnection->prepareStatement(sStatement);
+
+ Reference<XParameters> xParameter(xStatement, UNO_QUERY);
+ assert(xParameter.is());
+ xParameter->clearParameters();
+
+ lcl_setParams(xRows, xParameter, rColTypes);
+ xStatement->executeQuery();
+}
+
+void HsqlImporter::processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStream,
+ const ColumnTypeVector& rColTypes, const OUString& sTableName)
+{
+ rNode.readChildren(rStream);
+ std::vector<Any> row = rNode.readRow(rStream, rColTypes);
+ insertRow(row, sTableName, rColTypes);
+
+ sal_Int32 nNext = rNode.getLeft();
+ if (nNext > 0)
+ {
+ HsqlBinaryNode aLeft{ nNext };
+ processTree(aLeft, rStream, rColTypes, sTableName);
+ }
+ nNext = rNode.getRight();
+ if (nNext > 0)
+ {
+ HsqlBinaryNode aRight{ nNext };
+ processTree(aRight, rStream, rColTypes, sTableName);
+ }
+}
+
+/**
+ * Format from the indexed file position is the following:
+ * <Node x20><Row>
+ * Where Node is a 20 byte data, representing the rows in a binary tree:
+ * <Size x4><Balance x4><Left x4> <Right x4><Parent x4>
+ *
+ * Size is the size of <Row>;
+ * Balance: ?
+ * Left/Right/Parent: File postition of the Left/Right/Parent child
+ */
+void HsqlImporter::parseTableRows(const IndexVector& rIndexes,
+ const std::vector<sal_Int32>& rColTypes,
+ const OUString& sTableName)
+{
+ constexpr char BINARY_FILENAME[] = "data";
+
+ if (!m_xStorage->hasByName(BINARY_FILENAME))
+ {
+ SAL_WARN("dbaccess", "data file does not exist in storage during hsqldb import");
+ assert(false); // TODO throw error
+ }
+
+ Reference<css::io::XStream> xStream(
+ m_xStorage->openStreamElement(BINARY_FILENAME, ElementModes::READ));
+
+ HsqlRowInputStream rowInput;
+ Reference<XInputStream> xInput = xStream->getInputStream();
+ rowInput.setInputStream(xInput);
+ for (const auto& index : rIndexes)
+ {
+ if (index <= 0)
+ break;
+
+ HsqlBinaryNode aNode{ index };
+ processTree(aNode, rowInput, rColTypes, sTableName);
+ }
+ xInput->closeInput();
+}
+
+void HsqlImporter::importHsqlDatabase()
{
assert(m_xStorage);
@@ -45,12 +260,26 @@ void HsqlImporter::importSchema()
for (auto& sSql : statements)
{
- Reference<XStatement> statement = m_rConnection->createStatement();
- statement->executeQuery(sSql);
+ // SET TABLE ... INDEX ...
+ // These statements tell us the position of the data in the binary data
+ // file
+ IndexStmtParser aIndexParser(sSql);
+ if (aIndexParser.isIndexStatement())
+ {
+ IndexVector aIndexes = aIndexParser.getIndexes();
+ OUString sTableName = aIndexParser.getTableName();
+ std::vector<sal_Int32> aColTypes = parser.getTableColumnTypes(sTableName);
+
+ parseTableRows(aIndexes, aColTypes, sTableName);
+ }
+ else
+ {
+ // other, "normal" statements
+ Reference<XStatement> statement = m_rConnection->createStatement();
+ statement->executeQuery(sSql);
+ }
}
}
-
-void HsqlImporter::importHsqlDatabase() { importSchema(); }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/filter/hsqldb/hsqlimport.hxx b/dbaccess/source/filter/hsqldb/hsqlimport.hxx
index d4887633e184..b40f73079a7e 100644
--- a/dbaccess/source/filter/hsqldb/hsqlimport.hxx
+++ b/dbaccess/source/filter/hsqldb/hsqlimport.hxx
@@ -5,16 +5,6 @@
* 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 .
*/
#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_HSQLIMPORT_HXX
@@ -23,6 +13,9 @@
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
+#include "rowinputbinary.hxx"
+#include "hsqlbinarynode.hxx"
+
namespace dbahsql
{
class SAL_DLLPUBLIC_EXPORT HsqlImporter
@@ -32,7 +25,12 @@ private:
css::uno::Reference<css::embed::XStorage> m_xStorage;
protected:
- void importSchema();
+ void insertRow(const std::vector<css::uno::Any>& xRows, const OUString& sTable,
+ const std::vector<sal_Int32>& rColTypes);
+ void processTree(HsqlBinaryNode& rNode, HsqlRowInputStream& rStream,
+ const std::vector<sal_Int32>& rColTypes, const OUString& sTableName);
+ void parseTableRows(const std::vector<sal_Int32>& rIndexes,
+ const std::vector<sal_Int32>& rColTypes, const OUString& sTableName);
public:
HsqlImporter(css::uno::Reference<css::sdbc::XConnection>& rConnection,
diff --git a/dbaccess/source/filter/hsqldb/parseschema.cxx b/dbaccess/source/filter/hsqldb/parseschema.cxx
index a899fbba913e..5ee2b4d1e2c6 100644
--- a/dbaccess/source/filter/hsqldb/parseschema.cxx
+++ b/dbaccess/source/filter/hsqldb/parseschema.cxx
@@ -31,6 +31,8 @@ using namespace css::io;
using namespace css::uno;
using namespace css::embed;
+typedef std::vector<sal_Int32> ColumnTypeVector;
+
SchemaParser::SchemaParser(Reference<XStorage>& rStorage)
: m_rStorage(rStorage)
{
@@ -60,16 +62,26 @@ SqlStatementVector SchemaParser::parseSchema()
// every line contains exactly one DDL statement
OUString sSql = xTextInput->readLine();
- if (sSql.startsWith("SET") || sSql.startsWith("CREATE USER")
- || sSql.startsWith("CREATE SCHEMA") || sSql.startsWith("GRANT"))
+ if (sSql.startsWith("SET TABLE") && sSql.indexOf("INDEX") > 0)
+ { // nothing
+ }
+ else if (sSql.startsWith("SET") || sSql.startsWith("CREATE USER")
+ || sSql.startsWith("CREATE SCHEMA") || sSql.startsWith("GRANT"))
continue;
-
- if (sSql.startsWith("CREATE CACHED TABLE") || sSql.startsWith("CREATE TABLE"))
+ else if (sSql.startsWith("CREATE CACHED TABLE") || sSql.startsWith("CREATE TABLE"))
{
FbCreateStmtParser aCreateParser;
aCreateParser.parse(sSql);
sSql = aCreateParser.compose();
+
+ // Store columns for each table
+ ColumnTypeVector colTypes;
+ 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);
@@ -77,6 +89,12 @@ SqlStatementVector SchemaParser::parseSchema()
return parsedStatements;
}
+
+ColumnTypeVector SchemaParser::getTableColumnTypes(const OUString& sTableName) const
+{
+ return m_ColumnTypes.at(sTableName);
}
+} // namespace dbahsql
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/filter/hsqldb/parseschema.hxx b/dbaccess/source/filter/hsqldb/parseschema.hxx
index 6767ce08414a..af97ae578241 100644
--- a/dbaccess/source/filter/hsqldb/parseschema.hxx
+++ b/dbaccess/source/filter/hsqldb/parseschema.hxx
@@ -5,16 +5,6 @@
* 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 .
*/
#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_PARSECHEMA_HXX
@@ -23,6 +13,7 @@
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <vector>
+#include <map>
namespace dbahsql
{
@@ -33,9 +24,15 @@ class SchemaParser
private:
css::uno::Reference<css::embed::XStorage>& m_rStorage;
+ // column type for each table. It is filled after parsing schema.
+ std::map<OUString, std::vector<sal_Int32>> m_ColumnTypes;
+
public:
explicit SchemaParser(css::uno::Reference<css::embed::XStorage>& rStorage);
+
SqlStatementVector parseSchema();
+
+ std::vector<sal_Int32> getTableColumnTypes(const OUString& sTableName) const;
};
}
diff --git a/dbaccess/source/filter/hsqldb/rowinputbinary.cxx b/dbaccess/source/filter/hsqldb/rowinputbinary.cxx
new file mode 100644
index 000000000000..37cfa918fef5
--- /dev/null
+++ b/dbaccess/source/filter/hsqldb/rowinputbinary.cxx
@@ -0,0 +1,246 @@
+/* -*- 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 "rowinputbinary.hxx"
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/io/XConnectable.hpp>
+
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/stream.hxx>
+
+namespace dbahsql
+{
+using namespace css::uno;
+using namespace css::sdbc;
+using namespace css::io;
+
+typedef std::vector<sal_Int32> ColumnTypeVector;
+
+HsqlRowInputStream::HsqlRowInputStream() {}
+
+void HsqlRowInputStream::setInputStream(Reference<XInputStream>& rStream)
+{
+ m_pStream.reset(utl::UcbStreamHelper::CreateStream(rStream, true));
+ m_pStream->SetEndian(SvStreamEndian::BIG);
+}
+
+SvStream* HsqlRowInputStream::getInputStream() const { return m_pStream.get(); }
+
+void HsqlRowInputStream::seek(sal_Int32 nPos) { m_pStream->Seek(nPos); }
+
+OUString HsqlRowInputStream::readString()
+{
+ sal_Int32 nLen = 0;
+ m_pStream->ReadInt32(nLen);
+ return readUTF(nLen);
+}
+
+OUString HsqlRowInputStream::readUTF(sal_Int32 nUTFLen)
+{
+ Sequence<sal_Unicode> aBuffer(nUTFLen);
+ sal_Unicode* pStr = aBuffer.getArray();
+
+ sal_Int32 nCount = 0;
+ sal_Int32 nStrLen = 0;
+ while (nCount < nUTFLen)
+ {
+ unsigned char cIn = 0;
+ m_pStream->ReadUChar(cIn);
+ sal_uInt8 c = reinterpret_cast<sal_uInt8&>(cIn);
+ sal_uInt8 char2, char3;
+ switch (c >> 4)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 0xxxxxxx
+ nCount++;
+ pStr[nStrLen++] = c;
+ break;
+
+ case 12:
+ case 13:
+ // 110x xxxx 10xx xxxx
+ nCount += 2;
+ if (nCount > nUTFLen)
+ {
+ throw WrongFormatException();
+ }
+
+ m_pStream->ReadUChar(cIn);
+ char2 = reinterpret_cast<sal_uInt8&>(cIn);
+ if ((char2 & 0xC0) != 0x80)
+ {
+ throw WrongFormatException();
+ }
+
+ pStr[nStrLen++] = (sal_Unicode(c & 0x1F) << 6) | (char2 & 0x3F);
+ break;
+
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ nCount += 3;
+ if (nCount > nUTFLen)
+ {
+ throw WrongFormatException();
+ }
+
+ m_pStream->ReadUChar(cIn);
+ char2 = reinterpret_cast<sal_uInt8&>(cIn);
+ m_pStream->ReadUChar(cIn);
+ char3 = reinterpret_cast<sal_uInt8&>(cIn);
+
+ if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
+ {
+ throw WrongFormatException();
+ }
+ pStr[nStrLen++] = (sal_Unicode(c & 0x0F) << 12) | (sal_Unicode(char2 & 0x3F) << 6)
+ | (char3 & 0x3F);
+ break;
+
+ default:
+ // 10xx xxxx, 1111 xxxx
+ throw WrongFormatException();
+ }
+ }
+ return OUString(pStr, nStrLen);
+}
+
+bool HsqlRowInputStream::checkNull()
+{
+ unsigned char cIn = 0;
+ m_pStream->ReadUChar(cIn);
+ sal_uInt8 nNull = reinterpret_cast<sal_uInt8&>(cIn);
+ return nNull == 0;
+}
+
+std::vector<Any> HsqlRowInputStream::readOneRow(const ColumnTypeVector& nColTypes)
+{
+ auto nLen = nColTypes.size();
+ std::vector<Any> aData;
+
+ for (size_t i = 0; i < nLen; ++i)
+ {
+ if (checkNull())
+ {
+ aData.push_back(Any());
+ continue;
+ }
+
+ sal_Int32 nType = nColTypes[i];
+
+ // TODO throw error on EoF
+
+ switch (nType)
+ {
+ case DataType::CHAR:
+ case DataType::VARCHAR:
+ case DataType::LONGVARCHAR:
+ aData.push_back(makeAny(readString()));
+ break;
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ {
+ sal_Int16 value = 0;
+ m_pStream->ReadInt16(value);
+ aData.push_back(makeAny(value));
+ }
+ break;
+ case DataType::INTEGER:
+ {
+ sal_Int32 value = 0;
+ m_pStream->ReadInt32(value);
+ aData.push_back(makeAny(value));
+ }
+ break;
+ case DataType::BIGINT:
+ {
+ sal_Int64 value = 0;
+ m_pStream->ReadInt64(value);
+ aData.push_back(makeAny(value));
+ }
+ break;
+ case DataType::REAL:
+ case DataType::FLOAT:
+ case DataType::DOUBLE:
+ {
+ double value = 0;
+ m_pStream->ReadDouble(value);
+ // FIXME double is not necessarily 4 bytes
+ aData.push_back(makeAny(value));
+ }
+ break;
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ {
+ sal_Int32 nSize = 0;
+ m_pStream->ReadInt32(nSize);
+
+ std::vector<sal_uInt8> aBytes(nSize);
+ m_pStream->ReadBytes(aBytes.data(), nSize);
+
+ // TODO make a numeric out of this.
+ }
+ break;
+ case DataType::DATE:
+ break;
+ case DataType::TIME:
+ break;
+ case DataType::TIMESTAMP:
+ break;
+ case DataType::BOOLEAN:
+ {
+ sal_uInt8 nBool = 0;
+ m_pStream->ReadUChar(nBool);
+ aData.push_back(makeAny(static_cast<bool>(nBool)));
+ }
+ break;
+ case DataType::OTHER:
+ // TODO
+ break;
+ case DataType::BINARY:
+ case DataType::VARBINARY:
+ case DataType::LONGVARBINARY:
+ {
+ sal_Int32 nSize = 0;
+ m_pStream->ReadInt32(nSize);
+
+ Sequence<sal_uInt8> aBytes(nSize);
+ m_pStream->ReadBytes(aBytes.getArray(), nSize);
+ aData.push_back(makeAny(aBytes));
+ }
+ break;
+
+ default:
+ // TODO other exception
+ throw WrongFormatException();
+ }
+ }
+ return aData;
+}
+
+} // namespace dbahsql
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/dbaccess/source/filter/hsqldb/rowinputbinary.hxx b/dbaccess/source/filter/hsqldb/rowinputbinary.hxx
new file mode 100644
index 000000000000..e2e56944c55b
--- /dev/null
+++ b/dbaccess/source/filter/hsqldb/rowinputbinary.hxx
@@ -0,0 +1,46 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_ROWINPUTBINARY_HXX
+#define INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_ROWINPUTBINARY_HXX
+
+#include <vector>
+#include <tools/stream.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <tools/stream.hxx>
+
+namespace dbahsql
+{
+class HsqlRowInputStream
+{
+private:
+ std::unique_ptr<SvStream> m_pStream = nullptr;
+
+protected:
+ OUString readString();
+ bool checkNull();
+
+ // reimplement reading of an UTF string with a given length
+ OUString readUTF(sal_Int32 nLen);
+
+public:
+ HsqlRowInputStream();
+ std::vector<css::uno::Any> readOneRow(const std::vector<sal_Int32>& colTypes);
+ void seek(sal_Int32 nPos);
+ void setInputStream(css::uno::Reference<css::io::XInputStream>& rStream);
+ SvStream* getInputStream() const;
+};
+
+} // namespace dbahsql
+
+#endif // INCLUDED_DBACCESS_SOURCE_FILTER_HSQLDB_ROWINPUTBINARY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */