/************************************************************************* * * $RCSfile: viewcontainer.cxx,v $ * * $Revision: 1.3 $ * * last change: $Author: oj $ $Date: 2001-04-26 09:12:09 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifndef _DBA_CORE_VIEWCONTAINER_HXX_ #include "viewcontainer.hxx" #endif #ifndef DBACCESS_SHARED_DBASTRINGS_HRC #include "dbastrings.hrc" #endif #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _WLDCRD_HXX #include #endif #ifndef _COMPHELPER_ENUMHELPER_HXX_ #include #endif #ifndef _DBA_CORE_RESOURCE_HXX_ #include "core_resource.hxx" #endif #ifndef _DBA_CORE_RESOURCE_HRC_ #include "core_resource.hrc" #endif #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_KEYRULE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ #include #endif #ifndef _COMPHELPER_TYPES_HXX_ #include #endif #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include #endif #ifndef _COMPHELPER_EXTRACT_HXX_ #include #endif #ifndef _DBHELPER_DBEXCEPTION_HXX_ #include #endif #ifndef _CONNECTIVITY_SDBCX_VIEW_HXX_ #include #endif using namespace dbaccess; using namespace dbtools; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::container; using namespace ::osl; using namespace ::comphelper; using namespace ::cppu; using namespace ::connectivity::sdbcx; //========================================================================== //= OViewContainer //========================================================================== DBG_NAME(OViewContainer) //------------------------------------------------------------------------------ OViewContainer::OViewContainer(::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, const Reference< XConnection >& _xCon, IWarningsContainer* _pWarningsContainer) :OCollection(_rParent,_xCon->getMetaData()->storesMixedCaseQuotedIdentifiers(),_rMutex,::std::vector< ::rtl::OUString>()) ,m_bConstructed(sal_False) ,m_xConnection(_xCon) ,m_xMetaData(_xCon->getMetaData()) ,m_pWarningsContainer(_pWarningsContainer) { DBG_CTOR(OViewContainer, NULL); } //------------------------------------------------------------------------------ OViewContainer::~OViewContainer() { // dispose(); DBG_DTOR(OViewContainer, NULL); } // ----------------------------------------------------------------------------- void SAL_CALL OViewContainer::acquire() throw(::com::sun::star::uno::RuntimeException) { m_rParent.acquire(); } // ----------------------------------------------------------------------------- void SAL_CALL OViewContainer::release() throw(::com::sun::star::uno::RuntimeException) { m_rParent.release(); } //------------------------------------------------------------------------------ /** compare two strings */ extern int #if defined( WNT ) __cdecl #endif #if defined( ICC ) && defined( OS2 ) _Optlink #endif NameCompare( const void* pFirst, const void* pSecond); // ------------------------------------------------------------------------- void OViewContainer::construct(const Reference< XNameAccess >& _rxMasterContainer, const Sequence< ::rtl::OUString >& _rTableFilter, const Sequence< ::rtl::OUString >& _rTableTypeFilter) { m_xMasterViews = _rxMasterContainer; if(m_xMasterViews.is()) { sal_Int32 nTableFilterLen = _rTableFilter.getLength(); sal_Bool bNoTableFilters = ((nTableFilterLen == 1) && _rTableFilter[0].equalsAsciiL("%", 1)); if(!bNoTableFilters) { Sequence< ::rtl::OUString > aTableFilter = _rTableFilter; Sequence< ::rtl::OUString > aTableTypeFilter = _rTableTypeFilter; // build sorted versions of the filter sequences, so the visibility decision is faster qsort(aTableFilter.getArray(), nTableFilterLen, sizeof(::rtl::OUString), NameCompare); // as we want to modify nTableFilterLen, remember this // for wildcard search : remove all table filters which are a wildcard expression and build a WilCard // for them ::std::vector< WildCard > aWCSearch; // contains the wildcards for the table filter ::rtl::OUString* pTableFilters = aTableFilter.getArray(); sal_Int32 nShiftPos = 0; String sCurrentWCExpression; for (sal_Int32 i=0; iindexOf('%') != -1) { sCurrentWCExpression = sal_Unicode('*'); sCurrentWCExpression += (const sal_Unicode*)pTableFilters[i].replace('%', '*'); sCurrentWCExpression += sal_Unicode('*'); aWCSearch.push_back(WildCard(sCurrentWCExpression)); } else { if (nShiftPos != i) pTableFilters[nShiftPos] = pTableFilters[i]; ++nShiftPos; } } // now aTableFilter contains nShiftPos non-wc-strings and aWCSearch all wc-strings aTableFilter.realloc(nShiftPos); nTableFilterLen = nShiftPos; Sequence< ::rtl::OUString> aNames = m_xMasterViews->getElementNames(); const ::rtl::OUString* pBegin = aNames.getConstArray(); const ::rtl::OUString* pEnd = pBegin + aNames.getLength(); for(;pBegin != pEnd;++pBegin) { if(isNameValid(*pBegin,aTableFilter,aTableTypeFilter,aWCSearch)) { m_aElements.push_back(m_aNameMap.insert(ObjectMap::value_type(*pBegin, NULL)).first); } } } else { // no filter so insert all names Sequence< ::rtl::OUString> aNames = m_xMasterViews->getElementNames(); const ::rtl::OUString* pBegin = aNames.getConstArray(); const ::rtl::OUString* pEnd = pBegin + aNames.getLength(); for(;pBegin != pEnd;++pBegin) m_aElements.push_back(m_aNameMap.insert(ObjectMap::value_type(*pBegin, NULL)).first); } m_bConstructed = sal_True; } } //------------------------------------------------------------------------------ void OViewContainer::disposing() { MutexGuard aGuard(m_rMutex); OCollection::disposing(); m_xMasterViews = NULL; m_xMetaData = NULL; m_bConstructed = sal_False; } // XServiceInfo //------------------------------------------------------------------------------ IMPLEMENT_SERVICE_INFO2(OViewContainer, "com.sun.star.sdb.dbaccess.OViewContainer", SERVICE_SDBCX_CONTAINER, SERVICE_SDBCX_TABLES) // ------------------------------------------------------------------------- sal_Bool OViewContainer::isNameValid( const ::rtl::OUString& _rName, const Sequence< ::rtl::OUString >& _rTableFilter, const Sequence< ::rtl::OUString >& _rTableTypeFilter, const ::std::vector< WildCard >& _rWCSearch) const { sal_Int32 nTableFilterLen = _rTableFilter.getLength(); sal_Bool bFilterMatch = (NULL != bsearch(&_rName, _rTableFilter.getConstArray(), nTableFilterLen, sizeof(::rtl::OUString), NameCompare)); // the table is allowed to "pass" if we had no filters at all or any of the non-wildcard filters matches if (!bFilterMatch && _rWCSearch.size()) { // or if one of the wildcrad expression matches String sWCCompare = (const sal_Unicode*)_rName; for ( ::std::vector< WildCard >::const_iterator aLoop = _rWCSearch.begin(); aLoop != _rWCSearch.end() && !bFilterMatch; ++aLoop ) bFilterMatch = aLoop->Matches(sWCCompare); } if (bFilterMatch) {// the table name is allowed (not filtered out) // no type filter if(!_rTableTypeFilter.getLength()) return sal_True; // this is expensive but there is no other way to get the type of the table Reference xTable; ::cppu::extractInterface(xTable,m_xMasterViews->getByName(_rName)); ::rtl::OUString aTypeName; xTable->getPropertyValue(PROPERTY_TYPE) >>= aTypeName; const ::rtl::OUString* pTypeBegin = _rTableTypeFilter.getConstArray(); const ::rtl::OUString* pTypeEnd = pTypeBegin + _rTableTypeFilter.getLength(); for(;pTypeBegin != pTypeEnd;++pTypeBegin) { if(*pTypeBegin == aTypeName) return sal_True; // same as break and then checking } } return sal_False; } // ------------------------------------------------------------------------- void OViewContainer::impl_refresh() throw(RuntimeException) { } // ----------------------------------------------------------------------------- Reference< XNamed > OViewContainer::createObject(const ::rtl::OUString& _rName) { OSL_ENSURE(m_xMasterViews.is(),"getByName: m_xMasterViews must be set!"); Reference< XNamed > xProp; if(m_xMasterViews.is() && m_xMasterViews->hasByName(_rName)) m_xMasterViews->getByName(_rName) >>= xProp; return xProp; } // ----------------------------------------------------------------------------- Reference< XPropertySet > OViewContainer::createEmptyObject() { Reference< XPropertySet > xRet; // frist we have to look if the master tables does support this // and if then create a table object as well with the master tables Reference xMasterColumnsSup; Reference xDataFactory(m_xMasterViews,UNO_QUERY); if(xDataFactory.is()) xRet = xDataFactory->createDataDescriptor(); else xRet = new ::connectivity::sdbcx::OView(isCaseSensitive(),m_xMetaData); return xRet; } // ----------------------------------------------------------------------------- // XAppend void SAL_CALL OViewContainer::appendByDescriptor( const Reference< XPropertySet >& descriptor ) throw(SQLException, ElementExistException, RuntimeException) { ::osl::MutexGuard aGuard(m_rMutex); // append the new table with a create stmt ::rtl::OUString aName = getString(descriptor->getPropertyValue(PROPERTY_NAME)); ObjectMap::iterator aIter = m_aNameMap.find(aName); if( aIter != m_aNameMap.end() || (m_xMasterViews.is() && m_xMasterViews->hasByName(aName))) throw ElementExistException(aName,*this); Reference xAppend(m_xMasterViews,UNO_QUERY); Reference< XPropertySet > xProp = descriptor; if(xAppend.is()) { xAppend->appendByDescriptor(descriptor); if(m_xMasterViews->hasByName(aName)) m_xMasterViews->getByName(aName) >>= xProp; } else { ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("CREATE VIEW "); ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; if(m_xMetaData->supportsCatalogsInTableDefinitions()) descriptor->getPropertyValue(PROPERTY_CATALOGNAME) >>= sCatalog; if(m_xMetaData->supportsSchemasInTableDefinitions()) descriptor->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema; descriptor->getPropertyValue(PROPERTY_NAME) >>= sTable; ::dbtools::composeTableName(m_xMetaData,sCatalog,sSchema,sTable,sComposedName,sal_True); if(!sComposedName.getLength()) ::dbtools::throwFunctionSequenceException(*this); aSql += sComposedName + ::rtl::OUString::createFromAscii(" AS "); ::rtl::OUString sCommand; descriptor->getPropertyValue(PROPERTY_NAME) >>= sCommand; aSql += sCommand; OSL_ENSURE(m_xConnection.is(),"Connection is null!"); Reference< XStatement > xStmt = m_xConnection->createStatement( ); if(xStmt.is()) xStmt->execute(aSql); } OCollection::appendByDescriptor(xProp); } // ------------------------------------------------------------------------- // XDrop void SAL_CALL OViewContainer::dropByName( const ::rtl::OUString& elementName ) throw(SQLException, NoSuchElementException, RuntimeException) { ::osl::MutexGuard aGuard(m_rMutex); ObjectMap::iterator aIter = m_aNameMap.find(elementName); if( aIter == m_aNameMap.end()) throw NoSuchElementException(elementName,*this); Reference< XDrop > xDrop(m_xMasterViews,UNO_QUERY); if(xDrop.is()) xDrop->dropByName(elementName); else { ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; Reference xTable(aIter->second.get(),UNO_QUERY); if(xTable.is()) { if(m_xMetaData->supportsCatalogsInTableDefinitions()) xTable->getPropertyValue(PROPERTY_CATALOGNAME) >>= sCatalog; if(m_xMetaData->supportsSchemasInTableDefinitions()) xTable->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema; xTable->getPropertyValue(PROPERTY_NAME) >>= sTable; ::dbtools::composeTableName(m_xMetaData,sCatalog,sSchema,sTable,sComposedName,sal_True); } if(!sComposedName.getLength()) ::dbtools::throwFunctionSequenceException(*this); ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP VIEW "); aSql += sComposedName; Reference< XStatement > xStmt = m_xConnection->createStatement( ); if(xStmt.is()) xStmt->execute(aSql); } OCollection::dropByName(elementName); } // ----------------------------------------------------------------------------- void SAL_CALL OViewContainer::dropByIndex( sal_Int32 index ) throw(SQLException, IndexOutOfBoundsException, RuntimeException) { ::osl::MutexGuard aGuard(m_rMutex); if (index < 0 || index >= getCount()) throw IndexOutOfBoundsException(); dropByName((*m_aElements[index]).first); } // -------------------------------------------------------------------------