connectivity/Library_firebird_sdbc.mk            |    2 
 connectivity/source/drivers/firebird/Catalog.cxx |   17 +++
 connectivity/source/drivers/firebird/Catalog.hxx |    2 
 connectivity/source/drivers/firebird/Tables.cxx  |   14 ++
 connectivity/source/drivers/firebird/Tables.hxx  |    2 
 connectivity/source/drivers/firebird/View.cxx    |   90 ++++++++++++++++++
 connectivity/source/drivers/firebird/View.hxx    |   60 ++++++++++++
 connectivity/source/drivers/firebird/Views.cxx   |  112 +++++++++++++++++++++++
 connectivity/source/drivers/firebird/Views.hxx   |   42 ++++++++
 9 files changed, 339 insertions(+), 2 deletions(-)

New commits:
commit 0adff3f2476f797843fb62d6810de90bfb333e10
Author:     Julien Nabet <serval2...@yahoo.fr>
AuthorDate: Wed Jan 26 23:09:40 2022 +0100
Commit:     Julien Nabet <serval2...@yahoo.fr>
CommitDate: Thu Jan 27 17:35:20 2022 +0100

    tdf#126960, tdf#131330: FB make views editable+refresh auto after creation
    
    Change-Id: I78783056659a26cc8139d74eefc225de1a11ca7a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129011
    Tested-by: Jenkins
    Reviewed-by: Julien Nabet <serval2...@yahoo.fr>

diff --git a/connectivity/Library_firebird_sdbc.mk 
b/connectivity/Library_firebird_sdbc.mk
index ce0dbe6902ed..720dfeb878f7 100644
--- a/connectivity/Library_firebird_sdbc.mk
+++ b/connectivity/Library_firebird_sdbc.mk
@@ -61,6 +61,8 @@ $(eval $(call gb_Library_add_exception_objects,firebird_sdbc,\
     connectivity/source/drivers/firebird/User \
     connectivity/source/drivers/firebird/Users \
     connectivity/source/drivers/firebird/Util \
+    connectivity/source/drivers/firebird/View \
+    connectivity/source/drivers/firebird/Views \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/connectivity/source/drivers/firebird/Catalog.cxx 
b/connectivity/source/drivers/firebird/Catalog.cxx
index c743b42cc75f..2ef4f514b12a 100644
--- a/connectivity/source/drivers/firebird/Catalog.cxx
+++ b/connectivity/source/drivers/firebird/Catalog.cxx
@@ -10,6 +10,7 @@
 #include "Catalog.hxx"
 #include "Tables.hxx"
 #include "Users.hxx"
+#include "Views.hxx"
 
 #include <com/sun/star/sdbc/XRow.hpp>
 
@@ -53,8 +54,20 @@ void Catalog::refreshTables()
 
 void Catalog::refreshViews()
 {
-    // TODO: implement me.
-    // Sets m_pViews (OCatalog)
+    css::uno::Reference<css::sdbc::XResultSet> xViews
+        = m_xMetaData->getTables(css::uno::Any(), "%", "%", { "VIEW" });
+
+    if (!xViews.is())
+        return;
+
+    ::std::vector<OUString> aViewNames;
+
+    fillNames(xViews, aViewNames);
+
+    if (!m_pViews)
+        m_pViews.reset(new Views(m_xConnection, *this, m_aMutex, aViewNames));
+    else
+        m_pViews->reFill(aViewNames);
 }
 
 //----- IRefreshableGroups ---------------------------------------------------
diff --git a/connectivity/source/drivers/firebird/Catalog.hxx 
b/connectivity/source/drivers/firebird/Catalog.hxx
index 4a562e22a26e..b6bf02f6b69d 100644
--- a/connectivity/source/drivers/firebird/Catalog.hxx
+++ b/connectivity/source/drivers/firebird/Catalog.hxx
@@ -30,6 +30,8 @@ namespace connectivity::firebird
 
             // IRefreshableUsers
             virtual void refreshUsers() override;
+
+            sdbcx::OCollection* getPrivateTables() const { return 
m_pTables.get(); }
         };
 
 } // namespace connectivity::firebird
diff --git a/connectivity/source/drivers/firebird/Tables.cxx 
b/connectivity/source/drivers/firebird/Tables.cxx
index b686f66ecb9c..9c59f65f436c 100644
--- a/connectivity/source/drivers/firebird/Tables.cxx
+++ b/connectivity/source/drivers/firebird/Tables.cxx
@@ -204,4 +204,18 @@ void Tables::dropObject(sal_Int32 nPosition, const 
OUString& sName)
         "DROP " + sType + " " + ::dbtools::quoteName(sQuoteString,sName));
 }
 
+void connectivity::firebird::Tables::appendNew(const OUString& _rsNewTable)
+{
+    insertElement(_rsNewTable, nullptr);
+
+    // notify our container listeners
+    css::container::ContainerEvent aEvent(static_cast<XContainer*>(this),
+                                          css::uno::makeAny(_rsNewTable), 
css::uno::Any(),
+                                          css::uno::Any());
+    comphelper::OInterfaceIteratorHelper3 aListenerLoop(m_aContainerListeners);
+    while (aListenerLoop.hasMoreElements())
+        aListenerLoop.next()->elementInserted(aEvent);
+}
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/connectivity/source/drivers/firebird/Tables.hxx 
b/connectivity/source/drivers/firebird/Tables.hxx
index d7fe019ef2a6..7d84edb2084a 100644
--- a/connectivity/source/drivers/firebird/Tables.hxx
+++ b/connectivity/source/drivers/firebird/Tables.hxx
@@ -51,6 +51,8 @@ namespace connectivity::firebird
             // XDrop
             virtual void dropObject(sal_Int32 nPosition, const OUString& 
rName) override;
 
+            void appendNew(const OUString& _rsNewTable);
+
         };
 
 } // namespace connectivity::firebird
