diff options
Diffstat (limited to 'dbaccess/source/core/api/SingleSelectQueryComposer.cxx')
-rw-r--r-- | dbaccess/source/core/api/SingleSelectQueryComposer.cxx | 237 |
1 files changed, 174 insertions, 63 deletions
diff --git a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx index 8bc9a665bc9d..69520d043c52 100644 --- a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx +++ b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx @@ -43,6 +43,8 @@ #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/sdb/BooleanComparisonMode.hpp> #include <com/sun/star/sdb/SQLFilterOperator.hpp> +#include <com/sun/star/sdb/XQueriesSupplier.hpp> +#include <com/sun/star/sdb/CommandType.hpp> #include <com/sun/star/sdbc/ColumnSearch.hpp> #include <com/sun/star/sdbc/DataType.hpp> #include <com/sun/star/sdbc/XResultSetMetaData.hpp> @@ -188,6 +190,53 @@ namespace if ( _bDispose ) _rIterator.dispose(); } + void lcl_addFilterCriteria_throw(sal_Int32 i_nFilterOperator,const ::rtl::OUString& i_sValue,::rtl::OUStringBuffer& o_sRet) + { + switch( i_nFilterOperator ) + { + case SQLFilterOperator::EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::NOT_EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::LESS: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::GREATER: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::LESS_EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::GREATER_EQUAL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::LIKE: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::NOT_LIKE: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE "))); + o_sRet.append(i_sValue); + break; + case SQLFilterOperator::SQLNULL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ); + break; + case SQLFilterOperator::NOT_SQLNULL: + o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ); + break; + default: + throw SQLException(); + } + } + } DBG_NAME(OSingleSelectQueryComposer) @@ -207,6 +256,7 @@ OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAcc ,m_aContext( _rContext ) ,m_pTables(NULL) ,m_nBoolCompareMode( BooleanComparisonMode::EQUAL_INTEGER ) + ,m_nCommandType(CommandType::COMMAND) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::OSingleSelectQueryComposer" ); DBG_CTOR(OSingleSelectQueryComposer,NULL); @@ -233,6 +283,9 @@ OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAcc { OSL_VERIFY( aValue >>= m_nBoolCompareMode ); } + Reference< XQueriesSupplier > xQueriesAccess(m_xConnection, UNO_QUERY); + if (xQueriesAccess.is()) + m_xConnectionQueries = xQueriesAccess->getQueries(); } catch(Exception&) { @@ -304,6 +357,7 @@ void SAL_CALL OSingleSelectQueryComposer::setQuery( const ::rtl::OUString& comma ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); ::osl::MutexGuard aGuard( m_aMutex ); + m_nCommandType = CommandType::COMMAND; // first clear the tables and columns clearCurrentCollections(); // now set the new one @@ -317,6 +371,84 @@ void SAL_CALL OSingleSelectQueryComposer::setQuery( const ::rtl::OUString& comma for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) m_aElementaryParts[ eLoopParts ] = ::rtl::OUString(); } +// ------------------------------------------------------------------------- +void SAL_CALL OSingleSelectQueryComposer::setCommand( const ::rtl::OUString& Command,sal_Int32 _nCommandType ) throw(SQLException, RuntimeException) +{ + ::rtl::OUStringBuffer sSQL; + switch(_nCommandType) + { + case CommandType::COMMAND: + setElementaryQuery(Command); + return; + case CommandType::TABLE: + if ( m_xConnectionTables->hasByName(Command) ) + { + sSQL.appendAscii("SELECT * FROM "); + Reference< XPropertySet > xTable; + try + { + m_xConnectionTables->getByName( Command ) >>= xTable; + } + catch(const WrappedTargetException& e) + { + SQLException e2; + if ( e.TargetException >>= e2 ) + throw e2; + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + + sSQL.append(dbtools::composeTableNameForSelect(m_xConnection,xTable)); + } + else + { + String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) ); + sMessage.SearchAndReplaceAscii( "$table$", Command ); + throwGenericSQLException(sMessage,*this); + } + break; + case CommandType::QUERY: + if ( m_xConnectionQueries->hasByName(Command) ) + { + + Reference<XPropertySet> xQuery(m_xConnectionQueries->getByName(Command),UNO_QUERY); + ::rtl::OUString sCommand; + xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand; + sSQL.append(sCommand); + } + else + { + String sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) ); + sMessage.SearchAndReplaceAscii( "$table$", Command ); + throwGenericSQLException(sMessage,*this); + } + + break; + default: + break; + } + ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); + + ::osl::MutexGuard aGuard( m_aMutex ); + m_nCommandType = _nCommandType; + m_sCommand = Command; + // first clear the tables and columns + clearCurrentCollections(); + // now set the new one + ::rtl::OUString sCommand = sSQL.makeStringAndClear(); + setElementaryQuery(sCommand); + m_sOrignal = sCommand; +/* + // reset the additive iterator to the same statement + parseAndCheck_throwError( m_aSqlParser, m_sOrignal, m_aAdditiveIterator, *this ); + + // we have no "elementary" parts anymore (means filter/groupby/having/order clauses) + for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) + m_aElementaryParts[ eLoopParts ] = ::rtl::OUString(); +*/ +} // ----------------------------------------------------------------------------- void OSingleSelectQueryComposer::setQuery_Impl( const ::rtl::OUString& command ) { @@ -348,18 +480,18 @@ Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getSt return getStructuredCondition(F_tmp); } // ----------------------------------------------------------------------------- -void SAL_CALL OSingleSelectQueryComposer::appendHavingClauseByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ) throw (SQLException, RuntimeException) +void SAL_CALL OSingleSelectQueryComposer::appendHavingClauseByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendHavingClauseByColumn" ); ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> F_tmp(&OSingleSelectQueryComposer::implSetHavingClause); - setConditionByColumn(column,andCriteria,F_tmp); + setConditionByColumn(column,andCriteria,F_tmp,filterOperator); } // ----------------------------------------------------------------------------- -void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ) throw(SQLException, RuntimeException) +void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw(SQLException, RuntimeException) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendFilterByColumn" ); ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> F_tmp(&OSingleSelectQueryComposer::implSetFilter); - setConditionByColumn(column,andCriteria,F_tmp); + setConditionByColumn(column,andCriteria,F_tmp,filterOperator); } // ----------------------------------------------------------------------------- ::rtl::OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column) @@ -657,6 +789,13 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr ::std::vector< ::rtl::OUString> aNames; ::vos::ORef< OSQLColumns> aSelectColumns; sal_Bool bCase = sal_True; + Reference< XNameAccess> xQueryColumns; + if ( m_nCommandType == CommandType::QUERY ) + { + Reference<XColumnsSupplier> xSup(m_xConnectionQueries->getByName(m_sCommand),UNO_QUERY); + if(xSup.is()) + xQueryColumns = xSup->getColumns(); + } do { @@ -738,7 +877,7 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr { // This is a valid case. If we can syntactically parse the query, but not semantically // (e.g. because it is based on a table we do not know), then there will be no SelectColumns - aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ); + aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ,xQueryColumns); break; } @@ -746,13 +885,21 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr const ::comphelper::TStringMixEqualFunctor aCaseCompareFunctor( bCase ); typedef ::std::set< size_t > SizeTSet; SizeTSet aUsedSelectColumns; + ::connectivity::parse::OParseColumn::StringMap aColumnNames; sal_Int32 nCount = xResultSetMeta->getColumnCount(); OSL_ENSURE( (size_t) nCount == aSelectColumns->get().size(), "OSingleSelectQueryComposer::getColumns: inconsistent column counts, this might result in wrong columns!" ); for(sal_Int32 i=1;i<=nCount;++i) { ::rtl::OUString sColumnName = xResultSetMeta->getColumnName(i); - ::rtl::OUString sColumnLabel = xResultSetMeta->getColumnLabel(i); + ::rtl::OUString sColumnLabel; + if ( xQueryColumns.is() && xQueryColumns->hasByName(sColumnName) ) + { + Reference<XPropertySet> xQueryColumn(xQueryColumns->getByName(sColumnName),UNO_QUERY_THROW); + xQueryColumn->getPropertyValue(PROPERTY_LABEL) >>= sColumnLabel; + } + else + sColumnLabel = xResultSetMeta->getColumnLabel(i); sal_Bool bFound = sal_False; OSQLColumns::Vector::const_iterator aFind = ::connectivity::find(aSelectColumns->get().begin(),aSelectColumns->get().end(),sColumnLabel,aCaseCompare); size_t nFoundSelectColumnPos = aFind - aSelectColumns->get().begin(); @@ -788,7 +935,7 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr if ( i > static_cast< sal_Int32>( aSelectColumns->get().size() ) ) { aSelectColumns->get().push_back( - ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ) + ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ,aColumnNames) ); OSL_ENSURE( aSelectColumns->get().size() == (size_t)i, "OSingleSelectQueryComposer::getColumns: inconsistency!" ); } @@ -932,16 +1079,16 @@ sal_Bool OSingleSelectQueryComposer::setANDCriteria( OSQLParseNode * pCondition, aItem.Name = getColumnName(pCondition->getChild(0),_rIterator); aItem.Value <<= aValue; aItem.Handle = 0; // just to know that this is not one the known ones - if (SQL_ISRULE(pCondition,like_predicate)) + if ( SQL_ISRULE(pCondition,like_predicate) ) { - if (pCondition->count() == 5) + if ( SQL_ISTOKEN(pCondition->getChild(1)->getChild(0),NOT) ) aItem.Handle = SQLFilterOperator::NOT_LIKE; else aItem.Handle = SQLFilterOperator::LIKE; } else if (SQL_ISRULE(pCondition,test_for_null)) { - if (SQL_ISTOKEN(pCondition->getChild(2),NOT) ) + if (SQL_ISTOKEN(pCondition->getChild(1)->getChild(2),NOT) ) aItem.Handle = SQLFilterOperator::NOT_SQLNULL; else aItem.Handle = SQLFilterOperator::SQLNULL; @@ -1103,7 +1250,7 @@ sal_Bool OSingleSelectQueryComposer::setComparsionPredicate(OSQLParseNode * pCon aValue = aValue.copy(aColumnName.getLength()); aValue.trim(); - aItem.Name = UniString(getColumnName(pCondition->getChild(0),_rIterator)); + aItem.Name = getColumnName(pCondition->getChild(0),_rIterator); aItem.Value <<= aValue; aItem.Handle = pCondition->getNodeType(); rFilter.push_back(aItem); @@ -1384,49 +1531,7 @@ namespace sRet.append(pAndIter->Name); ::rtl::OUString sValue; pAndIter->Value >>= sValue; - switch( pAndIter->Handle ) - { - case SQLFilterOperator::EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))); - sRet.append(sValue); - break; - case SQLFilterOperator::NOT_EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> "))); - sRet.append(sValue); - break; - case SQLFilterOperator::LESS: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < "))); - sRet.append(sValue); - break; - case SQLFilterOperator::GREATER: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > "))); - sRet.append(sValue); - break; - case SQLFilterOperator::LESS_EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= "))); - sRet.append(sValue); - break; - case SQLFilterOperator::GREATER_EQUAL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= "))); - sRet.append(sValue); - break; - case SQLFilterOperator::LIKE: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))); - sRet.append(sValue); - break; - case SQLFilterOperator::NOT_LIKE: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE "))); - sRet.append(sValue); - break; - case SQLFilterOperator::SQLNULL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ); - break; - case SQLFilterOperator::NOT_SQLNULL: - sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ); - break; - default: - throw IllegalArgumentException(); - } + lcl_addFilterCriteria_throw(pAndIter->Handle,sValue,sRet); ++pAndIter; if ( pAndIter != pAndEnd ) sRet.append(STR_AND); @@ -1453,7 +1558,7 @@ void SAL_CALL OSingleSelectQueryComposer::setStructuredHavingClause( const Seque setHavingClause(lcl_getCondition(filter)); } // ----------------------------------------------------------------------------- -void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor) +void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor,sal_Int32 filterOperator) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setConditionByColumn" ); ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); @@ -1518,18 +1623,24 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert aSQL.append( ::dbtools::quoteName( aQuote, aName ) ); } + if ( aValue.hasValue() ) { if( !m_xTypeConverter.is() ) m_aContext.createComponent( "com.sun.star.script.Converter", m_xTypeConverter ); OSL_ENSURE(m_xTypeConverter.is(),"NO typeconverter!"); + if ( nType != DataType::BOOLEAN && DataType::BIT != nType ) + { + ::rtl::OUString sEmpty; + lcl_addFilterCriteria_throw(filterOperator,sEmpty,aSQL); + } + switch(nType) { case DataType::VARCHAR: case DataType::CHAR: case DataType::LONGVARCHAR: - aSQL.append( STR_LIKE ); aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); break; case DataType::CLOB: @@ -1540,7 +1651,6 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert const ::sal_Int64 nLength = xClob->length(); if ( sal_Int64(nLength + aSQL.getLength() + STR_LIKE.getLength() ) < sal_Int64(SAL_MAX_INT32) ) { - aSQL.append( STR_LIKE ); aSQL.appendAscii("'"); aSQL.append( xClob->getSubString(1,(sal_Int32)nLength) ); aSQL.appendAscii("'"); @@ -1548,7 +1658,6 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert } else { - aSQL.append( STR_LIKE ); aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); } } @@ -1562,11 +1671,8 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert { if(nSearchable == ColumnSearch::CHAR) { - aSQL.append( STR_LIKE ); aSQL.appendAscii( "\'" ); } - else - aSQL.append( STR_EQUAL ); aSQL.appendAscii( "0x" ); const sal_Int8* pBegin = aSeq.getConstArray(); const sal_Int8* pEnd = pBegin + aSeq.getLength(); @@ -1592,13 +1698,18 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert } break; default: - aSQL.append( STR_EQUAL ); aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); break; } } else - aSQL.appendAscii( " IS NULL" ) ; + { + sal_Int32 nFilterOp = filterOperator; + if ( filterOperator != SQLFilterOperator::SQLNULL && filterOperator != SQLFilterOperator::NOT_SQLNULL ) + nFilterOp = SQLFilterOperator::SQLNULL; + ::rtl::OUString sEmpty; + lcl_addFilterCriteria_throw(nFilterOp,sEmpty,aSQL); + } // filter anhaengen // select ohne where und order by aufbauen |