[Libreoffice-commits] core.git: connectivity/source

Lionel Elie Mamane lionel at mamane.lu
Tue Jan 5 04:01:03 PST 2016


 connectivity/source/drivers/firebird/Connection.cxx |   83 ++++++++++++++++++++
 connectivity/source/drivers/firebird/Connection.hxx |    8 +
 2 files changed, 91 insertions(+)

New commits:
commit c88fd50c4e8815546e9830a41bf08edf9f165923
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Jan 5 12:00:00 2016 +0000

    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 at mamane.lu>
    Tested-by: Lionel Elie Mamane <lionel at mamane.lu>

diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx
index e9d453a..be6178b 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 0a9a46f..29784dd 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);
 


More information about the Libreoffice-commits mailing list