diff --git a/connectivity/source/drivers/firebird/View.cxx 
b/connectivity/source/drivers/firebird/View.cxx
new file mode 100644
index 000000000000..506cafb40463
--- /dev/null
+++ b/connectivity/source/drivers/firebird/View.cxx
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#include "View.hxx"
+#include <iostream>
+
+#include <propertyids.hxx>
+
+#include <com/sun/star/sdbc/XRow.hpp>
+
+namespace connectivity::firebird
+{
+View::View(const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, 
bool _bCaseSensitive,
+           const OUString& _rSchemaName, const OUString& _rName)
+    : View_Base(_bCaseSensitive, _rName, _rxConnection->getMetaData(), 
OUString(), _rSchemaName,
+                OUString())
+    , m_xConnection(_rxConnection)
+{
+}
+
+View::~View() {}
+
+void SAL_CALL View::acquire() noexcept { View_Base::acquire(); };
+void SAL_CALL View::release() noexcept { View_Base::release(); };
+css::uno::Any SAL_CALL View::queryInterface(const css::uno::Type& _rType)
+{
+    css::uno::Any aReturn = View_Base::queryInterface(_rType);
+    if (!aReturn.hasValue())
+        aReturn = View_IBASE::queryInterface(_rType);
+    return aReturn;
+}
+
+css::uno::Sequence<css::uno::Type> SAL_CALL View::getTypes()
+{
+    return ::comphelper::concatSequences(View_Base::getTypes(), 
View_IBASE::getTypes());
+}
+
+css::uno::Sequence<sal_Int8> SAL_CALL View::getImplementationId()
+{
+    return css::uno::Sequence<sal_Int8>();
+}
+
+void SAL_CALL View::alterCommand(const OUString& _rNewCommand)
+{
+    OUString aCommand = "ALTER VIEW \"" + m_Name + "\" AS " + _rNewCommand;
+    m_xMetaData->getConnection()->createStatement()->execute(aCommand);
+}
+
+void SAL_CALL View::getFastPropertyValue(css::uno::Any& _rValue, sal_Int32 
_nHandle) const
+{
+    if (_nHandle == PROPERTY_ID_COMMAND)
+    {
+        // retrieve the very current command, don't rely on the base classes 
cached value
+        // (which we initialized empty, anyway)
+        _rValue <<= impl_getCommand();
+        return;
+    }
+
+    View_Base::getFastPropertyValue(_rValue, _nHandle);
+}
+
+OUString View::impl_getCommand() const
+{
+    OUString aCommand("SELECT RDB$VIEW_SOURCE FROM RDB$RELATIONS WHERE 
RDB$RELATION_NAME = '"
+                      + m_Name + "'");
+    std::cerr << "TODO aCommand=" << aCommand << "\n";
+    // OUString aCommand("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS 
WHERE TABLE_SCHEMA = '"
+    //                  + m_SchemaName + "' AND TABLE_NAME = '" + m_Name + 
"'");
+    //::utl::SharedUNOComponent< XStatement > xStatement; xStatement.set( 
m_xConnection->createStatement(), UNO_QUERY_THROW );
+    css::uno::Reference<css::sdbc::XStatement> statement = 
m_xConnection->createStatement();
+    css::uno::Reference<css::sdbc::XResultSet> xResult = 
statement->executeQuery(aCommand);
+
+    css::uno::Reference<css::sdbc::XRow> xRow(xResult, 
css::uno::UNO_QUERY_THROW);
+    if (!xResult->next())
+    {
+        // hmm. There is no view the name as we know it. Can only mean some 
other instance
+        // dropped this view meanwhile...
+        std::abort();
+    }
+
+    return xRow->getString(1);
+}
+
+} // namespace connectivity::firebird
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/connectivity/source/drivers/firebird/View.hxx 
b/connectivity/source/drivers/firebird/View.hxx
new file mode 100644
index 000000000000..2b300a8d06d9
--- /dev/null
+++ b/connectivity/source/drivers/firebird/View.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <connectivity/sdbcx/VView.hxx>
+
+#include <com/sun/star/sdbcx/XAlterView.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+namespace connectivity::firebird
+{
+typedef ::connectivity::sdbcx::OView View_Base;
+typedef ::cppu::ImplHelper1<css::sdbcx::XAlterView> View_IBASE;
+
+class View : public View_Base, public View_IBASE
+{
+public:
+    View(const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, 
bool _bCaseSensitive,
+         const OUString& _rSchemaName, const OUString& _rName);
+
+    // UNO
+    virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& aType) 
override;
+    virtual void SAL_CALL acquire() noexcept override;
+    virtual void SAL_CALL release() noexcept override;
+
+    virtual css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override;
+    virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() 
override;
+
+    // XAlterView
+    virtual void SAL_CALL alterCommand(const OUString& NewCommand) override;
+
+protected:
+    virtual ~View() override;
+
+protected:
+    // OPropertyContainer
+    virtual void SAL_CALL getFastPropertyValue(css::uno::Any& _rValue,
+                                               sal_Int32 _nHandle) const 
override;
+
+private:
+    /** retrieves the current command of the View */
+    OUString impl_getCommand() const;
+
+private:
+    css::uno::Reference<css::sdbc::XConnection> m_xConnection;
+
+    using View_Base::getFastPropertyValue;
+};
+
+} // namespace connectivity::firebird
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/connectivity/source/drivers/firebird/Views.cxx 
b/connectivity/source/drivers/firebird/Views.cxx
new file mode 100644
index 000000000000..2e5bec42adc3
--- /dev/null
+++ b/connectivity/source/drivers/firebird/Views.cxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#include "Tables.hxx"
+#include "Views.hxx"
+#include "View.hxx"
+#include "Catalog.hxx"
+#include <connectivity/dbtools.hxx>
+#include <comphelper/types.hxx>
+#include <TConnection.hxx>
+
+connectivity::firebird::Views::Views(
+    const css::uno::Reference<css::sdbc::XConnection>& _rxConnection, 
::cppu::OWeakObject& _rParent,
+    ::osl::Mutex& _rMutex, const ::std::vector<OUString>& _rVector)
+    : sdbcx::OCollection(_rParent, true, _rMutex, _rVector)
+    , m_xConnection(_rxConnection)
+    , m_xMetaData(_rxConnection->getMetaData())
+    , m_bInDrop(false)
+{
+}
+
+connectivity::sdbcx::ObjectType 
connectivity::firebird::Views::createObject(const OUString& _rName)
+{
+    OUString sCatalog, sSchema, sTable;
+    ::dbtools::qualifiedNameComponents(m_xMetaData, _rName, sCatalog, sSchema, 
sTable,
+                                       
::dbtools::EComposeRule::InDataManipulation);
+    return new View(m_xConnection, isCaseSensitive(), sSchema, sTable);
+}
+
+void connectivity::firebird::Views::impl_refresh()
+{
+    static_cast<Catalog&>(m_rParent).refreshViews();
+}
+
+css::uno::Reference<css::beans::XPropertySet> 
connectivity::firebird::Views::createDescriptor()
+{
+    return new connectivity::sdbcx::OView(true, m_xMetaData);
+}
+
+// XAppend
+connectivity::sdbcx::ObjectType connectivity::firebird::Views::appendObject(
+    const OUString& _rForName, const 
css::uno::Reference<css::beans::XPropertySet>& descriptor)
+{
+    createView(descriptor);
+    return createObject(_rForName);
+}
+
+// XDrop
+void connectivity::firebird::Views::dropObject(sal_Int32 _nPos, const 
OUString& /*_sElementName*/)
+{
+    if (m_bInDrop)
+        return;
+
+    css::uno::Reference<XInterface> xObject(getObject(_nPos));
+    bool bIsNew = connectivity::sdbcx::ODescriptor::isNew(xObject);
+    if (!bIsNew)
+    {
+        OUString aSql("DROP VIEW");
+
+        css::uno::Reference<css::beans::XPropertySet> xProp(xObject, 
css::uno::UNO_QUERY);
+        aSql += ::dbtools::composeTableName(m_xMetaData, xProp,
+                                            
::dbtools::EComposeRule::InTableDefinitions, true);
+
+        css::uno::Reference<css::sdbc::XConnection> xConnection = 
m_xMetaData->getConnection();
+        css::uno::Reference<css::sdbc::XStatement> xStmt = 
xConnection->createStatement();
+        xStmt->execute(aSql);
+        ::comphelper::disposeComponent(xStmt);
+    }
+}
+
+void connectivity::firebird::Views::dropByNameImpl(const OUString& elementName)
+{
+    m_bInDrop = true;
+    connectivity::sdbcx::OCollection::dropByName(elementName);
+    m_bInDrop = false;
+}
+
+void connectivity::firebird::Views::createView(
+    const css::uno::Reference<css::beans::XPropertySet>& descriptor)
+{
+    css::uno::Reference<css::sdbc::XConnection> xConnection = 
m_xMetaData->getConnection();
+
+    OUString sCommand;
+    
descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_COMMAND))
+        >>= sCommand;
+
+    OUString aSql = "CREATE VIEW "
+                    + ::dbtools::composeTableName(m_xMetaData, descriptor,
+                                                  
::dbtools::EComposeRule::InTableDefinitions, true)
+                    + " AS " + sCommand;
+
+    css::uno::Reference<css::sdbc::XStatement> xStmt = 
xConnection->createStatement();
+    if (xStmt.is())
+    {
+        xStmt->execute(aSql);
+        ::comphelper::disposeComponent(xStmt);
+    }
+    connectivity::firebird::Tables* pTables = 
static_cast<connectivity::firebird::Tables*>(
+        
static_cast<connectivity::firebird::Catalog&>(m_rParent).getPrivateTables());
+    if (pTables)
+    {
+        OUString sName = ::dbtools::composeTableName(
+            m_xMetaData, descriptor, 
::dbtools::EComposeRule::InDataManipulation, false);
+        pTables->appendNew(sName);
+    }
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/connectivity/source/drivers/firebird/Views.hxx 
b/connectivity/source/drivers/firebird/Views.hxx
new file mode 100644
index 000000000000..6887bdc66ed0
--- /dev/null
+++ b/connectivity/source/drivers/firebird/Views.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <connectivity/sdbcx/VCollection.hxx>
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+namespace connectivity::firebird
+{
+class Views final : public connectivity::sdbcx::OCollection
+{
+    css::uno::Reference<css::sdbc::XConnection> m_xConnection;
+    css::uno::Reference<css::sdbc::XDatabaseMetaData> m_xMetaData;
+    bool m_bInDrop;
+
+    // OCollection
+    virtual connectivity::sdbcx::ObjectType createObject(const OUString& 
_rName) override;
+    virtual void impl_refresh() override;
+    virtual css::uno::Reference<css::beans::XPropertySet> createDescriptor() 
override;
+    virtual sdbcx::ObjectType
+    appendObject(const OUString& _rForName,
+                 const css::uno::Reference<css::beans::XPropertySet>& 
descriptor) override;
+
+    void createView(const css::uno::Reference<css::beans::XPropertySet>& 
descriptor);
+
+public:
+    Views(const css::uno::Reference<css::sdbc::XConnection>& _rxConnection,
+          ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
+          const ::std::vector<OUString>& _rVector);
+
+    // XDrop
+    virtual void dropObject(sal_Int32 _nPos, const OUString& _sElementName) 
override;
+
+    void dropByNameImpl(const OUString& elementName);
+};
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */

Reply via email to