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