1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9b5730f6SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9b5730f6SAndrew Rist  * distributed with this work for additional information
6*9b5730f6SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9b5730f6SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist  * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9b5730f6SAndrew Rist  *
11*9b5730f6SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9b5730f6SAndrew Rist  *
13*9b5730f6SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist  * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9b5730f6SAndrew Rist  * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist  * under the License.
19*9b5730f6SAndrew Rist  *
20*9b5730f6SAndrew Rist  *************************************************************/
21*9b5730f6SAndrew Rist 
22*9b5730f6SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "hsqldb/HView.hxx"
28cdf0e10cSrcweir #include "hsqldb/HTools.hxx"
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "propertyids.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "connectivity/dbexception.hxx"
33cdf0e10cSrcweir #include "connectivity/dbtools.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir /** === begin UNO includes === **/
36cdf0e10cSrcweir #include <com/sun/star/lang/WrappedTargetException.hpp>
37cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
39cdf0e10cSrcweir /** === end UNO includes === **/
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
42cdf0e10cSrcweir #include <tools/diagnose_ex.h>
43cdf0e10cSrcweir #include <unotools/sharedunocomponent.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir //........................................................................
46cdf0e10cSrcweir namespace connectivity { namespace hsqldb
47cdf0e10cSrcweir {
48cdf0e10cSrcweir //........................................................................
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 	/** === begin UNO using === **/
51cdf0e10cSrcweir 	using ::com::sun::star::uno::Reference;
52cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY;
53cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY_THROW;
54cdf0e10cSrcweir 	using ::com::sun::star::uno::Exception;
55cdf0e10cSrcweir 	using ::com::sun::star::uno::RuntimeException;
56cdf0e10cSrcweir 	using ::com::sun::star::uno::Any;
57cdf0e10cSrcweir 	using ::com::sun::star::uno::makeAny;
58cdf0e10cSrcweir     using ::com::sun::star::sdbc::XDatabaseMetaData;
59cdf0e10cSrcweir     using ::com::sun::star::sdbc::SQLException;
60cdf0e10cSrcweir     using ::com::sun::star::sdbc::XConnection;
61cdf0e10cSrcweir     using ::com::sun::star::lang::WrappedTargetException;
62cdf0e10cSrcweir     using ::com::sun::star::sdbc::XResultSet;
63cdf0e10cSrcweir     using ::com::sun::star::sdbc::XStatement;
64cdf0e10cSrcweir     using ::com::sun::star::lang::DisposedException;
65cdf0e10cSrcweir     using ::com::sun::star::sdbc::XRow;
66cdf0e10cSrcweir 	/** === end UNO using === **/
67cdf0e10cSrcweir 
68cdf0e10cSrcweir 	//====================================================================
69cdf0e10cSrcweir 	//= HView
70cdf0e10cSrcweir 	//====================================================================
71cdf0e10cSrcweir 	//--------------------------------------------------------------------
HView(const Reference<XConnection> & _rxConnection,sal_Bool _bCaseSensitive,const::rtl::OUString & _rSchemaName,const::rtl::OUString & _rName)72cdf0e10cSrcweir     HView::HView( const Reference< XConnection >& _rxConnection, sal_Bool _bCaseSensitive,
73cdf0e10cSrcweir         const ::rtl::OUString& _rSchemaName, const ::rtl::OUString& _rName )
74cdf0e10cSrcweir         :HView_Base( _bCaseSensitive, _rName, _rxConnection->getMetaData(), 0, ::rtl::OUString(), _rSchemaName, ::rtl::OUString() )
75cdf0e10cSrcweir         ,m_xConnection( _rxConnection )
76cdf0e10cSrcweir     {
77cdf0e10cSrcweir     }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	//--------------------------------------------------------------------
~HView()80cdf0e10cSrcweir     HView::~HView()
81cdf0e10cSrcweir     {
82cdf0e10cSrcweir     }
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     //--------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(HView,HView_Base,HView_IBASE)85cdf0e10cSrcweir     IMPLEMENT_FORWARD_XINTERFACE2( HView, HView_Base, HView_IBASE )
86cdf0e10cSrcweir     IMPLEMENT_FORWARD_XTYPEPROVIDER2( HView, HView_Base, HView_IBASE )
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     //--------------------------------------------------------------------
89cdf0e10cSrcweir     void SAL_CALL HView::alterCommand( const ::rtl::OUString& _rNewCommand ) throw (SQLException, RuntimeException)
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         // not really atomic ... as long as we do not have something like
92cdf0e10cSrcweir         //   ALTER VIEW <name> TO <command>
93cdf0e10cSrcweir         // in HSQL, we need to do it this way ...
94cdf0e10cSrcweir         //
95cdf0e10cSrcweir         // I can imagine scenarios where this fails, e.g. when dropping the view
96cdf0e10cSrcweir         // succeedes, re-creating it fails, some other thread alters a table which
97cdf0e10cSrcweir         // the view was based on, and then we try to restore the view with the
98cdf0e10cSrcweir         // original command, which then fails, too.
99cdf0e10cSrcweir         //
100cdf0e10cSrcweir         // However, there's not much chance to prevent this kind of errors without
101cdf0e10cSrcweir         // backend support.
102cdf0e10cSrcweir 
103cdf0e10cSrcweir         ::rtl::OUString sQualifiedName( ::dbtools::composeTableName(
104cdf0e10cSrcweir             m_xMetaData, m_CatalogName, m_SchemaName, m_Name, true, ::dbtools::eInDataManipulation ) );
105cdf0e10cSrcweir 
106cdf0e10cSrcweir         ::utl::SharedUNOComponent< XStatement > xStatement; xStatement.set( m_xConnection->createStatement(), UNO_QUERY_THROW );
107cdf0e10cSrcweir 
108cdf0e10cSrcweir         // create a statement which can be used to re-create the original view, in case
109cdf0e10cSrcweir         // dropping it succeeds, but creating it with a new statement fails
110cdf0e10cSrcweir         ::rtl::OUStringBuffer aRestoreCommand;
111cdf0e10cSrcweir         aRestoreCommand.appendAscii( "CREATE VIEW " );
112cdf0e10cSrcweir         aRestoreCommand.append     ( sQualifiedName );
113cdf0e10cSrcweir         aRestoreCommand.appendAscii( " AS " );
114cdf0e10cSrcweir         aRestoreCommand.append     ( impl_getCommand_throw( true ) );
115cdf0e10cSrcweir         ::rtl::OUString sRestoreCommand( aRestoreCommand.makeStringAndClear() );
116cdf0e10cSrcweir 
117cdf0e10cSrcweir         bool bDropSucceeded( false );
118cdf0e10cSrcweir         try
119cdf0e10cSrcweir         {
120cdf0e10cSrcweir             // drop the existing view
121cdf0e10cSrcweir             ::rtl::OUStringBuffer aCommand;
122cdf0e10cSrcweir             aCommand.appendAscii( "DROP VIEW " );
123cdf0e10cSrcweir             aCommand.append     ( sQualifiedName );
124cdf0e10cSrcweir             xStatement->execute( aCommand.makeStringAndClear() );
125cdf0e10cSrcweir             bDropSucceeded = true;
126cdf0e10cSrcweir 
127cdf0e10cSrcweir             // create a new one with the same name
128cdf0e10cSrcweir             aCommand.appendAscii( "CREATE VIEW " );
129cdf0e10cSrcweir             aCommand.append     ( sQualifiedName );
130cdf0e10cSrcweir             aCommand.appendAscii( " AS " );
131cdf0e10cSrcweir             aCommand.append     ( _rNewCommand );
132cdf0e10cSrcweir             xStatement->execute( aCommand.makeStringAndClear() );
133cdf0e10cSrcweir         }
134cdf0e10cSrcweir         catch( const SQLException& )
135cdf0e10cSrcweir         {
136cdf0e10cSrcweir             if ( bDropSucceeded )
137cdf0e10cSrcweir                 // drop succeeded, but creation failed -> re-create the view with the original
138cdf0e10cSrcweir                 // statemnet
139cdf0e10cSrcweir                 xStatement->execute( sRestoreCommand );
140cdf0e10cSrcweir             throw;
141cdf0e10cSrcweir         }
142cdf0e10cSrcweir         catch( const RuntimeException& )
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             if ( bDropSucceeded )
145cdf0e10cSrcweir                 xStatement->execute( sRestoreCommand );
146cdf0e10cSrcweir             throw;
147cdf0e10cSrcweir         }
148cdf0e10cSrcweir         catch( const Exception& )
149cdf0e10cSrcweir         {
150cdf0e10cSrcweir             if ( bDropSucceeded )
151cdf0e10cSrcweir                 xStatement->execute( sRestoreCommand );
152cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
153cdf0e10cSrcweir         }
154cdf0e10cSrcweir     }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     //--------------------------------------------------------------------
getFastPropertyValue(Any & _rValue,sal_Int32 _nHandle) const157cdf0e10cSrcweir     void SAL_CALL HView::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
158cdf0e10cSrcweir     {
159cdf0e10cSrcweir         if ( _nHandle == PROPERTY_ID_COMMAND )
160cdf0e10cSrcweir         {
161cdf0e10cSrcweir             // retrieve the very current command, don't rely on the base classes cached value
162cdf0e10cSrcweir             // (which we initialized empty, anyway)
163cdf0e10cSrcweir             _rValue <<= impl_getCommand_throw( false );
164cdf0e10cSrcweir             return;
165cdf0e10cSrcweir         }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir         HView_Base::getFastPropertyValue( _rValue, _nHandle );
168cdf0e10cSrcweir     }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     //--------------------------------------------------------------------
impl_getCommand_throw(bool _bAllowSQLException) const171cdf0e10cSrcweir     ::rtl::OUString HView::impl_getCommand_throw( bool _bAllowSQLException ) const
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         ::rtl::OUString sCommand;
174cdf0e10cSrcweir 
175cdf0e10cSrcweir         try
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             ::rtl::OUStringBuffer aCommand;
178cdf0e10cSrcweir             aCommand.appendAscii( "SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.SYSTEM_VIEWS " );
179cdf0e10cSrcweir             HTools::appendTableFilterCrit( aCommand, m_CatalogName, m_SchemaName, m_Name, false );
180cdf0e10cSrcweir             ::utl::SharedUNOComponent< XStatement > xStatement; xStatement.set( m_xConnection->createStatement(), UNO_QUERY_THROW );
181cdf0e10cSrcweir             Reference< XResultSet > xResult( xStatement->executeQuery( aCommand.makeStringAndClear() ), UNO_QUERY_THROW );
182cdf0e10cSrcweir             if ( !xResult->next() )
183cdf0e10cSrcweir             {
184cdf0e10cSrcweir                 // hmm. There is no view view the name as we know it. Can only mean some other instance
185cdf0e10cSrcweir                 // dropped this view meanwhile ...
186cdf0e10cSrcweir                 throw DisposedException();
187cdf0e10cSrcweir             }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir             Reference< XRow > xRow( xResult, UNO_QUERY_THROW );
190cdf0e10cSrcweir             sCommand = xRow->getString( 1 );
191cdf0e10cSrcweir         }
192cdf0e10cSrcweir         catch( const RuntimeException& ) { throw; }
193cdf0e10cSrcweir         catch( const SQLException& e )
194cdf0e10cSrcweir         {
195cdf0e10cSrcweir             if ( _bAllowSQLException )
196cdf0e10cSrcweir                 throw;
197cdf0e10cSrcweir             throw WrappedTargetException( e.Message, static_cast< XAlterView* >( const_cast< HView* >( this ) ), ::cppu::getCaughtException() );
198cdf0e10cSrcweir         }
199cdf0e10cSrcweir         catch( const Exception& )
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         return sCommand;
205cdf0e10cSrcweir     }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir //........................................................................
208cdf0e10cSrcweir } } // namespace connectivity::hsqldb
209cdf0e10cSrcweir //........................................................................
210