summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/ChangeLog4
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp46
2 files changed, 39 insertions, 11 deletions
diff --git a/libopie2/opiepim/ChangeLog b/libopie2/opiepim/ChangeLog
index 84517fb..acb6cb1 100644
--- a/libopie2/opiepim/ChangeLog
+++ b/libopie2/opiepim/ChangeLog
@@ -1,34 +1,36 @@
12005-03.19 Stefan Eilers <stefan@eilers-online.net> 12005-03-20 Stefan Eilers <stefan@eilers-online.net>
2 * #1608 Quickfix for problem with DateDiff on SQL backend. I have to rethink this solution, but due to the short time, this should work.
32005-03-19 Stefan Eilers <stefan@eilers-online.net>
2 * Minor update for sorted(). Now ignoring any category search if "DoNotShowWithCategory" filter is activated. 4 * Minor update for sorted(). Now ignoring any category search if "DoNotShowWithCategory" filter is activated.
3 * Fixing uninitialized member variable, caused crash of backend 5 * Fixing uninitialized member variable, caused crash of backend
42005-03-18 Stefan Eilers <stefan@eilers-online.net> 62005-03-18 Stefan Eilers <stefan@eilers-online.net>
5 * Rewrote generic sorted filter and added filter for "DoNotShowWithCategory", needed by addressbook (other filters need to be added!) 7 * Rewrote generic sorted filter and added filter for "DoNotShowWithCategory", needed by addressbook (other filters need to be added!)
62005-01-16 Stefan Eilers <stefan@eilers-online.net> 82005-01-16 Stefan Eilers <stefan@eilers-online.net>
7 * Added new OPimEventSortVector class, improved OPimSortVector 9 * Added new OPimEventSortVector class, improved OPimSortVector
8 * OPimAccessBackend now supports generic sorting. 10 * OPimAccessBackend now supports generic sorting.
92005-01-03 Stefan Eilers <stefan@eilers-online.net> 112005-01-03 Stefan Eilers <stefan@eilers-online.net>
10 * Fixing bug in API documentation 12 * Fixing bug in API documentation
11 * Moving hasQuerySettings() and querySettings() to OPimAccessTemplate to be available for all frontends 13 * Moving hasQuerySettings() and querySettings() to OPimAccessTemplate to be available for all frontends
122004-12-28 Stefan Eilers <stefan@eilers-online.net> 142004-12-28 Stefan Eilers <stefan@eilers-online.net>
13 * Make improved query by example accessable via frontend 15 * Make improved query by example accessable via frontend
14 * Some API documentation improvement 16 * Some API documentation improvement
15 * Cleanup of backend api.. 17 * Cleanup of backend api..
16 * Fixing bug #1501 18 * Fixing bug #1501
172004-11-23 Stefan Eilers <stefan@eilers-online.net> 192004-11-23 Stefan Eilers <stefan@eilers-online.net>
18 * Implement fast and full featured version of sorted() for addressbook 20 * Implement fast and full featured version of sorted() for addressbook
19 * Implement generic queryByExample for all Addressboook backends. It allows incremental search. 21 * Implement generic queryByExample for all Addressboook backends. It allows incremental search.
20 * Update of API Documentation 22 * Update of API Documentation
212004-11-18 Holger Freyther <freyther@handhelds.org> 232004-11-18 Holger Freyther <freyther@handhelds.org>
22 * Every Access can give a set of Occurrences for a period or a datetime 24 * Every Access can give a set of Occurrences for a period or a datetime
23 * QueryByExample, Find, Sort can be generically accessed by OPimBase 25 * QueryByExample, Find, Sort can be generically accessed by OPimBase
24 pointer interface 26 pointer interface
25 * OPimBackendOccurrence gets split up to OPimOccurrences by 27 * OPimBackendOccurrence gets split up to OPimOccurrences by
26 OPimTemplateBase 28 OPimTemplateBase
27 * Add safeCast to various OPimRecords 29 * Add safeCast to various OPimRecords
28 * Kill memleak in OPimTodo 30 * Kill memleak in OPimTodo
29 * Add SortVector implementations for OPimTodo and OPimContact 31 * Add SortVector implementations for OPimTodo and OPimContact
30 32
31 2004-??-??The Opie Team <opie@handhelds.org> 33 2004-??-??The Opie Team <opie@handhelds.org>
32 * Implemented some important modifications to allow to use OPimRecords as it is, without 34 * Implemented some important modifications to allow to use OPimRecords as it is, without
33 have to cast them. This makes it possible to write applications which handling pim 35 have to cast them. This makes it possible to write applications which handling pim
34 data in a generic manner (see opimconvertion tool) (eilers) \ No newline at end of file 36 data in a generic manner (see opimconvertion tool) (eilers) \ No newline at end of file
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index 2368865..50421e2 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -358,498 +358,524 @@ OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* a
358 OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) 358 OPimContactAccessBackend(), m_changed(false), m_driver( NULL )
359{ 359{
360 odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; 360 odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl;
361 QTime t; 361 QTime t;
362 t.start(); 362 t.start();
363 363
364 /* Expecting to access the default filename if nothing else is set */ 364 /* Expecting to access the default filename if nothing else is set */
365 if ( filename.isEmpty() ){ 365 if ( filename.isEmpty() ){
366 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 366 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
367 } else 367 } else
368 m_fileName = filename; 368 m_fileName = filename;
369 369
370 // Get the standart sql-driver from the OSQLManager.. 370 // Get the standart sql-driver from the OSQLManager..
371 OSQLManager man; 371 OSQLManager man;
372 m_driver = man.standard(); 372 m_driver = man.standard();
373 m_driver->setUrl( m_fileName ); 373 m_driver->setUrl( m_fileName );
374 374
375 load(); 375 load();
376 376
377 odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl; 377 odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl;
378} 378}
379 379
380OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () 380OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL ()
381{ 381{
382 if( m_driver ) 382 if( m_driver )
383 delete m_driver; 383 delete m_driver;
384} 384}
385 385
386bool OPimContactAccessBackend_SQL::load () 386bool OPimContactAccessBackend_SQL::load ()
387{ 387{
388 if (!m_driver->open() ) 388 if (!m_driver->open() )
389 return false; 389 return false;
390 390
391 // Don't expect that the database exists. 391 // Don't expect that the database exists.
392 // It is save here to create the table, even if it 392 // It is save here to create the table, even if it
393 // do exist. ( Is that correct for all databases ?? ) 393 // do exist. ( Is that correct for all databases ?? )
394 CreateQuery creat; 394 CreateQuery creat;
395 OSQLResult res = m_driver->query( &creat ); 395 OSQLResult res = m_driver->query( &creat );
396 396
397 update(); 397 update();
398 398
399 return true; 399 return true;
400 400
401} 401}
402 402
403bool OPimContactAccessBackend_SQL::reload() 403bool OPimContactAccessBackend_SQL::reload()
404{ 404{
405 return load(); 405 return load();
406} 406}
407 407
408bool OPimContactAccessBackend_SQL::save() 408bool OPimContactAccessBackend_SQL::save()
409{ 409{
410 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 410 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
411} 411}
412 412
413 413
414void OPimContactAccessBackend_SQL::clear () 414void OPimContactAccessBackend_SQL::clear ()
415{ 415{
416 ClearQuery cle; 416 ClearQuery cle;
417 OSQLResult res = m_driver->query( &cle ); 417 OSQLResult res = m_driver->query( &cle );
418 418
419 reload(); 419 reload();
420} 420}
421 421
422bool OPimContactAccessBackend_SQL::wasChangedExternally() 422bool OPimContactAccessBackend_SQL::wasChangedExternally()
423{ 423{
424 return false; 424 return false;
425} 425}
426 426
427UIDArray OPimContactAccessBackend_SQL::allRecords() const 427UIDArray OPimContactAccessBackend_SQL::allRecords() const
428{ 428{
429 429
430 // FIXME: Think about cute handling of changed tables.. 430 // FIXME: Think about cute handling of changed tables..
431 // Thus, we don't have to call update here... 431 // Thus, we don't have to call update here...
432 if ( m_changed ) 432 if ( m_changed )
433 ((OPimContactAccessBackend_SQL*)this)->update(); 433 ((OPimContactAccessBackend_SQL*)this)->update();
434 434
435 return m_uids; 435 return m_uids;
436} 436}
437 437
438bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) 438bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact )
439{ 439{
440 odebug << "add in contact SQL-Backend" << oendl; 440 odebug << "add in contact SQL-Backend" << oendl;
441 InsertQuery ins( newcontact ); 441 InsertQuery ins( newcontact );
442 OSQLResult res = m_driver->query( &ins ); 442 OSQLResult res = m_driver->query( &ins );
443 443
444 if ( res.state() == OSQLResult::Failure ) 444 if ( res.state() == OSQLResult::Failure )
445 return false; 445 return false;
446 446
447 int c = m_uids.count(); 447 int c = m_uids.count();
448 m_uids.resize( c+1 ); 448 m_uids.resize( c+1 );
449 m_uids[c] = newcontact.uid(); 449 m_uids[c] = newcontact.uid();
450 450
451 return true; 451 return true;
452} 452}
453 453
454 454
455bool OPimContactAccessBackend_SQL::remove ( int uid ) 455bool OPimContactAccessBackend_SQL::remove ( int uid )
456{ 456{
457 RemoveQuery rem( uid ); 457 RemoveQuery rem( uid );
458 OSQLResult res = m_driver->query(&rem ); 458 OSQLResult res = m_driver->query(&rem );
459 459
460 if ( res.state() == OSQLResult::Failure ) 460 if ( res.state() == OSQLResult::Failure )
461 return false; 461 return false;
462 462
463 m_changed = true; 463 m_changed = true;
464 464
465 return true; 465 return true;
466} 466}
467 467
468bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) 468bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact )
469{ 469{
470 if ( !remove( contact.uid() ) ) 470 if ( !remove( contact.uid() ) )
471 return false; 471 return false;
472 472
473 return add( contact ); 473 return add( contact );
474} 474}
475 475
476 476
477OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const 477OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
478{ 478{
479 odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; 479 odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl;
480 QTime t; 480 QTime t;
481 t.start(); 481 t.start();
482 482
483 OPimContact retContact( requestNonCustom( uid ) ); 483 OPimContact retContact( requestNonCustom( uid ) );
484 retContact.setExtraMap( requestCustom( uid ) ); 484 retContact.setExtraMap( requestCustom( uid ) );
485 485
486 odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; 486 odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl;
487 return retContact; 487 return retContact;
488} 488}
489 489
490OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const 490OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const
491{ 491{
492 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; 492 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl;
493 odebug << "searching for " << uid << "" << oendl; 493 odebug << "searching for " << uid << "" << oendl;
494 494
495 QTime t; 495 QTime t;
496 t.start(); 496 t.start();
497 497
498 uint numReadAhead = readAhead(); 498 uint numReadAhead = readAhead();
499 QArray<int> searchList( numReadAhead ); 499 QArray<int> searchList( numReadAhead );
500 500
501 uint size =0; 501 uint size =0;
502 502
503 // Build an array with all elements which should be requested and cached 503 // Build an array with all elements which should be requested and cached
504 // We will just request "numReadAhead" elements, starting from "current" position in 504 // We will just request "numReadAhead" elements, starting from "current" position in
505 // the list of many uids ! 505 // the list of many uids !
506 switch( direction ) { 506 switch( direction ) {
507 /* forward */ 507 /* forward */
508 case Frontend::Forward: 508 case Frontend::Forward:
509 for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { 509 for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) {
510 searchList[size] = queryUids[i]; 510 searchList[size] = queryUids[i];
511 size++; 511 size++;
512 } 512 }
513 break; 513 break;
514 /* reverse */ 514 /* reverse */
515 case Frontend::Reverse: 515 case Frontend::Reverse:
516 for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { 516 for ( uint i = current; i != 0 && size < numReadAhead; i-- ) {
517 searchList[size] = queryUids[i]; 517 searchList[size] = queryUids[i];
518 size++; 518 size++;
519 } 519 }
520 break; 520 break;
521 } 521 }
522 522
523 //Shrink to real size.. 523 //Shrink to real size..
524 searchList.resize( size ); 524 searchList.resize( size );
525 525
526 OPimContact retContact( requestContactsAndCache( uid, searchList ) ); 526 OPimContact retContact( requestContactsAndCache( uid, searchList ) );
527 527
528 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; 528 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl;
529 return retContact; 529 return retContact;
530} 530}
531 531
532 532
533UIDArray OPimContactAccessBackend_SQL::queryByExample ( const UIDArray& uidlist, const OPimContact &query, int settings, 533UIDArray OPimContactAccessBackend_SQL::queryByExample ( const UIDArray& uidlist, const OPimContact &query, int settings,
534 const QDateTime& qd ) const 534 const QDateTime& qd ) const
535{ 535{
536 QString qu = "SELECT uid FROM addressbook WHERE"; 536 QString qu = "SELECT uid FROM addressbook WHERE";
537 537
538 // Just add uid's selection if we really try to search in a subset of all uids! Otherwise this would 538 // Just add uid's selection if we really try to search in a subset of all uids! Otherwise this would
539 // just take time and memory! 539 // just take time and memory!
540 if ( uidlist.count() != m_uids.count() ) { 540 if ( uidlist.count() != m_uids.count() ) {
541 qu += " ("; 541 qu += " (";
542 542
543 for ( uint i = 0; i < uidlist.count(); i++ ) { 543 for ( uint i = 0; i < uidlist.count(); i++ ) {
544 qu += " uid = " + QString::number( uidlist[i] ) + " OR"; 544 qu += " uid = " + QString::number( uidlist[i] ) + " OR";
545 } 545 }
546 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 546 qu.remove( qu.length()-2, 2 ); // Hmmmm..
547 qu += " ) AND "; 547 qu += " ) AND ";
548 } 548 }
549 549
550 QString searchQuery =""; 550 QString searchQuery = "";
551 QString temp_searchQuery = "";
551 552
552 QDate startDate; 553 QDate startDate;
553 554
554 if ( qd.isValid() ) 555 if ( qd.isValid() )
555 startDate = qd.date(); 556 startDate = qd.date();
556 else 557 else
557 startDate = QDate::currentDate(); 558 startDate = QDate::currentDate();
558 559
559 560
560 QMap<int, QString> queryFields = query.toMap(); 561 QMap<int, QString> queryFields = query.toMap();
561 QStringList fieldList = OPimContactFields::untrfields( false ); 562 QStringList fieldList = OPimContactFields::untrfields( false );
562 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 563 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
563 564
564 // Convert every filled field to a SQL-Query 565 // Convert every filled field to a SQL-Query
565// bool isAnyFieldSelected = false; 566// bool isAnyFieldSelected = false;
566 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 567 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
567 568
568 int id = translate[*it]; 569 int id = translate[*it];
569 QString queryStr = queryFields[id]; 570 QString queryStr = queryFields[id];
570 QDate* endDate = 0l; 571 QDate* endDate = 0l;
571 572
572 if ( !queryStr.isEmpty() ){ 573 if ( !queryStr.isEmpty() ){
573 // If something is alredy stored in the query, add an "AND" 574 // If something is alredy stored in the query, add an "AND"
574 // to the end of the string to prepare for the next .. 575 // to the end of the string to prepare for the next ..
575 if ( !searchQuery.isEmpty() ) 576 if ( !searchQuery.isEmpty() )
576 searchQuery += " AND"; 577 searchQuery += " AND";
577 578
578// isAnyFieldSelected = true; 579// isAnyFieldSelected = true;
579 switch( id ){ 580 switch( id ){
580 case Qtopia::Birthday: 581 case Qtopia::Birthday:
581 endDate = new QDate( query.birthday() ); 582 endDate = new QDate( query.birthday() );
582 // Fall through ! 583 // Fall through !
583 case Qtopia::Anniversary: 584 case Qtopia::Anniversary:
584 if ( endDate == 0l ) 585 if ( endDate == 0l )
585 endDate = new QDate( query.anniversary() ); 586 endDate = new QDate( query.anniversary() );
586 587
587 if ( settings & OPimContactAccess::DateDiff ) { 588 if ( settings & OPimContactAccess::DateDiff ) {
588 searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) 589 // To handle datediffs correctly, we need to remove the year information from
590 // the birthday and anniversary.
591 // To do this efficiently, we will create a temporary table which contains the
592 // information we need and do the query on it.
593 // This table is just visible for this process and will be removed
594 // automatically after using.
595 temp_searchQuery = "CREATE TEMP TABLE bs ( uid, \"Birthday\", \"Anniversary\" );";
596 temp_searchQuery += "INSERT INTO bs SELECT uid,substr(\"Birthday\", 6, 10),substr(\"Anniversary\", 6, 10) FROM addressbook WHERE ( \"Birthday\" != '' OR \"Anniversary\" != '' );";
597
598 temp_searchQuery += QString( "SELECT uid FROM bs WHERE (\"%1\" <= '%2-%3\' AND \"%4\" >= '%5-%6')" )
589 .arg( *it ) 599 .arg( *it )
590 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) 600 //.arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) )
591 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) 601 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) )
592 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) 602 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) )
593 .arg( *it ) 603 .arg( *it )
594 .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) 604 //.arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) )
595 .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) 605 .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) )
596 .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; 606 .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ;
597 } 607 }
598 608
599 if ( settings & OPimContactAccess::DateYear ){ 609 if ( settings & OPimContactAccess::DateYear ){
600 if ( settings & OPimContactAccess::DateDiff ) 610 // if ( settings & OPimContactAccess::DateDiff )
601 searchQuery += " AND"; 611 // searchQuery += " AND";
602 612
603 searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) 613 searchQuery += QString( " (\"%1\" LIKE '%2-%')" )
604 .arg( *it ) 614 .arg( *it )
605 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); 615 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) );
606 } 616 }
607 617
608 if ( settings & OPimContactAccess::DateMonth ){ 618 if ( settings & OPimContactAccess::DateMonth ){
609 if ( ( settings & OPimContactAccess::DateDiff ) 619 if ( ( settings & OPimContactAccess::DateDiff )
610 || ( settings & OPimContactAccess::DateYear ) ) 620 || ( settings & OPimContactAccess::DateYear ) )
611 searchQuery += " AND"; 621 searchQuery += " AND";
612 622
613 searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) 623 searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" )
614 .arg( *it ) 624 .arg( *it )
615 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); 625 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) );
616 } 626 }
617 627
618 if ( settings & OPimContactAccess::DateDay ){ 628 if ( settings & OPimContactAccess::DateDay ){
619 if ( ( settings & OPimContactAccess::DateDiff ) 629 if ( ( settings & OPimContactAccess::DateDiff )
620 || ( settings & OPimContactAccess::DateYear ) 630 || ( settings & OPimContactAccess::DateYear )
621 || ( settings & OPimContactAccess::DateMonth ) ) 631 || ( settings & OPimContactAccess::DateMonth ) )
622 searchQuery += " AND"; 632 searchQuery += " AND";
623 633
624 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) 634 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" )
625 .arg( *it ) 635 .arg( *it )
626 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); 636 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) );
627 } 637 }
628 638
629 break; 639 break;
630 default: 640 default:
631 // Switching between case sensitive and insensitive... 641 // Switching between case sensitive and insensitive...
632 // LIKE is not case sensitive, GLOB is case sensitive 642 // LIKE is not case sensitive, GLOB is case sensitive
633 // Do exist a better solution to switch this ? 643 // Do exist a better solution to switch this ?
634 if ( settings & OPimContactAccess::IgnoreCase ) 644 if ( settings & OPimContactAccess::IgnoreCase )
635 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" 645 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'"
636 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; 646 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")";
637 else 647 else
638 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" 648 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'"
639 + queryStr + "'" + ")"; 649 + queryStr + "'" + ")";
640 650
641 } 651 }
642 } 652 }
643 653
644 delete endDate; 654 delete endDate;
645 } 655 }
646 // Skip trailing "AND"
647// if ( isAnyFieldSelected )
648// qu = qu.left( qu.length() - 4 );
649 656
650 qu += searchQuery; 657 // The following is very ugly! (eilers)
658 if ( !temp_searchQuery.isEmpty() && !searchQuery.isEmpty() ){
659 // If we use DateDiff, we have to intersect two queries.
660 qu = temp_searchQuery + QString( " INTERSECT " ) + qu + searchQuery;
661 } else if ( temp_searchQuery.isEmpty() && !searchQuery.isEmpty() ){
662 qu += searchQuery;
663 } else if ( !temp_searchQuery.isEmpty() && searchQuery.isEmpty() ){
664 // This will cause wrong results!! Uid filter is not used here!
665 qu = temp_searchQuery;
666 } else if ( temp_searchQuery.isEmpty() && searchQuery.isEmpty() ){
667 UIDArray empty;
668 return empty;
669 }
651 670
652 odebug << "queryByExample query: " << qu << "" << oendl; 671 odebug << "queryByExample query: " << qu << "" << oendl;
653 672
654 // Execute query and return the received uid's 673 // Execute query and return the received uid's
655 OSQLRawQuery raw( qu ); 674 OSQLRawQuery raw( qu );
656 OSQLResult res = m_driver->query( &raw ); 675 OSQLResult res = m_driver->query( &raw );
657 if ( res.state() != OSQLResult::Success ){ 676 if ( res.state() != OSQLResult::Success ){
658 UIDArray empty; 677 UIDArray empty;
659 return empty; 678 return empty;
660 } 679 }
661 680
662 UIDArray list = extractUids( res ); 681 UIDArray list = extractUids( res );
663 682
683 // Remove temp table if created
684 if ( !temp_searchQuery.isEmpty( ) ){
685 qu = "DROP TABLE bs";
686 OSQLRawQuery raw( qu );
687 OSQLResult res = m_driver->query( &raw );
688 }
689
664 return list; 690 return list;
665} 691}
666 692
667UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 693UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
668{ 694{
669#if 0 695#if 0
670 QArray<int> nix(0); 696 QArray<int> nix(0);
671 return nix; 697 return nix;
672 698
673#else 699#else
674 QString qu = "SELECT uid FROM addressbook WHERE ("; 700 QString qu = "SELECT uid FROM addressbook WHERE (";
675 QString searchlist; 701 QString searchlist;
676 702
677 QStringList fieldList = OPimContactFields::untrfields( false ); 703 QStringList fieldList = OPimContactFields::untrfields( false );
678 // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 704 // QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
679 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 705 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
680 if ( !searchlist.isEmpty() ) 706 if ( !searchlist.isEmpty() )
681 searchlist += " OR "; 707 searchlist += " OR ";
682 searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; 708 searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") ";
683 } 709 }
684 710
685 qu = qu + searchlist + ")"; 711 qu = qu + searchlist + ")";
686 712
687 odebug << "query: " << qu << "" << oendl; 713 odebug << "query: " << qu << "" << oendl;
688 714
689 OSQLRawQuery raw( qu ); 715 OSQLRawQuery raw( qu );
690 OSQLResult res = m_driver->query( &raw ); 716 OSQLResult res = m_driver->query( &raw );
691 717
692 return extractUids( res ); 718 return extractUids( res );
693 719
694 720
695#endif 721#endif
696} 722}
697 723
698const uint OPimContactAccessBackend_SQL::querySettings() const 724const uint OPimContactAccessBackend_SQL::querySettings() const
699{ 725{
700 return OPimContactAccess::IgnoreCase 726 return OPimContactAccess::IgnoreCase
701 | OPimContactAccess::WildCards 727 | OPimContactAccess::WildCards
702 | OPimContactAccess::DateDiff 728 | OPimContactAccess::DateDiff
703 | OPimContactAccess::DateYear 729 | OPimContactAccess::DateYear
704 | OPimContactAccess::DateMonth 730 | OPimContactAccess::DateMonth
705 | OPimContactAccess::DateDay 731 | OPimContactAccess::DateDay
706 ; 732 ;
707} 733}
708 734
709bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 735bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
710{ 736{
711 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 737 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
712 * may be added with any of the other settings. IgnoreCase should never used alone. 738 * may be added with any of the other settings. IgnoreCase should never used alone.
713 * Wildcards, RegExp, ExactMatch should never used at the same time... 739 * Wildcards, RegExp, ExactMatch should never used at the same time...
714 */ 740 */
715 741
716 // Step 1: Check whether the given settings are supported by this backend 742 // Step 1: Check whether the given settings are supported by this backend
717 if ( ( querySettings & ( 743 if ( ( querySettings & (
718 OPimContactAccess::IgnoreCase 744 OPimContactAccess::IgnoreCase
719 | OPimContactAccess::WildCards 745 | OPimContactAccess::WildCards
720 | OPimContactAccess::DateDiff 746 | OPimContactAccess::DateDiff
721 | OPimContactAccess::DateYear 747 | OPimContactAccess::DateYear
722 | OPimContactAccess::DateMonth 748 | OPimContactAccess::DateMonth
723 | OPimContactAccess::DateDay 749 | OPimContactAccess::DateDay
724// | OPimContactAccess::RegExp 750// | OPimContactAccess::RegExp
725// | OPimContactAccess::ExactMatch 751// | OPimContactAccess::ExactMatch
726 ) ) != querySettings ) 752 ) ) != querySettings )
727 return false; 753 return false;
728 754
729 // Step 2: Check whether the given combinations are ok.. 755 // Step 2: Check whether the given combinations are ok..
730 756
731 // IngoreCase alone is invalid 757 // IngoreCase alone is invalid
732 if ( querySettings == OPimContactAccess::IgnoreCase ) 758 if ( querySettings == OPimContactAccess::IgnoreCase )
733 return false; 759 return false;
734 760
735 // WildCards, RegExp and ExactMatch should never used at the same time 761 // WildCards, RegExp and ExactMatch should never used at the same time
736 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 762 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
737 | OPimContactAccess::DateDiff 763 | OPimContactAccess::DateDiff
738 | OPimContactAccess::DateYear 764 | OPimContactAccess::DateYear
739 | OPimContactAccess::DateMonth 765 | OPimContactAccess::DateMonth
740 | OPimContactAccess::DateDay 766 | OPimContactAccess::DateDay
741 ) 767 )
742 ){ 768 ){
743 case OPimContactAccess::RegExp: 769 case OPimContactAccess::RegExp:
744 return ( true ); 770 return ( true );
745 case OPimContactAccess::WildCards: 771 case OPimContactAccess::WildCards:
746 return ( true ); 772 return ( true );
747 case OPimContactAccess::ExactMatch: 773 case OPimContactAccess::ExactMatch:
748 return ( true ); 774 return ( true );
749 case 0: // one of the upper removed bits were set.. 775 case 0: // one of the upper removed bits were set..
750 return ( true ); 776 return ( true );
751 default: 777 default:
752 return ( false ); 778 return ( false );
753 } 779 }
754 780
755} 781}
756 782
757UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder, 783UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder,
758 int filter, const QArray<int>& categories )const 784 int filter, const QArray<int>& categories )const
759{ 785{
760 QTime t; 786 QTime t;
761 t.start(); 787 t.start();
762 788
763 QString query = "SELECT uid FROM addressbook"; 789 QString query = "SELECT uid FROM addressbook";
764 790
765 query += " WHERE ("; 791 query += " WHERE (";
766 for ( uint i = 0; i < ar.count(); i++ ) { 792 for ( uint i = 0; i < ar.count(); i++ ) {
767 query += " uid = " + QString::number( ar[i] ) + " OR"; 793 query += " uid = " + QString::number( ar[i] ) + " OR";
768 } 794 }
769 query.remove( query.length()-2, 2 ); // Hmmmm.. 795 query.remove( query.length()-2, 2 ); // Hmmmm..
770 query += ")"; 796 query += ")";
771 797
772 798
773 if ( filter != OPimBase::FilterOff ){ 799 if ( filter != OPimBase::FilterOff ){
774 if ( filter & OPimContactAccess::DoNotShowWithCategory ){ 800 if ( filter & OPimContactAccess::DoNotShowWithCategory ){
775 query += " AND ( \"Categories\" == '' )"; 801 query += " AND ( \"Categories\" == '' )";
776 } else if ( filter & OPimBase::FilterCategory ){ 802 } else if ( filter & OPimBase::FilterCategory ){
777 query += " AND ("; 803 query += " AND (";
778 for ( uint i = 0; i < categories.count(); i++ ){ 804 for ( uint i = 0; i < categories.count(); i++ ){
779 query += "\"Categories\" LIKE"; 805 query += "\"Categories\" LIKE";
780 query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR"; 806 query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR";
781 } 807 }
782 query.remove( query.length()-2, 2 ); // Hmmmm.. 808 query.remove( query.length()-2, 2 ); // Hmmmm..
783 query += ")"; 809 query += ")";
784 } 810 }
785 811
786 if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){ 812 if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){
787 query += " AND ( \"Children\" != '' )"; 813 query += " AND ( \"Children\" != '' )";
788 } 814 }
789 815
790 if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){ 816 if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){
791 query += " AND ( \"Anniversary\" != '' )"; 817 query += " AND ( \"Anniversary\" != '' )";
792 } 818 }
793 819
794 if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){ 820 if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){
795 query += " AND ( \"Birthday\" != '' )"; 821 query += " AND ( \"Birthday\" != '' )";
796 } 822 }
797 823
798 if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){ 824 if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){
799 // Expect that no Street means no Address, too! (eilers) 825 // Expect that no Street means no Address, too! (eilers)
800 query += " AND ( \"Home Street\" != '' )"; 826 query += " AND ( \"Home Street\" != '' )";
801 } 827 }
802 828
803 if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){ 829 if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){
804 // Expect that no Street means no Address, too! (eilers) 830 // Expect that no Street means no Address, too! (eilers)
805 query += " AND ( \"Business Street\" != '' )"; 831 query += " AND ( \"Business Street\" != '' )";
806 } 832 }
807 833
808 } 834 }
809 835
810 query += " ORDER BY"; 836 query += " ORDER BY";
811 837
812 switch ( sortOrder ) { 838 switch ( sortOrder ) {
813 case OPimContactAccess::SortSummary: 839 case OPimContactAccess::SortSummary:
814 query += " \"Notes\""; 840 query += " \"Notes\"";
815 break; 841 break;
816 case OPimContactAccess::SortByCategory: 842 case OPimContactAccess::SortByCategory:
817 query += " \"Categories\""; 843 query += " \"Categories\"";
818 break; 844 break;
819 case OPimContactAccess::SortByDate: 845 case OPimContactAccess::SortByDate:
820 query += " \"\""; 846 query += " \"\"";
821 break; 847 break;
822 case OPimContactAccess::SortTitle: 848 case OPimContactAccess::SortTitle:
823 query += " \"Name Title\""; 849 query += " \"Name Title\"";
824 break; 850 break;
825 case OPimContactAccess::SortFirstName: 851 case OPimContactAccess::SortFirstName:
826 query += " \"First Name\""; 852 query += " \"First Name\"";
827 break; 853 break;
828 case OPimContactAccess::SortMiddleName: 854 case OPimContactAccess::SortMiddleName:
829 query += " \"Middle Name\""; 855 query += " \"Middle Name\"";
830 break; 856 break;
831 case OPimContactAccess::SortLastName: 857 case OPimContactAccess::SortLastName:
832 query += " \"Last Name\""; 858 query += " \"Last Name\"";
833 break; 859 break;
834 case OPimContactAccess::SortFileAsName: 860 case OPimContactAccess::SortFileAsName:
835 query += " \"File As\""; 861 query += " \"File As\"";
836 break; 862 break;
837 case OPimContactAccess::SortSuffix: 863 case OPimContactAccess::SortSuffix:
838 query += " \"Suffix\""; 864 query += " \"Suffix\"";
839 break; 865 break;
840 case OPimContactAccess::SortEmail: 866 case OPimContactAccess::SortEmail:
841 query += " \"Default Email\""; 867 query += " \"Default Email\"";
842 break; 868 break;
843 case OPimContactAccess::SortNickname: 869 case OPimContactAccess::SortNickname:
844 query += " \"Nickname\""; 870 query += " \"Nickname\"";
845 break; 871 break;
846 case OPimContactAccess::SortAnniversary: 872 case OPimContactAccess::SortAnniversary:
847 query += " \"Anniversary\""; 873 query += " \"Anniversary\"";
848 break; 874 break;
849 case OPimContactAccess::SortBirthday: 875 case OPimContactAccess::SortBirthday:
850 query += " \"Birthday\""; 876 query += " \"Birthday\"";
851 break; 877 break;
852 case OPimContactAccess::SortGender: 878 case OPimContactAccess::SortGender:
853 query += " \"Gender\""; 879 query += " \"Gender\"";
854 break; 880 break;
855 default: 881 default: