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,33 +1,35 @@
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
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
@@ -518,178 +518,204 @@ OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUi
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