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