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