6 files changed, 309 insertions, 5 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 132c9fc..dd9dbde 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | |||
@@ -1,112 +1,115 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * Version: $Id$ | 13 | * Version: $Id$ |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * History: | 15 | * History: |
16 | * $Log$ | 16 | * $Log$ |
17 | * Revision 1.3 2003/12/08 15:18:10 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
17 | * Revision 1.2 2003/09/29 07:44:26 eilers | 20 | * Revision 1.2 2003/09/29 07:44:26 eilers |
18 | * Improvement of PIM-SQL Databases, but search queries are still limited. | 21 | * Improvement of PIM-SQL Databases, but search queries are still limited. |
19 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. | 22 | * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. |
20 | * Todo: Started to add new attributes. Some type conversions missing. | 23 | * Todo: Started to add new attributes. Some type conversions missing. |
21 | * | 24 | * |
22 | * Revision 1.1 2003/09/22 14:31:16 eilers | 25 | * Revision 1.1 2003/09/22 14:31:16 eilers |
23 | * Added first experimental incarnation of sql-backend for addressbook. | 26 | * Added first experimental incarnation of sql-backend for addressbook. |
24 | * Some modifications to be able to compile the todo sql-backend. | 27 | * Some modifications to be able to compile the todo sql-backend. |
25 | * A lot of changes fill follow... | 28 | * A lot of changes fill follow... |
26 | * | 29 | * |
27 | */ | 30 | */ |
28 | 31 | ||
29 | #include "ocontactaccessbackend_sql.h" | 32 | #include "ocontactaccessbackend_sql.h" |
30 | 33 | ||
31 | #include <qarray.h> | 34 | #include <qarray.h> |
32 | #include <qdatetime.h> | 35 | #include <qdatetime.h> |
33 | #include <qstringlist.h> | 36 | #include <qstringlist.h> |
34 | 37 | ||
35 | #include <qpe/global.h> | 38 | #include <qpe/global.h> |
36 | #include <qpe/recordfields.h> | 39 | #include <qpe/recordfields.h> |
37 | 40 | ||
38 | #include <opie/ocontactfields.h> | 41 | #include <opie/ocontactfields.h> |
39 | #include <opie/oconversion.h> | 42 | #include <opie/oconversion.h> |
40 | #include <opie2/osqldriver.h> | 43 | #include <opie2/osqldriver.h> |
41 | #include <opie2/osqlresult.h> | 44 | #include <opie2/osqlresult.h> |
42 | #include <opie2/osqlmanager.h> | 45 | #include <opie2/osqlmanager.h> |
43 | #include <opie2/osqlquery.h> | 46 | #include <opie2/osqlquery.h> |
44 | 47 | ||
45 | 48 | ||
46 | 49 | ||
47 | 50 | ||
48 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead | 51 | // If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead |
49 | // vertical like "uid, type, value". | 52 | // vertical like "uid, type, value". |
50 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! | 53 | // DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! |
51 | #define __STORE_HORIZONTAL_ | 54 | #define __STORE_HORIZONTAL_ |
52 | 55 | ||
53 | // Distinct loading is not very fast. If I expect that every person has just | 56 | // Distinct loading is not very fast. If I expect that every person has just |
54 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, | 57 | // one (and always one) 'Last Name', I can request all uid's for existing lastnames, |
55 | // which is faster.. | 58 | // which is faster.. |
56 | // But this may not be true for all entries, like company contacts.. | 59 | // But this may not be true for all entries, like company contacts.. |
57 | // The current AddressBook application handles this problem, but other may not.. (eilers) | 60 | // The current AddressBook application handles this problem, but other may not.. (eilers) |
58 | #define __USE_SUPERFAST_LOADQUERY | 61 | #define __USE_SUPERFAST_LOADQUERY |
59 | 62 | ||
60 | 63 | ||
61 | /* | 64 | /* |
62 | * Implementation of used query types | 65 | * Implementation of used query types |
63 | * CREATE query | 66 | * CREATE query |
64 | * LOAD query | 67 | * LOAD query |
65 | * INSERT | 68 | * INSERT |
66 | * REMOVE | 69 | * REMOVE |
67 | * CLEAR | 70 | * CLEAR |
68 | */ | 71 | */ |
69 | namespace { | 72 | namespace { |
70 | /** | 73 | /** |
71 | * CreateQuery for the Todolist Table | 74 | * CreateQuery for the Todolist Table |
72 | */ | 75 | */ |
73 | class CreateQuery : public OSQLQuery { | 76 | class CreateQuery : public OSQLQuery { |
74 | public: | 77 | public: |
75 | CreateQuery(); | 78 | CreateQuery(); |
76 | ~CreateQuery(); | 79 | ~CreateQuery(); |
77 | QString query()const; | 80 | QString query()const; |
78 | }; | 81 | }; |
79 | 82 | ||
80 | /** | 83 | /** |
81 | * Clears (delete) a Table | 84 | * Clears (delete) a Table |
82 | */ | 85 | */ |
83 | class ClearQuery : public OSQLQuery { | 86 | class ClearQuery : public OSQLQuery { |
84 | public: | 87 | public: |
85 | ClearQuery(); | 88 | ClearQuery(); |
86 | ~ClearQuery(); | 89 | ~ClearQuery(); |
87 | QString query()const; | 90 | QString query()const; |
88 | 91 | ||
89 | }; | 92 | }; |
90 | 93 | ||
91 | 94 | ||
92 | /** | 95 | /** |
93 | * LoadQuery | 96 | * LoadQuery |
94 | * this one queries for all uids | 97 | * this one queries for all uids |
95 | */ | 98 | */ |
96 | class LoadQuery : public OSQLQuery { | 99 | class LoadQuery : public OSQLQuery { |
97 | public: | 100 | public: |
98 | LoadQuery(); | 101 | LoadQuery(); |
99 | ~LoadQuery(); | 102 | ~LoadQuery(); |
100 | QString query()const; | 103 | QString query()const; |
101 | }; | 104 | }; |
102 | 105 | ||
103 | /** | 106 | /** |
104 | * inserts/adds a OContact to the table | 107 | * inserts/adds a OContact to the table |
105 | */ | 108 | */ |
106 | class InsertQuery : public OSQLQuery { | 109 | class InsertQuery : public OSQLQuery { |
107 | public: | 110 | public: |
108 | InsertQuery(const OContact& ); | 111 | InsertQuery(const OContact& ); |
109 | ~InsertQuery(); | 112 | ~InsertQuery(); |
110 | QString query()const; | 113 | QString query()const; |
111 | private: | 114 | private: |
112 | OContact m_contact; | 115 | OContact m_contact; |
@@ -361,214 +364,220 @@ namespace { | |||
361 | + "," | 364 | + "," |
362 | + QString::number( id++ ) | 365 | + QString::number( id++ ) |
363 | + ",'" | 366 | + ",'" |
364 | + it.key() //.latin1() | 367 | + it.key() //.latin1() |
365 | + "'," | 368 | + "'," |
366 | + "0" // Priority for future enhancements | 369 | + "0" // Priority for future enhancements |
367 | + ",'" | 370 | + ",'" |
368 | + it.data() //.latin1() | 371 | + it.data() //.latin1() |
369 | + "');"; | 372 | + "');"; |
370 | } | 373 | } |
371 | // qu += "commit;"; | 374 | // qu += "commit;"; |
372 | qWarning("add %s", qu.latin1() ); | 375 | qWarning("add %s", qu.latin1() ); |
373 | return qu; | 376 | return qu; |
374 | } | 377 | } |
375 | 378 | ||
376 | 379 | ||
377 | RemoveQuery::RemoveQuery(int uid ) | 380 | RemoveQuery::RemoveQuery(int uid ) |
378 | : OSQLQuery(), m_uid( uid ) {} | 381 | : OSQLQuery(), m_uid( uid ) {} |
379 | RemoveQuery::~RemoveQuery() {} | 382 | RemoveQuery::~RemoveQuery() {} |
380 | QString RemoveQuery::query()const { | 383 | QString RemoveQuery::query()const { |
381 | QString qu = "DELETE from addressbook where uid = " | 384 | QString qu = "DELETE from addressbook where uid = " |
382 | + QString::number(m_uid) + ";"; | 385 | + QString::number(m_uid) + ";"; |
383 | qu += "DELETE from custom_data where uid = " | 386 | qu += "DELETE from custom_data where uid = " |
384 | + QString::number(m_uid) + ";"; | 387 | + QString::number(m_uid) + ";"; |
385 | return qu; | 388 | return qu; |
386 | } | 389 | } |
387 | 390 | ||
388 | 391 | ||
389 | 392 | ||
390 | 393 | ||
391 | FindQuery::FindQuery(int uid) | 394 | FindQuery::FindQuery(int uid) |
392 | : OSQLQuery(), m_uid( uid ) { | 395 | : OSQLQuery(), m_uid( uid ) { |
393 | } | 396 | } |
394 | FindQuery::FindQuery(const QArray<int>& ints) | 397 | FindQuery::FindQuery(const QArray<int>& ints) |
395 | : OSQLQuery(), m_uids( ints ){ | 398 | : OSQLQuery(), m_uids( ints ){ |
396 | } | 399 | } |
397 | FindQuery::~FindQuery() { | 400 | FindQuery::~FindQuery() { |
398 | } | 401 | } |
399 | QString FindQuery::query()const{ | 402 | QString FindQuery::query()const{ |
400 | // if ( m_uids.count() == 0 ) | 403 | // if ( m_uids.count() == 0 ) |
401 | return single(); | 404 | return single(); |
402 | } | 405 | } |
403 | /* | 406 | /* |
404 | else | 407 | else |
405 | return multi(); | 408 | return multi(); |
406 | } | 409 | } |
407 | QString FindQuery::multi()const { | 410 | QString FindQuery::multi()const { |
408 | QString qu = "select uid, type, value from addressbook where"; | 411 | QString qu = "select uid, type, value from addressbook where"; |
409 | for (uint i = 0; i < m_uids.count(); i++ ) { | 412 | for (uint i = 0; i < m_uids.count(); i++ ) { |
410 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 413 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
411 | } | 414 | } |
412 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 415 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
413 | return qu; | 416 | return qu; |
414 | } | 417 | } |
415 | */ | 418 | */ |
416 | #ifdef __STORE_HORIZONTAL_ | 419 | #ifdef __STORE_HORIZONTAL_ |
417 | QString FindQuery::single()const{ | 420 | QString FindQuery::single()const{ |
418 | QString qu = "select *"; | 421 | QString qu = "select *"; |
419 | qu += " from addressbook where uid = " + QString::number(m_uid); | 422 | qu += " from addressbook where uid = " + QString::number(m_uid); |
420 | 423 | ||
421 | // qWarning("find query: %s", qu.latin1() ); | 424 | // qWarning("find query: %s", qu.latin1() ); |
422 | return qu; | 425 | return qu; |
423 | } | 426 | } |
424 | #else | 427 | #else |
425 | QString FindQuery::single()const{ | 428 | QString FindQuery::single()const{ |
426 | QString qu = "select uid, type, value from addressbook where uid = "; | 429 | QString qu = "select uid, type, value from addressbook where uid = "; |
427 | qu += QString::number(m_uid); | 430 | qu += QString::number(m_uid); |
428 | return qu; | 431 | return qu; |
429 | } | 432 | } |
430 | #endif | 433 | #endif |
431 | 434 | ||
432 | 435 | ||
433 | FindCustomQuery::FindCustomQuery(int uid) | 436 | FindCustomQuery::FindCustomQuery(int uid) |
434 | : OSQLQuery(), m_uid( uid ) { | 437 | : OSQLQuery(), m_uid( uid ) { |
435 | } | 438 | } |
436 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 439 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
437 | : OSQLQuery(), m_uids( ints ){ | 440 | : OSQLQuery(), m_uids( ints ){ |
438 | } | 441 | } |
439 | FindCustomQuery::~FindCustomQuery() { | 442 | FindCustomQuery::~FindCustomQuery() { |
440 | } | 443 | } |
441 | QString FindCustomQuery::query()const{ | 444 | QString FindCustomQuery::query()const{ |
442 | // if ( m_uids.count() == 0 ) | 445 | // if ( m_uids.count() == 0 ) |
443 | return single(); | 446 | return single(); |
444 | } | 447 | } |
445 | QString FindCustomQuery::single()const{ | 448 | QString FindCustomQuery::single()const{ |
446 | QString qu = "select uid, type, value from custom_data where uid = "; | 449 | QString qu = "select uid, type, value from custom_data where uid = "; |
447 | qu += QString::number(m_uid); | 450 | qu += QString::number(m_uid); |
448 | return qu; | 451 | return qu; |
449 | } | 452 | } |
450 | 453 | ||
451 | }; | 454 | }; |
452 | 455 | ||
453 | 456 | ||
454 | /* --------------------------------------------------------------------------- */ | 457 | /* --------------------------------------------------------------------------- */ |
455 | 458 | ||
456 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, | 459 | OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, |
457 | const QString& filename ): m_changed(false) | 460 | const QString& filename ): |
461 | OContactAccessBackend(), m_changed(false), m_driver( NULL ) | ||
458 | { | 462 | { |
459 | qWarning("C'tor OContactAccessBackend_SQL starts"); | 463 | qWarning("C'tor OContactAccessBackend_SQL starts"); |
460 | QTime t; | 464 | QTime t; |
461 | t.start(); | 465 | t.start(); |
462 | 466 | ||
463 | /* Expecting to access the default filename if nothing else is set */ | 467 | /* Expecting to access the default filename if nothing else is set */ |
464 | if ( filename.isEmpty() ){ | 468 | if ( filename.isEmpty() ){ |
465 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 469 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
466 | } else | 470 | } else |
467 | m_fileName = filename; | 471 | m_fileName = filename; |
468 | 472 | ||
469 | // Get the standart sql-driver from the OSQLManager.. | 473 | // Get the standart sql-driver from the OSQLManager.. |
470 | OSQLManager man; | 474 | OSQLManager man; |
471 | m_driver = man.standard(); | 475 | m_driver = man.standard(); |
472 | m_driver->setUrl( m_fileName ); | 476 | m_driver->setUrl( m_fileName ); |
473 | 477 | ||
474 | load(); | 478 | load(); |
475 | 479 | ||
476 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); | 480 | qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() ); |
477 | } | 481 | } |
478 | 482 | ||
483 | OContactAccessBackend_SQL::~OContactAccessBackend_SQL () | ||
484 | { | ||
485 | if( m_driver ) | ||
486 | delete m_driver; | ||
487 | } | ||
479 | 488 | ||
480 | bool OContactAccessBackend_SQL::load () | 489 | bool OContactAccessBackend_SQL::load () |
481 | { | 490 | { |
482 | if (!m_driver->open() ) | 491 | if (!m_driver->open() ) |
483 | return false; | 492 | return false; |
484 | 493 | ||
485 | // Don't expect that the database exists. | 494 | // Don't expect that the database exists. |
486 | // It is save here to create the table, even if it | 495 | // It is save here to create the table, even if it |
487 | // do exist. ( Is that correct for all databases ?? ) | 496 | // do exist. ( Is that correct for all databases ?? ) |
488 | CreateQuery creat; | 497 | CreateQuery creat; |
489 | OSQLResult res = m_driver->query( &creat ); | 498 | OSQLResult res = m_driver->query( &creat ); |
490 | 499 | ||
491 | update(); | 500 | update(); |
492 | 501 | ||
493 | return true; | 502 | return true; |
494 | 503 | ||
495 | } | 504 | } |
496 | 505 | ||
497 | bool OContactAccessBackend_SQL::reload() | 506 | bool OContactAccessBackend_SQL::reload() |
498 | { | 507 | { |
499 | return load(); | 508 | return load(); |
500 | } | 509 | } |
501 | 510 | ||
502 | bool OContactAccessBackend_SQL::save() | 511 | bool OContactAccessBackend_SQL::save() |
503 | { | 512 | { |
504 | return m_driver->close(); | 513 | return m_driver->close(); |
505 | } | 514 | } |
506 | 515 | ||
507 | 516 | ||
508 | void OContactAccessBackend_SQL::clear () | 517 | void OContactAccessBackend_SQL::clear () |
509 | { | 518 | { |
510 | ClearQuery cle; | 519 | ClearQuery cle; |
511 | OSQLResult res = m_driver->query( &cle ); | 520 | OSQLResult res = m_driver->query( &cle ); |
512 | CreateQuery qu; | 521 | CreateQuery qu; |
513 | res = m_driver->query(&qu); | 522 | res = m_driver->query(&qu); |
514 | } | 523 | } |
515 | 524 | ||
516 | bool OContactAccessBackend_SQL::wasChangedExternally() | 525 | bool OContactAccessBackend_SQL::wasChangedExternally() |
517 | { | 526 | { |
518 | return false; | 527 | return false; |
519 | } | 528 | } |
520 | 529 | ||
521 | QArray<int> OContactAccessBackend_SQL::allRecords() const | 530 | QArray<int> OContactAccessBackend_SQL::allRecords() const |
522 | { | 531 | { |
523 | 532 | ||
524 | // FIXME: Think about cute handling of changed tables.. | 533 | // FIXME: Think about cute handling of changed tables.. |
525 | // Thus, we don't have to call update here... | 534 | // Thus, we don't have to call update here... |
526 | if ( m_changed ) | 535 | if ( m_changed ) |
527 | ((OContactAccessBackend_SQL*)this)->update(); | 536 | ((OContactAccessBackend_SQL*)this)->update(); |
528 | 537 | ||
529 | return m_uids; | 538 | return m_uids; |
530 | } | 539 | } |
531 | 540 | ||
532 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) | 541 | bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) |
533 | { | 542 | { |
534 | InsertQuery ins( newcontact ); | 543 | InsertQuery ins( newcontact ); |
535 | OSQLResult res = m_driver->query( &ins ); | 544 | OSQLResult res = m_driver->query( &ins ); |
536 | 545 | ||
537 | if ( res.state() == OSQLResult::Failure ) | 546 | if ( res.state() == OSQLResult::Failure ) |
538 | return false; | 547 | return false; |
539 | 548 | ||
540 | int c = m_uids.count(); | 549 | int c = m_uids.count(); |
541 | m_uids.resize( c+1 ); | 550 | m_uids.resize( c+1 ); |
542 | m_uids[c] = newcontact.uid(); | 551 | m_uids[c] = newcontact.uid(); |
543 | 552 | ||
544 | return true; | 553 | return true; |
545 | } | 554 | } |
546 | 555 | ||
547 | 556 | ||
548 | bool OContactAccessBackend_SQL::remove ( int uid ) | 557 | bool OContactAccessBackend_SQL::remove ( int uid ) |
549 | { | 558 | { |
550 | RemoveQuery rem( uid ); | 559 | RemoveQuery rem( uid ); |
551 | OSQLResult res = m_driver->query(&rem ); | 560 | OSQLResult res = m_driver->query(&rem ); |
552 | 561 | ||
553 | if ( res.state() == OSQLResult::Failure ) | 562 | if ( res.state() == OSQLResult::Failure ) |
554 | return false; | 563 | return false; |
555 | 564 | ||
556 | m_changed = true; | 565 | m_changed = true; |
557 | 566 | ||
558 | return true; | 567 | return true; |
559 | } | 568 | } |
560 | 569 | ||
561 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) | 570 | bool OContactAccessBackend_SQL::replace ( const OContact &contact ) |
562 | { | 571 | { |
563 | if ( !remove( contact.uid() ) ) | 572 | if ( !remove( contact.uid() ) ) |
564 | return false; | 573 | return false; |
565 | 574 | ||
566 | return add( contact ); | 575 | return add( contact ); |
567 | } | 576 | } |
568 | 577 | ||
569 | 578 | ||
570 | OContact OContactAccessBackend_SQL::find ( int uid ) const | 579 | OContact OContactAccessBackend_SQL::find ( int uid ) const |
571 | { | 580 | { |
572 | qWarning("OContactAccessBackend_SQL::find()"); | 581 | qWarning("OContactAccessBackend_SQL::find()"); |
573 | QTime t; | 582 | QTime t; |
574 | t.start(); | 583 | t.start(); |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h index bb22551..b8f1d8d 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h | |||
@@ -1,96 +1,101 @@ | |||
1 | /* | 1 | /* |
2 | * SQL Backend for the OPIE-Contact Database. | 2 | * SQL Backend for the OPIE-Contact Database. |
3 | * | 3 | * |
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | 4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) |
5 | * | 5 | * |
6 | * ===================================================================== | 6 | * ===================================================================== |
7 | *This program is free software; you can redistribute it and/or | 7 | *This program is free software; you can redistribute it and/or |
8 | *modify it under the terms of the GNU Library General Public | 8 | *modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. | 10 | * version 2 of the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * ===================================================================== | 14 | * ===================================================================== |
15 | * Version: $Id$ | 15 | * Version: $Id$ |
16 | * ===================================================================== | 16 | * ===================================================================== |
17 | * History: | 17 | * History: |
18 | * $Log$ | 18 | * $Log$ |
19 | * Revision 1.2 2003/12/08 15:18:11 eilers | ||
20 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
21 | * | ||
19 | * Revision 1.1 2003/09/22 14:31:16 eilers | 22 | * Revision 1.1 2003/09/22 14:31:16 eilers |
20 | * Added first experimental incarnation of sql-backend for addressbook. | 23 | * Added first experimental incarnation of sql-backend for addressbook. |
21 | * Some modifications to be able to compile the todo sql-backend. | 24 | * Some modifications to be able to compile the todo sql-backend. |
22 | * A lot of changes fill follow... | 25 | * A lot of changes fill follow... |
23 | * | 26 | * |
24 | * | 27 | * |
25 | */ | 28 | */ |
26 | 29 | ||
27 | #ifndef _OContactAccessBackend_SQL_ | 30 | #ifndef _OContactAccessBackend_SQL_ |
28 | #define _OContactAccessBackend_SQL_ | 31 | #define _OContactAccessBackend_SQL_ |
29 | 32 | ||
30 | #include "ocontactaccessbackend.h" | 33 | #include "ocontactaccessbackend.h" |
31 | #include "ocontactaccess.h" | 34 | #include "ocontactaccess.h" |
32 | 35 | ||
33 | #include <qlist.h> | 36 | #include <qlist.h> |
34 | #include <qdict.h> | 37 | #include <qdict.h> |
35 | 38 | ||
36 | class OSQLDriver; | 39 | class OSQLDriver; |
37 | class OSQLResult; | 40 | class OSQLResult; |
38 | class OSQLResultItem; | 41 | class OSQLResultItem; |
39 | 42 | ||
40 | /* the default xml implementation */ | 43 | /* the default xml implementation */ |
41 | /** | 44 | /** |
42 | * This class is the SQL implementation of a Contact backend | 45 | * This class is the SQL implementation of a Contact backend |
43 | * it does implement everything available for OContact. | 46 | * it does implement everything available for OContact. |
44 | * @see OPimAccessBackend for more information of available methods | 47 | * @see OPimAccessBackend for more information of available methods |
45 | */ | 48 | */ |
46 | class OContactAccessBackend_SQL : public OContactAccessBackend { | 49 | class OContactAccessBackend_SQL : public OContactAccessBackend { |
47 | public: | 50 | public: |
48 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); | 51 | OContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); |
49 | 52 | ||
53 | ~OContactAccessBackend_SQL (); | ||
54 | |||
50 | bool save(); | 55 | bool save(); |
51 | 56 | ||
52 | bool load (); | 57 | bool load (); |
53 | 58 | ||
54 | void clear (); | 59 | void clear (); |
55 | 60 | ||
56 | bool wasChangedExternally(); | 61 | bool wasChangedExternally(); |
57 | 62 | ||
58 | QArray<int> allRecords() const; | 63 | QArray<int> allRecords() const; |
59 | 64 | ||
60 | OContact find ( int uid ) const; | 65 | OContact find ( int uid ) const; |
61 | // FIXME: Add lookahead-cache support ! | 66 | // FIXME: Add lookahead-cache support ! |
62 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; | 67 | //OContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; |
63 | 68 | ||
64 | QArray<int> queryByExample ( const OContact &query, int settings, | 69 | QArray<int> queryByExample ( const OContact &query, int settings, |
65 | const QDateTime& d ); | 70 | const QDateTime& d ); |
66 | 71 | ||
67 | QArray<int> matchRegexp( const QRegExp &r ) const; | 72 | QArray<int> matchRegexp( const QRegExp &r ) const; |
68 | 73 | ||
69 | const uint querySettings(); | 74 | const uint querySettings(); |
70 | 75 | ||
71 | bool hasQuerySettings (uint querySettings) const; | 76 | bool hasQuerySettings (uint querySettings) const; |
72 | 77 | ||
73 | // Currently only asc implemented.. | 78 | // Currently only asc implemented.. |
74 | QArray<int> sorted( bool asc, int , int , int ); | 79 | QArray<int> sorted( bool asc, int , int , int ); |
75 | bool add ( const OContact &newcontact ); | 80 | bool add ( const OContact &newcontact ); |
76 | 81 | ||
77 | bool replace ( const OContact &contact ); | 82 | bool replace ( const OContact &contact ); |
78 | 83 | ||
79 | bool remove ( int uid ); | 84 | bool remove ( int uid ); |
80 | bool reload(); | 85 | bool reload(); |
81 | 86 | ||
82 | private: | 87 | private: |
83 | QArray<int> extractUids( OSQLResult& res ) const; | 88 | QArray<int> extractUids( OSQLResult& res ) const; |
84 | QMap<int, QString> requestNonCustom( int uid ) const; | 89 | QMap<int, QString> requestNonCustom( int uid ) const; |
85 | QMap<QString, QString> requestCustom( int uid ) const; | 90 | QMap<QString, QString> requestCustom( int uid ) const; |
86 | void update(); | 91 | void update(); |
87 | 92 | ||
88 | protected: | 93 | protected: |
89 | bool m_changed; | 94 | bool m_changed; |
90 | QString m_fileName; | 95 | QString m_fileName; |
91 | QArray<int> m_uids; | 96 | QArray<int> m_uids; |
92 | 97 | ||
93 | OSQLDriver* m_driver; | 98 | OSQLDriver* m_driver; |
94 | }; | 99 | }; |
95 | 100 | ||
96 | #endif | 101 | #endif |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp new file mode 100644 index 0000000..9769bf7 --- a/dev/null +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Calender Database. | ||
3 | * | ||
4 | * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ===================================================================== | ||
13 | * Version: $Id$ | ||
14 | * ===================================================================== | ||
15 | * History: | ||
16 | * $Log$ | ||
17 | * Revision 1.1 2003/12/08 15:18:12 eilers | ||
18 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
19 | * | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | #include <qarray.h> | ||
27 | #include <qstringlist.h> | ||
28 | |||
29 | #include "orecur.h" | ||
30 | #include "odatebookaccessbackend_sql.h" | ||
31 | |||
32 | #include <opie2/osqldriver.h> | ||
33 | #include <opie2/osqlresult.h> | ||
34 | #include <opie2/osqlmanager.h> | ||
35 | #include <opie2/osqlquery.h> | ||
36 | |||
37 | namespace { | ||
38 | |||
39 | |||
40 | |||
41 | }; | ||
42 | |||
43 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | ||
44 | const QString& fileName ) | ||
45 | : ODateBookAccessBackend(), m_driver( NULL ) | ||
46 | { | ||
47 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | ||
48 | |||
49 | // Get the standart sql-driver from the OSQLManager.. | ||
50 | OSQLManager man; | ||
51 | m_driver = man.standard(); | ||
52 | m_driver->setUrl( m_fileName ); | ||
53 | |||
54 | initFields(); | ||
55 | |||
56 | load(); | ||
57 | } | ||
58 | |||
59 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | ||
60 | } | ||
61 | |||
62 | void ODateBookAccessBackend_SQL::initFields() | ||
63 | { | ||
64 | |||
65 | // This map contains the translation of the fieldtype id's to | ||
66 | // the names of the table columns | ||
67 | m_fieldMap.insert( OEvent::FUid, "uid" ); | ||
68 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); | ||
69 | m_fieldMap.insert( OEvent::FDescription, "Description" ); | ||
70 | m_fieldMap.insert( OEvent::FLocation, "Location" ); | ||
71 | m_fieldMap.insert( OEvent::FType, "Type" ); | ||
72 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); | ||
73 | m_fieldMap.insert( OEvent::FSound, "Sound" ); | ||
74 | m_fieldMap.insert( OEvent::FRType, "RType" ); | ||
75 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); | ||
76 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); | ||
77 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); | ||
78 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); | ||
79 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); | ||
80 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); | ||
81 | m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); | ||
82 | m_fieldMap.insert( OEvent::FStart, "Start" ); | ||
83 | m_fieldMap.insert( OEvent::FEnd, "End" ); | ||
84 | m_fieldMap.insert( OEvent::FNote, "Note" ); | ||
85 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); | ||
86 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); | ||
87 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); | ||
88 | } | ||
89 | |||
90 | bool ODateBookAccessBackend_SQL::load() | ||
91 | { | ||
92 | if (!m_driver->open() ) | ||
93 | return false; | ||
94 | |||
95 | // Don't expect that the database exists. | ||
96 | // It is save here to create the table, even if it | ||
97 | // do exist. ( Is that correct for all databases ?? ) | ||
98 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; | ||
99 | |||
100 | QMap<int, QString>::Iterator it; | ||
101 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
102 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); | ||
103 | } | ||
104 | qu += " );"; | ||
105 | |||
106 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | ||
107 | |||
108 | OSQLRawQuery raw( qu ); | ||
109 | OSQLResult res = m_driver->query( &raw ); | ||
110 | if ( res.state() != OSQLResult::Success ) | ||
111 | return false; | ||
112 | |||
113 | update(); | ||
114 | |||
115 | return true; | ||
116 | } | ||
117 | |||
118 | void ODateBookAccessBackend_SQL::update() | ||
119 | { | ||
120 | |||
121 | QString qu = "select uid from datebook"; | ||
122 | OSQLRawQuery raw( qu ); | ||
123 | OSQLResult res = m_driver->query( &raw ); | ||
124 | if ( res.state() != OSQLResult::Success ){ | ||
125 | m_uids.clear(); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | m_uids = extractUids( res ); | ||
130 | |||
131 | } | ||
132 | |||
133 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
134 | { | ||
135 | qWarning("extractUids"); | ||
136 | |||
137 | OSQLResultItem::ValueList list = res.results(); | ||
138 | OSQLResultItem::ValueList::Iterator it; | ||
139 | QArray<int> ints(list.count() ); | ||
140 | qWarning(" count = %d", list.count() ); | ||
141 | |||
142 | int i = 0; | ||
143 | for (it = list.begin(); it != list.end(); ++it ) { | ||
144 | ints[i] = (*it).data("uid").toInt(); | ||
145 | i++; | ||
146 | } | ||
147 | |||
148 | return ints; | ||
149 | |||
150 | } | ||
151 | |||
152 | bool ODateBookAccessBackend_SQL::reload() | ||
153 | { | ||
154 | return load(); | ||
155 | } | ||
156 | |||
157 | bool ODateBookAccessBackend_SQL::save() | ||
158 | { | ||
159 | return m_driver->close(); | ||
160 | } | ||
161 | |||
162 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | ||
163 | { | ||
164 | return m_uids; | ||
165 | } | ||
166 | |||
167 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { | ||
168 | return QArray<int>(); | ||
169 | } | ||
170 | |||
171 | void ODateBookAccessBackend_SQL::clear() | ||
172 | { | ||
173 | QString qu = "drop table datebook;"; | ||
174 | qu += "drop table custom_data;"; | ||
175 | |||
176 | OSQLRawQuery raw( qu ); | ||
177 | OSQLResult res = m_driver->query( &raw ); | ||
178 | |||
179 | } | ||
180 | |||
181 | |||
182 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | ||
183 | } | ||
184 | |||
185 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { | ||
186 | return true; | ||
187 | } | ||
188 | bool ODateBookAccessBackend_SQL::remove( int uid ) { | ||
189 | |||
190 | return true; | ||
191 | } | ||
192 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { | ||
193 | remove( ev.uid() ); | ||
194 | return add( ev ); | ||
195 | } | ||
196 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { | ||
197 | return allRecords(); | ||
198 | } | ||
199 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { | ||
200 | |||
201 | return ints; | ||
202 | } | ||
203 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { | ||
204 | |||
205 | return ints; | ||
206 | } | ||
207 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { | ||
208 | |||
209 | return list; | ||
210 | } | ||
211 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { | ||
212 | |||
213 | return list; | ||
214 | } | ||
215 | |||
216 | |||
217 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | ||
218 | { | ||
219 | |||
220 | return m_currentQuery; | ||
221 | } | ||
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h new file mode 100644 index 0000000..85e0d4f --- a/dev/null +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
2 | #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H | ||
3 | |||
4 | #include <qmap.h> | ||
5 | |||
6 | #include "odatebookaccessbackend.h" | ||
7 | |||
8 | class OSQLDriver; | ||
9 | |||
10 | /** | ||
11 | * This is the default SQL implementation for DateBoook SQL storage | ||
12 | * It fully implements the interface | ||
13 | * @see ODateBookAccessBackend | ||
14 | * @see OPimAccessBackend | ||
15 | */ | ||
16 | class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { | ||
17 | public: | ||
18 | ODateBookAccessBackend_SQL( const QString& appName, | ||
19 | const QString& fileName = QString::null); | ||
20 | ~ODateBookAccessBackend_SQL(); | ||
21 | |||
22 | bool load(); | ||
23 | bool reload(); | ||
24 | bool save(); | ||
25 | |||
26 | QArray<int> allRecords()const; | ||
27 | QArray<int> matchRegexp(const QRegExp &r) const; | ||
28 | QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() ); | ||
29 | OEvent find( int uid )const; | ||
30 | void clear(); | ||
31 | bool add( const OEvent& ev ); | ||
32 | bool remove( int uid ); | ||
33 | bool replace( const OEvent& ev ); | ||
34 | |||
35 | QArray<UID> rawEvents()const; | ||
36 | QArray<UID> rawRepeats()const; | ||
37 | QArray<UID> nonRepeats()const; | ||
38 | |||
39 | OEvent::ValueList directNonRepeats(); | ||
40 | OEvent::ValueList directRawRepeats(); | ||
41 | |||
42 | private: | ||
43 | bool loadFile(); | ||
44 | QString m_fileName; | ||
45 | QArray<int> m_uids; | ||
46 | |||
47 | QMap<int, QString> m_fieldMap; | ||
48 | |||
49 | OSQLDriver* m_driver; | ||
50 | |||
51 | class Private; | ||
52 | Private *d; | ||
53 | |||
54 | void initFields(); | ||
55 | void update(); | ||
56 | QArray<int> extractUids( OSQLResult& res ) const; | ||
57 | |||
58 | }; | ||
59 | |||
60 | #endif | ||
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index 39c43c5..929d004 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | |||
@@ -1,542 +1,548 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | 6 | ||
7 | #include <sys/types.h> | 7 | #include <sys/types.h> |
8 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
10 | 10 | ||
11 | #include <unistd.h> | 11 | #include <unistd.h> |
12 | 12 | ||
13 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
14 | #include <qfile.h> | 14 | #include <qfile.h> |
15 | 15 | ||
16 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
17 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | 18 | #include <qtopia/timeconversion.h> |
19 | 19 | ||
20 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
21 | #include "orecur.h" | 21 | #include "orecur.h" |
22 | #include "otimezone.h" | 22 | #include "otimezone.h" |
23 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
24 | 24 | ||
25 | namespace { | 25 | namespace { |
26 | // FROM TT again | 26 | // FROM TT again |
27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | 27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) |
28 | { | 28 | { |
29 | char needleChar; | 29 | char needleChar; |
30 | char haystackChar; | 30 | char haystackChar; |
31 | if (!needle || !haystack || !hLen || !nLen) | 31 | if (!needle || !haystack || !hLen || !nLen) |
32 | return 0; | 32 | return 0; |
33 | 33 | ||
34 | const char* hsearch = haystack; | 34 | const char* hsearch = haystack; |
35 | 35 | ||
36 | if ((needleChar = *needle++) != 0) { | 36 | if ((needleChar = *needle++) != 0) { |
37 | nLen--; //(to make up for needle++) | 37 | nLen--; //(to make up for needle++) |
38 | do { | 38 | do { |
39 | do { | 39 | do { |
40 | if ((haystackChar = *hsearch++) == 0) | 40 | if ((haystackChar = *hsearch++) == 0) |
41 | return (0); | 41 | return (0); |
42 | if (hsearch >= haystack + hLen) | 42 | if (hsearch >= haystack + hLen) |
43 | return (0); | 43 | return (0); |
44 | } while (haystackChar != needleChar); | 44 | } while (haystackChar != needleChar); |
45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | 45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); |
46 | hsearch--; | 46 | hsearch--; |
47 | } | 47 | } |
48 | return ((char *)hsearch); | 48 | return ((char *)hsearch); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | namespace { | 52 | namespace { |
53 | time_t start, end, created, rp_end; | 53 | time_t start, end, created, rp_end; |
54 | ORecur* rec; | 54 | ORecur* rec; |
55 | ORecur* recur() { | 55 | ORecur* recur() { |
56 | if (!rec) | 56 | if (!rec) |
57 | rec = new ORecur; | 57 | rec = new ORecur; |
58 | 58 | ||
59 | return rec; | 59 | return rec; |
60 | } | 60 | } |
61 | int alarmTime; | 61 | int alarmTime; |
62 | int snd; | 62 | int snd; |
63 | enum Attribute{ | 63 | enum Attribute{ |
64 | FDescription = 0, | 64 | FDescription = 0, |
65 | FLocation, | 65 | FLocation, |
66 | FCategories, | 66 | FCategories, |
67 | FUid, | 67 | FUid, |
68 | FType, | 68 | FType, |
69 | FAlarm, | 69 | FAlarm, |
70 | FSound, | 70 | FSound, |
71 | FRType, | 71 | FRType, |
72 | FRWeekdays, | 72 | FRWeekdays, |
73 | FRPosition, | 73 | FRPosition, |
74 | FRFreq, | 74 | FRFreq, |
75 | FRHasEndDate, | 75 | FRHasEndDate, |
76 | FREndDate, | 76 | FREndDate, |
77 | FRStart, | 77 | FRStart, |
78 | FREnd, | 78 | FREnd, |
79 | FNote, | 79 | FNote, |
80 | FCreated, | 80 | FCreated, // Should't this be called FRCreated ? |
81 | FTimeZone, | 81 | FTimeZone, |
82 | FRecParent, | 82 | FRecParent, |
83 | FRecChildren, | 83 | FRecChildren, |
84 | FExceptions | 84 | FExceptions |
85 | }; | 85 | }; |
86 | |||
87 | // FIXME: Use OEvent::toMap() here !! (eilers) | ||
86 | inline void save( const OEvent& ev, QString& buf ) { | 88 | inline void save( const OEvent& ev, QString& buf ) { |
87 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); | 89 | qWarning("Saving %d %s", ev.uid(), ev.description().latin1() ); |
88 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 90 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
89 | if (!ev.location().isEmpty() ) | 91 | if (!ev.location().isEmpty() ) |
90 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 92 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
91 | 93 | ||
92 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 94 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
93 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 95 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
94 | 96 | ||
95 | if (ev.isAllDay() ) | 97 | if (ev.isAllDay() ) |
96 | buf += " type=\"AllDay\""; // is that all ?? (eilers) | 98 | buf += " type=\"AllDay\""; // is that all ?? (eilers) |
97 | 99 | ||
98 | if (ev.hasNotifiers() ) { | 100 | if (ev.hasNotifiers() ) { |
99 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 101 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
100 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 102 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
101 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 103 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
102 | if ( alarm.sound() == OPimAlarm::Loud ) | 104 | if ( alarm.sound() == OPimAlarm::Loud ) |
103 | buf += "loud"; | 105 | buf += "loud"; |
104 | else | 106 | else |
105 | buf += "silent"; | 107 | buf += "silent"; |
106 | buf += "\""; | 108 | buf += "\""; |
107 | } | 109 | } |
108 | if ( ev.hasRecurrence() ) { | 110 | if ( ev.hasRecurrence() ) { |
109 | buf += ev.recurrence().toString(); | 111 | buf += ev.recurrence().toString(); |
110 | } | 112 | } |
111 | 113 | ||
112 | /* | 114 | /* |
113 | * fscking timezones :) well, we'll first convert | 115 | * fscking timezones :) well, we'll first convert |
114 | * the QDateTime to a QDateTime in UTC time | 116 | * the QDateTime to a QDateTime in UTC time |
115 | * and then we'll create a nice time_t | 117 | * and then we'll create a nice time_t |
116 | */ | 118 | */ |
117 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 119 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
118 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; | 120 | buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; |
119 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; | 121 | buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; |
120 | if (!ev.note().isEmpty() ) { | 122 | if (!ev.note().isEmpty() ) { |
121 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; | 123 | buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; |
122 | } | 124 | } |
123 | 125 | ||
124 | buf += " timezone=\""; | 126 | buf += " timezone=\""; |
125 | if ( ev.timeZone().isEmpty() ) | 127 | if ( ev.timeZone().isEmpty() ) |
126 | buf += "None"; | 128 | buf += "None"; |
127 | else | 129 | else |
128 | buf += ev.timeZone(); | 130 | buf += ev.timeZone(); |
129 | buf += "\""; | 131 | buf += "\""; |
130 | 132 | ||
131 | if (ev.parent() != 0 ) { | 133 | if (ev.parent() != 0 ) { |
132 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; | 134 | buf += " recparent=\""+QString::number(ev.parent() )+"\""; |
133 | } | 135 | } |
134 | 136 | ||
135 | if (ev.children().count() != 0 ) { | 137 | if (ev.children().count() != 0 ) { |
136 | QArray<int> children = ev.children(); | 138 | QArray<int> children = ev.children(); |
137 | buf += " recchildren=\""; | 139 | buf += " recchildren=\""; |
138 | for ( uint i = 0; i < children.count(); i++ ) { | 140 | for ( uint i = 0; i < children.count(); i++ ) { |
139 | if ( i != 0 ) buf += " "; | 141 | if ( i != 0 ) buf += " "; |
140 | buf += QString::number( children[i] ); | 142 | buf += QString::number( children[i] ); |
141 | } | 143 | } |
142 | buf+= "\""; | 144 | buf+= "\""; |
143 | } | 145 | } |
144 | 146 | ||
145 | // skip custom writing | 147 | // skip custom writing |
146 | } | 148 | } |
147 | 149 | ||
148 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { | 150 | inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { |
149 | QMap<int, OEvent>::ConstIterator it; | 151 | QMap<int, OEvent>::ConstIterator it; |
150 | QString buf; | 152 | QString buf; |
151 | QCString str; | 153 | QCString str; |
152 | int total_written; | 154 | int total_written; |
153 | for ( it = list.begin(); it != list.end(); ++it ) { | 155 | for ( it = list.begin(); it != list.end(); ++it ) { |
154 | buf = "<event"; | 156 | buf = "<event"; |
155 | save( it.data(), buf ); | 157 | save( it.data(), buf ); |
156 | buf += " />\n"; | 158 | buf += " />\n"; |
157 | str = buf.utf8(); | 159 | str = buf.utf8(); |
158 | 160 | ||
159 | total_written = file.writeBlock(str.data(), str.length() ); | 161 | total_written = file.writeBlock(str.data(), str.length() ); |
160 | if ( total_written != int(str.length() ) ) | 162 | if ( total_written != int(str.length() ) ) |
161 | return false; | 163 | return false; |
162 | } | 164 | } |
163 | return true; | 165 | return true; |
164 | } | 166 | } |
165 | } | 167 | } |
166 | 168 | ||
167 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , | 169 | ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , |
168 | const QString& fileName ) | 170 | const QString& fileName ) |
169 | : ODateBookAccessBackend() { | 171 | : ODateBookAccessBackend() { |
170 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; | 172 | m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; |
171 | m_changed = false; | 173 | m_changed = false; |
172 | } | 174 | } |
173 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { | 175 | ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { |
174 | } | 176 | } |
175 | bool ODateBookAccessBackend_XML::load() { | 177 | bool ODateBookAccessBackend_XML::load() { |
176 | return loadFile(); | 178 | return loadFile(); |
177 | } | 179 | } |
178 | bool ODateBookAccessBackend_XML::reload() { | 180 | bool ODateBookAccessBackend_XML::reload() { |
179 | clear(); | 181 | clear(); |
180 | return load(); | 182 | return load(); |
181 | } | 183 | } |
182 | bool ODateBookAccessBackend_XML::save() { | 184 | bool ODateBookAccessBackend_XML::save() { |
183 | if (!m_changed) return true; | 185 | if (!m_changed) return true; |
184 | 186 | ||
185 | int total_written; | 187 | int total_written; |
186 | QString strFileNew = m_name + ".new"; | 188 | QString strFileNew = m_name + ".new"; |
187 | 189 | ||
188 | QFile f( strFileNew ); | 190 | QFile f( strFileNew ); |
189 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; | 191 | if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; |
190 | 192 | ||
191 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | 193 | QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); |
192 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; | 194 | buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; |
193 | buf += "<events>\n"; | 195 | buf += "<events>\n"; |
194 | QCString str = buf.utf8(); | 196 | QCString str = buf.utf8(); |
195 | total_written = f.writeBlock( str.data(), str.length() ); | 197 | total_written = f.writeBlock( str.data(), str.length() ); |
196 | if ( total_written != int(str.length() ) ) { | 198 | if ( total_written != int(str.length() ) ) { |
197 | f.close(); | 199 | f.close(); |
198 | QFile::remove( strFileNew ); | 200 | QFile::remove( strFileNew ); |
199 | return false; | 201 | return false; |
200 | } | 202 | } |
201 | 203 | ||
202 | if (!forAll( m_raw, f ) ) { | 204 | if (!forAll( m_raw, f ) ) { |
203 | f.close(); | 205 | f.close(); |
204 | QFile::remove( strFileNew ); | 206 | QFile::remove( strFileNew ); |
205 | return false; | 207 | return false; |
206 | } | 208 | } |
207 | if (!forAll( m_rep, f ) ) { | 209 | if (!forAll( m_rep, f ) ) { |
208 | f.close(); | 210 | f.close(); |
209 | QFile::remove( strFileNew ); | 211 | QFile::remove( strFileNew ); |
210 | return false; | 212 | return false; |
211 | } | 213 | } |
212 | 214 | ||
213 | buf = "</events>\n</DATEBOOK>\n"; | 215 | buf = "</events>\n</DATEBOOK>\n"; |
214 | str = buf.utf8(); | 216 | str = buf.utf8(); |
215 | total_written = f.writeBlock( str.data(), str.length() ); | 217 | total_written = f.writeBlock( str.data(), str.length() ); |
216 | if ( total_written != int(str.length() ) ) { | 218 | if ( total_written != int(str.length() ) ) { |
217 | f.close(); | 219 | f.close(); |
218 | QFile::remove( strFileNew ); | 220 | QFile::remove( strFileNew ); |
219 | return false; | 221 | return false; |
220 | } | 222 | } |
221 | f.close(); | 223 | f.close(); |
222 | 224 | ||
223 | if ( ::rename( strFileNew, m_name ) < 0 ) { | 225 | if ( ::rename( strFileNew, m_name ) < 0 ) { |
224 | QFile::remove( strFileNew ); | 226 | QFile::remove( strFileNew ); |
225 | return false; | 227 | return false; |
226 | } | 228 | } |
227 | 229 | ||
228 | m_changed = false; | 230 | m_changed = false; |
229 | return true; | 231 | return true; |
230 | } | 232 | } |
231 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { | 233 | QArray<int> ODateBookAccessBackend_XML::allRecords()const { |
232 | QArray<int> ints( m_raw.count()+ m_rep.count() ); | 234 | QArray<int> ints( m_raw.count()+ m_rep.count() ); |
233 | uint i = 0; | 235 | uint i = 0; |
234 | QMap<int, OEvent>::ConstIterator it; | 236 | QMap<int, OEvent>::ConstIterator it; |
235 | 237 | ||
236 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 238 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
237 | ints[i] = it.key(); | 239 | ints[i] = it.key(); |
238 | i++; | 240 | i++; |
239 | } | 241 | } |
240 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 242 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
241 | ints[i] = it.key(); | 243 | ints[i] = it.key(); |
242 | i++; | 244 | i++; |
243 | } | 245 | } |
244 | 246 | ||
245 | return ints; | 247 | return ints; |
246 | } | 248 | } |
247 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { | 249 | QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int, const QDateTime& ) { |
248 | return QArray<int>(); | 250 | return QArray<int>(); |
249 | } | 251 | } |
250 | void ODateBookAccessBackend_XML::clear() { | 252 | void ODateBookAccessBackend_XML::clear() { |
251 | m_changed = true; | 253 | m_changed = true; |
252 | m_raw.clear(); | 254 | m_raw.clear(); |
253 | m_rep.clear(); | 255 | m_rep.clear(); |
254 | } | 256 | } |
255 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ | 257 | OEvent ODateBookAccessBackend_XML::find( int uid ) const{ |
256 | if ( m_raw.contains( uid ) ) | 258 | if ( m_raw.contains( uid ) ) |
257 | return m_raw[uid]; | 259 | return m_raw[uid]; |
258 | else | 260 | else |
259 | return m_rep[uid]; | 261 | return m_rep[uid]; |
260 | } | 262 | } |
261 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { | 263 | bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { |
262 | m_changed = true; | 264 | m_changed = true; |
263 | if (ev.hasRecurrence() ) | 265 | if (ev.hasRecurrence() ) |
264 | m_rep.insert( ev.uid(), ev ); | 266 | m_rep.insert( ev.uid(), ev ); |
265 | else | 267 | else |
266 | m_raw.insert( ev.uid(), ev ); | 268 | m_raw.insert( ev.uid(), ev ); |
267 | 269 | ||
268 | return true; | 270 | return true; |
269 | } | 271 | } |
270 | bool ODateBookAccessBackend_XML::remove( int uid ) { | 272 | bool ODateBookAccessBackend_XML::remove( int uid ) { |
271 | m_changed = true; | 273 | m_changed = true; |
272 | m_rep.remove( uid ); | 274 | m_rep.remove( uid ); |
273 | m_rep.remove( uid ); | 275 | m_rep.remove( uid ); |
274 | 276 | ||
275 | return true; | 277 | return true; |
276 | } | 278 | } |
277 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { | 279 | bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { |
278 | replace( ev.uid() ); | 280 | replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) |
279 | return add( ev ); | 281 | return add( ev ); |
280 | } | 282 | } |
281 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { | 283 | QArray<int> ODateBookAccessBackend_XML::rawEvents()const { |
282 | return allRecords(); | 284 | return allRecords(); |
283 | } | 285 | } |
284 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { | 286 | QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { |
285 | QArray<int> ints( m_rep.count() ); | 287 | QArray<int> ints( m_rep.count() ); |
286 | uint i = 0; | 288 | uint i = 0; |
287 | QMap<int, OEvent>::ConstIterator it; | 289 | QMap<int, OEvent>::ConstIterator it; |
288 | 290 | ||
289 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { | 291 | for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { |
290 | ints[i] = it.key(); | 292 | ints[i] = it.key(); |
291 | i++; | 293 | i++; |
292 | } | 294 | } |
293 | 295 | ||
294 | return ints; | 296 | return ints; |
295 | } | 297 | } |
296 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { | 298 | QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { |
297 | QArray<int> ints( m_raw.count() ); | 299 | QArray<int> ints( m_raw.count() ); |
298 | uint i = 0; | 300 | uint i = 0; |
299 | QMap<int, OEvent>::ConstIterator it; | 301 | QMap<int, OEvent>::ConstIterator it; |
300 | 302 | ||
301 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { | 303 | for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { |
302 | ints[i] = it.key(); | 304 | ints[i] = it.key(); |
303 | i++; | 305 | i++; |
304 | } | 306 | } |
305 | 307 | ||
306 | return ints; | 308 | return ints; |
307 | } | 309 | } |
308 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { | 310 | OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { |
309 | OEvent::ValueList list; | 311 | OEvent::ValueList list; |
310 | QMap<int, OEvent>::ConstIterator it; | 312 | QMap<int, OEvent>::ConstIterator it; |
311 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) | 313 | for (it = m_raw.begin(); it != m_raw.end(); ++it ) |
312 | list.append( it.data() ); | 314 | list.append( it.data() ); |
313 | 315 | ||
314 | return list; | 316 | return list; |
315 | } | 317 | } |
316 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { | 318 | OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { |
317 | OEvent::ValueList list; | 319 | OEvent::ValueList list; |
318 | QMap<int, OEvent>::ConstIterator it; | 320 | QMap<int, OEvent>::ConstIterator it; |
319 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) | 321 | for (it = m_rep.begin(); it != m_rep.end(); ++it ) |
320 | list.append( it.data() ); | 322 | list.append( it.data() ); |
321 | 323 | ||
322 | return list; | 324 | return list; |
323 | } | 325 | } |
326 | |||
327 | // FIXME: Use OEvent::fromMap() (eilers) | ||
324 | bool ODateBookAccessBackend_XML::loadFile() { | 328 | bool ODateBookAccessBackend_XML::loadFile() { |
325 | m_changed = false; | 329 | m_changed = false; |
326 | 330 | ||
327 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 331 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
328 | if ( fd < 0 ) return false; | 332 | if ( fd < 0 ) return false; |
329 | 333 | ||
330 | struct stat attribute; | 334 | struct stat attribute; |
331 | if ( ::fstat(fd, &attribute ) == -1 ) { | 335 | if ( ::fstat(fd, &attribute ) == -1 ) { |
332 | ::close( fd ); | 336 | ::close( fd ); |
333 | return false; | 337 | return false; |
334 | } | 338 | } |
335 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 339 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
336 | if ( map_addr == ( (caddr_t)-1) ) { | 340 | if ( map_addr == ( (caddr_t)-1) ) { |
337 | ::close( fd ); | 341 | ::close( fd ); |
338 | return false; | 342 | return false; |
339 | } | 343 | } |
340 | 344 | ||
341 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 345 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
342 | ::close( fd ); | 346 | ::close( fd ); |
343 | 347 | ||
344 | QAsciiDict<int> dict(FExceptions+1); | 348 | QAsciiDict<int> dict(FExceptions+1); |
345 | dict.setAutoDelete( true ); | 349 | dict.setAutoDelete( true ); |
346 | dict.insert( "description", new int(FDescription) ); | 350 | dict.insert( "description", new int(FDescription) ); |
347 | dict.insert( "location", new int(FLocation) ); | 351 | dict.insert( "location", new int(FLocation) ); |
348 | dict.insert( "categories", new int(FCategories) ); | 352 | dict.insert( "categories", new int(FCategories) ); |
349 | dict.insert( "uid", new int(FUid) ); | 353 | dict.insert( "uid", new int(FUid) ); |
350 | dict.insert( "type", new int(FType) ); | 354 | dict.insert( "type", new int(FType) ); |
351 | dict.insert( "alarm", new int(FAlarm) ); | 355 | dict.insert( "alarm", new int(FAlarm) ); |
352 | dict.insert( "sound", new int(FSound) ); | 356 | dict.insert( "sound", new int(FSound) ); |
353 | dict.insert( "rtype", new int(FRType) ); | 357 | dict.insert( "rtype", new int(FRType) ); |
354 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 358 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
355 | dict.insert( "rposition", new int(FRPosition) ); | 359 | dict.insert( "rposition", new int(FRPosition) ); |
356 | dict.insert( "rfreq", new int(FRFreq) ); | 360 | dict.insert( "rfreq", new int(FRFreq) ); |
357 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 361 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
358 | dict.insert( "enddt", new int(FREndDate) ); | 362 | dict.insert( "enddt", new int(FREndDate) ); |
359 | dict.insert( "start", new int(FRStart) ); | 363 | dict.insert( "start", new int(FRStart) ); |
360 | dict.insert( "end", new int(FREnd) ); | 364 | dict.insert( "end", new int(FREnd) ); |
361 | dict.insert( "note", new int(FNote) ); | 365 | dict.insert( "note", new int(FNote) ); |
362 | dict.insert( "created", new int(FCreated) ); | 366 | dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? |
363 | dict.insert( "recparent", new int(FRecParent) ); | 367 | dict.insert( "recparent", new int(FRecParent) ); |
364 | dict.insert( "recchildren", new int(FRecChildren) ); | 368 | dict.insert( "recchildren", new int(FRecChildren) ); |
365 | dict.insert( "exceptions", new int(FExceptions) ); | 369 | dict.insert( "exceptions", new int(FExceptions) ); |
366 | dict.insert( "timezone", new int(FTimeZone) ); | 370 | dict.insert( "timezone", new int(FTimeZone) ); |
367 | 371 | ||
368 | char* dt = (char*)map_addr; | 372 | char* dt = (char*)map_addr; |
369 | int len = attribute.st_size; | 373 | int len = attribute.st_size; |
370 | int i = 0; | 374 | int i = 0; |
371 | char* point; | 375 | char* point; |
372 | const char* collectionString = "<event "; | 376 | const char* collectionString = "<event "; |
373 | int strLen = ::strlen(collectionString); | 377 | int strLen = ::strlen(collectionString); |
374 | int *find; | 378 | int *find; |
375 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { | 379 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
376 | i = point -dt; | 380 | i = point -dt; |
377 | i+= strLen; | 381 | i+= strLen; |
378 | 382 | ||
379 | alarmTime = -1; | 383 | alarmTime = -1; |
380 | snd = 0; // silent | 384 | snd = 0; // silent |
381 | 385 | ||
382 | OEvent ev; | 386 | OEvent ev; |
383 | rec = 0; | 387 | rec = 0; |
384 | 388 | ||
385 | while ( TRUE ) { | 389 | while ( TRUE ) { |
386 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 390 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
387 | ++i; | 391 | ++i; |
388 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 392 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
389 | break; | 393 | break; |
390 | 394 | ||
391 | 395 | ||
392 | // we have another attribute, read it. | 396 | // we have another attribute, read it. |
393 | int j = i; | 397 | int j = i; |
394 | while ( j < len && dt[j] != '=' ) | 398 | while ( j < len && dt[j] != '=' ) |
395 | ++j; | 399 | ++j; |
396 | QCString attr( dt+i, j-i+1); | 400 | QCString attr( dt+i, j-i+1); |
397 | 401 | ||
398 | i = ++j; // skip = | 402 | i = ++j; // skip = |
399 | 403 | ||
400 | // find the start of quotes | 404 | // find the start of quotes |
401 | while ( i < len && dt[i] != '"' ) | 405 | while ( i < len && dt[i] != '"' ) |
402 | ++i; | 406 | ++i; |
403 | j = ++i; | 407 | j = ++i; |
404 | 408 | ||
405 | bool haveUtf = FALSE; | 409 | bool haveUtf = FALSE; |
406 | bool haveEnt = FALSE; | 410 | bool haveEnt = FALSE; |
407 | while ( j < len && dt[j] != '"' ) { | 411 | while ( j < len && dt[j] != '"' ) { |
408 | if ( ((unsigned char)dt[j]) > 0x7f ) | 412 | if ( ((unsigned char)dt[j]) > 0x7f ) |
409 | haveUtf = TRUE; | 413 | haveUtf = TRUE; |
410 | if ( dt[j] == '&' ) | 414 | if ( dt[j] == '&' ) |
411 | haveEnt = TRUE; | 415 | haveEnt = TRUE; |
412 | ++j; | 416 | ++j; |
413 | } | 417 | } |
414 | if ( i == j ) { | 418 | if ( i == j ) { |
415 | // empty value | 419 | // empty value |
416 | i = j + 1; | 420 | i = j + 1; |
417 | continue; | 421 | continue; |
418 | } | 422 | } |
419 | 423 | ||
420 | QCString value( dt+i, j-i+1 ); | 424 | QCString value( dt+i, j-i+1 ); |
421 | i = j + 1; | 425 | i = j + 1; |
422 | 426 | ||
423 | QString str = (haveUtf ? QString::fromUtf8( value ) | 427 | QString str = (haveUtf ? QString::fromUtf8( value ) |
424 | : QString::fromLatin1( value ) ); | 428 | : QString::fromLatin1( value ) ); |
425 | if ( haveEnt ) | 429 | if ( haveEnt ) |
426 | str = Qtopia::plainString( str ); | 430 | str = Qtopia::plainString( str ); |
427 | 431 | ||
428 | /* | 432 | /* |
429 | * add key + value | 433 | * add key + value |
430 | */ | 434 | */ |
431 | find = dict[attr.data()]; | 435 | find = dict[attr.data()]; |
432 | if (!find) | 436 | if (!find) |
433 | ev.setCustomField( attr, str ); | 437 | ev.setCustomField( attr, str ); |
434 | else { | 438 | else { |
435 | setField( ev, *find, str ); | 439 | setField( ev, *find, str ); |
436 | } | 440 | } |
437 | } | 441 | } |
438 | /* time to finalize */ | 442 | /* time to finalize */ |
439 | finalizeRecord( ev ); | 443 | finalizeRecord( ev ); |
440 | delete rec; | 444 | delete rec; |
441 | } | 445 | } |
442 | ::munmap(map_addr, attribute.st_size ); | 446 | ::munmap(map_addr, attribute.st_size ); |
443 | m_changed = false; // changed during add | 447 | m_changed = false; // changed during add |
444 | 448 | ||
445 | return true; | 449 | return true; |
446 | } | 450 | } |
451 | |||
452 | // FIXME: Use OEvent::fromMap() which makes this obsolete.. (eilers) | ||
447 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { | 453 | void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { |
448 | /* AllDay is alway in UTC */ | 454 | /* AllDay is alway in UTC */ |
449 | if ( ev.isAllDay() ) { | 455 | if ( ev.isAllDay() ) { |
450 | OTimeZone utc = OTimeZone::utc(); | 456 | OTimeZone utc = OTimeZone::utc(); |
451 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); | 457 | ev.setStartDateTime( utc.fromUTCDateTime( start ) ); |
452 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); | 458 | ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); |
453 | ev.setTimeZone( "UTC"); // make sure it is really utc | 459 | ev.setTimeZone( "UTC"); // make sure it is really utc |
454 | }else { | 460 | }else { |
455 | /* to current date time */ | 461 | /* to current date time */ |
456 | // qWarning(" Start is %d", start ); | 462 | // qWarning(" Start is %d", start ); |
457 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); | 463 | OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); |
458 | QDateTime date = zone.toDateTime( start ); | 464 | QDateTime date = zone.toDateTime( start ); |
459 | qWarning(" Start is %s", date.toString().latin1() ); | 465 | qWarning(" Start is %s", date.toString().latin1() ); |
460 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); | 466 | ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); |
461 | 467 | ||
462 | date = zone.toDateTime( end ); | 468 | date = zone.toDateTime( end ); |
463 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); | 469 | ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); |
464 | } | 470 | } |
465 | if ( rec && rec->doesRecur() ) { | 471 | if ( rec && rec->doesRecur() ) { |
466 | OTimeZone utc = OTimeZone::utc(); | 472 | OTimeZone utc = OTimeZone::utc(); |
467 | ORecur recu( *rec ); // call copy c'tor; | 473 | ORecur recu( *rec ); // call copy c'tor; |
468 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); | 474 | recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); |
469 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); | 475 | recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); |
470 | recu.setStart( ev.startDateTime().date() ); | 476 | recu.setStart( ev.startDateTime().date() ); |
471 | ev.setRecurrence( recu ); | 477 | ev.setRecurrence( recu ); |
472 | } | 478 | } |
473 | 479 | ||
474 | if (alarmTime != -1 ) { | 480 | if (alarmTime != -1 ) { |
475 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); | 481 | QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); |
476 | OPimAlarm al( snd , dt ); | 482 | OPimAlarm al( snd , dt ); |
477 | ev.notifiers().add( al ); | 483 | ev.notifiers().add( al ); |
478 | } | 484 | } |
479 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { | 485 | if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { |
480 | qWarning("already contains assign uid"); | 486 | qWarning("already contains assign uid"); |
481 | ev.setUid( 1 ); | 487 | ev.setUid( 1 ); |
482 | } | 488 | } |
483 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); | 489 | qWarning("addind %d %s", ev.uid(), ev.description().latin1() ); |
484 | if ( ev.hasRecurrence() ) | 490 | if ( ev.hasRecurrence() ) |
485 | m_rep.insert( ev.uid(), ev ); | 491 | m_rep.insert( ev.uid(), ev ); |
486 | else | 492 | else |
487 | m_raw.insert( ev.uid(), ev ); | 493 | m_raw.insert( ev.uid(), ev ); |
488 | 494 | ||
489 | } | 495 | } |
490 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { | 496 | void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { |
491 | // qWarning(" setting %s", value.latin1() ); | 497 | // qWarning(" setting %s", value.latin1() ); |
492 | switch( id ) { | 498 | switch( id ) { |
493 | case FDescription: | 499 | case FDescription: |
494 | e.setDescription( value ); | 500 | e.setDescription( value ); |
495 | break; | 501 | break; |
496 | case FLocation: | 502 | case FLocation: |
497 | e.setLocation( value ); | 503 | e.setLocation( value ); |
498 | break; | 504 | break; |
499 | case FCategories: | 505 | case FCategories: |
500 | e.setCategories( e.idsFromString( value ) ); | 506 | e.setCategories( e.idsFromString( value ) ); |
501 | break; | 507 | break; |
502 | case FUid: | 508 | case FUid: |
503 | e.setUid( value.toInt() ); | 509 | e.setUid( value.toInt() ); |
504 | break; | 510 | break; |
505 | case FType: | 511 | case FType: |
506 | if ( value == "AllDay" ) { | 512 | if ( value == "AllDay" ) { |
507 | e.setAllDay( true ); | 513 | e.setAllDay( true ); |
508 | e.setTimeZone( "UTC" ); | 514 | e.setTimeZone( "UTC" ); |
509 | } | 515 | } |
510 | break; | 516 | break; |
511 | case FAlarm: | 517 | case FAlarm: |
512 | alarmTime = value.toInt(); | 518 | alarmTime = value.toInt(); |
513 | break; | 519 | break; |
514 | case FSound: | 520 | case FSound: |
515 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; | 521 | snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; |
516 | break; | 522 | break; |
517 | // recurrence stuff | 523 | // recurrence stuff |
518 | case FRType: | 524 | case FRType: |
519 | if ( value == "Daily" ) | 525 | if ( value == "Daily" ) |
520 | recur()->setType( ORecur::Daily ); | 526 | recur()->setType( ORecur::Daily ); |
521 | else if ( value == "Weekly" ) | 527 | else if ( value == "Weekly" ) |
522 | recur()->setType( ORecur::Weekly); | 528 | recur()->setType( ORecur::Weekly); |
523 | else if ( value == "MonthlyDay" ) | 529 | else if ( value == "MonthlyDay" ) |
524 | recur()->setType( ORecur::MonthlyDay ); | 530 | recur()->setType( ORecur::MonthlyDay ); |
525 | else if ( value == "MonthlyDate" ) | 531 | else if ( value == "MonthlyDate" ) |
526 | recur()->setType( ORecur::MonthlyDate ); | 532 | recur()->setType( ORecur::MonthlyDate ); |
527 | else if ( value == "Yearly" ) | 533 | else if ( value == "Yearly" ) |
528 | recur()->setType( ORecur::Yearly ); | 534 | recur()->setType( ORecur::Yearly ); |
529 | else | 535 | else |
530 | recur()->setType( ORecur::NoRepeat ); | 536 | recur()->setType( ORecur::NoRepeat ); |
531 | break; | 537 | break; |
532 | case FRWeekdays: | 538 | case FRWeekdays: |
533 | recur()->setDays( value.toInt() ); | 539 | recur()->setDays( value.toInt() ); |
534 | break; | 540 | break; |
535 | case FRPosition: | 541 | case FRPosition: |
536 | recur()->setPosition( value.toInt() ); | 542 | recur()->setPosition( value.toInt() ); |
537 | break; | 543 | break; |
538 | case FRFreq: | 544 | case FRFreq: |
539 | recur()->setFrequency( value.toInt() ); | 545 | recur()->setFrequency( value.toInt() ); |
540 | break; | 546 | break; |
541 | case FRHasEndDate: | 547 | case FRHasEndDate: |
542 | recur()->setHasEndDate( value.toInt() ); | 548 | recur()->setHasEndDate( value.toInt() ); |
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index 3913661..75a0860 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp | |||
@@ -206,205 +206,208 @@ namespace { | |||
206 | else{ | 206 | else{ |
207 | qu += QString( "''" ) + "," | 207 | qu += QString( "''" ) + "," |
208 | + "''" + ","; | 208 | + "''" + ","; |
209 | } | 209 | } |
210 | 210 | ||
211 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) | 211 | qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) |
212 | + "'" + QString::number(sYear) + "-" | 212 | + "'" + QString::number(sYear) + "-" |
213 | + QString::number(sMonth) | 213 | + QString::number(sMonth) |
214 | + "-" + QString::number(sDay) + "'" + "," | 214 | + "-" + QString::number(sDay) + "'" + "," |
215 | + "'" + QString::number(eYear) + "-" | 215 | + "'" + QString::number(eYear) + "-" |
216 | + QString::number(eMonth) | 216 | + QString::number(eMonth) |
217 | + "-"+QString::number(eDay) + "'" | 217 | + "-"+QString::number(eDay) + "'" |
218 | + ")"; | 218 | + ")"; |
219 | 219 | ||
220 | qWarning("add %s", qu.latin1() ); | 220 | qWarning("add %s", qu.latin1() ); |
221 | return qu; | 221 | return qu; |
222 | } | 222 | } |
223 | 223 | ||
224 | RemoveQuery::RemoveQuery(int uid ) | 224 | RemoveQuery::RemoveQuery(int uid ) |
225 | : OSQLQuery(), m_uid( uid ) {} | 225 | : OSQLQuery(), m_uid( uid ) {} |
226 | RemoveQuery::~RemoveQuery() {} | 226 | RemoveQuery::~RemoveQuery() {} |
227 | QString RemoveQuery::query()const { | 227 | QString RemoveQuery::query()const { |
228 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); | 228 | QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); |
229 | return qu; | 229 | return qu; |
230 | } | 230 | } |
231 | 231 | ||
232 | 232 | ||
233 | ClearQuery::ClearQuery() | 233 | ClearQuery::ClearQuery() |
234 | : OSQLQuery() {} | 234 | : OSQLQuery() {} |
235 | ClearQuery::~ClearQuery() {} | 235 | ClearQuery::~ClearQuery() {} |
236 | QString ClearQuery::query()const { | 236 | QString ClearQuery::query()const { |
237 | QString qu = "drop table todolist"; | 237 | QString qu = "drop table todolist"; |
238 | return qu; | 238 | return qu; |
239 | } | 239 | } |
240 | FindQuery::FindQuery(int uid) | 240 | FindQuery::FindQuery(int uid) |
241 | : OSQLQuery(), m_uid(uid ) { | 241 | : OSQLQuery(), m_uid(uid ) { |
242 | } | 242 | } |
243 | FindQuery::FindQuery(const QArray<int>& ints) | 243 | FindQuery::FindQuery(const QArray<int>& ints) |
244 | : OSQLQuery(), m_uids(ints){ | 244 | : OSQLQuery(), m_uids(ints){ |
245 | } | 245 | } |
246 | FindQuery::~FindQuery() { | 246 | FindQuery::~FindQuery() { |
247 | } | 247 | } |
248 | QString FindQuery::query()const{ | 248 | QString FindQuery::query()const{ |
249 | if (m_uids.count() == 0 ) | 249 | if (m_uids.count() == 0 ) |
250 | return single(); | 250 | return single(); |
251 | else | 251 | else |
252 | return multi(); | 252 | return multi(); |
253 | } | 253 | } |
254 | QString FindQuery::single()const{ | 254 | QString FindQuery::single()const{ |
255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); | 255 | QString qu = "select * from todolist where uid = " + QString::number(m_uid); |
256 | return qu; | 256 | return qu; |
257 | } | 257 | } |
258 | QString FindQuery::multi()const { | 258 | QString FindQuery::multi()const { |
259 | QString qu = "select * from todolist where "; | 259 | QString qu = "select * from todolist where "; |
260 | for (uint i = 0; i < m_uids.count(); i++ ) { | 260 | for (uint i = 0; i < m_uids.count(); i++ ) { |
261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; | 261 | qu += " UID = " + QString::number( m_uids[i] ) + " OR"; |
262 | } | 262 | } |
263 | qu.remove( qu.length()-2, 2 ); | 263 | qu.remove( qu.length()-2, 2 ); |
264 | return qu; | 264 | return qu; |
265 | } | 265 | } |
266 | 266 | ||
267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} | 267 | OverDueQuery::OverDueQuery(): OSQLQuery() {} |
268 | OverDueQuery::~OverDueQuery() {} | 268 | OverDueQuery::~OverDueQuery() {} |
269 | QString OverDueQuery::query()const { | 269 | QString OverDueQuery::query()const { |
270 | QDate date = QDate::currentDate(); | 270 | QDate date = QDate::currentDate(); |
271 | QString str; | 271 | QString str; |
272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); | 272 | str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); |
273 | 273 | ||
274 | return str; | 274 | return str; |
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) | 278 | EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) |
279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} | 279 | : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} |
280 | EffQuery::~EffQuery() {} | 280 | EffQuery::~EffQuery() {} |
281 | QString EffQuery::query()const { | 281 | QString EffQuery::query()const { |
282 | return m_inc ? with() : out(); | 282 | return m_inc ? with() : out(); |
283 | } | 283 | } |
284 | QString EffQuery::with()const { | 284 | QString EffQuery::with()const { |
285 | QString str; | 285 | QString str; |
286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") | 286 | str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") |
287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) | 287 | .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) |
288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); | 288 | .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); |
289 | return str; | 289 | return str; |
290 | } | 290 | } |
291 | QString EffQuery::out()const { | 291 | QString EffQuery::out()const { |
292 | QString str; | 292 | QString str; |
293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") | 293 | str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") |
294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) | 294 | .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) |
295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); | 295 | .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); |
296 | 296 | ||
297 | return str; | 297 | return str; |
298 | } | 298 | } |
299 | }; | 299 | }; |
300 | 300 | ||
301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) | 301 | OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) |
302 | : OTodoAccessBackend(), m_dict(15), m_dirty(true) | 302 | : OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) |
303 | { | 303 | { |
304 | QString fi = file; | 304 | QString fi = file; |
305 | if ( fi.isEmpty() ) | 305 | if ( fi.isEmpty() ) |
306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); | 306 | fi = Global::applicationFileName( "todolist", "todolist.db" ); |
307 | OSQLManager man; | 307 | OSQLManager man; |
308 | m_driver = man.standard(); | 308 | m_driver = man.standard(); |
309 | m_driver->setUrl(fi); | 309 | m_driver->setUrl(fi); |
310 | // fillDict(); | 310 | // fillDict(); |
311 | } | 311 | } |
312 | 312 | ||
313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ | 313 | OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ |
314 | if( m_driver ) | ||
315 | delete m_driver; | ||
314 | } | 316 | } |
317 | |||
315 | bool OTodoAccessBackendSQL::load(){ | 318 | bool OTodoAccessBackendSQL::load(){ |
316 | if (!m_driver->open() ) | 319 | if (!m_driver->open() ) |
317 | return false; | 320 | return false; |
318 | 321 | ||
319 | CreateQuery creat; | 322 | CreateQuery creat; |
320 | OSQLResult res = m_driver->query(&creat ); | 323 | OSQLResult res = m_driver->query(&creat ); |
321 | 324 | ||
322 | m_dirty = true; | 325 | m_dirty = true; |
323 | return true; | 326 | return true; |
324 | } | 327 | } |
325 | bool OTodoAccessBackendSQL::reload(){ | 328 | bool OTodoAccessBackendSQL::reload(){ |
326 | return load(); | 329 | return load(); |
327 | } | 330 | } |
328 | 331 | ||
329 | bool OTodoAccessBackendSQL::save(){ | 332 | bool OTodoAccessBackendSQL::save(){ |
330 | return m_driver->close(); | 333 | return m_driver->close(); |
331 | } | 334 | } |
332 | QArray<int> OTodoAccessBackendSQL::allRecords()const { | 335 | QArray<int> OTodoAccessBackendSQL::allRecords()const { |
333 | if (m_dirty ) | 336 | if (m_dirty ) |
334 | update(); | 337 | update(); |
335 | 338 | ||
336 | return m_uids; | 339 | return m_uids; |
337 | } | 340 | } |
338 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ | 341 | QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ |
339 | QArray<int> ints(0); | 342 | QArray<int> ints(0); |
340 | return ints; | 343 | return ints; |
341 | } | 344 | } |
342 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ | 345 | OTodo OTodoAccessBackendSQL::find(int uid ) const{ |
343 | FindQuery query( uid ); | 346 | FindQuery query( uid ); |
344 | return todo( m_driver->query(&query) ); | 347 | return todo( m_driver->query(&query) ); |
345 | 348 | ||
346 | } | 349 | } |
347 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, | 350 | OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, |
348 | uint cur, Frontend::CacheDirection dir ) const{ | 351 | uint cur, Frontend::CacheDirection dir ) const{ |
349 | uint CACHE = readAhead(); | 352 | uint CACHE = readAhead(); |
350 | qWarning("searching for %d", uid ); | 353 | qWarning("searching for %d", uid ); |
351 | QArray<int> search( CACHE ); | 354 | QArray<int> search( CACHE ); |
352 | uint size =0; | 355 | uint size =0; |
353 | OTodo to; | 356 | OTodo to; |
354 | 357 | ||
355 | // we try to cache CACHE items | 358 | // we try to cache CACHE items |
356 | switch( dir ) { | 359 | switch( dir ) { |
357 | /* forward */ | 360 | /* forward */ |
358 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) | 361 | case 0: // FIXME: Not a good style to use magic numbers here (eilers) |
359 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { | 362 | for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { |
360 | qWarning("size %d %d", size, ints[i] ); | 363 | qWarning("size %d %d", size, ints[i] ); |
361 | search[size] = ints[i]; | 364 | search[size] = ints[i]; |
362 | size++; | 365 | size++; |
363 | } | 366 | } |
364 | break; | 367 | break; |
365 | /* reverse */ | 368 | /* reverse */ |
366 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) | 369 | case 1: // FIXME: Not a good style to use magic numbers here (eilers) |
367 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { | 370 | for (uint i = cur; i != 0 && size < CACHE; i-- ) { |
368 | search[size] = ints[i]; | 371 | search[size] = ints[i]; |
369 | size++; | 372 | size++; |
370 | } | 373 | } |
371 | break; | 374 | break; |
372 | } | 375 | } |
373 | search.resize( size ); | 376 | search.resize( size ); |
374 | FindQuery query( search ); | 377 | FindQuery query( search ); |
375 | OSQLResult res = m_driver->query( &query ); | 378 | OSQLResult res = m_driver->query( &query ); |
376 | if ( res.state() != OSQLResult::Success ) | 379 | if ( res.state() != OSQLResult::Success ) |
377 | return to; | 380 | return to; |
378 | 381 | ||
379 | return todo( res ); | 382 | return todo( res ); |
380 | } | 383 | } |
381 | void OTodoAccessBackendSQL::clear() { | 384 | void OTodoAccessBackendSQL::clear() { |
382 | ClearQuery cle; | 385 | ClearQuery cle; |
383 | OSQLResult res = m_driver->query( &cle ); | 386 | OSQLResult res = m_driver->query( &cle ); |
384 | CreateQuery qu; | 387 | CreateQuery qu; |
385 | res = m_driver->query(&qu); | 388 | res = m_driver->query(&qu); |
386 | } | 389 | } |
387 | bool OTodoAccessBackendSQL::add( const OTodo& t) { | 390 | bool OTodoAccessBackendSQL::add( const OTodo& t) { |
388 | InsertQuery ins( t ); | 391 | InsertQuery ins( t ); |
389 | OSQLResult res = m_driver->query( &ins ); | 392 | OSQLResult res = m_driver->query( &ins ); |
390 | 393 | ||
391 | if ( res.state() == OSQLResult::Failure ) | 394 | if ( res.state() == OSQLResult::Failure ) |
392 | return false; | 395 | return false; |
393 | int c = m_uids.count(); | 396 | int c = m_uids.count(); |
394 | m_uids.resize( c+1 ); | 397 | m_uids.resize( c+1 ); |
395 | m_uids[c] = t.uid(); | 398 | m_uids[c] = t.uid(); |
396 | 399 | ||
397 | return true; | 400 | return true; |
398 | } | 401 | } |
399 | bool OTodoAccessBackendSQL::remove( int uid ) { | 402 | bool OTodoAccessBackendSQL::remove( int uid ) { |
400 | RemoveQuery rem( uid ); | 403 | RemoveQuery rem( uid ); |
401 | OSQLResult res = m_driver->query(&rem ); | 404 | OSQLResult res = m_driver->query(&rem ); |
402 | 405 | ||
403 | if ( res.state() == OSQLResult::Failure ) | 406 | if ( res.state() == OSQLResult::Failure ) |
404 | return false; | 407 | return false; |
405 | 408 | ||
406 | m_dirty = true; | 409 | m_dirty = true; |
407 | return true; | 410 | return true; |
408 | } | 411 | } |
409 | /* | 412 | /* |
410 | * FIXME better set query | 413 | * FIXME better set query |