20#include <com/sun/star/embed/XStorage.hpp>
21#include <com/sun/star/embed/ElementModes.hpp>
22#include <com/sun/star/io/XInputStream.hpp>
23#include <com/sun/star/io/WrongFormatException.hpp>
24#include <com/sun/star/util/Date.hpp>
26#include <com/sun/star/sdbc/XConnection.hpp>
27#include <com/sun/star/sdbc/XParameters.hpp>
28#include <com/sun/star/sdbc/DataType.hpp>
29#include <com/sun/star/sdbc/SQLException.hpp>
31#include <rtl/ustrbuf.hxx>
45using namespace css::io;
46using namespace css::uno;
47using namespace css::sdbc;
49void lcl_setParams(
const std::vector<Any>& row, Reference<XParameters>
const& xParam,
50 const std::vector<dbahsql::ColumnDefinition>& rColTypes)
52 assert(row.size() == rColTypes.size());
54 for (
size_t i = 0;
i < rColTypes.size(); ++
i)
56 if (!row.at(i).hasValue())
57 xParam->setNull(i + 1, rColTypes.at(i).getDataType());
59 switch (rColTypes.at(i).getDataType())
62 case DataType::VARCHAR:
63 case DataType::LONGVARCHAR:
66 if (row.at(i) >>= sVal)
68 xParam->setString(nColIndex + 1, sVal);
72 case DataType::TINYINT:
73 case DataType::SMALLINT:
76 if (row.at(i) >>= nVal)
78 xParam->setShort(nColIndex + 1, nVal);
82 case DataType::INTEGER:
85 if (row.at(i) >>= nVal)
87 xParam->setInt(nColIndex + 1, nVal);
91 case DataType::BIGINT:
94 if (row.at(i) >>= nVal)
96 xParam->setLong(nColIndex + 1, nVal);
101 case DataType::FLOAT:
102 case DataType::DOUBLE:
105 if (row.at(i) >>= nVal)
107 xParam->setDouble(nColIndex + 1, nVal);
111 case DataType::NUMERIC:
112 case DataType::DECIMAL:
114 Sequence<Any> aNumeric;
115 if (row.at(i) >>= aNumeric)
117 sal_Int32 nScale = 0;
118 if (aNumeric[1] >>= nScale)
119 xParam->setObjectWithInfo(nColIndex + 1, aNumeric[0],
120 rColTypes.at(i).getDataType(), nScale);
126 css::util::Date date;
127 if (row.at(i) >>= date)
129 xParam->setDate(nColIndex + 1, date);
135 css::util::Time time;
136 if (row.at(i) >>= time)
138 xParam->setTime(nColIndex + 1, time);
142 case DataType::TIMESTAMP:
144 css::util::DateTime dateTime;
145 if (row.at(i) >>= dateTime)
147 xParam->setTimestamp(nColIndex + 1, dateTime);
151 case DataType::BOOLEAN:
154 if (row.at(i) >>= bVal)
155 xParam->setBoolean(nColIndex + 1, bVal);
158 case DataType::OTHER:
161 case DataType::BINARY:
162 case DataType::VARBINARY:
163 case DataType::LONGVARBINARY:
165 Sequence<sal_Int8> nVal;
166 if (row.at(i) >>= nVal)
168 xParam->setBytes(nColIndex + 1, nVal);
173 throw WrongFormatException();
179OUString lcl_createInsertStatement(std::u16string_view sTableName,
180 const std::vector<dbahsql::ColumnDefinition>& rColTypes)
182 assert(rColTypes.size() > 0);
183 OUStringBuffer
sql(OUString::Concat(
"INSERT INTO ") + sTableName +
" (");
186 for (
size_t i = 0;
i < rColTypes.size(); ++
i)
188 sql.append(rColTypes.at(i).getName());
189 if (i < rColTypes.size() - 1)
192 sql.append(
") VALUES (");
193 for (
size_t i = 0;
i < rColTypes.size(); ++
i)
196 if (i < rColTypes.size() - 1)
200 return sql.makeStringAndClear();
207using namespace css::embed;
210 : m_rConnection(rConnection)
216 std::u16string_view sTableName,
217 const std::vector<ColumnDefinition>& rColTypes)
219 OUString sStatement = lcl_createInsertStatement(sTableName, rColTypes);
220 Reference<XPreparedStatement> xStatement =
m_rConnection->prepareStatement(sStatement);
222 Reference<XParameters> xParameter(xStatement, UNO_QUERY);
223 assert(xParameter.is());
224 xParameter->clearParameters();
226 lcl_setParams(xRows, xParameter, rColTypes);
227 xStatement->executeQuery();
231 const std::vector<ColumnDefinition>& rColTypes,
232 const OUString& sTableName, sal_Int32 nIndexCount)
235 sal_Int32 nNext = rNode.
getLeft();
263 const std::vector<ColumnDefinition>& rColTypes,
264 const OUString& sTableName)
266 static constexpr OUStringLiteral BINARY_FILENAME =
u"data";
270 SAL_WARN(
"dbaccess",
"data file does not exist in storage during hsqldb import");
274 Reference<css::io::XStream>
xStream(
275 m_xStorage->openStreamElement(BINARY_FILENAME, ElementModes::READ));
278 Reference<XInputStream> xInput =
xStream->getInputStream();
281 if (!rIndexes.empty())
284 processTree(aPrimaryNode, rowInput, rColTypes, sTableName, rIndexes.size());
287 xInput->closeInput();
295 std::unique_ptr<SQLException> pException;
300 catch (SQLException&
ex)
302 pException.reset(
new SQLException{ std::move(
ex) });
305 auto statements =
parser.getCreateStatements();
307 if (statements.empty() && !pException)
309 SAL_WARN(
"dbaccess",
"dbashql: there is nothing to import");
314 for (
const auto& sSql : statements)
316 Reference<XStatement> statement =
m_rConnection->createStatement();
319 statement->executeQuery(sSql);
321 catch (SQLException&
ex)
325 ex.NextException <<= *pException;
326 pException.reset(
new SQLException{ std::move(
ex) });
331 for (
const auto& tableIndex :
parser.getTableIndexes())
335 std::vector<ColumnDefinition> aColTypes =
parser.getTableColumnTypes(tableIndex.first);
338 catch (
const std::out_of_range& e)
340 std::unique_ptr<SQLException>
ex(
new SQLException);
341 const char* msg = e.what();
342 ex->SQLState = OUString(msg, strlen(msg), RTL_TEXTENCODING_ASCII_US);
345 ex->NextException <<= *pException;
346 pException = std::move(
ex);
348 catch (SQLException&
ex)
352 ex.NextException <<= *pException;
353 pException.reset(
new SQLException{ std::move(
ex) });
358 for (
const auto& sSql :
parser.getAlterStatements())
360 Reference<XStatement> statement =
m_rConnection->createStatement();
363 statement->executeQuery(sSql);
365 catch (SQLException&
ex)
369 ex.NextException <<= *pException;
370 pException.reset(
new SQLException{ std::move(
ex) });
376 SAL_WARN(
"dbaccess",
"Error during migration");
379 ::comphelper::getProcessComponentContext());
void readChildren(HsqlRowInputStream const &rInput)
Read position of children from data file.
sal_Int32 getLeft() const
Get Position of left children.
std::vector< css::uno::Any > readRow(HsqlRowInputStream &rInput, const std::vector< ColumnDefinition > &aColTypes, sal_Int32 nIndexCount)
Read the row represented by this node.
sal_Int32 getRight() const
Get Position of right children.
css::uno::Reference< css::sdbc::XConnection > & m_rConnection
HsqlImporter(css::uno::Reference< css::sdbc::XConnection > &rConnection, const css::uno::Reference< css::embed::XStorage > &rStorage)
void insertRow(const std::vector< css::uno::Any > &xRows, std::u16string_view sTable, const std::vector< ColumnDefinition > &rColTypes)
css::uno::Reference< css::embed::XStorage > m_xStorage
void processTree(HsqlBinaryNode &rNode, HsqlRowInputStream &rStream, const std::vector< ColumnDefinition > &rColTypes, const OUString &sTableName, sal_Int32 nIndexCount)
void parseTableRows(const std::vector< sal_Int32 > &rIndexes, const std::vector< ColumnDefinition > &rColTypes, const OUString &sTableName)
Format from the indexed file position is the following: <Node x20><Row> Where Node is a 20 byte data,...
void importHsqlDatabase(weld::Window *pParent)
Migrate a HSQL database to another.
virtual css::uno::Reference< css::awt::XWindow > GetXWindow()=0
#define SAL_WARN(area, stream)