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