Logo Search packages:      
Sourcecode: datakiosk version File versions  Download package

datatablesearch.cpp

/***************************************************************************
*   Copyright (C) 2005 by Adam Treat                                      *
*   treat@kde.org                                                         *
*                                                                         *
*   Copyright (C) 2004 by Scott Wheeler                                   *
*   wheeler@kde.org                                                       *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/

#include <kapplication.h>
#include <kdatastream.h>
#include <kdebug.h>

#include <qcursor.h>

#include "datatablesearch.h"
#include "datasearchpopup.h"
#include "datatable.h"
#include "datakiosk.h"

#define widget (kapp->mainWidget())

DataTableSearch::DataTableSearch( SearchMode mode,
                                  SearchLevel level ) :
        m_mode( mode ),
        m_level( level )
{}

DataTableSearch::DataTableSearch( const DataTableList &dataTables,
                                  const ComponentList &components,
                                  const QString &name,
                                  SearchMode mode,
                                  SearchLevel level ) :
        m_name( name ),
        m_dataTables( dataTables ),
        m_originals( components ),
        m_mode( mode ),
        m_level( level )
{
    if ( m_level == Simple )
        search();
}

void DataTableSearch::search()
{
    switch ( m_level )
    {
    case Simple:
        simpleSearchDataTable();
        return;
    case Advanced:
        advancedSearchDataTable();
        return;
    case Custom:
        customSearchDataTable();
        return;
    default:
        return;
    }
}

void DataTableSearch::dataSearchPopup()
{
    DataSearchPopup::Result r =
        DataSearchPopup( m_originals, m_level, widget, name().latin1() ).exec();

    if ( !r.components.empty() )
        m_updates = r.components;
}

void DataTableSearch::simpleSearchDataTable()
{
    DataTable* dataTable = m_dataTables[0];
    ComponentList::Iterator componentIt = m_originals.begin();
    for ( ; componentIt != m_originals.end(); ++componentIt )
    {
        QString query = ( *componentIt ).query();

        if ( query.isEmpty() )
        {
            dataTable->setSearchFilter( QString::null );
            execQuery( dataTable, dataTable->defaultFilter() );
            return ;
        }

        QStringList list;
        QStringList queries = QStringList::split( ' ', query );

        uint j = 0;
        for ( QStringList::Iterator it = queries.begin(); it != queries.end(); ++it )
        {
            ++j;

            list.append( "(" );
            for ( int i = 0; i < dataTable->dataTableView() ->numCols(); ++i )
            {
                if ( dataTable->dataField( i ) ->relation() )
                {
                    list.append(
                        relationSnippet(
                            *it,
                            dataTable->dataField( i ) ->fullName(),
                            dataTable->dataField( i ) ->relation() ->fullKey(),
                            dataTable->dataField( i ) ->relation() ->table(),
                            dataTable->dataField( i ) ->relation() ->fullField()
                        )
                    );

                    if ( i != dataTable->dataTableView() ->numCols() - 1 )
                        list.append( " OR " );
                    continue;
                }

                list.append( operatorSnippet( *it, dataTable->dataField( i ) ->fullName() ) );

                if ( i != dataTable->dataTableView() ->numCols() - 1 )
                    list.append( " OR " );
            }
            list.append( ")" );

            if ( j != queries.count() )
                list.append( " AND " );
        }

        if ( dataTable->defaultFilter() != QString::null )         //parent relation
        {
            list.prepend( " AND (" );
            list.append( ")" );
        }

        dataTable->setSearchFilter( list.join( "" ) );
        execQuery( dataTable, dataTable->defaultFilter().append( dataTable->searchFilter() ) );
    }
}

void DataTableSearch::advancedSearchDataTable()
{
    dataSearchPopup();
    QString sql = constructSQLForList( m_dataTables[ 0 ], true );
    m_dataTables[ 0 ] ->setSearchFilter( sql );
    execQuery( m_dataTables[ 0 ], sql );
}

void DataTableSearch::customSearchDataTable()
{
    dataSearchPopup();
    ComponentList components = m_updates.empty() ? m_originals : m_updates;
    ComponentList::Iterator componentIt = components.begin();
    for ( ; componentIt != components.end(); ++componentIt )
    {
        DataTable *dataTable = ( *componentIt ).dataTable();
        if ( !dataTable )
            continue;
        QString sql = ( *componentIt ).query();
        if ( dataTable != m_dataTables[0] )
            sql.prepend( " AND " );
        dataTable->setSearchFilter( sql );
        execQuery( dataTable, dataTable->defaultFilter().append( dataTable->searchFilter() ) );
    }
    return;
}

void DataTableSearch::execQuery( DataTable* dataTable, const QString &query )
{
    if ( !dataTable )
        return;

    dataTable->dataTableView() ->setFilter( query );
    dataTable->dataTableEdit() ->setFilter( dataTable->dataTableView() ->filter() );

    static_cast<DataKiosk*>( widget ) ->setStatusLeft( query );
    if ( query != QString::null )
        kdDebug() << query << endl;

    QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
    QTime t;
    t.start();
    dataTable->tableRefresh();
    dataTable->slotSelectFirstRow();
    static_cast<DataKiosk*>( widget ) ->setStatusRight( QString::number( t.elapsed() ) );
    QApplication::restoreOverrideCursor();
}

QString DataTableSearch::constructSQLForList( DataTable* dataTable, bool isRoot )
{
    QStringList list;

    ComponentList components = m_updates.empty() ? m_originals : m_updates;
    ComponentList::Iterator componentIt = components.begin();
    for ( ; componentIt != components.end(); ++componentIt )
    {
        DataField *field = ( *componentIt ).dataField();
        /*        kdDebug() << field->name() << endl;*/

        MatchMode mode = ( *componentIt ).matchMode();
        /*        kdDebug() << field->name() << endl;*/

        QString query = ( *componentIt ).query();
        /*        kdDebug() << query << endl;*/

        if ( dataTable ->dataField( field->name() ) == field )
        {
            if ( field ->relation() )
            {
                if ( !list.empty() && list[ list.count() ] != searchModeSnippet() )
                    list.append( searchModeSnippet() );

                list.append(
                    relationSnippet(
                        query,
                        field ->fullName(),
                        field ->relation() ->fullKey(),
                        field ->relation() ->table(),
                        field ->relation() ->fullField(),
                        mode
                    )
                );
                continue;
            }

            if ( !list.empty() && list[ list.count() ] != searchModeSnippet() )
                list.append( searchModeSnippet() );

            list.append( operatorSnippet( query, field ->fullName(), mode ) );
        }
        else
        {
            /*
            (PROPERTY_ID IN
             (SELECT PROPERTY_ID FROM IR_PROPERTY_LISTING WHERE
              (LISTING_FIRM_ID IN
               (SELECT FIRM_ID FROM IR_FIRM WHERE (FIRM_SHORT_CODE LIKE '%%')))))
               */

            //Get a list of dataTables affected by this field
            QStringList complex = getInheritanceTree( dataTable, field );
            if ( complex.empty() )
                continue;

            if ( !list.empty() && list[ list.count() ] != searchModeSnippet() )
                list.append( searchModeSnippet() );

            uint j = 0;
            for ( QStringList::Iterator it = complex.begin(); it != complex.end(); ++it )
            {
                ++j;
                DataTableList::Iterator it2 = m_dataTables.begin();
                for ( ; it2 != m_dataTables.end(); ++it2 )
                {
                    if ( ( *it ) == ( *it2 ) ->name() )
                    {
                        QString subselect = subselectSnippet( ( *it2 ) ->parentKey(),
                                                              ( *it2 ) ->foreignKey(),
                                                              ( *it2 ) ->tableName() );
                        list.append( subselect );

                        if ( j == complex.size() )
                        {
                            if ( field ->relation() )
                            {
                                QString relation = relationSnippet(
                                                       query,
                                                       field ->fullName(),
                                                       field ->relation() ->fullKey(),
                                                       field ->relation() ->table(),
                                                       field ->relation() ->fullField(),
                                                       mode
                                                   );
                                list.append( relation );
                            }
                            else
                            {
                                QString operators = operatorSnippet( query, field ->fullName(), mode );
                                list.append( operators );
                            }

                            for ( uint k = 0; k < j; ++k )
                                list.append( subselectEndSnippet() );
                        }

                        if ( isRoot )
                        {
                            QString sql = constructSQLForList( ( *it2 ) );
                            sql.prepend( " AND " );
                            ( *it2 ) ->setSearchFilter( sql );
//                             kdDebug() << ( *it2 ) ->name() << endl;
//                             kdDebug() << ( *it2 )->defaultFilter().append( ( *it2 )->searchFilter() ) << endl;
                        }
                    }
                }
            }
        }
    }

    return list.join( "" );
}

