summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Elie Mamane <lionel@mamane.lu>2016-01-05 12:00:00 +0000
committerLionel Elie Mamane <lionel@mamane.lu>2016-01-05 12:00:42 +0000
commitc88fd50c4e8815546e9830a41bf08edf9f165923 (patch)
treea83ebedec74413f0849c53daca77c02942fc1018
parentc01bcbc88522c5f86820105a45e2e5593ae01501 (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.cxx83
-rw-r--r--connectivity/source/drivers/firebird/Connection.hxx8
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);