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 <lio...@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 <lio...@mamane.lu>
    Tested-by: Lionel Elie Mamane <lio...@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);
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to