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 //========================================================================== 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 //------------------------------------------------------------------------------ 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 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 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 258 void SAL_CALL OViewContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (RuntimeException) 259 { 260 } 261 // ----------------------------------------------------------------------------- 262 void SAL_CALL OViewContainer::elementReplaced( const ContainerEvent& /*Event*/ ) throw (RuntimeException) 263 { 264 } 265 // ----------------------------------------------------------------------------- 266 ::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