1*96de5490SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*96de5490SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*96de5490SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*96de5490SAndrew Rist  * distributed with this work for additional information
6*96de5490SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*96de5490SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*96de5490SAndrew Rist  * "License"); you may not use this file except in compliance
9*96de5490SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*96de5490SAndrew Rist  *
11*96de5490SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*96de5490SAndrew Rist  *
13*96de5490SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*96de5490SAndrew Rist  * software distributed under the License is distributed on an
15*96de5490SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*96de5490SAndrew Rist  * KIND, either express or implied.  See the License for the
17*96de5490SAndrew Rist  * specific language governing permissions and limitations
18*96de5490SAndrew Rist  * under the License.
19*96de5490SAndrew Rist  *
20*96de5490SAndrew Rist  *************************************************************/
21*96de5490SAndrew Rist 
22*96de5490SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dbaccess.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "viewcontainer.hxx"
28cdf0e10cSrcweir #include "dbastrings.hrc"
29cdf0e10cSrcweir #include "core_resource.hxx"
30cdf0e10cSrcweir #include "core_resource.hrc"
31cdf0e10cSrcweir #include "View.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <tools/debug.hxx>
34cdf0e10cSrcweir #include <tools/wldcrd.hxx>
35cdf0e10cSrcweir #include <comphelper/enumhelper.hxx>
36cdf0e10cSrcweir #include <comphelper/types.hxx>
37cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
38cdf0e10cSrcweir #include <comphelper/extract.hxx>
39cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
40cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp>
44cdf0e10cSrcweir #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
45cdf0e10cSrcweir #include <com/sun/star/sdbc/KeyRule.hpp>
46cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
47cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
48cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
49cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
50cdf0e10cSrcweir #include <com/sun/star/sdbcx/KeyType.hpp>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir using namespace dbaccess;
53cdf0e10cSrcweir using namespace dbtools;
54cdf0e10cSrcweir using namespace ::com::sun::star::uno;
55cdf0e10cSrcweir using namespace ::com::sun::star::lang;
56cdf0e10cSrcweir using namespace ::com::sun::star::beans;
57cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
58cdf0e10cSrcweir using namespace ::com::sun::star::sdb;
59cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
60cdf0e10cSrcweir using namespace ::com::sun::star::util;
61cdf0e10cSrcweir using namespace ::com::sun::star::container;
62cdf0e10cSrcweir using namespace ::osl;
63cdf0e10cSrcweir using namespace ::comphelper;
64cdf0e10cSrcweir using namespace ::cppu;
65cdf0e10cSrcweir using namespace ::connectivity::sdbcx;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir //==========================================================================
68cdf0e10cSrcweir //= OViewContainer
69cdf0e10cSrcweir //==========================================================================
DBG_NAME(OViewContainer)70cdf0e10cSrcweir DBG_NAME(OViewContainer)
71cdf0e10cSrcweir //------------------------------------------------------------------------------
72cdf0e10cSrcweir OViewContainer::OViewContainer(::cppu::OWeakObject& _rParent
73cdf0e10cSrcweir 								 ,::osl::Mutex& _rMutex
74cdf0e10cSrcweir 								 ,const Reference< XConnection >& _xCon
75cdf0e10cSrcweir 								 ,sal_Bool _bCase
76cdf0e10cSrcweir 								 ,IRefreshListener*	_pRefreshListener
77cdf0e10cSrcweir 								 ,::dbtools::IWarningsContainer* _pWarningsContainer
78cdf0e10cSrcweir                                  ,oslInterlockedCount& _nInAppend)
79cdf0e10cSrcweir 	:OFilteredContainer(_rParent,_rMutex,_xCon,_bCase,_pRefreshListener,_pWarningsContainer,_nInAppend)
80cdf0e10cSrcweir     ,m_bInElementRemoved(false)
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     DBG_CTOR(OViewContainer, NULL);
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir //------------------------------------------------------------------------------
~OViewContainer()86cdf0e10cSrcweir OViewContainer::~OViewContainer()
87cdf0e10cSrcweir {
88cdf0e10cSrcweir 	//	dispose();
89cdf0e10cSrcweir 	DBG_DTOR(OViewContainer, NULL);
90cdf0e10cSrcweir }
91cdf0e10cSrcweir //------------------------------------------------------------------------------
92cdf0e10cSrcweir // XServiceInfo
93cdf0e10cSrcweir //------------------------------------------------------------------------------
94cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO2(OViewContainer, "com.sun.star.sdb.dbaccess.OViewContainer", SERVICE_SDBCX_CONTAINER, SERVICE_SDBCX_TABLES)
95cdf0e10cSrcweir // -----------------------------------------------------------------------------
createObject(const::rtl::OUString & _rName)96cdf0e10cSrcweir ObjectType OViewContainer::createObject(const ::rtl::OUString& _rName)
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	ObjectType xProp;
99cdf0e10cSrcweir 	if ( m_xMasterContainer.is() && m_xMasterContainer->hasByName(_rName) )
100cdf0e10cSrcweir 		xProp.set(m_xMasterContainer->getByName(_rName),UNO_QUERY);
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	if ( !xProp.is() )
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir 		::rtl::OUString sCatalog,sSchema,sTable;
105cdf0e10cSrcweir 		::dbtools::qualifiedNameComponents(m_xMetaData,
106cdf0e10cSrcweir 											_rName,
107cdf0e10cSrcweir 											sCatalog,
108cdf0e10cSrcweir 											sSchema,
109cdf0e10cSrcweir 											sTable,
110cdf0e10cSrcweir 											::dbtools::eInDataManipulation);
111cdf0e10cSrcweir 		return new View(m_xConnection,
112cdf0e10cSrcweir                         isCaseSensitive(),
113cdf0e10cSrcweir                         sCatalog,
114cdf0e10cSrcweir 						sSchema,
115cdf0e10cSrcweir 						sTable
116cdf0e10cSrcweir 						);
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 	return xProp;
120cdf0e10cSrcweir }
121cdf0e10cSrcweir // -----------------------------------------------------------------------------
createDescriptor()122cdf0e10cSrcweir Reference< XPropertySet > OViewContainer::createDescriptor()
123cdf0e10cSrcweir {
124cdf0e10cSrcweir 	Reference< XPropertySet > xRet;
125cdf0e10cSrcweir 	// frist we have to look if the master tables does support this
126cdf0e10cSrcweir 	// and if then create a table object as well with the master tables
127cdf0e10cSrcweir 	Reference<XColumnsSupplier > xMasterColumnsSup;
128cdf0e10cSrcweir 	Reference<XDataDescriptorFactory> xDataFactory(m_xMasterContainer,UNO_QUERY);
129cdf0e10cSrcweir 	if(xDataFactory.is())
130cdf0e10cSrcweir 		xRet = xDataFactory->createDataDescriptor();
131cdf0e10cSrcweir 	else
132cdf0e10cSrcweir 		xRet = new ::connectivity::sdbcx::OView(isCaseSensitive(),m_xMetaData);
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	return xRet;
135cdf0e10cSrcweir }
136cdf0e10cSrcweir // -----------------------------------------------------------------------------
137cdf0e10cSrcweir // XAppend
appendObject(const::rtl::OUString & _rForName,const Reference<XPropertySet> & descriptor)138cdf0e10cSrcweir ObjectType OViewContainer::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir 	// append the new table with a create stmt
141cdf0e10cSrcweir 	::rtl::OUString aName = getString(descriptor->getPropertyValue(PROPERTY_NAME));
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	Reference<XAppend> xAppend(m_xMasterContainer,UNO_QUERY);
144cdf0e10cSrcweir 	Reference< XPropertySet > xProp = descriptor;
145cdf0e10cSrcweir 	if(xAppend.is())
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir         EnsureReset aReset(m_nInAppend);
148cdf0e10cSrcweir 
149cdf0e10cSrcweir         xAppend->appendByDescriptor(descriptor);
150cdf0e10cSrcweir 		if(m_xMasterContainer->hasByName(aName))
151cdf0e10cSrcweir 			xProp.set(m_xMasterContainer->getByName(aName),UNO_QUERY);
152cdf0e10cSrcweir 	}
153cdf0e10cSrcweir 	else
154cdf0e10cSrcweir 	{
155cdf0e10cSrcweir 		::rtl::OUString sComposedName = ::dbtools::composeTableName( m_xMetaData, descriptor, ::dbtools::eInTableDefinitions, false, false, true );
156cdf0e10cSrcweir 		if(!sComposedName.getLength())
157cdf0e10cSrcweir 			::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 		::rtl::OUString sCommand;
160cdf0e10cSrcweir 		descriptor->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir         ::rtl::OUStringBuffer aSQL;
163cdf0e10cSrcweir         aSQL.appendAscii( "CREATE VIEW " );
164cdf0e10cSrcweir         aSQL.append     ( sComposedName );
165cdf0e10cSrcweir         aSQL.appendAscii( " AS " );
166cdf0e10cSrcweir         aSQL.append     ( sCommand );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 		Reference<XConnection> xCon = m_xConnection;
169cdf0e10cSrcweir 		OSL_ENSURE(xCon.is(),"Connection is null!");
170cdf0e10cSrcweir 		if ( xCon.is() )
171cdf0e10cSrcweir 		{
172cdf0e10cSrcweir             ::utl::SharedUNOComponent< XStatement > xStmt( xCon->createStatement() );
173cdf0e10cSrcweir 			if ( xStmt.is() )
174cdf0e10cSrcweir 				xStmt->execute( aSQL.makeStringAndClear() );
175cdf0e10cSrcweir 		}
176cdf0e10cSrcweir 	}
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     return createObject( _rForName );
179cdf0e10cSrcweir }
180cdf0e10cSrcweir // -------------------------------------------------------------------------
181cdf0e10cSrcweir // XDrop
dropObject(sal_Int32 _nPos,const::rtl::OUString _sElementName)182cdf0e10cSrcweir void OViewContainer::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     if ( !m_bInElementRemoved )
185cdf0e10cSrcweir     {
186cdf0e10cSrcweir 	    Reference< XDrop > xDrop(m_xMasterContainer,UNO_QUERY);
187cdf0e10cSrcweir 	    if(xDrop.is())
188cdf0e10cSrcweir 		    xDrop->dropByName(_sElementName);
189cdf0e10cSrcweir 	    else
190cdf0e10cSrcweir 	    {
191cdf0e10cSrcweir 		    ::rtl::OUString sCatalog,sSchema,sTable,sComposedName;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 		    Reference<XPropertySet> xTable(getObject(_nPos),UNO_QUERY);
194cdf0e10cSrcweir 		    if ( xTable.is() )
195cdf0e10cSrcweir 		    {
196cdf0e10cSrcweir 			    xTable->getPropertyValue(PROPERTY_CATALOGNAME)	>>= sCatalog;
197cdf0e10cSrcweir 			    xTable->getPropertyValue(PROPERTY_SCHEMANAME)	>>= sSchema;
198cdf0e10cSrcweir 			    xTable->getPropertyValue(PROPERTY_NAME)			>>= sTable;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 			    sComposedName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions );
201cdf0e10cSrcweir 		    }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 		    if(!sComposedName.getLength())
204cdf0e10cSrcweir 			    ::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 		    ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP VIEW ");
207cdf0e10cSrcweir 		    aSql += sComposedName;
208cdf0e10cSrcweir 		    Reference<XConnection> xCon = m_xConnection;
209cdf0e10cSrcweir 		    OSL_ENSURE(xCon.is(),"Connection is null!");
210cdf0e10cSrcweir 		    if ( xCon.is() )
211cdf0e10cSrcweir 		    {
212cdf0e10cSrcweir 			    Reference< XStatement > xStmt = xCon->createStatement(  );
213cdf0e10cSrcweir 			    if(xStmt.is())
214cdf0e10cSrcweir 				    xStmt->execute(aSql);
215cdf0e10cSrcweir 			    ::comphelper::disposeComponent(xStmt);
216cdf0e10cSrcweir 		    }
217cdf0e10cSrcweir 	    }
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir }
220cdf0e10cSrcweir // -----------------------------------------------------------------------------
elementInserted(const ContainerEvent & Event)221cdf0e10cSrcweir void SAL_CALL OViewContainer::elementInserted( const ContainerEvent& Event ) throw (RuntimeException)
222cdf0e10cSrcweir {
223cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
224cdf0e10cSrcweir 	::rtl::OUString sName;
225cdf0e10cSrcweir 	if  (   ( Event.Accessor >>= sName )
226cdf0e10cSrcweir         &&  ( !m_nInAppend )
227cdf0e10cSrcweir         &&  ( !hasByName( sName ) )
228cdf0e10cSrcweir         )
229cdf0e10cSrcweir 	{
230cdf0e10cSrcweir 		Reference<XPropertySet> xProp(Event.Element,UNO_QUERY);
231cdf0e10cSrcweir 		::rtl::OUString sType;
232cdf0e10cSrcweir 		xProp->getPropertyValue(PROPERTY_TYPE) >>= sType;
233cdf0e10cSrcweir 		if ( sType == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")) )
234cdf0e10cSrcweir 			insertElement(sName,createObject(sName));
235cdf0e10cSrcweir 	}
236cdf0e10cSrcweir }
237cdf0e10cSrcweir // -----------------------------------------------------------------------------
elementRemoved(const ContainerEvent & Event)238cdf0e10cSrcweir void SAL_CALL OViewContainer::elementRemoved( const ContainerEvent& Event ) throw (RuntimeException)
239cdf0e10cSrcweir {
240cdf0e10cSrcweir     ::osl::MutexGuard aGuard(m_rMutex);
241cdf0e10cSrcweir 	::rtl::OUString sName;
242cdf0e10cSrcweir 	if ( (Event.Accessor >>= sName) && hasByName(sName) )
243cdf0e10cSrcweir 	{
244cdf0e10cSrcweir         m_bInElementRemoved = true;
245cdf0e10cSrcweir         try
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             dropByName(sName);
248cdf0e10cSrcweir         }
249cdf0e10cSrcweir 	    catch(Exception&)
250cdf0e10cSrcweir 	    {
251cdf0e10cSrcweir 		    m_bInElementRemoved = sal_False;
252cdf0e10cSrcweir 		    throw;
253cdf0e10cSrcweir 	    }
254cdf0e10cSrcweir         m_bInElementRemoved = false;
255cdf0e10cSrcweir 	}
256cdf0e10cSrcweir }
257cdf0e10cSrcweir // -----------------------------------------------------------------------------
disposing(const::com::sun::star::lang::EventObject &)258cdf0e10cSrcweir void SAL_CALL OViewContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (RuntimeException)
259cdf0e10cSrcweir {
260cdf0e10cSrcweir }
261cdf0e10cSrcweir // -----------------------------------------------------------------------------
elementReplaced(const ContainerEvent &)262cdf0e10cSrcweir void SAL_CALL OViewContainer::elementReplaced( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
263cdf0e10cSrcweir {
264cdf0e10cSrcweir }
265cdf0e10cSrcweir // -----------------------------------------------------------------------------
getTableTypeRestriction() const266cdf0e10cSrcweir ::rtl::OUString OViewContainer::getTableTypeRestriction() const
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     // no restriction at all (other than the ones provided externally)
269cdf0e10cSrcweir     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VIEW" ) );
270cdf0e10cSrcweir }
271