-rw-r--r-- | libopie2/opiepim/ChangeLog | 4 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 46 |
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 @@ | |||
1 | 2005-03.19 Stefan Eilers <stefan@eilers-online.net> | 1 | 2005-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. | ||
3 | 2005-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 |
4 | 2005-03-18 Stefan Eilers <stefan@eilers-online.net> | 6 | 2005-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!) |
6 | 2005-01-16 Stefan Eilers <stefan@eilers-online.net> | 8 | 2005-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. |
9 | 2005-01-03 Stefan Eilers <stefan@eilers-online.net> | 11 | 2005-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 |
12 | 2004-12-28 Stefan Eilers <stefan@eilers-online.net> | 14 | 2004-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 |
17 | 2004-11-23 Stefan Eilers <stefan@eilers-online.net> | 19 | 2004-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 |
21 | 2004-11-18 Holger Freyther <freyther@handhelds.org> | 23 | 2004-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 | ||
380 | OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () | 380 | OPimContactAccessBackend_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 | ||
386 | bool OPimContactAccessBackend_SQL::load () | 386 | bool 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 | ||
403 | bool OPimContactAccessBackend_SQL::reload() | 403 | bool OPimContactAccessBackend_SQL::reload() |
404 | { | 404 | { |
405 | return load(); | 405 | return load(); |
406 | } | 406 | } |
407 | 407 | ||
408 | bool OPimContactAccessBackend_SQL::save() | 408 | bool 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 | ||
414 | void OPimContactAccessBackend_SQL::clear () | 414 | void 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 | ||
422 | bool OPimContactAccessBackend_SQL::wasChangedExternally() | 422 | bool OPimContactAccessBackend_SQL::wasChangedExternally() |
423 | { | 423 | { |
424 | return false; | 424 | return false; |
425 | } | 425 | } |
426 | 426 | ||
427 | UIDArray OPimContactAccessBackend_SQL::allRecords() const | 427 | UIDArray 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 | ||
438 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) | 438 | bool 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 | ||
455 | bool OPimContactAccessBackend_SQL::remove ( int uid ) | 455 | bool 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 | ||
468 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) | 468 | bool 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 | ||
477 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const | 477 | OPimContact 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 | ||
490 | OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const | 490 | OPimContact 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 | ||
533 | UIDArray OPimContactAccessBackend_SQL::queryByExample ( const UIDArray& uidlist, const OPimContact &query, int settings, | 533 | UIDArray 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 | ||
667 | UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 693 | UIDArray 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 | ||
698 | const uint OPimContactAccessBackend_SQL::querySettings() const | 724 | const 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 | ||
709 | bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const | 735 | bool 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 | ||
757 | UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder, | 783 | UIDArray 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: |