xref: /AOO41X/main/dbaccess/source/core/api/viewcontainer.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
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_dbaccess.hxx"
26 
27 #include "viewcontainer.hxx"
28 #include "dbastrings.hrc"
29 #include "core_resource.hxx"
30 #include "core_resource.hrc"
31 #include "View.hxx"
32 
33 #include <tools/debug.hxx>
34 #include <tools/wldcrd.hxx>
35 #include <comphelper/enumhelper.hxx>
36 #include <comphelper/types.hxx>
37 #include <connectivity/dbtools.hxx>
38 #include <comphelper/extract.hxx>
39 #include <connectivity/dbexception.hxx>
40 #include <rtl/ustrbuf.hxx>
41 
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/sdbc/XConnection.hpp>
44 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
45 #include <com/sun/star/sdbc/KeyRule.hpp>
46 #include <com/sun/star/sdbc/ColumnValue.hpp>
47 #include <com/sun/star/sdbc/XRow.hpp>
48 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
49 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
50 #include <com/sun/star/sdbcx/KeyType.hpp>
51 
52 using namespace dbaccess;
53 using namespace dbtools;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::beans;
57 using namespace ::com::sun::star::sdbc;
58 using namespace ::com::sun::star::sdb;
59 using namespace ::com::sun::star::sdbcx;
60 using namespace ::com::sun::star::util;
61 using namespace ::com::sun::star::container;
62 using namespace ::osl;
63 using namespace ::comphelper;
64 using namespace ::cppu;
65 using namespace ::connectivity::sdbcx;
66 
67 //==========================================================================
68 //= OViewContainer
69 //==========================================================================
DBG_NAME(OViewContainer)70 DBG_NAME(OViewContainer)
71 //------------------------------------------------------------------------------
72 OViewContainer::OViewContainer(::cppu::OWeakObject& _rParent
73                                  ,::osl::Mutex& _rMutex
74                                  ,const Reference< XConnection >& _xCon
75                                  ,sal_Bool _bCase
76                                  ,IRefreshListener* _pRefreshListener
77                                  ,::dbtools::IWarningsContainer* _pWarningsContainer
78                                  ,oslInterlockedCount& _nInAppend)
79     :OFilteredContainer(_rParent,_rMutex,_xCon,_bCase,_pRefreshListener,_pWarningsContainer,_nInAppend)
80     ,m_bInElementRemoved(false)
81 {
82     DBG_CTOR(OViewContainer, NULL);
83 }
84 
85 //------------------------------------------------------------------------------
~OViewContainer()86 OViewContainer::~OViewContainer()
87 {
88     //  dispose();
89     DBG_DTOR(OViewContainer, NULL);
90 }
91 //------------------------------------------------------------------------------
92 // XServiceInfo
93 //------------------------------------------------------------------------------
94 IMPLEMENT_SERVICE_INFO2(OViewContainer, "com.sun.star.sdb.dbaccess.OViewContainer", SERVICE_SDBCX_CONTAINER, SERVICE_SDBCX_TABLES)
95 // -----------------------------------------------------------------------------
createObject(const::rtl::OUString & _rName)96 ObjectType OViewContainer::createObject(const ::rtl::OUString& _rName)
97 {
98     ObjectType xProp;
99     if ( m_xMasterContainer.is() && m_xMasterContainer->hasByName(_rName) )
100         xProp.set(m_xMasterContainer->getByName(_rName),UNO_QUERY);
101 
102     if ( !xProp.is() )
103     {
104         ::rtl::OUString sCatalog,sSchema,sTable;
105         ::dbtools::qualifiedNameComponents(m_xMetaData,
106                                             _rName,
107                                             sCatalog,
108                                             sSchema,
109                                             sTable,
110                                             ::dbtools::eInDataManipulation);
111         return new View(m_xConnection,
112                         isCaseSensitive(),
113                         sCatalog,
114                         sSchema,
115                         sTable
116                         );
117     }
118 
119     return xProp;
120 }
121 // -----------------------------------------------------------------------------
createDescriptor()122 Reference< XPropertySet > OViewContainer::createDescriptor()
123 {
124     Reference< XPropertySet > xRet;
125     // frist we have to look if the master tables does support this
126     // and if then create a table object as well with the master tables
127     Reference<XColumnsSupplier > xMasterColumnsSup;
128     Reference<XDataDescriptorFactory> xDataFactory(m_xMasterContainer,UNO_QUERY);
129     if(xDataFactory.is())
130         xRet = xDataFactory->createDataDescriptor();
131     else
132         xRet = new ::connectivity::sdbcx::OView(isCaseSensitive(),m_xMetaData);
133 
134     return xRet;
135 }
136 // -----------------------------------------------------------------------------
137 // XAppend
appendObject(const::rtl::OUString & _rForName,const Reference<XPropertySet> & descriptor)138 ObjectType OViewContainer::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
139 {
140     // append the new table with a create stmt
141     ::rtl::OUString aName = getString(descriptor->getPropertyValue(PROPERTY_NAME));
142 
143     Reference<XAppend> xAppend(m_xMasterContainer,UNO_QUERY);
144     Reference< XPropertySet > xProp = descriptor;
145     if(xAppend.is())
146     {
147         EnsureReset aReset(m_nInAppend);
148 
149         xAppend->appendByDescriptor(descriptor);
150         if(m_xMasterContainer->hasByName(aName))
151             xProp.set(m_xMasterContainer->getByName(aName),UNO_QUERY);
152     }
153     else
154     {
155         ::rtl::OUString sComposedName = ::dbtools::composeTableName( m_xMetaData, descriptor, ::dbtools::eInTableDefinitions, false, false, true );
156         if(!sComposedName.getLength())
157             ::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
158 
159         ::rtl::OUString sCommand;
160         descriptor->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
161 
162         ::rtl::OUStringBuffer aSQL;
163         aSQL.appendAscii( "CREATE VIEW " );
164         aSQL.append     ( sComposedName );
165         aSQL.appendAscii( " AS " );
166         aSQL.append     ( sCommand );
167 
168         Reference<XConnection> xCon = m_xConnection;
169         OSL_ENSURE(xCon.is(),"Connection is null!");
170         if ( xCon.is() )
171         {
172             ::utl::SharedUNOComponent< XStatement > xStmt( xCon->createStatement() );
173             if ( xStmt.is() )
174                 xStmt->execute( aSQL.makeStringAndClear() );
175         }
176     }
177 
178     return createObject( _rForName );
179 }
180 // -------------------------------------------------------------------------
181 // XDrop
dropObject(sal_Int32 _nPos,const::rtl::OUString _sElementName)182 void OViewContainer::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
183 {
184     if ( !m_bInElementRemoved )
185     {
186         Reference< XDrop > xDrop(m_xMasterContainer,UNO_QUERY);
187         if(xDrop.is())
188             xDrop->dropByName(_sElementName);
189         else
190         {
191             ::rtl::OUString sCatalog,sSchema,sTable,sComposedName;
192 
193             Reference<XPropertySet> xTable(getObject(_nPos),UNO_QUERY);
194             if ( xTable.is() )
195             {
196                 xTable->getPropertyValue(PROPERTY_CATALOGNAME)  >>= sCatalog;
197                 xTable->getPropertyValue(PROPERTY_SCHEMANAME)   >>= sSchema;
198                 xTable->getPropertyValue(PROPERTY_NAME)         >>= sTable;
199 
200                 sComposedName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions );
201             }
202 
203             if(!sComposedName.getLength())
204                 ::dbtools::throwFunctionSequenceException(static_cast<XTypeProvider*>(static_cast<OFilteredContainer*>(this)));
205 
206             ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP VIEW ");
207             aSql += sComposedName;
208             Reference<XConnection> xCon = m_xConnection;
209             OSL_ENSURE(xCon.is(),"Connection is null!");
210             if ( xCon.is() )
211             {
212                 Reference< XStatement > xStmt = xCon->createStatement(  );
213                 if(xStmt.is())
214                     xStmt->execute(aSql);
215                 ::comphelper::disposeComponent(xStmt);
216             }
217         }
218     }
219 }
220 // -----------------------------------------------------------------------------
elementInserted(const ContainerEvent & Event)221 void SAL_CALL OViewContainer::elementInserted( const ContainerEvent& Event ) throw (RuntimeException)
222 {
223     ::osl::MutexGuard aGuard(m_rMutex);
224     ::rtl::OUString sName;
225     if  (   ( Event.Accessor >>= sName )
226         &&  ( !m_nInAppend )
227         &&  ( !hasByName( sName ) )
228         )
229     {
230         Reference<XPropertySet> xProp(Event.Element,UNO_QUERY);
231         ::rtl::OUString sType;
232         xProp->getPropertyValue(PROPERTY_TYPE) >>= sType;
233         if ( sType == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")) )
234             insertElement(sName,createObject(sName));
235     }
236 }
237 // -----------------------------------------------------------------------------
elementRemoved(const ContainerEvent & Event)238 void SAL_CALL OViewContainer::elementRemoved( const ContainerEvent& Event ) throw (RuntimeException)
239 {
240     ::osl::MutexGuard aGuard(m_rMutex);
241     ::rtl::OUString sName;
242     if ( (Event.Accessor >>= sName) && hasByName(sName) )
243     {
244         m_bInElementRemoved = true;
245         try
246         {
247             dropByName(sName);
248         }
249         catch(Exception&)
250         {
251             m_bInElementRemoved = sal_False;
252             throw;
253         }
254         m_bInElementRemoved = false;
255     }
256 }
257 // -----------------------------------------------------------------------------
disposing(const::com::sun::star::lang::EventObject &)258 void SAL_CALL OViewContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (RuntimeException)
259 {
260 }
261 // -----------------------------------------------------------------------------
elementReplaced(const ContainerEvent &)262 void SAL_CALL OViewContainer::elementReplaced( const ContainerEvent& /*Event*/ ) throw (RuntimeException)
263 {
264 }
265 // -----------------------------------------------------------------------------
getTableTypeRestriction() const266 ::rtl::OUString OViewContainer::getTableTypeRestriction() const
267 {
268     // no restriction at all (other than the ones provided externally)
269     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VIEW" ) );
270 }
271