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