QStringList DataTableSearch::getInheritanceTree( DataTable* dataTable, DataField* dataField )
{
    DataTable * childList = 0;
    DataTableList::Iterator it = m_dataTables.begin();
    for ( ; it != m_dataTables.end(); ++it )
        if ( ( *it ) ->dataField( dataField->name() ) == dataField )
        {
            childList = ( *it );
            break;
        }

    QStringList complex;
    complex.prepend( childList->name() );
    QString root = childList->parentName();
    while ( dataTable ->name() != root )
    {
        if ( root.isEmpty() )
            return QStringList();

        complex.prepend( root );
        DataTableList::Iterator it2 = m_dataTables.begin();
        for ( ; it2 != m_dataTables.end(); ++it2 )
        {
            if ( ( *it2 ) ->name() == root )
            {
                root = ( *it2 ) ->parentName();
                break;
            }
        }
    }

    return complex;
}

QString DataTableSearch::searchModeSnippet()
{
    switch ( m_mode )
    {
    case MatchAny:
        return " OR " ;
    case MatchAll:
        return " AND ";
    default:
        return QString::null;
    }
}

QString DataTableSearch::relationSnippet( const QString &query, const QString &name, const QString &key,
        const QString &table, const QString &field, MatchMode mode )
{

    QStringList list;
    list.append( subselectSnippet( name, key, table ) );
    list.append( operatorSnippet( query, field, mode ) );
    list.append( subselectEndSnippet() );
    return list.join( "" );
}

