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