summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp154
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h5
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h28
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h40
-rw-r--r--libopie2/opiepim/core/opimtemplatebase.h16
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
@@ -291,46 +291,47 @@ namespace {
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{
@@ -464,35 +465,76 @@ bool OPimContactAccessBackend_SQL::remove ( int uid )
464 465
465bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) 466bool 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
474OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const 475OPimContact 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
488OPimContact 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
489QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) 531QArray<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
@@ -759,47 +801,104 @@ QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
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
766QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const 808QMap<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 */
838OPimContact 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
880QMap<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();
@@ -807,35 +906,30 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co
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
830QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const 924QMap<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;
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
@@ -64,49 +64,50 @@ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
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
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
@@ -87,25 +87,25 @@ public:
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
@@ -119,26 +119,34 @@ public:
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 );
129protected: 129protected:
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
140private: 148private:
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;
@@ -152,35 +160,47 @@ OPimAccessBackend<T>::OPimAccessBackend(int acc)
152 m_front = 0l; 160 m_front = 0l;
153} 161}
154template <class T> 162template <class T>
155OPimAccessBackend<T>::~OPimAccessBackend() { 163OPimAccessBackend<T>::~OPimAccessBackend() {
156 164
157} 165}
158template <class T> 166template <class T>
159void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { 167void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
160 m_front = fr; 168 m_front = fr;
161} 169}
162template <class T> 170template <class T>
163void OPimAccessBackend<T>::cache( const T& t )const { 171void 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
176template <class T>
177T 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
167template <class T> 186template <class T>
168void OPimAccessBackend<T>::setSaneCacheSize( int size) { 187void 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}
172template <class T> 191template <class T>
173T OPimAccessBackend<T>::find( int uid, const QArray<int>&, 192T 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}
177template <class T> 197template <class T>
178void OPimAccessBackend<T>::setReadAhead( uint count ) { 198void OPimAccessBackend<T>::setReadAhead( uint count ) {
179 m_read = count; 199 m_read = count;
180} 200}
181template <class T> 201template <class T>
182uint OPimAccessBackend<T>::readAhead()const { 202uint OPimAccessBackend<T>::readAhead()const {
183 return m_read; 203 return m_read;
184} 204}
185template <class T> 205template <class T>
186int OPimAccessBackend<T>::access()const { 206int OPimAccessBackend<T>::access()const {
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
@@ -26,25 +26,24 @@
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
45namespace Opie { 44namespace Opie {
46 45
47class OPimAccessTemplatePrivate; 46class 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
@@ -119,42 +118,45 @@ public:
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 /**
@@ -167,40 +169,42 @@ public:
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;
183protected: 186protected:
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
197private: 201private:
198 OPimAccessTemplatePrivate *d; 202 OPimAccessTemplatePrivate *d;
199 203
200}; 204};
201 205
202template <class T> 206template <class T>
203OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) 207OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
204 : OTemplateBase<T>(), m_backEnd( end ) 208 : OTemplateBase<T>(), m_backEnd( end )
205{ 209{
206 if (end ) 210 if (end )
@@ -209,25 +213,25 @@ OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
209template <class T> 213template <class T>
210OPimAccessTemplate<T>::~OPimAccessTemplate() { 214OPimAccessTemplate<T>::~OPimAccessTemplate() {
211 owarn << "~OPimAccessTemplate<T>" << oendl; 215 owarn << "~OPimAccessTemplate<T>" << oendl;
212 delete m_backEnd; 216 delete m_backEnd;
213} 217}
214template <class T> 218template <class T>
215bool OPimAccessTemplate<T>::load() { 219bool OPimAccessTemplate<T>::load() {
216 invalidateCache(); 220 invalidateCache();
217 return m_backEnd->load(); 221 return m_backEnd->load();
218} 222}
219template <class T> 223template <class T>
220bool OPimAccessTemplate<T>::reload() { 224bool 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}
224template <class T> 228template <class T>
225bool OPimAccessTemplate<T>::save() { 229bool OPimAccessTemplate<T>::save() {
226 return m_backEnd->save(); 230 return m_backEnd->save();
227} 231}
228template <class T> 232template <class T>
229typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { 233typename 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}
@@ -242,74 +246,90 @@ QArray<int> OPimAccessTemplate<T>::records()const {
242 return m_backEnd->allRecords(); 246 return m_backEnd->allRecords();
243} 247}
244template <class T> 248template <class T>
245typename OPimAccessTemplate<T>::List 249typename OPimAccessTemplate<T>::List
246OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) { 250OPimAccessTemplate<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}
252template <class T> 256template <class T>
253T OPimAccessTemplate<T>::find( int uid ) const{ 257T 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
268template <class T>
269T OPimAccessTemplate<T>::cacheFind( int uid ) const
270{
271 return m_cache.find( uid );
272}
273
258template <class T> 274template <class T>
259T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar, 275T 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}
275template <class T> 291template <class T>
276void OPimAccessTemplate<T>::clear() { 292void OPimAccessTemplate<T>::clear() {
277 invalidateCache(); 293 invalidateCache();
278 m_backEnd->clear(); 294 m_backEnd->clear();
279} 295}
280template <class T> 296template <class T>
281bool OPimAccessTemplate<T>::add( const T& t ) { 297bool 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
286template <class T> 302template <class T>
287bool OPimAccessTemplate<T>::add( const OPimRecord& rec) { 303bool 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
297template <class T> 315template <class T>
298bool OPimAccessTemplate<T>::add( const OPimRecord* rec) { 316bool 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
308template <class T> 328template <class T>
309bool OPimAccessTemplate<T>::remove( const T& t ) { 329bool OPimAccessTemplate<T>::remove( const T& t ) {
310 return remove( t.uid() ); 330 return remove( t.uid() );
311} 331}
312template <class T> 332template <class T>
313bool OPimAccessTemplate<T>::remove( int uid ) { 333bool 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 );
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
@@ -22,24 +22,25 @@
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
38namespace Opie { 39namespace 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
@@ -61,48 +62,61 @@ struct OPimBase {
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 */
67private: 68private:
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 */
75class OTemplateBasePrivate; 76class OTemplateBasePrivate;
76template <class T = OPimRecord> 77template <class T = OPimRecord>
77class OTemplateBase : public OPimBase { 78class OTemplateBase : public OPimBase {
78public: 79public:
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
98private: 112private:
99 OTemplateBasePrivate *d; 113 OTemplateBasePrivate *d;
100}; 114};
101 115
102 116
103template <class T> 117template <class T>
104OPimRecord* OTemplateBase<T>::record()const { 118OPimRecord* OTemplateBase<T>::record()const {
105 T* t = new T; 119 T* t = new T;
106 return t; 120 return t;
107} 121}
108template <class T> 122template <class T>