QString DataTableSearch::subselectSnippet( const QString &parentKey, const QString &foreignKey,
        const QString &tableName )
{
    QStringList list;
    list.append( "(" );
    list.append( parentKey );
    list.append( " IN (SELECT " );
    list.append( foreignKey );
    list.append( " FROM " );
    list.append( tableName );
    list.append( " WHERE " );
    return list.join( "" );
}

QString DataTableSearch::subselectEndSnippet()
{
    return "))";
}

QString DataTableSearch::operatorSnippet( const QString &query, const QString &name, MatchMode mode )
{
    QStringList list;
    list.append( "(" );
    list.append( name );

    switch ( mode )
    {
    case DataTableSearch::Contains:
        list.append( " LIKE '%" );
        list.append( query );
        list.append( "%'" );
        break;
    case DataTableSearch::DoesNotContain:
        list.append( " NOT LIKE '%" );
        list.append( query );
        list.append( "%'" );
        break;
    case DataTableSearch::Equals:
        list.append( " = '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::DoesNotEqual:
        list.append( " != '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::IsNull:
        list.append( " IS NULL" );
        break;
    case DataTableSearch::IsNotNull:
        list.append( " IS NOT NULL" );
        break;
    case DataTableSearch::Before:
        list.append( " < '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::After:
        list.append( " > '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::OnOrBefore:
        list.append( " <= '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::OnOrAfter:
        list.append( " >= '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::LessThan:
        list.append( " < '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::GreaterThan:
        list.append( " > '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::LessOrEquals:
        list.append( " <= '" );
        list.append( query );
        list.append( "'" );
        break;
    case DataTableSearch::GreaterOrEquals:
        list.append( " >= '" );
        list.append( query );
        list.append( "'" );
        break;
    }

    list.append( ")" );
    return list.join( "" );
}

QString DataTableSearch::parentName() const
{
    DataTableList::ConstIterator it = m_dataTables.begin();
    return ( *it ) ->name();
}

bool DataTableSearch::isEmpty() const
{
    if ( isNull() )
        return true;

    ComponentList::ConstIterator it = m_originals.begin();
    for ( ; it != m_originals.end(); ++it )
    {
        if ( !( *it ).query().isEmpty() )
            return false;
    }

    return true;
}

DataTableSearch::Component::Component() :
        m_mode( Contains )
{}

DataTableSearch::Component::Component( const QString &query,
                                       DataTable *dataTable,
                                       DataField *dataField,
                                       bool prompt,
                                       MatchMode mode ) :
        m_query( query ),
        m_dataTable( dataTable ),
        m_dataField( dataField ),
        m_prompt( prompt ),
        m_mode( mode )
{}

bool DataTableSearch::Component::operator==( const Component &v ) const
{
    return m_query == v.m_query &&
           m_mode == v.m_mode;
}

#ifdef widget
#undef widget
#endif


Generated by  Doxygen 1.6.0   Back to index