summaryrefslogtreecommitdiff
path: root/dbaccess/source/core/api/SingleSelectQueryComposer.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/core/api/SingleSelectQueryComposer.cxx')
-rw-r--r--dbaccess/source/core/api/SingleSelectQueryComposer.cxx237
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