author | eilers <eilers> | 2004-12-20 14:14:07 (UTC) |
---|---|---|
committer | eilers <eilers> | 2004-12-20 14:14:07 (UTC) |
commit | 18e47153532d016d878f47e0ce11cb1a9716218e (patch) (side-by-side diff) | |
tree | 52eb6c25258fda0b2f295a29809c4603f5e17b0b /libopie2/opiepim/backend | |
parent | 876e48baa20213d8265041cfac3034fe92cb0590 (diff) | |
download | opie-18e47153532d016d878f47e0ce11cb1a9716218e.zip opie-18e47153532d016d878f47e0ce11cb1a9716218e.tar.gz opie-18e47153532d016d878f47e0ce11cb1a9716218e.tar.bz2 |
Recovery of the following Changes:
* Implement fast and full featured version of sorted() for addressbook
* Implement generic queryByExample for all Addressboook backends. It allows incremental search.
* Update of API Documentation
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.cpp | 205 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.h | 9 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 144 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.h | 23 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp | 14 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_vcard.h | 4 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp | 205 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.h | 9 | ||||
-rw-r--r-- | libopie2/opiepim/backend/opimaccessbackend.h | 40 |
9 files changed, 379 insertions, 274 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.cpp b/libopie2/opiepim/backend/ocontactaccessbackend.cpp index 6ef60eb..b4fdd46 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend.cpp @@ -28,27 +28,220 @@ */ #include "ocontactaccessbackend.h" #include <opie2/private/opimcontactsortvector.h> #include <opie2/ocontactaccess.h> #include <opie2/odebug.h> +#include <qdatetime.h> + namespace Opie { OPimContactAccessBackend::OPimContactAccessBackend() {} -UIDArray -OPimContactAccessBackend::queryByExample( const OPimContact&, int, - const QDateTime& )const { - return UIDArray(); +UIDArray OPimContactAccessBackend::queryByExample( const UIDArray& uid_array, const OPimContact& query, int settings, + const QDateTime& d )const { + odebug << "Using Unaccelerated OPimContactAccessBackend implementation of queryByExample!" << oendl; + + UIDArray m_currentQuery( uid_array.count() ); + uint arraycounter = 0; + + for( uint it = 0; it < uid_array.count(); ++it ){ + /* Search all fields and compare them with query object. Store them into list + * if all fields matches. + */ + QDate* queryDate = 0l; + QDate* checkDate = 0l; + bool allcorrect = true; + for ( int i = 0; i < Qtopia::Groups; i++ ) { + // Birthday and anniversary are special nonstring fields and should + // be handled specially + switch ( i ){ + case Qtopia::Birthday: + queryDate = new QDate( query.birthday() ); + checkDate = new QDate( find( uid_array[it] ).birthday() ); + // fall through + case Qtopia::Anniversary: + if ( queryDate == 0l ){ + queryDate = new QDate( query.anniversary() ); + checkDate = new QDate( find( uid_array[it] ).anniversary() ); + } + + if ( queryDate->isValid() ){ + if( checkDate->isValid() ){ + if ( settings & OPimContactAccess::DateYear ){ + if ( queryDate->year() != checkDate->year() ) + allcorrect = false; + } + if ( settings & OPimContactAccess::DateMonth ){ + if ( queryDate->month() != checkDate->month() ) + allcorrect = false; + } + if ( settings & OPimContactAccess::DateDay ){ + if ( queryDate->day() != checkDate->day() ) + allcorrect = false; + } + if ( settings & OPimContactAccess::DateDiff ) { + QDate current; + // If we get an additional date, we + // will take this date instead of + // the current one.. + if ( !d.date().isValid() ) + current = QDate::currentDate(); + else + current = d.date(); + + // We have to equalize the year, otherwise + // the search will fail.. + checkDate->setYMD( current.year(), + checkDate->month(), + checkDate->day() ); + if ( *checkDate < current ) + checkDate->setYMD( current.year()+1, + checkDate->month(), + checkDate->day() ); + + // Check whether the birthday/anniversary date is between + // the current/given date and the maximum date + // ( maximum time range ) ! + if ( current.daysTo( *queryDate ) >= 0 ){ + if ( !( ( *checkDate >= current ) && + ( *checkDate <= *queryDate ) ) ){ + allcorrect = false; + } + } + } + } else{ + // checkDate is invalid. Therefore this entry is always rejected + allcorrect = false; + } + } + + delete queryDate; + queryDate = 0l; + delete checkDate; + checkDate = 0l; + break; + default: + /* Just compare fields which are not empty in the query object */ + if ( !query.field(i).isEmpty() ){ + switch ( settings & ~( OPimContactAccess::IgnoreCase + | OPimContactAccess::DateDiff + | OPimContactAccess::DateYear + | OPimContactAccess::DateMonth + | OPimContactAccess::DateDay + | OPimContactAccess::MatchOne + ) ){ + + case OPimContactAccess::RegExp:{ + QRegExp expr ( query.field(i), + !(settings & OPimContactAccess::IgnoreCase), + false ); + if ( expr.find ( find( uid_array[it] ).field(i), 0 ) == -1 ) + allcorrect = false; + } + break; + case OPimContactAccess::WildCards:{ + QRegExp expr ( query.field(i), + !(settings & OPimContactAccess::IgnoreCase), + true ); + if ( expr.find ( find( uid_array[it] ).field(i), 0 ) == -1 ) + allcorrect = false; + } + break; + case OPimContactAccess::ExactMatch:{ + if (settings & OPimContactAccess::IgnoreCase){ + if ( query.field(i).upper() != + find( uid_array[it] ).field(i).upper() ) + allcorrect = false; + }else{ + if ( query.field(i) != find( uid_array[it] ).field(i) ) + allcorrect = false; + } + } + break; + } + } + } + } + if ( allcorrect ){ + m_currentQuery[arraycounter++] = uid_array[it]; + } + } + + // Shrink to fit.. + m_currentQuery.resize(arraycounter); + + return m_currentQuery; + } -UIDArray -OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, +const uint OPimContactAccessBackend::querySettings() const +{ + return ( OPimContactAccess::WildCards + | OPimContactAccess::IgnoreCase + | OPimContactAccess::RegExp + | OPimContactAccess::ExactMatch + | OPimContactAccess::DateDiff + | OPimContactAccess::DateYear + | OPimContactAccess::DateMonth + | OPimContactAccess::DateDay + ); +} + +bool OPimContactAccessBackend::hasQuerySettings (uint querySettings) const +{ + /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay + * may be added with any of the other settings. IgnoreCase should never used alone. + * Wildcards, RegExp, ExactMatch should never used at the same time... + */ + + // Step 1: Check whether the given settings are supported by this backend + if ( ( querySettings & ( + OPimContactAccess::IgnoreCase + | OPimContactAccess::WildCards + | OPimContactAccess::DateDiff + | OPimContactAccess::DateYear + | OPimContactAccess::DateMonth + | OPimContactAccess::DateDay + | OPimContactAccess::RegExp + | OPimContactAccess::ExactMatch + ) ) != querySettings ) + return false; + + // Step 2: Check whether the given combinations are ok.. + + // IngoreCase alone is invalid + if ( querySettings == OPimContactAccess::IgnoreCase ) + return false; + + // WildCards, RegExp and ExactMatch should never used at the same time + switch ( querySettings & ~( OPimContactAccess::IgnoreCase + | OPimContactAccess::DateDiff + | OPimContactAccess::DateYear + | OPimContactAccess::DateMonth + | OPimContactAccess::DateDay + ) + ){ + case OPimContactAccess::RegExp: + return ( true ); + case OPimContactAccess::WildCards: + return ( true ); + case OPimContactAccess::ExactMatch: + return ( true ); + case 0: // one of the upper removed bits were set.. + return ( true ); + default: + return ( false ); + } +} + + +UIDArray OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, int filter, const QArray<int>& categories)const { odebug << "Using Unaccelerated OPimContactAccessBackend sorted Implementation" << oendl; Internal::OPimContactSortVector vector(ar.count(), asc, sortOrder ); int item = 0; uint cat_count = categories.count(); uint eve_count = ar.count(); diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h index efb04c7..ee6dbc2 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend.h @@ -75,29 +75,32 @@ class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { */ virtual bool wasChangedExternally() = 0; /** * Return all possible settings. * @return All settings provided by the current backend * (i.e.: query_WildCards & query_IgnoreCase) */ - virtual const uint querySettings() = 0; + virtual const uint querySettings() const; /** * Check whether settings are correct. * @return <i>true</i> if the given settings are correct and possible. */ - virtual bool hasQuerySettings (uint querySettings) const = 0; + virtual bool hasQuerySettings (uint querySettings) const; + /** + * Advanced search mechanism. + */ + UIDArray queryByExample( const UIDArray& uidlist, const OPimContact&, int settings, const QDateTime &d = QDateTime() ) const; /** * Slow and inefficent default implementation */ //@{ - UIDArray queryByExample( const OPimContact&, int settings, const QDateTime& d = QDateTime() )const; UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const; //@} private: class Private; Private *d; diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 3d284f7..9375f43 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp @@ -122,39 +122,39 @@ namespace { }; /** * a find query for noncustom elements */ class FindQuery : public OSQLQuery { public: FindQuery(int uid); - FindQuery(const QArray<int>& ); + FindQuery(const UIDArray& ); ~FindQuery(); QString query()const; private: QString single()const; QString multi()const; - QArray<int> m_uids; + UIDArray m_uids; int m_uid; }; /** * a find query for custom elements */ class FindCustomQuery : public OSQLQuery { public: FindCustomQuery(int uid); - FindCustomQuery(const QArray<int>& ); + FindCustomQuery(const UIDArray& ); ~FindCustomQuery(); QString query()const; private: QString single()const; QString multi()const; - QArray<int> m_uids; + UIDArray m_uids; int m_uid; }; // We using two tables to store the information: // 1. addressbook : It contains General information about the contact (non custom) // 2. custom_data : Not official supported entries @@ -289,17 +289,17 @@ namespace { } FindQuery::FindQuery(int uid) : OSQLQuery(), m_uid( uid ) { } - FindQuery::FindQuery(const QArray<int>& ints) + FindQuery::FindQuery(const UIDArray& ints) : OSQLQuery(), m_uids( ints ){ } FindQuery::~FindQuery() { } QString FindQuery::query()const{ if ( m_uids.count() == 0 ) return single(); else @@ -324,17 +324,17 @@ namespace { // owarn << "find query: " << qu << "" << oendl; return qu; } FindCustomQuery::FindCustomQuery(int uid) : OSQLQuery(), m_uid( uid ) { } - FindCustomQuery::FindCustomQuery(const QArray<int>& ints) + FindCustomQuery::FindCustomQuery(const UIDArray& ints) : OSQLQuery(), m_uids( ints ){ } FindCustomQuery::~FindCustomQuery() { } QString FindCustomQuery::query()const{ // if ( m_uids.count() == 0 ) return single(); } @@ -417,17 +417,17 @@ void OPimContactAccessBackend_SQL::clear () reload(); } bool OPimContactAccessBackend_SQL::wasChangedExternally() { return false; } -QArray<int> OPimContactAccessBackend_SQL::allRecords() const +UIDArray OPimContactAccessBackend_SQL::allRecords() const { // FIXME: Think about cute handling of changed tables.. // Thus, we don't have to call update here... if ( m_changed ) ((OPimContactAccessBackend_SQL*)this)->update(); return m_uids; @@ -480,17 +480,17 @@ OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const OPimContact retContact( requestNonCustom( uid ) ); retContact.setExtraMap( requestCustom( uid ) ); odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; return retContact; } -OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const +OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const { odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; odebug << "searching for " << uid << "" << oendl; QTime t; t.start(); uint numReadAhead = readAhead(); @@ -523,17 +523,18 @@ OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& quer OPimContact retContact( requestContactsAndCache( uid, searchList ) ); odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; return retContact; } -QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) +UIDArray OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, + const QDateTime& qd ) const { QString qu = "SELECT uid FROM addressbook WHERE"; QString searchQuery =""; QDate startDate; if ( qd.isValid() ) startDate = qd.date(); @@ -634,26 +635,26 @@ QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &qu qu += searchQuery; odebug << "queryByExample query: " << qu << "" << oendl; // Execute query and return the received uid's OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ - QArray<int> empty; + UIDArray empty; return empty; } - QArray<int> list = extractUids( res ); + UIDArray list = extractUids( res ); return list; } -QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const +UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { #if 0 QArray<int> nix(0); return nix; #else QString qu = "SELECT uid FROM addressbook WHERE ("; QString searchlist; @@ -674,17 +675,17 @@ QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const OSQLResult res = m_driver->query( &raw ); return extractUids( res ); #endif } -const uint OPimContactAccessBackend_SQL::querySettings() +const uint OPimContactAccessBackend_SQL::querySettings() const { return OPimContactAccess::IgnoreCase | OPimContactAccess::WildCards | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ; @@ -733,37 +734,132 @@ bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const case 0: // one of the upper removed bits were set.. return ( true ); default: return ( false ); } } -QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) +UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder, + int filter, const QArray<int>& categories )const { QTime t; t.start(); - QString query = "SELECT uid FROM addressbook "; - query += "ORDER BY \"Last Name\" "; + QString query = "SELECT uid FROM addressbook"; + + query += " WHERE ("; + for ( uint i = 0; i < ar.count(); i++ ) { + query += " uid = " + QString::number( ar[i] ) + " OR"; + } + query.remove( query.length()-2, 2 ); // Hmmmm.. + query += ")"; + + + if ( filter != OPimBase::FilterOff ){ + if ( filter & OPimContactAccess::DoNotShowWithCategory ){ + query += " AND ( \"Categories\" == '' )"; + } else if ( filter & OPimBase::FilterCategory ){ + query += " AND ("; + for ( uint i = 0; i < categories.count(); i++ ){ + query += "\"Categories\" LIKE"; + query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR"; + } + query.remove( query.length()-2, 2 ); // Hmmmm.. + query += ")"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){ + query += " AND ( \"Children\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){ + query += " AND ( \"Anniversary\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){ + query += " AND ( \"Birthday\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){ + // Expect that no Street means no Address, too! (eilers) + query += " AND ( \"Home Street\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){ + // Expect that no Street means no Address, too! (eilers) + query += " AND ( \"Business Street\" != '' )"; + } + + } + + query += " ORDER BY"; + + switch ( sortOrder ) { + case OPimContactAccess::SortSummary: + query += " \"Notes\""; + break; + case OPimContactAccess::SortByCategory: + query += " \"Categories\""; + break; + case OPimContactAccess::SortByDate: + query += " \"\""; + break; + case OPimContactAccess::SortTitle: + query += " \"Name Title\""; + break; + case OPimContactAccess::SortFirstName: + query += " \"First Name\""; + break; + case OPimContactAccess::SortMiddleName: + query += " \"Middle Name\""; + break; + case OPimContactAccess::SortLastName: + query += " \"Last Name\""; + break; + case OPimContactAccess::SortFileAsName: + query += " \"File As\""; + break; + case OPimContactAccess::SortSuffix: + query += " \"Suffix\""; + break; + case OPimContactAccess::SortEmail: + query += " \"Default Email\""; + break; + case OPimContactAccess::SortNickname: + query += " \"Nickname\""; + break; + case OPimContactAccess::SortAnniversary: + query += " \"Anniversary\""; + break; + case OPimContactAccess::SortBirthday: + query += " \"Birthday\""; + break; + case OPimContactAccess::SortGender: + query += " \"Gender\""; + break; + default: + query += " \"Last Name\""; + } if ( !asc ) - query += "DESC"; + query += " DESC"; + - // odebug << "sorted query is: " << query << "" << oendl; + odebug << "sorted query is: " << query << "" << oendl; OSQLRawQuery raw( query ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ - QArray<int> empty; + UIDArray empty; return empty; } - QArray<int> list = extractUids( res ); + UIDArray list = extractUids( res ); odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; return list; } void OPimContactAccessBackend_SQL::update() { @@ -781,24 +877,24 @@ void OPimContactAccessBackend_SQL::update() m_uids = extractUids( res ); m_changed = false; odebug << "Update ends " << t.elapsed() << " ms" << oendl; } -QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const +UIDArray OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const { odebug << "extractUids" << oendl; QTime t; t.start(); OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; - QArray<int> ints(list.count() ); + UIDArray ints(list.count() ); odebug << " count = " << list.count() << "" << oendl; int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; @@ -832,23 +928,23 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed << " ms, mapping: " << t3needed << " ms" << oendl; return nonCustomMap; } /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ -OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const +OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const UIDArray& uidlist )const { // We want to get all contacts with one query. // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned // by using the cache.. - QArray<int> cachelist = uidlist; + UIDArray cachelist = uidlist; OPimContact retContact; odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; QTime t; t.start(); int t2needed = 0; diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h index 28d9746..299c175 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h @@ -65,50 +65,51 @@ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend { bool save(); bool load (); void clear (); bool wasChangedExternally(); - QArray<int> allRecords() const; + UIDArray allRecords() const; OPimContact find( int uid ) const; - OPimContact find( int uid, const QArray<int>& items, uint cur, Frontend::CacheDirection ) const; + OPimContact find( int uid, const UIDArray& items, uint cur, Frontend::CacheDirection ) const; - QArray<int> queryByExample ( const OPimContact &query, int settings, - const QDateTime& d ); + UIDArray queryByExample ( const OPimContact &query, int settings, + const QDateTime& d ) const; - QArray<int> matchRegexp( const QRegExp &r ) const; + UIDArray matchRegexp( const QRegExp &r ) const; - const uint querySettings(); + const uint querySettings() const; bool hasQuerySettings (uint querySettings) const; - // Currently only asc implemented.. - QArray<int> sorted( bool asc, int , int , int ); - bool add ( const OPimContact &newcontact ); + UIDArray sorted( const UIDArray& ar, bool asc, int sortOrder, + int filter, const QArray<int>& categories)const; + + bool add ( const OPimContact &newcontact ); bool replace ( const OPimContact &contact ); bool remove ( int uid ); bool reload(); private: - QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; + UIDArray extractUids( Opie::DB::OSQLResult& res ) const; QMap<int, QString> requestNonCustom( int uid ) const; QMap<QString, QString> requestCustom( int uid ) const; QMap<int, QString> fillNonCustomMap( const Opie::DB::OSQLResultItem& resultItem ) const; OPimContact requestContactsAndCache( int uid, const QArray<int>& cachelist ) const; void update(); protected: bool m_changed; QString m_fileName; - QArray<int> m_uids; + UIDArray m_uids; Opie::DB::OSQLDriver* m_driver; }; } #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp index 5bb21c7..f3b6d56 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp @@ -152,38 +152,28 @@ bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact ) return true; } OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const { return m_map[uid]; } -QArray<int> OPimContactAccessBackend_VCard::allRecords() const +UIDArray OPimContactAccessBackend_VCard::allRecords() const { - QArray<int> ar( m_map.count() ); + UIDArray ar( m_map.count() ); QMap<int, OPimContact>::ConstIterator it; int i = 0; for ( it = m_map.begin(); it != m_map.end(); ++it ) { ar[i] = it.key(); i++; } return ar; } -const uint OPimContactAccessBackend_VCard::querySettings() -{ - return 0; // No search possible -} - -bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const -{ - return false; // No search possible, therefore all settings invalid ;) -} - bool OPimContactAccessBackend_VCard::wasChangedExternally() { return false; // Don't expect concurrent access } // *** Private stuff *** OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj ) { diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h index b734530..3591988 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h @@ -53,20 +53,18 @@ class OPimContactAccessBackend_VCard : public OPimContactAccessBackend { bool save(); void clear (); bool add ( const OPimContact& newcontact ); bool remove ( int uid ); bool replace ( const OPimContact& contact ); OPimContact find ( int uid ) const; - QArray<int> allRecords() const; + UIDArray allRecords() const; - const uint querySettings(); - bool hasQuerySettings (uint querySettings) const; bool wasChangedExternally(); private: OPimContact parseVObject( VObject* obj ); VObject* createVObject( const OPimContact& c ); QString convDateToVCardDate( const QDate& c ) const; QDate convVCardDateToDate( const QString& datestr ); VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index 5df7253..f96f1bf 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp @@ -178,19 +178,19 @@ bool OPimContactAccessBackend_XML::wasChangedExternally() { QFileInfo fi( m_fileName ); QDateTime lastmod = fi.lastModified (); return (lastmod != m_readtime); } -QArray<int> OPimContactAccessBackend_XML::allRecords() const +UIDArray OPimContactAccessBackend_XML::allRecords() const { - QArray<int> uid_list( m_contactList.count() ); + UIDArray uid_list( m_contactList.count() ); uint counter = 0; QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ uid_list[counter++] = (*it)->uid(); } return ( uid_list ); @@ -204,237 +204,44 @@ OPimContact OPimContactAccessBackend_XML::find ( int uid ) const if ( found ){ foundContact = *found; } return ( foundContact ); } -QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, - const QDateTime& d )const -{ - QArray<int> m_currentQuery( m_contactList.count() ); - QListIterator<OPimContact> it( m_contactList ); - uint arraycounter = 0; - - for( ; it.current(); ++it ){ - /* Search all fields and compare them with query object. Store them into list - * if all fields matches. - */ - QDate* queryDate = 0l; - QDate* checkDate = 0l; - bool allcorrect = true; - for ( int i = 0; i < Qtopia::Groups; i++ ) { - // Birthday and anniversary are special nonstring fields and should - // be handled specially - switch ( i ){ - case Qtopia::Birthday: - queryDate = new QDate( query.birthday() ); - checkDate = new QDate( (*it)->birthday() ); - // fall through - case Qtopia::Anniversary: - if ( queryDate == 0l ){ - queryDate = new QDate( query.anniversary() ); - checkDate = new QDate( (*it)->anniversary() ); - } - - if ( queryDate->isValid() ){ - if( checkDate->isValid() ){ - if ( settings & OPimContactAccess::DateYear ){ - if ( queryDate->year() != checkDate->year() ) - allcorrect = false; - } - if ( settings & OPimContactAccess::DateMonth ){ - if ( queryDate->month() != checkDate->month() ) - allcorrect = false; - } - if ( settings & OPimContactAccess::DateDay ){ - if ( queryDate->day() != checkDate->day() ) - allcorrect = false; - } - if ( settings & OPimContactAccess::DateDiff ) { - QDate current; - // If we get an additional date, we - // will take this date instead of - // the current one.. - if ( !d.date().isValid() ) - current = QDate::currentDate(); - else - current = d.date(); - - // We have to equalize the year, otherwise - // the search will fail.. - checkDate->setYMD( current.year(), - checkDate->month(), - checkDate->day() ); - if ( *checkDate < current ) - checkDate->setYMD( current.year()+1, - checkDate->month(), - checkDate->day() ); - - // Check whether the birthday/anniversary date is between - // the current/given date and the maximum date - // ( maximum time range ) ! - if ( current.daysTo( *queryDate ) >= 0 ){ - if ( !( ( *checkDate >= current ) && - ( *checkDate <= *queryDate ) ) ){ - allcorrect = false; - } - } - } - } else{ - // checkDate is invalid. Therefore this entry is always rejected - allcorrect = false; - } - } - delete queryDate; - queryDate = 0l; - delete checkDate; - checkDate = 0l; - break; - default: - /* Just compare fields which are not empty in the query object */ - if ( !query.field(i).isEmpty() ){ - switch ( settings & ~( OPimContactAccess::IgnoreCase - | OPimContactAccess::DateDiff - | OPimContactAccess::DateYear - | OPimContactAccess::DateMonth - | OPimContactAccess::DateDay - | OPimContactAccess::MatchOne - ) ){ - - case OPimContactAccess::RegExp:{ - QRegExp expr ( query.field(i), - !(settings & OPimContactAccess::IgnoreCase), - false ); - if ( expr.find ( (*it)->field(i), 0 ) == -1 ) - allcorrect = false; - } - break; - case OPimContactAccess::WildCards:{ - QRegExp expr ( query.field(i), - !(settings & OPimContactAccess::IgnoreCase), - true ); - if ( expr.find ( (*it)->field(i), 0 ) == -1 ) - allcorrect = false; - } - break; - case OPimContactAccess::ExactMatch:{ - if (settings & OPimContactAccess::IgnoreCase){ - if ( query.field(i).upper() != - (*it)->field(i).upper() ) - allcorrect = false; - }else{ - if ( query.field(i) != (*it)->field(i) ) - allcorrect = false; - } - } - break; - } - } - } - } - if ( allcorrect ){ - m_currentQuery[arraycounter++] = (*it)->uid(); - } - } - - // Shrink to fit.. - m_currentQuery.resize(arraycounter); - - return m_currentQuery; -} - -QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const +UIDArray OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const { - QArray<int> m_currentQuery( m_contactList.count() ); + UIDArray m_currentQuery( m_contactList.count() ); QListIterator<OPimContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ if ( (*it)->match( r ) ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } -const uint OPimContactAccessBackend_XML::querySettings() -{ - return ( OPimContactAccess::WildCards - | OPimContactAccess::IgnoreCase - | OPimContactAccess::RegExp - | OPimContactAccess::ExactMatch - | OPimContactAccess::DateDiff - | OPimContactAccess::DateYear - | OPimContactAccess::DateMonth - | OPimContactAccess::DateDay - ); -} -bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const -{ - /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay - * may be added with any of the other settings. IgnoreCase should never used alone. - * Wildcards, RegExp, ExactMatch should never used at the same time... - */ - - // Step 1: Check whether the given settings are supported by this backend - if ( ( querySettings & ( - OPimContactAccess::IgnoreCase - | OPimContactAccess::WildCards - | OPimContactAccess::DateDiff - | OPimContactAccess::DateYear - | OPimContactAccess::DateMonth - | OPimContactAccess::DateDay - | OPimContactAccess::RegExp - | OPimContactAccess::ExactMatch - ) ) != querySettings ) - return false; - - // Step 2: Check whether the given combinations are ok.. - - // IngoreCase alone is invalid - if ( querySettings == OPimContactAccess::IgnoreCase ) - return false; - - // WildCards, RegExp and ExactMatch should never used at the same time - switch ( querySettings & ~( OPimContactAccess::IgnoreCase - | OPimContactAccess::DateDiff - | OPimContactAccess::DateYear - | OPimContactAccess::DateMonth - | OPimContactAccess::DateDay - ) - ){ - case OPimContactAccess::RegExp: - return ( true ); - case OPimContactAccess::WildCards: - return ( true ); - case OPimContactAccess::ExactMatch: - return ( true ); - case 0: // one of the upper removed bits were set.. - return ( true ); - default: - return ( false ); - } -} #if 0 // Currently only asc implemented.. -QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) +UIDArray OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) { QMap<QString, int> nameToUid; QStringList names; - QArray<int> m_currentQuery( m_contactList.count() ); + UIDArray m_currentQuery( m_contactList.count() ); // First fill map and StringList with all Names // Afterwards sort namelist and use map to fill array to return.. QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); } diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h index 3e4f1e1..39378ec 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h @@ -53,26 +53,21 @@ class OPimContactAccessBackend_XML : public OPimContactAccessBackend { bool save(); bool load (); void clear (); bool wasChangedExternally(); - QArray<int> allRecords() const; + UIDArray allRecords() const; OPimContact find ( int uid ) const; - QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d )const; - QArray<int> matchRegexp( const QRegExp &r ) const; - - const uint querySettings(); - - bool hasQuerySettings (uint querySettings) const; + UIDArray matchRegexp( const QRegExp &r ) const; bool add ( const OPimContact &newcontact ); bool replace ( const OPimContact &contact ); bool remove ( int uid ); bool reload(); diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index 0d112c9..7321758 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h @@ -61,23 +61,44 @@ public: //@{ virtual bool load() = 0; virtual bool reload() = 0; virtual bool save() = 0; virtual void clear() = 0; //@} + //@{ + // FIXME: Uncommented some of the abstract functions below. This should be removed as they are implemented in + // all typespecifc backenends (eilers) + /** + * Return all possible settings for queryByExample() + * @return All settings provided by the current backend + * (i.e.: query_WildCards & query_IgnoreCase) + * See implementation in the specific backends for contacts, todo and dates. + */ + virtual const uint querySettings() const { return 0; } /* FIXME: Make Abstrakt !! = 0; */ + + /** + * Check whether settings are correct for queryByExample() + * See implementation in the specific backends for OPimContactAccess, OPimTodoAccess and ODateBookAccess. + * @return <i>true</i> if the given settings are correct and possible. + */ + virtual bool hasQuerySettings (uint querySettings) const { return false; } /* FIXME: Make Abstrakt !! = 0; */ + //@} + //@{ virtual UIDArray allRecords()const = 0; virtual UIDArray matchRegexp(const QRegExp &r) const; - virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const = 0; - virtual UIDArray queryByExample( const OPimRecord* rec, int, const QDateTime& d = QDateTime() )const; - virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; + virtual UIDArray queryByExample( const UIDArray&, const T& t, + int settings, const QDateTime& d = QDateTime() )const { return UIDArray(); } /* FIXME: Make Abstrakt !! = 0; */ + virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const; + virtual UIDArray queryByExample( const OPimRecord* rec, int settings, const QDateTime& d = QDateTime() )const; + virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const = 0; virtual UIDArray sorted( bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; virtual OPimBackendOccurrence::List occurrences( const QDate& start, const QDate& end)const; virtual OPimBackendOccurrence::List occurrences( const QDateTime& dt )const; //@} //@{ virtual T find(UID uid )const = 0; @@ -145,33 +166,34 @@ UIDArray OPimAccessBackend<T>::matchRegexp( const QRegExp& reg )const { result[used_records++] = all_rec[i]; /* shrink to fit */ result.resize( used_records ); return result; } template <class T> +UIDArray OPimAccessBackend<T>::queryByExample( const T& rec, int settings, + const QDateTime& datetime )const { + + return queryByExample( allRecords(), rec, settings, datetime ); +} + +template <class T> UIDArray OPimAccessBackend<T>::queryByExample( const OPimRecord* rec, int settings, const QDateTime& datetime )const { T* tmp_rec = T::safeCast( rec ); UIDArray ar; if ( tmp_rec ) ar = queryByExample( *tmp_rec, settings, datetime ); return ar; } template <class T> -UIDArray OPimAccessBackend<T>::sorted( const UIDArray& ids, bool, - int, int, const QArray<int>& ) const { - return ids; -} - -template <class T> UIDArray OPimAccessBackend<T>::sorted( bool asc, int order, int filter, const QArray<int>& cats )const { return sorted( allRecords(), asc, order, filter, cats ); } template<class T> OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDate&, const QDate& )const { |