diff options
author | Lionel Elie Mamane <lionel@mamane.lu> | 2016-01-05 12:00:00 +0000 |
---|---|---|
committer | Lionel Elie Mamane <lionel@mamane.lu> | 2016-01-05 12:00:42 +0000 |
commit | c88fd50c4e8815546e9830a41bf08edf9f165923 (patch) | |
tree | a83ebedec74413f0849c53daca77c02942fc1018 | |
parent | c01bcbc88522c5f86820105a45e2e5593ae01501 (diff) |
Revert "WIP tdf#72987 Use firebird backup format for .odb no need for rebuild indexes"
This reverts commit f961fef03906fc059a4a0c008799f68fc22727c1.
This can be done only *after* the firebird driver switches to the backup format.
Change-Id: I71874ab6d4b4da9648e08d037786a56f9421751d
Reviewed-on: https://gerrit.libreoffice.org/21113
Reviewed-by: Lionel Elie Mamane <lionel@mamane.lu>
Tested-by: Lionel Elie Mamane <lionel@mamane.lu>
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.cxx | 83 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Connection.hxx | 8 |
2 files changed, 91 insertions, 0 deletions
diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx index e9d453a030ee..be6178b43b07 100644 --- a/connectivity/source/drivers/firebird/Connection.cxx +++ b/connectivity/source/drivers/firebird/Connection.cxx @@ -294,6 +294,12 @@ void Connection::construct(const ::rtl::OUString& url, const Sequence< PropertyV if (m_bIsEmbedded) // Add DocumentEventListener to save the .fdb as needed { + // TODO: this is only needed when we change icu versions, so ideally + // we somehow keep track of which icu version we have. There might + // be something db internal that we can check, or we might have to store + // it in the .odb. + rebuildIndexes(); + // We need to attach as a document listener in order to be able to store // the temporary db back into the .odb when saving uno::Reference<XDocumentEventBroadcaster> xBroadcaster(m_xParentDocument, UNO_QUERY); @@ -816,4 +822,81 @@ uno::Reference< XTablesSupplier > Connection::createCatalog() } +void Connection::rebuildIndexes() throw (SQLException, RuntimeException, std::exception) +{ + MutexGuard aGuard(m_aMutex); + + try + { + // We only need to do this for character based columns on user-created tables. + + // Ideally we'd use a FOR SELECT ... INTO .... DO ..., but that seems to + // only be possible using PSQL, i.e. using a stored procedure. + OUString sSql( + // multiple columns possible per index, only select once + "SELECT DISTINCT indices.RDB$INDEX_NAME " + "FROM RDB$INDICES indices " + "JOIN RDB$INDEX_SEGMENTS index_segments " + "ON (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) " + "JOIN RDB$RELATION_FIELDS relation_fields " + "ON (index_segments.RDB$FIELD_NAME = relation_fields.RDB$FIELD_NAME) " + "JOIN RDB$FIELDS fields " + "ON (relation_fields.RDB$FIELD_SOURCE = fields.RDB$FIELD_NAME) " + + "WHERE (indices.RDB$SYSTEM_FLAG = 0) " + // TODO: what about blr_text2 etc. ? + "AND ((fields.RDB$FIELD_TYPE = " + OUString::number((int) blr_text) + ") " + " OR (fields.RDB$FIELD_TYPE = " + OUString::number((int) blr_varying) + ")) " + "AND (indices.RDB$INDEX_INACTIVE IS NULL OR indices.RDB$INDEX_INACTIVE = 0) " + ); + + uno::Reference< XStatement > xCharIndicesStatement = createStatement(); + uno::Reference< XResultSet > xCharIndices = + xCharIndicesStatement->executeQuery(sSql); + uno::Reference< XRow > xRow(xCharIndices, UNO_QUERY_THROW); + + uno::Reference< XStatement > xAlterIndexStatement = createStatement(); + + // ALTER is a DDL statement, hence using Statement will cause a commit + // after every alter -- in this case this is inappropriate (xCharIndicesStatement + // and its ResultSet become invalidated) hence we use the native api. + while (xCharIndices->next()) + { + OUString sIndexName(sanitizeIdentifier(xRow->getString(1))); + SAL_INFO("connectivity.firebird", "rebuilding index " + sIndexName); + OString sAlterIndex = "ALTER INDEX \"" + + OUStringToOString(sIndexName, RTL_TEXTENCODING_UTF8) + + "\" ACTIVE"; + + ISC_STATUS_ARRAY aStatusVector; + ISC_STATUS aErr; + + aErr = isc_dsql_execute_immediate(aStatusVector, + &getDBHandle(), + &getTransaction(), + 0, // Length: 0 for null terminated + sAlterIndex.getStr(), + FIREBIRD_SQL_DIALECT, + nullptr); + if (aErr) + evaluateStatusVector(aStatusVector, + "rebuildIndexes:isc_dsql_execute_immediate", + *this); + } + commit(); + } + catch (const Exception&) + { + throw; + } + catch (const std::exception&) + { + throw; + } + catch (...) // const Firebird::Exception& firebird throws this, but doesn't install the fb_exception.h that declares it + { + throw std::runtime_error("Generic Firebird::Exception"); + } + +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx index 0a9a46f614d5..29784ddc55be 100644 --- a/connectivity/source/drivers/firebird/Connection.hxx +++ b/connectivity/source/drivers/firebird/Connection.hxx @@ -139,6 +139,14 @@ namespace connectivity /** Statements owned by this connection. */ OWeakRefArray m_aStatements; + /** + * Firebird stores binary collations for indexes on Character based + * columns, these can be binary-incompatible between different icu + * version, hence we need to rebuild the indexes when switching icu + * versions. + */ + void rebuildIndexes() + throw (css::sdbc::SQLException, css::uno::RuntimeException, std::exception); void buildTypeInfo() throw (css::sdbc::SQLException); |