1
/***************************************************************************
2
* Copyright (C) 2005 by Adam Treat *
5
* Copyright (C) 2004 by Scott Wheeler *
8
* This program is free software; you can redistribute it and/or modify *
9
* it under the terms of the GNU General Public License as published by *
10
* the Free Software Foundation; either version 2 of the License, or *
11
* (at your option) any later version. *
13
***************************************************************************/
15
#include <kapplication.h>
16
#include <kdatastream.h>
21
#include "datatablesearch.h"
22
#include "datasearchpopup.h"
23
#include "datatable.h"
24
#include "datakiosk.h"
26
#define widget (kapp->mainWidget())
28
DataTableSearch::DataTableSearch( SearchMode mode,
34
DataTableSearch::DataTableSearch( const DataTableList &dataTables,
35
const ComponentList &components,
40
m_dataTables( dataTables ),
41
m_originals( components ),
45
if ( m_level == Simple )
49
void DataTableSearch::search()
54
simpleSearchDataTable();
57
advancedSearchDataTable();
60
customSearchDataTable();
67
void DataTableSearch::dataSearchPopup()
69
DataSearchPopup::Result r =
70
DataSearchPopup( m_originals, m_level, widget, name().latin1() ).exec();
72
if ( !r.components.empty() )
73
m_updates = r.components;
76
void DataTableSearch::simpleSearchDataTable()
78
DataTable* dataTable = m_dataTables[0];
79
ComponentList::Iterator componentIt = m_originals.begin();
80
for ( ; componentIt != m_originals.end(); ++componentIt )
82
QString query = ( *componentIt ).query();
84
if ( query.isEmpty() )
86
dataTable->setSearchFilter( QString::null );
87
execQuery( dataTable, dataTable->defaultFilter() );
92
QStringList queries = QStringList::split( ' ', query );
95
for ( QStringList::Iterator it = queries.begin(); it != queries.end(); ++it )
100
for ( int i = 0; i < dataTable->dataTableView() ->numCols(); ++i )
102
if ( dataTable->dataField( i ) ->relation() )
107
dataTable->dataField( i ) ->fullName(),
108
dataTable->dataField( i ) ->relation() ->fullKey(),
109
dataTable->dataField( i ) ->relation() ->table(),
110
dataTable->dataField( i ) ->relation() ->fullField()
114
if ( i != dataTable->dataTableView() ->numCols() - 1 )
115
list.append( " OR " );
119
list.append( operatorSnippet( *it, dataTable->dataField( i ) ->fullName() ) );
121
if ( i != dataTable->dataTableView() ->numCols() - 1 )
122
list.append( " OR " );
126
if ( j != queries.count() )
127
list.append( " AND " );
130
if ( dataTable->defaultFilter() != QString::null ) //parent relation
132
list.prepend( " AND (" );
136
dataTable->setSearchFilter( list.join( "" ) );
137
execQuery( dataTable, dataTable->defaultFilter().append( dataTable->searchFilter() ) );
141
void DataTableSearch::advancedSearchDataTable()
144
QString sql = constructSQLForList( m_dataTables[ 0 ], true );
145
m_dataTables[ 0 ] ->setSearchFilter( sql );
146
execQuery( m_dataTables[ 0 ], sql );
149
void DataTableSearch::customSearchDataTable()
152
ComponentList components = m_updates.empty() ? m_originals : m_updates;
153
ComponentList::Iterator componentIt = components.begin();
154
for ( ; componentIt != components.end(); ++componentIt )
156
DataTable *dataTable = ( *componentIt ).dataTable();
159
QString sql = ( *componentIt ).query();
160
if ( dataTable != m_dataTables[0] )
161
sql.prepend( " AND " );
162
dataTable->setSearchFilter( sql );
163
execQuery( dataTable, dataTable->defaultFilter().append( dataTable->searchFilter() ) );
168
void DataTableSearch::execQuery( DataTable* dataTable, const QString &query )
173
dataTable->dataTableView() ->setFilter( query );
174
dataTable->dataTableEdit() ->setFilter( dataTable->dataTableView() ->filter() );
176
static_cast<DataKiosk*>( widget ) ->setStatusLeft( query );
177
if ( query != QString::null )
178
kdDebug() << query << endl;
180
QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
183
dataTable->tableRefresh();
184
dataTable->slotSelectFirstRow();
185
static_cast<DataKiosk*>( widget ) ->setStatusRight( QString::number( t.elapsed() ) );
186
QApplication::restoreOverrideCursor();
189
QString DataTableSearch::constructSQLForList( DataTable* dataTable, bool isRoot )
193
ComponentList components = m_updates.empty() ? m_originals : m_updates;
194
ComponentList::Iterator componentIt = components.begin();
195
for ( ; componentIt != components.end(); ++componentIt )
197
DataField *field = ( *componentIt ).dataField();
198
/* kdDebug() << field->name() << endl;*/
200
MatchMode mode = ( *componentIt ).matchMode();
201
/* kdDebug() << field->name() << endl;*/
203
QString query = ( *componentIt ).query();
204
/* kdDebug() << query << endl;*/
206
if ( dataTable ->dataField( field->name() ) == field )
208
if ( field ->relation() )
210
if ( !list.empty() && list[ list.count() ] != searchModeSnippet() )
211
list.append( searchModeSnippet() );
217
field ->relation() ->fullKey(),
218
field ->relation() ->table(),
219
field ->relation() ->fullField(),
226
if ( !list.empty() && list[ list.count() ] != searchModeSnippet() )
227
list.append( searchModeSnippet() );
229
list.append( operatorSnippet( query, field ->fullName(), mode ) );
235
(SELECT PROPERTY_ID FROM IR_PROPERTY_LISTING WHERE
237
(SELECT FIRM_ID FROM IR_FIRM WHERE (FIRM_SHORT_CODE LIKE '%%')))))
240
//Get a list of dataTables affected by this field
241
QStringList complex = getInheritanceTree( dataTable, field );
242
if ( complex.empty() )
245
if ( !list.empty() && list[ list.count() ] != searchModeSnippet() )
246
list.append( searchModeSnippet() );
249
for ( QStringList::Iterator it = complex.begin(); it != complex.end(); ++it )
252
DataTableList::Iterator it2 = m_dataTables.begin();
253
for ( ; it2 != m_dataTables.end(); ++it2 )
255
if ( ( *it ) == ( *it2 ) ->name() )
257
QString subselect = subselectSnippet( ( *it2 ) ->parentKey(),
258
( *it2 ) ->foreignKey(),
259
( *it2 ) ->tableName() );
260
list.append( subselect );
262
if ( j == complex.size() )
264
if ( field ->relation() )
266
QString relation = relationSnippet(
269
field ->relation() ->fullKey(),
270
field ->relation() ->table(),
271
field ->relation() ->fullField(),
274
list.append( relation );
278
QString operators = operatorSnippet( query, field ->fullName(), mode );
279
list.append( operators );
282
for ( uint k = 0; k < j; ++k )
283
list.append( subselectEndSnippet() );
288
QString sql = constructSQLForList( ( *it2 ) );
289
sql.prepend( " AND " );
290
( *it2 ) ->setSearchFilter( sql );
291
// kdDebug() << ( *it2 ) ->name() << endl;
292
// kdDebug() << ( *it2 )->defaultFilter().append( ( *it2 )->searchFilter() ) << endl;
300
return list.join( "" );
303
QStringList DataTableSearch::getInheritanceTree( DataTable* dataTable, DataField* dataField )
305
DataTable * childList = 0;
306
DataTableList::Iterator it = m_dataTables.begin();
307
for ( ; it != m_dataTables.end(); ++it )
308
if ( ( *it ) ->dataField( dataField->name() ) == dataField )
315
complex.prepend( childList->name() );
316
QString root = childList->parentName();
317
while ( dataTable ->name() != root )
319
if ( root.isEmpty() )
320
return QStringList();
322
complex.prepend( root );
323
DataTableList::Iterator it2 = m_dataTables.begin();
324
for ( ; it2 != m_dataTables.end(); ++it2 )
326
if ( ( *it2 ) ->name() == root )
328
root = ( *it2 ) ->parentName();
337
QString DataTableSearch::searchModeSnippet()
346
return QString::null;
350
QString DataTableSearch::relationSnippet( const QString &query, const QString &name, const QString &key,
351
const QString &table, const QString &field, MatchMode mode )
355
list.append( subselectSnippet( name, key, table ) );
356
list.append( operatorSnippet( query, field, mode ) );
357
list.append( subselectEndSnippet() );
358
return list.join( "" );
361
QString DataTableSearch::subselectSnippet( const QString &parentKey, const QString &foreignKey,
362
const QString &tableName )
366
list.append( parentKey );
367
list.append( " IN (SELECT " );
368
list.append( foreignKey );
369
list.append( " FROM " );
370
list.append( tableName );
371
list.append( " WHERE " );
372
return list.join( "" );
375
QString DataTableSearch::subselectEndSnippet()
380
QString DataTableSearch::operatorSnippet( const QString &query, const QString &name, MatchMode mode )
388
case DataTableSearch::Contains:
389
list.append( " LIKE '%" );
390
list.append( query );
393
case DataTableSearch::DoesNotContain:
394
list.append( " NOT LIKE '%" );
395
list.append( query );
398
case DataTableSearch::Equals:
399
list.append( " = '" );
400
list.append( query );
403
case DataTableSearch::DoesNotEqual:
404
list.append( " != '" );
405
list.append( query );
408
case DataTableSearch::IsNull:
409
list.append( " IS NULL" );
411
case DataTableSearch::IsNotNull:
412
list.append( " IS NOT NULL" );
414
case DataTableSearch::Before:
415
list.append( " < '" );
416
list.append( query );
419
case DataTableSearch::After:
420
list.append( " > '" );
421
list.append( query );
424
case DataTableSearch::OnOrBefore:
425
list.append( " <= '" );
426
list.append( query );
429
case DataTableSearch::OnOrAfter:
430
list.append( " >= '" );
431
list.append( query );
434
case DataTableSearch::LessThan:
435
list.append( " < '" );
436
list.append( query );
439
case DataTableSearch::GreaterThan:
440
list.append( " > '" );
441
list.append( query );
444
case DataTableSearch::LessOrEquals:
445
list.append( " <= '" );
446
list.append( query );
449
case DataTableSearch::GreaterOrEquals:
450
list.append( " >= '" );
451
list.append( query );
457
return list.join( "" );
460
QString DataTableSearch::parentName() const
462
DataTableList::ConstIterator it = m_dataTables.begin();
463
return ( *it ) ->name();
466
bool DataTableSearch::isEmpty() const
471
ComponentList::ConstIterator it = m_originals.begin();
472
for ( ; it != m_originals.end(); ++it )
474
if ( !( *it ).query().isEmpty() )
481
DataTableSearch::Component::Component() :
485
DataTableSearch::Component::Component( const QString &query,
486
DataTable *dataTable,
487
DataField *dataField,
491
m_dataTable( dataTable ),
492
m_dataField( dataField ),
497
bool DataTableSearch::Component::operator==( const Component &v ) const
499
return m_query == v.m_query &&