-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 154 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.h | 5 | ||||
-rw-r--r-- | libopie2/opiepim/backend/opimaccessbackend.h | 28 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 40 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimtemplatebase.h | 16 |
5 files changed, 196 insertions, 47 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index dda23cc..abfd944 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | |||
@@ -255,118 +255,119 @@ namespace { | |||
255 | 255 | ||
256 | // Now add custom data.. | 256 | // Now add custom data.. |
257 | int id = 0; | 257 | int id = 0; |
258 | id = 0; | 258 | id = 0; |
259 | QMap<QString, QString> customMap = m_contact.toExtraMap(); | 259 | QMap<QString, QString> customMap = m_contact.toExtraMap(); |
260 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | 260 | for( QMap<QString, QString>::Iterator it = customMap.begin(); |
261 | it != customMap.end(); ++it ){ | 261 | it != customMap.end(); ++it ){ |
262 | qu += "insert into custom_data VALUES(" | 262 | qu += "insert into custom_data VALUES(" |
263 | + QString::number( m_contact.uid() ) | 263 | + QString::number( m_contact.uid() ) |
264 | + "," | 264 | + "," |
265 | + QString::number( id++ ) | 265 | + QString::number( id++ ) |
266 | + ",'" | 266 | + ",'" |
267 | + it.key() | 267 | + it.key() |
268 | + "'," | 268 | + "'," |
269 | + "0" // Priority for future enhancements | 269 | + "0" // Priority for future enhancements |
270 | + ",'" | 270 | + ",'" |
271 | + it.data() | 271 | + it.data() |
272 | + "');"; | 272 | + "');"; |
273 | } | 273 | } |
274 | // qu += "commit;"; | 274 | // qu += "commit;"; |
275 | odebug << "add " << qu << "" << oendl; | 275 | odebug << "add " << qu << "" << oendl; |
276 | return qu; | 276 | return qu; |
277 | } | 277 | } |
278 | 278 | ||
279 | 279 | ||
280 | RemoveQuery::RemoveQuery(int uid ) | 280 | RemoveQuery::RemoveQuery(int uid ) |
281 | : OSQLQuery(), m_uid( uid ) {} | 281 | : OSQLQuery(), m_uid( uid ) {} |
282 | RemoveQuery::~RemoveQuery() {} | 282 | RemoveQuery::~RemoveQuery() {} |
283 | QString RemoveQuery::query()const { | 283 | QString RemoveQuery::query()const { |
284 | QString qu = "DELETE from addressbook where uid = " | 284 | QString qu = "DELETE from addressbook where uid = " |
285 | + QString::number(m_uid) + ";"; | 285 | + QString::number(m_uid) + ";"; |
286 | qu += "DELETE from custom_data where uid = " | 286 | qu += "DELETE from custom_data where uid = " |
287 | + QString::number(m_uid) + ";"; | 287 | + QString::number(m_uid) + ";"; |
288 | return qu; | 288 | return qu; |
289 | } | 289 | } |
290 | 290 | ||
291 | 291 | ||
292 | 292 | ||
293 | 293 | ||
294 | FindQuery::FindQuery(int uid) | 294 | FindQuery::FindQuery(int uid) |
295 | : OSQLQuery(), m_uid( uid ) { | 295 | : OSQLQuery(), m_uid( uid ) { |
296 | } | 296 | } |
297 | FindQuery::FindQuery(const QArray<int>& ints) | 297 | FindQuery::FindQuery(const QArray<int>& ints) |
298 | : OSQLQuery(), m_uids( ints ){ | 298 | : OSQLQuery(), m_uids( ints ){ |
299 | } | 299 | } |
300 | FindQuery::~FindQuery() { | 300 | FindQuery::~FindQuery() { |
301 | } | 301 | } |
302 | QString FindQuery::query()const{ | 302 | QString FindQuery::query()const{ |
303 | // if ( m_uids.count() == 0 ) | 303 | if ( m_uids.count() == 0 ) |
304 | return single(); | 304 | return single(); |
305 | else | ||
306 | return multi(); | ||
305 | } | 307 | } |
306 | /* | 308 | |
307 | else | 309 | QString FindQuery::multi()const { |
308 | return multi(); | 310 | QString qu = "select * from addressbook where"; |
309 | } | 311 | for (uint i = 0; i < m_uids.count(); i++ ) { |
310 | QString FindQuery::multi()const { | 312 | qu += " uid = " + QString::number( m_uids[i] ) + " OR"; |
311 | QString qu = "select uid, type, value from addressbook where"; | 313 | } |
312 | for (uint i = 0; i < m_uids.count(); i++ ) { | 314 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
313 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 315 | |
314 | } | 316 | odebug << "find query: " << qu << "" << oendl; |
315 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 317 | return qu; |
316 | return qu; | ||
317 | } | 318 | } |
318 | */ | ||
319 | QString FindQuery::single()const{ | ||
320 | QString qu = "select *"; | ||
321 | qu += " from addressbook where uid = " + QString::number(m_uid); | ||
322 | 319 | ||
323 | // owarn << "find query: " << qu << "" << oendl; | 320 | QString FindQuery::single()const{ |
324 | return qu; | 321 | QString qu = "select *"; |
322 | qu += " from addressbook where uid = " + QString::number(m_uid); | ||
323 | |||
324 | // owarn << "find query: " << qu << "" << oendl; | ||
325 | return qu; | ||
325 | } | 326 | } |
326 | 327 | ||
327 | 328 | ||
328 | FindCustomQuery::FindCustomQuery(int uid) | 329 | FindCustomQuery::FindCustomQuery(int uid) |
329 | : OSQLQuery(), m_uid( uid ) { | 330 | : OSQLQuery(), m_uid( uid ) { |
330 | } | 331 | } |
331 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 332 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
332 | : OSQLQuery(), m_uids( ints ){ | 333 | : OSQLQuery(), m_uids( ints ){ |
333 | } | 334 | } |
334 | FindCustomQuery::~FindCustomQuery() { | 335 | FindCustomQuery::~FindCustomQuery() { |
335 | } | 336 | } |
336 | QString FindCustomQuery::query()const{ | 337 | QString FindCustomQuery::query()const{ |
337 | // if ( m_uids.count() == 0 ) | 338 | // if ( m_uids.count() == 0 ) |
338 | return single(); | 339 | return single(); |
339 | } | 340 | } |
340 | QString FindCustomQuery::single()const{ | 341 | QString FindCustomQuery::single()const{ |
341 | QString qu = "select uid, type, value from custom_data where uid = "; | 342 | QString qu = "select uid, type, value from custom_data where uid = "; |
342 | qu += QString::number(m_uid); | 343 | qu += QString::number(m_uid); |
343 | return qu; | 344 | return qu; |
344 | } | 345 | } |
345 | 346 | ||
346 | }; | 347 | }; |
347 | 348 | ||
348 | 349 | ||
349 | /* --------------------------------------------------------------------------- */ | 350 | /* --------------------------------------------------------------------------- */ |
350 | 351 | ||
351 | namespace Opie { | 352 | namespace Opie { |
352 | 353 | ||
353 | OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, | 354 | OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, |
354 | const QString& filename ): | 355 | const QString& filename ): |
355 | OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) | 356 | OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) |
356 | { | 357 | { |
357 | odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; | 358 | odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; |
358 | QTime t; | 359 | QTime t; |
359 | t.start(); | 360 | t.start(); |
360 | 361 | ||
361 | /* Expecting to access the default filename if nothing else is set */ | 362 | /* Expecting to access the default filename if nothing else is set */ |
362 | if ( filename.isEmpty() ){ | 363 | if ( filename.isEmpty() ){ |
363 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 364 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
364 | } else | 365 | } else |
365 | m_fileName = filename; | 366 | m_fileName = filename; |
366 | 367 | ||
367 | // Get the standart sql-driver from the OSQLManager.. | 368 | // Get the standart sql-driver from the OSQLManager.. |
368 | OSQLManager man; | 369 | OSQLManager man; |
369 | m_driver = man.standard(); | 370 | m_driver = man.standard(); |
370 | m_driver->setUrl( m_fileName ); | 371 | m_driver->setUrl( m_fileName ); |
371 | 372 | ||
372 | load(); | 373 | load(); |
@@ -428,107 +429,148 @@ QArray<int> OPimContactAccessBackend_SQL::allRecords() const | |||
428 | // Thus, we don't have to call update here... | 429 | // Thus, we don't have to call update here... |
429 | if ( m_changed ) | 430 | if ( m_changed ) |
430 | ((OPimContactAccessBackend_SQL*)this)->update(); | 431 | ((OPimContactAccessBackend_SQL*)this)->update(); |
431 | 432 | ||
432 | return m_uids; | 433 | return m_uids; |
433 | } | 434 | } |
434 | 435 | ||
435 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) | 436 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) |
436 | { | 437 | { |
437 | odebug << "add in contact SQL-Backend" << oendl; | 438 | odebug << "add in contact SQL-Backend" << oendl; |
438 | InsertQuery ins( newcontact ); | 439 | InsertQuery ins( newcontact ); |
439 | OSQLResult res = m_driver->query( &ins ); | 440 | OSQLResult res = m_driver->query( &ins ); |
440 | 441 | ||
441 | if ( res.state() == OSQLResult::Failure ) | 442 | if ( res.state() == OSQLResult::Failure ) |
442 | return false; | 443 | return false; |
443 | 444 | ||
444 | int c = m_uids.count(); | 445 | int c = m_uids.count(); |
445 | m_uids.resize( c+1 ); | 446 | m_uids.resize( c+1 ); |
446 | m_uids[c] = newcontact.uid(); | 447 | m_uids[c] = newcontact.uid(); |
447 | 448 | ||
448 | return true; | 449 | return true; |
449 | } | 450 | } |
450 | 451 | ||
451 | 452 | ||
452 | bool OPimContactAccessBackend_SQL::remove ( int uid ) | 453 | bool OPimContactAccessBackend_SQL::remove ( int uid ) |
453 | { | 454 | { |
454 | RemoveQuery rem( uid ); | 455 | RemoveQuery rem( uid ); |
455 | OSQLResult res = m_driver->query(&rem ); | 456 | OSQLResult res = m_driver->query(&rem ); |
456 | 457 | ||
457 | if ( res.state() == OSQLResult::Failure ) | 458 | if ( res.state() == OSQLResult::Failure ) |
458 | return false; | 459 | return false; |
459 | 460 | ||
460 | m_changed = true; | 461 | m_changed = true; |
461 | 462 | ||
462 | return true; | 463 | return true; |
463 | } | 464 | } |
464 | 465 | ||
465 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) | 466 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) |
466 | { | 467 | { |
467 | if ( !remove( contact.uid() ) ) | 468 | if ( !remove( contact.uid() ) ) |
468 | return false; | 469 | return false; |
469 | 470 | ||
470 | return add( contact ); | 471 | return add( contact ); |
471 | } | 472 | } |
472 | 473 | ||
473 | 474 | ||
474 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const | 475 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const |
475 | { | 476 | { |
476 | odebug << "OPimContactAccessBackend_SQL::find()" << oendl; | 477 | odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; |
477 | QTime t; | 478 | QTime t; |
478 | t.start(); | 479 | t.start(); |
479 | 480 | ||
480 | OPimContact retContact( requestNonCustom( uid ) ); | 481 | OPimContact retContact( requestNonCustom( uid ) ); |
481 | retContact.setExtraMap( requestCustom( uid ) ); | 482 | retContact.setExtraMap( requestCustom( uid ) ); |
482 | 483 | ||
483 | odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; | 484 | odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; |
484 | return retContact; | 485 | return retContact; |
485 | } | 486 | } |
486 | 487 | ||
488 | OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const | ||
489 | { | ||
490 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; | ||
491 | odebug << "searching for " << uid << "" << oendl; | ||
492 | |||
493 | QTime t; | ||
494 | t.start(); | ||
495 | |||
496 | uint numReadAhead = readAhead(); | ||
497 | QArray<int> searchList( numReadAhead ); | ||
498 | |||
499 | uint size =0; | ||
500 | |||
501 | // Build an array with all elements which should be requested and cached | ||
502 | // We will just request "numReadAhead" elements, starting from "current" position in | ||
503 | // the list of many uids ! | ||
504 | switch( direction ) { | ||
505 | /* forward */ | ||
506 | case Frontend::Forward: | ||
507 | for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { | ||
508 | searchList[size] = queryUids[i]; | ||
509 | size++; | ||
510 | } | ||
511 | break; | ||
512 | /* reverse */ | ||
513 | case Frontend::Reverse: | ||
514 | for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { | ||
515 | searchList[size] = queryUids[i]; | ||
516 | size++; | ||
517 | } | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | //Shrink to real size.. | ||
522 | searchList.resize( size ); | ||
523 | |||
524 | OPimContact retContact( requestContactsAndCache( uid, searchList ) ); | ||
525 | |||
526 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; | ||
527 | return retContact; | ||
528 | } | ||
487 | 529 | ||
488 | 530 | ||
489 | QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) | 531 | QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) |
490 | { | 532 | { |
491 | QString qu = "SELECT uid FROM addressbook WHERE"; | 533 | QString qu = "SELECT uid FROM addressbook WHERE"; |
492 | QString searchQuery =""; | 534 | QString searchQuery =""; |
493 | 535 | ||
494 | QDate startDate; | 536 | QDate startDate; |
495 | 537 | ||
496 | if ( qd.isValid() ) | 538 | if ( qd.isValid() ) |
497 | startDate = qd.date(); | 539 | startDate = qd.date(); |
498 | else | 540 | else |
499 | startDate = QDate::currentDate(); | 541 | startDate = QDate::currentDate(); |
500 | 542 | ||
501 | 543 | ||
502 | QMap<int, QString> queryFields = query.toMap(); | 544 | QMap<int, QString> queryFields = query.toMap(); |
503 | QStringList fieldList = OPimContactFields::untrfields( false ); | 545 | QStringList fieldList = OPimContactFields::untrfields( false ); |
504 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 546 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
505 | 547 | ||
506 | // Convert every filled field to a SQL-Query | 548 | // Convert every filled field to a SQL-Query |
507 | // bool isAnyFieldSelected = false; | 549 | // bool isAnyFieldSelected = false; |
508 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 550 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
509 | 551 | ||
510 | int id = translate[*it]; | 552 | int id = translate[*it]; |
511 | QString queryStr = queryFields[id]; | 553 | QString queryStr = queryFields[id]; |
512 | QDate* endDate = 0l; | 554 | QDate* endDate = 0l; |
513 | 555 | ||
514 | if ( !queryStr.isEmpty() ){ | 556 | if ( !queryStr.isEmpty() ){ |
515 | // If something is alredy stored in the query, add an "AND" | 557 | // If something is alredy stored in the query, add an "AND" |
516 | // to the end of the string to prepare for the next .. | 558 | // to the end of the string to prepare for the next .. |
517 | if ( !searchQuery.isEmpty() ) | 559 | if ( !searchQuery.isEmpty() ) |
518 | searchQuery += " AND"; | 560 | searchQuery += " AND"; |
519 | 561 | ||
520 | // isAnyFieldSelected = true; | 562 | // isAnyFieldSelected = true; |
521 | switch( id ){ | 563 | switch( id ){ |
522 | case Qtopia::Birthday: | 564 | case Qtopia::Birthday: |
523 | endDate = new QDate( query.birthday() ); | 565 | endDate = new QDate( query.birthday() ); |
524 | // Fall through ! | 566 | // Fall through ! |
525 | case Qtopia::Anniversary: | 567 | case Qtopia::Anniversary: |
526 | if ( endDate == 0l ) | 568 | if ( endDate == 0l ) |
527 | endDate = new QDate( query.anniversary() ); | 569 | endDate = new QDate( query.anniversary() ); |
528 | 570 | ||
529 | if ( settings & OPimContactAccess::DateDiff ) { | 571 | if ( settings & OPimContactAccess::DateDiff ) { |
530 | searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) | 572 | searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) |
531 | .arg( *it ) | 573 | .arg( *it ) |
532 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) | 574 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) |
533 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) | 575 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) |
534 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) | 576 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) |
@@ -723,134 +765,186 @@ QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) | |||
723 | 765 | ||
724 | void OPimContactAccessBackend_SQL::update() | 766 | void OPimContactAccessBackend_SQL::update() |
725 | { | 767 | { |
726 | odebug << "Update starts" << oendl; | 768 | odebug << "Update starts" << oendl; |
727 | QTime t; | 769 | QTime t; |
728 | t.start(); | 770 | t.start(); |
729 | 771 | ||
730 | // Now load the database set and extract the uid's | 772 | // Now load the database set and extract the uid's |
731 | // which will be held locally | 773 | // which will be held locally |
732 | 774 | ||
733 | LoadQuery lo; | 775 | LoadQuery lo; |
734 | OSQLResult res = m_driver->query(&lo); | 776 | OSQLResult res = m_driver->query(&lo); |
735 | if ( res.state() != OSQLResult::Success ) | 777 | if ( res.state() != OSQLResult::Success ) |
736 | return; | 778 | return; |
737 | 779 | ||
738 | m_uids = extractUids( res ); | 780 | m_uids = extractUids( res ); |
739 | 781 | ||
740 | m_changed = false; | 782 | m_changed = false; |
741 | 783 | ||
742 | odebug << "Update ends " << t.elapsed() << " ms" << oendl; | 784 | odebug << "Update ends " << t.elapsed() << " ms" << oendl; |
743 | } | 785 | } |
744 | 786 | ||
745 | QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const | 787 | QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const |
746 | { | 788 | { |
747 | odebug << "extractUids" << oendl; | 789 | odebug << "extractUids" << oendl; |
748 | QTime t; | 790 | QTime t; |
749 | t.start(); | 791 | t.start(); |
750 | OSQLResultItem::ValueList list = res.results(); | 792 | OSQLResultItem::ValueList list = res.results(); |
751 | OSQLResultItem::ValueList::Iterator it; | 793 | OSQLResultItem::ValueList::Iterator it; |
752 | QArray<int> ints(list.count() ); | 794 | QArray<int> ints(list.count() ); |
753 | odebug << " count = " << list.count() << "" << oendl; | 795 | odebug << " count = " << list.count() << "" << oendl; |
754 | 796 | ||
755 | int i = 0; | 797 | int i = 0; |
756 | for (it = list.begin(); it != list.end(); ++it ) { | 798 | for (it = list.begin(); it != list.end(); ++it ) { |
757 | ints[i] = (*it).data("uid").toInt(); | 799 | ints[i] = (*it).data("uid").toInt(); |
758 | i++; | 800 | i++; |
759 | } | 801 | } |
760 | odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; | 802 | odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; |
761 | 803 | ||
762 | return ints; | 804 | return ints; |
763 | 805 | ||
764 | } | 806 | } |
765 | 807 | ||
766 | QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const | 808 | QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const |
767 | { | 809 | { |
768 | QTime t; | 810 | QTime t; |
769 | t.start(); | 811 | t.start(); |
770 | 812 | ||
771 | QMap<int, QString> nonCustomMap; | ||
772 | |||
773 | int t2needed = 0; | 813 | int t2needed = 0; |
774 | int t3needed = 0; | 814 | int t3needed = 0; |
775 | QTime t2; | 815 | QTime t2; |
776 | t2.start(); | 816 | t2.start(); |
777 | FindQuery query( uid ); | 817 | FindQuery query( uid ); |
778 | OSQLResult res_noncustom = m_driver->query( &query ); | 818 | OSQLResult res_noncustom = m_driver->query( &query ); |
779 | t2needed = t2.elapsed(); | 819 | t2needed = t2.elapsed(); |
780 | 820 | ||
781 | OSQLResultItem resItem = res_noncustom.first(); | 821 | OSQLResultItem resItem = res_noncustom.first(); |
782 | 822 | ||
823 | QMap<int, QString> nonCustomMap; | ||
783 | QTime t3; | 824 | QTime t3; |
784 | t3.start(); | 825 | t3.start(); |
826 | nonCustomMap = fillNonCustomMap( resItem ); | ||
827 | t3needed = t3.elapsed(); | ||
828 | |||
829 | |||
830 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | ||
831 | odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | ||
832 | << " ms, mapping: " << t3needed << " ms" << oendl; | ||
833 | |||
834 | return nonCustomMap; | ||
835 | } | ||
836 | |||
837 | /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ | ||
838 | OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const | ||
839 | { | ||
840 | // We want to get all contacts with one query. | ||
841 | // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). | ||
842 | // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned | ||
843 | // by using the cache.. | ||
844 | QArray<int> cachelist = uidlist; | ||
845 | |||
846 | odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; | ||
847 | |||
848 | QTime t; | ||
849 | t.start(); | ||
850 | |||
851 | int t2needed = 0; | ||
852 | int t3needed = 0; | ||
853 | QTime t2; | ||
854 | t2.start(); | ||
855 | FindQuery query( cachelist ); | ||
856 | OSQLResult res_noncustom = m_driver->query( &query ); | ||
857 | t2needed = t2.elapsed(); | ||
858 | |||
859 | QMap<int, QString> nonCustomMap; | ||
860 | QTime t3; | ||
861 | t3.start(); | ||
862 | OSQLResultItem resItem = res_noncustom.first(); | ||
863 | do { | ||
864 | OPimContact contact( fillNonCustomMap( resItem ) ); | ||
865 | contact.setExtraMap( requestCustom( contact.uid() ) ); | ||
866 | odebug << "Caching uid: " << contact.uid() << oendl; | ||
867 | cache( contact ); | ||
868 | resItem = res_noncustom.next(); | ||
869 | } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !! | ||
870 | t3needed = t3.elapsed(); | ||
871 | |||
872 | |||
873 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | ||
874 | odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | ||
875 | << " ms, mapping: " << t3needed << " ms" << oendl; | ||
876 | |||
877 | return cacheFind( uid ); | ||
878 | } | ||
879 | |||
880 | QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const | ||
881 | { | ||
882 | QMap<int, QString> nonCustomMap; | ||
883 | |||
785 | // Now loop through all columns | 884 | // Now loop through all columns |
786 | QStringList fieldList = OPimContactFields::untrfields( false ); | 885 | QStringList fieldList = OPimContactFields::untrfields( false ); |
787 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 886 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
788 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 887 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
789 | // Get data for the selected column and store it with the | 888 | // Get data for the selected column and store it with the |
790 | // corresponding id into the map.. | 889 | // corresponding id into the map.. |
791 | 890 | ||
792 | int id = translate[*it]; | 891 | int id = translate[*it]; |
793 | QString value = resItem.data( (*it) ); | 892 | QString value = resultItem.data( (*it) ); |
794 | 893 | ||
795 | // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; | 894 | // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; |
796 | 895 | ||
797 | switch( id ){ | 896 | switch( id ){ |
798 | case Qtopia::Birthday: | 897 | case Qtopia::Birthday: |
799 | case Qtopia::Anniversary:{ | 898 | case Qtopia::Anniversary:{ |
800 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) | 899 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) |
801 | QStringList list = QStringList::split( '-', value ); | 900 | QStringList list = QStringList::split( '-', value ); |
802 | QStringList::Iterator lit = list.begin(); | 901 | QStringList::Iterator lit = list.begin(); |
803 | int year = (*lit).toInt(); | 902 | int year = (*lit).toInt(); |
804 | int month = (*(++lit)).toInt(); | 903 | int month = (*(++lit)).toInt(); |
805 | int day = (*(++lit)).toInt(); | 904 | int day = (*(++lit)).toInt(); |
806 | if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ | 905 | if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ |
807 | QDate date( year, month, day ); | 906 | QDate date( year, month, day ); |
808 | nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); | 907 | nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); |
809 | } | 908 | } |
810 | } | 909 | } |
811 | break; | 910 | break; |
812 | case Qtopia::AddressCategory: | 911 | case Qtopia::AddressCategory: |
813 | odebug << "Category is: " << value << "" << oendl; | 912 | odebug << "Category is: " << value << "" << oendl; |
814 | default: | 913 | default: |
815 | nonCustomMap.insert( id, value ); | 914 | nonCustomMap.insert( id, value ); |
816 | } | 915 | } |
817 | } | 916 | } |
818 | 917 | ||
819 | // First insert uid | 918 | nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) ); |
820 | nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) ); | ||
821 | t3needed = t3.elapsed(); | ||
822 | |||
823 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | ||
824 | odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | ||
825 | << " ms, mapping: " << t3needed << " ms" << oendl; | ||
826 | 919 | ||
827 | return nonCustomMap; | 920 | return nonCustomMap; |
828 | } | 921 | } |
829 | 922 | ||
923 | |||
830 | QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const | 924 | QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const |
831 | { | 925 | { |
832 | QTime t; | 926 | QTime t; |
833 | t.start(); | 927 | t.start(); |
834 | 928 | ||
835 | QMap<QString, QString> customMap; | 929 | QMap<QString, QString> customMap; |
836 | 930 | ||
837 | FindCustomQuery query( uid ); | 931 | FindCustomQuery query( uid ); |
838 | OSQLResult res_custom = m_driver->query( &query ); | 932 | OSQLResult res_custom = m_driver->query( &query ); |
839 | 933 | ||
840 | if ( res_custom.state() == OSQLResult::Failure ) { | 934 | if ( res_custom.state() == OSQLResult::Failure ) { |
841 | owarn << "OSQLResult::Failure in find query !!" << oendl; | 935 | owarn << "OSQLResult::Failure in find query !!" << oendl; |
842 | QMap<QString, QString> empty; | 936 | QMap<QString, QString> empty; |
843 | return empty; | 937 | return empty; |
844 | } | 938 | } |
845 | 939 | ||
846 | OSQLResultItem::ValueList list = res_custom.results(); | 940 | OSQLResultItem::ValueList list = res_custom.results(); |
847 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 941 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
848 | for ( ; it != list.end(); ++it ) { | 942 | for ( ; it != list.end(); ++it ) { |
849 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); | 943 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); |
850 | } | 944 | } |
851 | 945 | ||
852 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; | 946 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; |
853 | return customMap; | 947 | return customMap; |
854 | } | 948 | } |
855 | 949 | ||
856 | } | 950 | } |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h index ba122ec..4f81735 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h | |||
@@ -28,86 +28,87 @@ | |||
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * SQL Backend for the OPIE-Contact Database. | 30 | * SQL Backend for the OPIE-Contact Database. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #ifndef _OPimContactAccessBackend_SQL_ | 33 | #ifndef _OPimContactAccessBackend_SQL_ |
34 | #define _OPimContactAccessBackend_SQL_ | 34 | #define _OPimContactAccessBackend_SQL_ |
35 | 35 | ||
36 | #include <opie2/ocontactaccessbackend.h> | 36 | #include <opie2/ocontactaccessbackend.h> |
37 | #include <opie2/ocontactaccess.h> | 37 | #include <opie2/ocontactaccess.h> |
38 | 38 | ||
39 | #include <qlist.h> | 39 | #include <qlist.h> |
40 | #include <qdict.h> | 40 | #include <qdict.h> |
41 | 41 | ||
42 | /* aren't in namespace Opie yet - alwin */ | 42 | /* aren't in namespace Opie yet - alwin */ |
43 | namespace Opie { | 43 | namespace Opie { |
44 | namespace DB { | 44 | namespace DB { |
45 | class OSQLDriver; | 45 | class OSQLDriver; |
46 | class OSQLResult; | 46 | class OSQLResult; |
47 | class OSQLResultItem; | 47 | class OSQLResultItem; |
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | namespace Opie { | 51 | namespace Opie { |
52 | 52 | ||
53 | /* the default xml implementation */ | 53 | /* the default xml implementation */ |
54 | /** | 54 | /** |
55 | * This class is the SQL implementation of a Contact backend | 55 | * This class is the SQL implementation of a Contact backend |
56 | * it does implement everything available for OPimContact. | 56 | * it does implement everything available for OPimContact. |
57 | * @see OPimAccessBackend for more information of available methods | 57 | * @see OPimAccessBackend for more information of available methods |
58 | */ | 58 | */ |
59 | class OPimContactAccessBackend_SQL : public OPimContactAccessBackend { | 59 | class OPimContactAccessBackend_SQL : public OPimContactAccessBackend { |
60 | public: | 60 | public: |
61 | OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); | 61 | OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); |
62 | 62 | ||
63 | ~OPimContactAccessBackend_SQL (); | 63 | ~OPimContactAccessBackend_SQL (); |
64 | 64 | ||
65 | bool save(); | 65 | bool save(); |
66 | 66 | ||
67 | bool load (); | 67 | bool load (); |
68 | 68 | ||
69 | void clear (); | 69 | void clear (); |
70 | 70 | ||
71 | bool wasChangedExternally(); | 71 | bool wasChangedExternally(); |
72 | 72 | ||
73 | QArray<int> allRecords() const; | 73 | QArray<int> allRecords() const; |
74 | 74 | ||
75 | OPimContact find ( int uid ) const; | 75 | OPimContact find ( int uid ) const; |
76 | // FIXME: Add lookahead-cache support ! | 76 | OPimContact find( int uid, const QArray<int>&, uint cur, Frontend::CacheDirection ) const; |
77 | //OPimContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | ||
78 | 77 | ||
79 | QArray<int> queryByExample ( const OPimContact &query, int settings, | 78 | QArray<int> queryByExample ( const OPimContact &query, int settings, |
80 | const QDateTime& d ); | 79 | const QDateTime& d ); |
81 | 80 | ||
82 | QArray<int> matchRegexp( const QRegExp &r ) const; | 81 | QArray<int> matchRegexp( const QRegExp &r ) const; |
83 | 82 | ||
84 | const uint querySettings(); | 83 | const uint querySettings(); |
85 | 84 | ||
86 | bool hasQuerySettings (uint querySettings) const; | 85 | bool hasQuerySettings (uint querySettings) const; |
87 | 86 | ||
88 | // Currently only asc implemented.. | 87 | // Currently only asc implemented.. |
89 | QArray<int> sorted( bool asc, int , int , int ); | 88 | QArray<int> sorted( bool asc, int , int , int ); |
90 | bool add ( const OPimContact &newcontact ); | 89 | bool add ( const OPimContact &newcontact ); |
91 | 90 | ||
92 | bool replace ( const OPimContact &contact ); | 91 | bool replace ( const OPimContact &contact ); |
93 | 92 | ||
94 | bool remove ( int uid ); | 93 | bool remove ( int uid ); |
95 | bool reload(); | 94 | bool reload(); |
96 | 95 | ||
97 | private: | 96 | private: |
98 | QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; | 97 | QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; |
99 | QMap<int, QString> requestNonCustom( int uid ) const; | 98 | QMap<int, QString> requestNonCustom( int uid ) const; |
100 | QMap<QString, QString> requestCustom( int uid ) const; | 99 | QMap<QString, QString> requestCustom( int uid ) const; |
100 | QMap<int, QString> fillNonCustomMap( const Opie::DB::OSQLResultItem& resultItem ) const; | ||
101 | OPimContact requestContactsAndCache( int uid, const QArray<int>& cachelist ) const; | ||
101 | void update(); | 102 | void update(); |
102 | 103 | ||
103 | protected: | 104 | protected: |
104 | bool m_changed; | 105 | bool m_changed; |
105 | QString m_fileName; | 106 | QString m_fileName; |
106 | QArray<int> m_uids; | 107 | QArray<int> m_uids; |
107 | 108 | ||
108 | Opie::DB::OSQLDriver* m_driver; | 109 | Opie::DB::OSQLDriver* m_driver; |
109 | }; | 110 | }; |
110 | 111 | ||
111 | } | 112 | } |
112 | 113 | ||
113 | #endif | 114 | #endif |
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index 0682063..15a7b7f 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h | |||
@@ -51,142 +51,162 @@ class OPimAccessBackend { | |||
51 | public: | 51 | public: |
52 | typedef OTemplateBase<T> Frontend; | 52 | typedef OTemplateBase<T> Frontend; |
53 | 53 | ||
54 | /** The access hint from the frontend */ | 54 | /** The access hint from the frontend */ |
55 | OPimAccessBackend(int access = 0); | 55 | OPimAccessBackend(int access = 0); |
56 | virtual ~OPimAccessBackend(); | 56 | virtual ~OPimAccessBackend(); |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * load the resource | 59 | * load the resource |
60 | */ | 60 | */ |
61 | virtual bool load() = 0; | 61 | virtual bool load() = 0; |
62 | 62 | ||
63 | /** | 63 | /** |
64 | * reload the resource | 64 | * reload the resource |
65 | */ | 65 | */ |
66 | virtual bool reload() = 0; | 66 | virtual bool reload() = 0; |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * save the resource and | 69 | * save the resource and |
70 | * all it's changes | 70 | * all it's changes |
71 | */ | 71 | */ |
72 | virtual bool save() = 0; | 72 | virtual bool save() = 0; |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * return an array of | 75 | * return an array of |
76 | * all available uids | 76 | * all available uids |
77 | */ | 77 | */ |
78 | virtual QArray<int> allRecords()const = 0; | 78 | virtual QArray<int> allRecords()const = 0; |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * return a List of records | 81 | * return a List of records |
82 | * that match the regex | 82 | * that match the regex |
83 | */ | 83 | */ |
84 | virtual QArray<int> matchRegexp(const QRegExp &r) const = 0; | 84 | virtual QArray<int> matchRegexp(const QRegExp &r) const = 0; |
85 | 85 | ||
86 | /** | 86 | /** |
87 | * queryByExample for T with the given Settings | 87 | * queryByExample for T with the given Settings |
88 | * | 88 | * |
89 | */ | 89 | */ |
90 | virtual QArray<int> queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() ) = 0; | 90 | virtual QArray<int> queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() ) = 0; |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * find the OPimRecord with uid @param uid | 93 | * find the OPimRecord with uid @param uid |
94 | * returns T and T.isEmpty() if nothing was found | 94 | * returns T and T.isEmpty() if nothing was found |
95 | */ | 95 | */ |
96 | virtual T find(int uid )const = 0; | 96 | virtual T find(int uid )const = 0; |
97 | 97 | ||
98 | virtual T find(int uid, const QArray<int>& items, | 98 | virtual T find(int uid, const QArray<int>& items, |
99 | uint current, typename Frontend::CacheDirection )const ; | 99 | uint current, typename Frontend::CacheDirection ) const; |
100 | /** | 100 | /** |
101 | * clear the back end | 101 | * clear the back end |
102 | */ | 102 | */ |
103 | virtual void clear() = 0; | 103 | virtual void clear() = 0; |
104 | 104 | ||
105 | /** | 105 | /** |
106 | * add T | 106 | * add T |
107 | */ | 107 | */ |
108 | virtual bool add( const T& t ) = 0; | 108 | virtual bool add( const T& t ) = 0; |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * remove | 111 | * remove |
112 | */ | 112 | */ |
113 | virtual bool remove( int uid ) = 0; | 113 | virtual bool remove( int uid ) = 0; |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * replace a record with T.uid() | 116 | * replace a record with T.uid() |
117 | */ | 117 | */ |
118 | virtual bool replace( const T& t ) = 0; | 118 | virtual bool replace( const T& t ) = 0; |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * setTheFrontEnd!!! | 121 | * setTheFrontEnd!!! |
122 | */ | 122 | */ |
123 | void setFrontend( Frontend* front ); | 123 | void setFrontend( Frontend* front ); |
124 | 124 | ||
125 | /** | 125 | /** |
126 | * set the read ahead count | 126 | * set the read ahead count |
127 | */ | 127 | */ |
128 | void setReadAhead( uint count ); | 128 | void setReadAhead( uint count ); |
129 | protected: | 129 | protected: |
130 | int access()const; | 130 | int access()const; |
131 | |||
131 | void cache( const T& t )const; | 132 | void cache( const T& t )const; |
132 | 133 | ||
134 | /** | ||
135 | * Returns the element with given uid out of the cache. | ||
136 | * Returns empty element if nothing was found. | ||
137 | * <b>Attention:</b> This just works if we have a frontend which contains the cache ! | ||
138 | */ | ||
139 | T cacheFind( int uid ) const; | ||
140 | |||
133 | /** | 141 | /** |
134 | * use a prime number here! | 142 | * use a prime number here! |
135 | */ | 143 | */ |
136 | void setSaneCacheSize( int ); | 144 | void setSaneCacheSize( int ); |
137 | 145 | ||
138 | uint readAhead()const; | 146 | uint readAhead()const; |
139 | 147 | ||
140 | private: | 148 | private: |
141 | OPimAccessBackendPrivate *d; | 149 | OPimAccessBackendPrivate *d; |
142 | Frontend* m_front; | 150 | Frontend* m_front; |
143 | uint m_read; | 151 | uint m_read; |
144 | int m_acc; | 152 | int m_acc; |
145 | 153 | ||
146 | }; | 154 | }; |
147 | 155 | ||
148 | template <class T> | 156 | template <class T> |
149 | OPimAccessBackend<T>::OPimAccessBackend(int acc) | 157 | OPimAccessBackend<T>::OPimAccessBackend(int acc) |
150 | : m_acc( acc ) | 158 | : m_acc( acc ) |
151 | { | 159 | { |
152 | m_front = 0l; | 160 | m_front = 0l; |
153 | } | 161 | } |
154 | template <class T> | 162 | template <class T> |
155 | OPimAccessBackend<T>::~OPimAccessBackend() { | 163 | OPimAccessBackend<T>::~OPimAccessBackend() { |
156 | 164 | ||
157 | } | 165 | } |
158 | template <class T> | 166 | template <class T> |
159 | void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { | 167 | void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { |
160 | m_front = fr; | 168 | m_front = fr; |
161 | } | 169 | } |
162 | template <class T> | 170 | template <class T> |
163 | void OPimAccessBackend<T>::cache( const T& t )const { | 171 | void OPimAccessBackend<T>::cache( const T& t )const { |
164 | if (m_front ) | 172 | if ( m_front ) |
165 | m_front->cache( t ); | 173 | m_front->cache( t ); |
166 | } | 174 | } |
175 | |||
176 | template <class T> | ||
177 | T OPimAccessBackend<T>::cacheFind( int uid )const { | ||
178 | if ( ! m_front ){ | ||
179 | qWarning ( "No frontend assigned ! Therefore we cannot access the cache to return the right element!" ); | ||
180 | return T(); | ||
181 | } | ||
182 | |||
183 | return m_front->cacheFind( uid ); | ||
184 | } | ||
185 | |||
167 | template <class T> | 186 | template <class T> |
168 | void OPimAccessBackend<T>::setSaneCacheSize( int size) { | 187 | void OPimAccessBackend<T>::setSaneCacheSize( int size) { |
169 | if (m_front ) | 188 | if ( m_front ) |
170 | m_front->setSaneCacheSize( size ); | 189 | m_front->setSaneCacheSize( size ); |
171 | } | 190 | } |
172 | template <class T> | 191 | template <class T> |
173 | T OPimAccessBackend<T>::find( int uid, const QArray<int>&, | 192 | T OPimAccessBackend<T>::find( int uid, const QArray<int>&, |
174 | uint, typename Frontend::CacheDirection )const { | 193 | uint, typename Frontend::CacheDirection ) const{ |
194 | qDebug( "*** Lookahead feature not supported. Fallback to default find!" ); | ||
175 | return find( uid ); | 195 | return find( uid ); |
176 | } | 196 | } |
177 | template <class T> | 197 | template <class T> |
178 | void OPimAccessBackend<T>::setReadAhead( uint count ) { | 198 | void OPimAccessBackend<T>::setReadAhead( uint count ) { |
179 | m_read = count; | 199 | m_read = count; |
180 | } | 200 | } |
181 | template <class T> | 201 | template <class T> |
182 | uint OPimAccessBackend<T>::readAhead()const { | 202 | uint OPimAccessBackend<T>::readAhead()const { |
183 | return m_read; | 203 | return m_read; |
184 | } | 204 | } |
185 | template <class T> | 205 | template <class T> |
186 | int OPimAccessBackend<T>::access()const { | 206 | int OPimAccessBackend<T>::access()const { |
187 | return m_acc; | 207 | return m_acc; |
188 | } | 208 | } |
189 | 209 | ||
190 | } | 210 | } |
191 | 211 | ||
192 | #endif | 212 | #endif |
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index 55d600a..6f01b46 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h | |||
@@ -1,351 +1,371 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Holger Freyther <zecke@handhelds.org> | 3 | Copyright (C) Holger Freyther <zecke@handhelds.org> |
4 | Copyright (C) Stefan Eilers <eilers.stefan@epost.de> | 4 | Copyright (C) Stefan Eilers <eilers.stefan@epost.de> |
5 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 5 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
6 | .=l. | 6 | .=l. |
7 | .>+-= | 7 | .>+-= |
8 | _;:, .> :=|. This program is free software; you can | 8 | _;:, .> :=|. This program is free software; you can |
9 | .> <`_, > . <= redistribute it and/or modify it under | 9 | .> <`_, > . <= redistribute it and/or modify it under |
10 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 10 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
11 | .="- .-=="i, .._ License as published by the Free Software | 11 | .="- .-=="i, .._ License as published by the Free Software |
12 | - . .-<_> .<> Foundation; either version 2 of the License, | 12 | - . .-<_> .<> Foundation; either version 2 of the License, |
13 | ._= =} : or (at your option) any later version. | 13 | ._= =} : or (at your option) any later version. |
14 | .%`+i> _;_. | 14 | .%`+i> _;_. |
15 | .i_,=:_. -<s. This program is distributed in the hope that | 15 | .i_,=:_. -<s. This program is distributed in the hope that |
16 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 16 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
17 | : .. .:, . . . without even the implied warranty of | 17 | : .. .:, . . . without even the implied warranty of |
18 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 18 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
19 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 19 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
20 | ..}^=.= = ; Library General Public License for more | 20 | ..}^=.= = ; Library General Public License for more |
21 | ++= -. .` .: details. | 21 | ++= -. .` .: details. |
22 | : = ...= . :.=- | 22 | : = ...= . :.=- |
23 | -. .:....=;==+<; You should have received a copy of the GNU | 23 | -. .:....=;==+<; You should have received a copy of the GNU |
24 | -_. . . )=. = Library General Public License along with | 24 | -_. . . )=. = Library General Public License along with |
25 | -- :-=` this library; see the file COPYING.LIB. | 25 | -- :-=` this library; see the file COPYING.LIB. |
26 | If not, write to the Free Software Foundation, | 26 | If not, write to the Free Software Foundation, |
27 | Inc., 59 Temple Place - Suite 330, | 27 | Inc., 59 Temple Place - Suite 330, |
28 | Boston, MA 02111-1307, USA. | 28 | Boston, MA 02111-1307, USA. |
29 | */ | 29 | */ |
30 | #ifndef OPIE_PIM_ACCESS_TEMPLATE_H | 30 | #ifndef OPIE_PIM_ACCESS_TEMPLATE_H |
31 | #define OPIE_PIM_ACCESS_TEMPLATE_H | 31 | #define OPIE_PIM_ACCESS_TEMPLATE_H |
32 | 32 | ||
33 | /* OPIE */ | 33 | /* OPIE */ |
34 | #include <opie2/opimrecord.h> | 34 | #include <opie2/opimrecord.h> |
35 | #include <opie2/opimaccessbackend.h> | 35 | #include <opie2/opimaccessbackend.h> |
36 | #include <opie2/opimrecordlist.h> | 36 | #include <opie2/opimrecordlist.h> |
37 | 37 | ||
38 | #include <opie2/opimcache.h> | ||
39 | #include <opie2/opimtemplatebase.h> | 38 | #include <opie2/opimtemplatebase.h> |
40 | #include <opie2/odebug.h> | 39 | #include <opie2/odebug.h> |
41 | 40 | ||
42 | /* QT */ | 41 | /* QT */ |
43 | #include <qarray.h> | 42 | #include <qarray.h> |
44 | 43 | ||
45 | namespace Opie { | 44 | namespace Opie { |
46 | 45 | ||
47 | class OPimAccessTemplatePrivate; | 46 | class OPimAccessTemplatePrivate; |
48 | /** | 47 | /** |
49 | * Thats the frontend to our OPIE PIM | 48 | * Thats the frontend to our OPIE PIM |
50 | * Library. Either you want to use it's | 49 | * Library. Either you want to use it's |
51 | * interface or you want to implement | 50 | * interface or you want to implement |
52 | * your own Access lib | 51 | * your own Access lib |
53 | * Just create a OPimRecord and inherit from | 52 | * Just create a OPimRecord and inherit from |
54 | * the templates | 53 | * the templates |
55 | */ | 54 | */ |
56 | 55 | ||
57 | template <class T = OPimRecord > | 56 | template <class T = OPimRecord > |
58 | class OPimAccessTemplate : public OTemplateBase<T> { | 57 | class OPimAccessTemplate : public OTemplateBase<T> { |
59 | public: | 58 | public: |
60 | enum Access { | 59 | enum Access { |
61 | Random = 0, | 60 | Random = 0, |
62 | SortedAccess | 61 | SortedAccess |
63 | }; | 62 | }; |
64 | typedef OPimRecordList<T> List; | 63 | typedef OPimRecordList<T> List; |
65 | typedef OPimAccessBackend<T> BackEnd; | 64 | typedef OPimAccessBackend<T> BackEnd; |
66 | typedef OPimCache<T> Cache; | 65 | typedef OPimCache<T> Cache; |
67 | 66 | ||
68 | /** | 67 | /** |
69 | * c'tor BackEnd | 68 | * c'tor BackEnd |
70 | * enum Access a small hint on how to handle the backend | 69 | * enum Access a small hint on how to handle the backend |
71 | */ | 70 | */ |
72 | OPimAccessTemplate( BackEnd* end); | 71 | OPimAccessTemplate( BackEnd* end); |
73 | 72 | ||
74 | virtual ~OPimAccessTemplate(); | 73 | virtual ~OPimAccessTemplate(); |
75 | 74 | ||
76 | /** | 75 | /** |
77 | * load from the backend | 76 | * load from the backend |
78 | */ | 77 | */ |
79 | bool load(); | 78 | bool load(); |
80 | 79 | ||
81 | /** Reload database. | 80 | /** Reload database. |
82 | * You should execute this function if the external database | 81 | * You should execute this function if the external database |
83 | * was changed. | 82 | * was changed. |
84 | * This function will load the external database and afterwards | 83 | * This function will load the external database and afterwards |
85 | * rejoin the local changes. Therefore the local database will be set consistent. | 84 | * rejoin the local changes. Therefore the local database will be set consistent. |
86 | */ | 85 | */ |
87 | virtual bool reload(); | 86 | virtual bool reload(); |
88 | 87 | ||
89 | /** Save contacts database. | 88 | /** Save contacts database. |
90 | * Save is more a "commit". After calling this function, all changes are public available. | 89 | * Save is more a "commit". After calling this function, all changes are public available. |
91 | * @return true if successful | 90 | * @return true if successful |
92 | */ | 91 | */ |
93 | bool save(); | 92 | bool save(); |
94 | 93 | ||
95 | /** | 94 | /** |
96 | * if the resource was changed externally | 95 | * if the resource was changed externally |
97 | * You should use the signal handling instead of polling possible changes ! | 96 | * You should use the signal handling instead of polling possible changes ! |
98 | * zecke: Do you implement a signal for otodoaccess ? | 97 | * zecke: Do you implement a signal for otodoaccess ? |
99 | */ | 98 | */ |
100 | bool wasChangedExternally()const; | 99 | bool wasChangedExternally()const; |
101 | 100 | ||
102 | /** | 101 | /** |
103 | * return a List of records | 102 | * return a List of records |
104 | * you can iterate over them | 103 | * you can iterate over them |
105 | */ | 104 | */ |
106 | virtual List allRecords()const; | 105 | virtual List allRecords()const; |
107 | 106 | ||
108 | /** | 107 | /** |
109 | * return a List of records | 108 | * return a List of records |
110 | * that match the regex | 109 | * that match the regex |
111 | */ | 110 | */ |
112 | virtual List matchRegexp( const QRegExp &r ) const; | 111 | virtual List matchRegexp( const QRegExp &r ) const; |
113 | 112 | ||
114 | /** | 113 | /** |
115 | * queryByExample. | 114 | * queryByExample. |
116 | * @see otodoaccess, ocontactaccess | 115 | * @see otodoaccess, ocontactaccess |
117 | */ | 116 | */ |
118 | virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() ); | 117 | virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() ); |
119 | 118 | ||
120 | /** | 119 | /** |
121 | * find the OPimRecord uid | 120 | * find the OPimRecord uid |
122 | */ | 121 | */ |
123 | virtual T find( int uid )const; | 122 | virtual T find( int uid )const; |
124 | 123 | ||
125 | /** | 124 | /** |
126 | * read ahead cache find method ;) | 125 | * read ahead cache find method ;) |
127 | */ | 126 | */ |
128 | virtual T find( int uid, const QArray<int>&, | 127 | virtual T find( int uid, const QArray<int>&, |
129 | uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; | 128 | uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; |
130 | 129 | ||
130 | |||
131 | /* invalidate cache here */ | 131 | /* invalidate cache here */ |
132 | /** | 132 | /** |
133 | * clears the backend and invalidates the backend | 133 | * clears the backend and invalidates the backend |
134 | */ | 134 | */ |
135 | void clear() ; | 135 | void clear() ; |
136 | 136 | ||
137 | /** | 137 | /** |
138 | * add T to the backend | 138 | * add T to the backend |
139 | * @param t The item to add. | 139 | * @param t The item to add. |
140 | * @return <i>true</i> if added successfully. | 140 | * @return <i>true</i> if added successfully. |
141 | */ | 141 | */ |
142 | virtual bool add( const T& t ) ; | 142 | virtual bool add( const T& t ) ; |
143 | |||
143 | bool add( const OPimRecord& ); | 144 | bool add( const OPimRecord& ); |
144 | // Needed for real generic access (eilers) | 145 | /** |
145 | // Info: Take this if you are working with OPimRecord, which is a generic base class, and | 146 | * Add an Opie PimRecord. |
146 | // you need to add it into any database, you cannot generate a reference to | 147 | * Info: Take this if you are working with OPimRecords and you need to add it into any database. |
147 | // it and casting may be not approriate, too. | 148 | * But take care that the accessing database is compatible to the real type of OPimRecord !! |
148 | // But take care that the accessing database is compatible to the real type of OPimRecord !! | 149 | * Otherwise this access will be rejected ! |
150 | */ | ||
149 | bool add( const OPimRecord* ); | 151 | bool add( const OPimRecord* ); |
150 | 152 | ||
151 | 153 | ||
152 | /* only the uid matters */ | 154 | /* only the uid matters */ |
153 | /** | 155 | /** |
154 | * remove T from the backend | 156 | * remove T from the backend |
155 | * @param t The item to remove | 157 | * @param t The item to remove |
156 | * @return <i>true</i> if successful. | 158 | * @return <i>true</i> if successful. |
157 | */ | 159 | */ |
158 | virtual bool remove( const T& t ); | 160 | virtual bool remove( const T& t ); |
159 | 161 | ||
160 | /** | 162 | /** |
161 | * remove the OPimRecord with uid | 163 | * remove the OPimRecord with uid |
162 | * @param uid The ID of the item to remove | 164 | * @param uid The ID of the item to remove |
163 | * @return <i>true</i> if successful. | 165 | * @return <i>true</i> if successful. |
164 | */ | 166 | */ |
165 | bool remove( int uid ); | 167 | bool remove( int uid ); |
166 | bool remove( const OPimRecord& ); | 168 | bool remove( const OPimRecord& ); |
167 | 169 | ||
168 | /** | 170 | /** |
169 | * replace T from backend | 171 | * replace T from backend |
170 | * @param t The item to replace | 172 | * @param t The item to replace |
171 | * @return <i>true</i> if successful. | 173 | * @return <i>true</i> if successful. |
172 | */ | 174 | */ |
173 | virtual bool replace( const T& t) ; | 175 | virtual bool replace( const T& t) ; |
174 | 176 | ||
175 | void setReadAhead( uint count ); | 177 | void setReadAhead( uint count ); |
176 | /** | 178 | /** |
177 | * @internal | 179 | * @internal |
178 | */ | 180 | */ |
181 | virtual T cacheFind( int uid )const; | ||
179 | void cache( const T& )const; | 182 | void cache( const T& )const; |
180 | void setSaneCacheSize( int ); | 183 | void setSaneCacheSize( int ); |
181 | 184 | ||
182 | QArray<int> records()const; | 185 | QArray<int> records()const; |
183 | protected: | 186 | protected: |
184 | /** | 187 | /** |
185 | * invalidate the cache | 188 | * invalidate the cache |
186 | */ | 189 | */ |
187 | void invalidateCache(); | 190 | void invalidateCache(); |
188 | 191 | ||
189 | void setBackEnd( BackEnd* end ); | 192 | void setBackEnd( BackEnd* end ); |
190 | /** | 193 | /** |
191 | * returns the backend | 194 | * returns the backend |
192 | */ | 195 | */ |
193 | BackEnd* backEnd(); | 196 | BackEnd* backEnd(); |
194 | BackEnd* m_backEnd; | 197 | BackEnd* m_backEnd; |
198 | |||
195 | Cache m_cache; | 199 | Cache m_cache; |
196 | 200 | ||
197 | private: | 201 | private: |
198 | OPimAccessTemplatePrivate *d; | 202 | OPimAccessTemplatePrivate *d; |
199 | 203 | ||
200 | }; | 204 | }; |
201 | 205 | ||
202 | template <class T> | 206 | template <class T> |
203 | OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) | 207 | OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) |
204 | : OTemplateBase<T>(), m_backEnd( end ) | 208 | : OTemplateBase<T>(), m_backEnd( end ) |
205 | { | 209 | { |
206 | if (end ) | 210 | if (end ) |
207 | end->setFrontend( this ); | 211 | end->setFrontend( this ); |
208 | } | 212 | } |
209 | template <class T> | 213 | template <class T> |
210 | OPimAccessTemplate<T>::~OPimAccessTemplate() { | 214 | OPimAccessTemplate<T>::~OPimAccessTemplate() { |
211 | owarn << "~OPimAccessTemplate<T>" << oendl; | 215 | owarn << "~OPimAccessTemplate<T>" << oendl; |
212 | delete m_backEnd; | 216 | delete m_backEnd; |
213 | } | 217 | } |
214 | template <class T> | 218 | template <class T> |
215 | bool OPimAccessTemplate<T>::load() { | 219 | bool OPimAccessTemplate<T>::load() { |
216 | invalidateCache(); | 220 | invalidateCache(); |
217 | return m_backEnd->load(); | 221 | return m_backEnd->load(); |
218 | } | 222 | } |
219 | template <class T> | 223 | template <class T> |
220 | bool OPimAccessTemplate<T>::reload() { | 224 | bool OPimAccessTemplate<T>::reload() { |
221 | invalidateCache(); // zecke: I think this should be added (se) | 225 | invalidateCache(); |
222 | return m_backEnd->reload(); | 226 | return m_backEnd->reload(); |
223 | } | 227 | } |
224 | template <class T> | 228 | template <class T> |
225 | bool OPimAccessTemplate<T>::save() { | 229 | bool OPimAccessTemplate<T>::save() { |
226 | return m_backEnd->save(); | 230 | return m_backEnd->save(); |
227 | } | 231 | } |
228 | template <class T> | 232 | template <class T> |
229 | typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { | 233 | typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { |
230 | QArray<int> ints = m_backEnd->allRecords(); | 234 | QArray<int> ints = m_backEnd->allRecords(); |
231 | List lis(ints, this ); | 235 | List lis(ints, this ); |
232 | return lis; | 236 | return lis; |
233 | } | 237 | } |
234 | template <class T> | 238 | template <class T> |
235 | typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const { | 239 | typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const { |
236 | QArray<int> ints = m_backEnd->matchRegexp( r ); | 240 | QArray<int> ints = m_backEnd->matchRegexp( r ); |
237 | List lis(ints, this ); | 241 | List lis(ints, this ); |
238 | return lis; | 242 | return lis; |
239 | } | 243 | } |
240 | template <class T> | 244 | template <class T> |
241 | QArray<int> OPimAccessTemplate<T>::records()const { | 245 | QArray<int> OPimAccessTemplate<T>::records()const { |
242 | return m_backEnd->allRecords(); | 246 | return m_backEnd->allRecords(); |
243 | } | 247 | } |
244 | template <class T> | 248 | template <class T> |
245 | typename OPimAccessTemplate<T>::List | 249 | typename OPimAccessTemplate<T>::List |
246 | OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) { | 250 | OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) { |
247 | QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); | 251 | QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); |
248 | 252 | ||
249 | List lis(ints, this ); | 253 | List lis(ints, this ); |
250 | return lis; | 254 | return lis; |
251 | } | 255 | } |
252 | template <class T> | 256 | template <class T> |
253 | T OPimAccessTemplate<T>::find( int uid ) const{ | 257 | T OPimAccessTemplate<T>::find( int uid ) const{ |
258 | // First search in cache.. | ||
259 | if ( m_cache.contains( uid ) ) | ||
260 | return m_cache.find( uid ); | ||
261 | |||
254 | T t = m_backEnd->find( uid ); | 262 | T t = m_backEnd->find( uid ); |
255 | cache( t ); | 263 | cache( t ); |
264 | |||
256 | return t; | 265 | return t; |
257 | } | 266 | } |
267 | |||
268 | template <class T> | ||
269 | T OPimAccessTemplate<T>::cacheFind( int uid ) const | ||
270 | { | ||
271 | return m_cache.find( uid ); | ||
272 | } | ||
273 | |||
258 | template <class T> | 274 | template <class T> |
259 | T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar, | 275 | T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar, |
260 | uint current, typename OTemplateBase<T>::CacheDirection dir )const { | 276 | uint current, typename OTemplateBase<T>::CacheDirection dir )const { |
261 | /* | 277 | /* |
262 | * better do T.isEmpty() | 278 | * better do T.isEmpty() |
263 | * after a find this way we would | 279 | * after a find this way we would |
264 | * avoid two finds in QCache... | 280 | * avoid two finds in QCache... |
265 | */ | 281 | */ |
266 | // owarn << "find it now " << uid << oendl; | 282 | // owarn << "find it now " << uid << oendl; |
267 | if (m_cache.contains( uid ) ) { | 283 | if ( m_cache.contains( uid ) ) { |
268 | return m_cache.find( uid ); | 284 | return m_cache.find( uid ); |
269 | } | 285 | } |
270 | 286 | ||
271 | T t = m_backEnd->find( uid, ar, current, dir ); | 287 | T t = m_backEnd->find( uid, ar, current, dir ); |
272 | cache( t ); | 288 | cache( t ); |
273 | return t; | 289 | return t; |
274 | } | 290 | } |
275 | template <class T> | 291 | template <class T> |
276 | void OPimAccessTemplate<T>::clear() { | 292 | void OPimAccessTemplate<T>::clear() { |
277 | invalidateCache(); | 293 | invalidateCache(); |
278 | m_backEnd->clear(); | 294 | m_backEnd->clear(); |
279 | } | 295 | } |
280 | template <class T> | 296 | template <class T> |
281 | bool OPimAccessTemplate<T>::add( const T& t ) { | 297 | bool OPimAccessTemplate<T>::add( const T& t ) { |
282 | cache( t ); | 298 | cache( t ); |
283 | return m_backEnd->add( t ); | 299 | return m_backEnd->add( t ); |
284 | } | 300 | } |
285 | 301 | ||
286 | template <class T> | 302 | template <class T> |
287 | bool OPimAccessTemplate<T>::add( const OPimRecord& rec) { | 303 | bool OPimAccessTemplate<T>::add( const OPimRecord& rec ) { |
288 | /* same type */ | 304 | /* same type */ |
289 | T tempInstance; | 305 | T tempInstance; |
290 | if ( rec.rtti() == tempInstance.rtti() ) { | 306 | if ( rec.rtti() == tempInstance.rtti() ) { |
291 | const T& t = static_cast<const T&>(rec); | 307 | const T& t = static_cast<const T&>(rec); |
292 | return add(t); | 308 | return add(t); |
309 | } else { | ||
310 | owarn << "Adding not possible: Objecttype mismatch" << oendl; | ||
293 | } | 311 | } |
294 | return false; | 312 | return false; |
295 | } | 313 | } |
296 | 314 | ||
297 | template <class T> | 315 | template <class T> |
298 | bool OPimAccessTemplate<T>::add( const OPimRecord* rec) { | 316 | bool OPimAccessTemplate<T>::add( const OPimRecord* rec) { |
299 | /* same type, but pointer */ | 317 | /* same type, but pointer */ |
300 | T tempInstance; | 318 | T tempInstance; |
301 | if ( rec -> rtti() == tempInstance.rtti() ) { | 319 | if ( rec -> rtti() == tempInstance.rtti() ) { |
302 | const T* t = static_cast<const T*>(rec); | 320 | const T* t = static_cast<const T*>(rec); |
303 | return add( *t ); | 321 | return add( *t ); |
322 | } else { | ||
323 | owarn << "Adding not possible: Objecttype mismatch" << oendl; | ||
304 | } | 324 | } |
305 | return false; | 325 | return false; |
306 | } | 326 | } |
307 | 327 | ||
308 | template <class T> | 328 | template <class T> |
309 | bool OPimAccessTemplate<T>::remove( const T& t ) { | 329 | bool OPimAccessTemplate<T>::remove( const T& t ) { |
310 | return remove( t.uid() ); | 330 | return remove( t.uid() ); |
311 | } | 331 | } |
312 | template <class T> | 332 | template <class T> |
313 | bool OPimAccessTemplate<T>::remove( int uid ) { | 333 | bool OPimAccessTemplate<T>::remove( int uid ) { |
314 | m_cache.remove( uid ); | 334 | m_cache.remove( uid ); |
315 | return m_backEnd->remove( uid ); | 335 | return m_backEnd->remove( uid ); |
316 | } | 336 | } |
317 | template <class T> | 337 | template <class T> |
318 | bool OPimAccessTemplate<T>::remove( const OPimRecord& rec) { | 338 | bool OPimAccessTemplate<T>::remove( const OPimRecord& rec) { |
319 | return remove( rec.uid() ); | 339 | return remove( rec.uid() ); |
320 | } | 340 | } |
321 | template <class T> | 341 | template <class T> |
322 | bool OPimAccessTemplate<T>::replace( const T& t ) { | 342 | bool OPimAccessTemplate<T>::replace( const T& t ) { |
323 | m_cache.replace( t ); | 343 | m_cache.replace( t ); |
324 | return m_backEnd->replace( t ); | 344 | return m_backEnd->replace( t ); |
325 | } | 345 | } |
326 | template <class T> | 346 | template <class T> |
327 | void OPimAccessTemplate<T>::invalidateCache() { | 347 | void OPimAccessTemplate<T>::invalidateCache() { |
328 | m_cache.invalidate(); | 348 | m_cache.invalidate(); |
329 | } | 349 | } |
330 | template <class T> | 350 | template <class T> |
331 | typename OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() { | 351 | typename OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() { |
332 | return m_backEnd; | 352 | return m_backEnd; |
333 | } | 353 | } |
334 | template <class T> | 354 | template <class T> |
335 | bool OPimAccessTemplate<T>::wasChangedExternally()const { | 355 | bool OPimAccessTemplate<T>::wasChangedExternally()const { |
336 | return false; | 356 | return false; |
337 | } | 357 | } |
338 | template <class T> | 358 | template <class T> |
339 | void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) { | 359 | void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) { |
340 | m_backEnd = end; | 360 | m_backEnd = end; |
341 | if (m_backEnd ) | 361 | if (m_backEnd ) |
342 | m_backEnd->setFrontend( this ); | 362 | m_backEnd->setFrontend( this ); |
343 | } | 363 | } |
344 | template <class T> | 364 | template <class T> |
345 | void OPimAccessTemplate<T>::cache( const T& t ) const{ | 365 | void OPimAccessTemplate<T>::cache( const T& t ) const{ |
346 | /* hacky we need to work around the const*/ | 366 | /* hacky we need to work around the const*/ |
347 | ((OPimAccessTemplate<T>*)this)->m_cache.add( t ); | 367 | ((OPimAccessTemplate<T>*)this)->m_cache.add( t ); |
348 | } | 368 | } |
349 | template <class T> | 369 | template <class T> |
350 | void OPimAccessTemplate<T>::setSaneCacheSize( int size ) { | 370 | void OPimAccessTemplate<T>::setSaneCacheSize( int size ) { |
351 | m_cache.setSize( size ); | 371 | m_cache.setSize( size ); |
diff --git a/libopie2/opiepim/core/opimtemplatebase.h b/libopie2/opiepim/core/opimtemplatebase.h index b48dfed..ec9a94e 100644 --- a/libopie2/opiepim/core/opimtemplatebase.h +++ b/libopie2/opiepim/core/opimtemplatebase.h | |||
@@ -1,122 +1,136 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Holger Freyther <zecke@handhelds.org> | 3 | Copyright (C) Holger Freyther <zecke@handhelds.org> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | #ifndef OTEMPLATEBASE_H | 29 | #ifndef OTEMPLATEBASE_H |
30 | #define OTEMPLATEBASE_H | 30 | #define OTEMPLATEBASE_H |
31 | 31 | ||
32 | /* OPIE */ | 32 | /* OPIE */ |
33 | #include <opie2/opimrecord.h> | 33 | #include <opie2/opimrecord.h> |
34 | #include <opie2/opimcache.h> | ||
34 | 35 | ||
35 | /* QT */ | 36 | /* QT */ |
36 | #include <qarray.h> | 37 | #include <qarray.h> |
37 | 38 | ||
38 | namespace Opie { | 39 | namespace Opie { |
39 | /** | 40 | /** |
40 | * Templates do not have a base class, This is why | 41 | * Templates do not have a base class, This is why |
41 | * we've this class | 42 | * we've this class |
42 | * this is here to give us the possibility | 43 | * this is here to give us the possibility |
43 | * to have a common base class | 44 | * to have a common base class |
44 | * You may not want to use that interface internaly | 45 | * You may not want to use that interface internaly |
45 | * POOR mans interface | 46 | * POOR mans interface |
46 | */ | 47 | */ |
47 | class OPimBasePrivate; | 48 | class OPimBasePrivate; |
48 | struct OPimBase { | 49 | struct OPimBase { |
49 | /** | 50 | /** |
50 | * return the rtti | 51 | * return the rtti |
51 | */ | 52 | */ |
52 | virtual int rtti() const = 0; | 53 | virtual int rtti() const = 0; |
53 | virtual OPimRecord* record()const = 0; | 54 | virtual OPimRecord* record()const = 0; |
54 | virtual OPimRecord* record(int uid)const = 0; | 55 | virtual OPimRecord* record(int uid)const = 0; |
55 | virtual bool add( const OPimRecord& ) = 0; | 56 | virtual bool add( const OPimRecord& ) = 0; |
56 | virtual bool add( const OPimRecord* ) = 0; | 57 | virtual bool add( const OPimRecord* ) = 0; |
57 | virtual bool remove( int uid ) = 0; | 58 | virtual bool remove( int uid ) = 0; |
58 | virtual bool remove( const OPimRecord& ) = 0; | 59 | virtual bool remove( const OPimRecord& ) = 0; |
59 | virtual void clear() = 0; | 60 | virtual void clear() = 0; |
60 | virtual bool load() = 0; | 61 | virtual bool load() = 0; |
61 | virtual bool save() = 0; | 62 | virtual bool save() = 0; |
62 | virtual QArray<int> records()const = 0; | 63 | virtual QArray<int> records()const = 0; |
63 | /* | 64 | /* |
64 | * ADD editing here? | 65 | * ADD editing here? |
65 | * -zecke | 66 | * -zecke |
66 | */ | 67 | */ |
67 | private: | 68 | private: |
68 | OPimBasePrivate* d; | 69 | OPimBasePrivate* d; |
69 | 70 | ||
70 | }; | 71 | }; |
71 | /** | 72 | /** |
72 | * internal template base | 73 | * internal template base |
73 | * T needs to implement the copy c'tor!!! | 74 | * Attention: T needs to implement the copy c'tor!!! |
74 | */ | 75 | */ |
75 | class OTemplateBasePrivate; | 76 | class OTemplateBasePrivate; |
76 | template <class T = OPimRecord> | 77 | template <class T = OPimRecord> |
77 | class OTemplateBase : public OPimBase { | 78 | class OTemplateBase : public OPimBase { |
78 | public: | 79 | public: |
80 | /** Look ahead direction of cache */ | ||
79 | enum CacheDirection { Forward=0, Reverse }; | 81 | enum CacheDirection { Forward=0, Reverse }; |
82 | |||
80 | OTemplateBase() { | 83 | OTemplateBase() { |
81 | }; | 84 | }; |
82 | virtual ~OTemplateBase() { | 85 | virtual ~OTemplateBase() { |
83 | } | 86 | } |
84 | virtual T find( int uid )const = 0; | 87 | virtual T find( int uid )const = 0; |
85 | 88 | ||
86 | /** | 89 | /** |
87 | * read ahead find | 90 | * read ahead find |
88 | */ | 91 | */ |
89 | virtual T find( int uid, const QArray<int>& items, | 92 | virtual T find( int uid, const QArray<int>& items, |
90 | uint current, CacheDirection dir = Forward )const = 0; | 93 | uint current, CacheDirection dir = Forward )const = 0; |
94 | |||
95 | /** | ||
96 | * Find in Cache.. | ||
97 | * Returns empty object if nothing found. | ||
98 | */ | ||
99 | virtual T cacheFind( int uid )const = 0; | ||
100 | |||
101 | /** | ||
102 | * Put element into Cache | ||
103 | */ | ||
91 | virtual void cache( const T& )const = 0; | 104 | virtual void cache( const T& )const = 0; |
92 | virtual void setSaneCacheSize( int ) = 0; | 105 | virtual void setSaneCacheSize( int ) = 0; |
93 | 106 | ||
94 | OPimRecord* record()const; | 107 | OPimRecord* record()const; |
95 | OPimRecord* record(int uid )const; | 108 | OPimRecord* record(int uid )const; |
96 | static T* rec(); | 109 | static T* rec(); |
110 | |||
97 | 111 | ||
98 | private: | 112 | private: |
99 | OTemplateBasePrivate *d; | 113 | OTemplateBasePrivate *d; |
100 | }; | 114 | }; |
101 | 115 | ||
102 | 116 | ||
103 | template <class T> | 117 | template <class T> |
104 | OPimRecord* OTemplateBase<T>::record()const { | 118 | OPimRecord* OTemplateBase<T>::record()const { |
105 | T* t = new T; | 119 | T* t = new T; |
106 | return t; | 120 | return t; |
107 | } | 121 | } |
108 | template <class T> | 122 | template <class T> |
109 | OPimRecord* OTemplateBase<T>::record(int uid )const { | 123 | OPimRecord* OTemplateBase<T>::record(int uid )const { |
110 | T t2 = find(uid ); | 124 | T t2 = find(uid ); |
111 | T* t1 = new T(t2); | 125 | T* t1 = new T(t2); |
112 | 126 | ||
113 | return t1; | 127 | return t1; |
114 | }; | 128 | }; |
115 | template <class T> | 129 | template <class T> |
116 | T* OTemplateBase<T>::rec() { | 130 | T* OTemplateBase<T>::rec() { |
117 | return new T; | 131 | return new T; |
118 | } | 132 | } |
119 | 133 | ||
120 | } | 134 | } |
121 | 135 | ||
122 | #endif | 136 | #endif |