summaryrefslogtreecommitdiff
path: root/libopie2
Side-by-side diff
Diffstat (limited to 'libopie2') (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
@@ -295,38 +295,39 @@ namespace {
: OSQLQuery(), m_uid( uid ) {
}
FindQuery::FindQuery(const QArray<int>& ints)
: OSQLQuery(), m_uids( ints ){
}
FindQuery::~FindQuery() {
}
QString FindQuery::query()const{
-// if ( m_uids.count() == 0 )
- return single();
+ if ( m_uids.count() == 0 )
+ return single();
+ else
+ return multi();
}
- /*
- else
- return multi();
- }
- QString FindQuery::multi()const {
- QString qu = "select uid, type, value from addressbook where";
- for (uint i = 0; i < m_uids.count(); i++ ) {
- qu += " UID = " + QString::number( m_uids[i] ) + " OR";
- }
- qu.remove( qu.length()-2, 2 ); // Hmmmm..
- return qu;
+
+ QString FindQuery::multi()const {
+ QString qu = "select * from addressbook where";
+ for (uint i = 0; i < m_uids.count(); i++ ) {
+ qu += " uid = " + QString::number( m_uids[i] ) + " OR";
+ }
+ qu.remove( qu.length()-2, 2 ); // Hmmmm..
+
+ odebug << "find query: " << qu << "" << oendl;
+ return qu;
}
- */
- QString FindQuery::single()const{
- QString qu = "select *";
- qu += " from addressbook where uid = " + QString::number(m_uid);
- // owarn << "find query: " << qu << "" << oendl;
- return qu;
+ QString FindQuery::single()const{
+ QString qu = "select *";
+ qu += " from addressbook where uid = " + QString::number(m_uid);
+
+ // owarn << "find query: " << qu << "" << oendl;
+ return qu;
}
FindCustomQuery::FindCustomQuery(int uid)
: OSQLQuery(), m_uid( uid ) {
}
FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
: OSQLQuery(), m_uids( ints ){
@@ -468,27 +469,68 @@ bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact )
return false;
return add( contact );
}
OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
{
- odebug << "OPimContactAccessBackend_SQL::find()" << oendl;
+ odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl;
QTime t;
t.start();
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
+{
+ odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl;
+ odebug << "searching for " << uid << "" << oendl;
+
+ QTime t;
+ t.start();
+
+ uint numReadAhead = readAhead();
+ QArray<int> searchList( numReadAhead );
+
+ uint size =0;
+
+ // Build an array with all elements which should be requested and cached
+ // We will just request "numReadAhead" elements, starting from "current" position in
+ // the list of many uids !
+ switch( direction ) {
+ /* forward */
+ case Frontend::Forward:
+ for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) {
+ searchList[size] = queryUids[i];
+ size++;
+ }
+ break;
+ /* reverse */
+ case Frontend::Reverse:
+ for ( uint i = current; i != 0 && size < numReadAhead; i-- ) {
+ searchList[size] = queryUids[i];
+ size++;
+ }
+ break;
+ }
+
+ //Shrink to real size..
+ searchList.resize( size );
+
+ 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 )
{
QString qu = "SELECT uid FROM addressbook WHERE";
QString searchQuery ="";
QDate startDate;
@@ -763,39 +805,96 @@ QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
}
QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const
{
QTime t;
t.start();
- QMap<int, QString> nonCustomMap;
-
int t2needed = 0;
int t3needed = 0;
QTime t2;
t2.start();
FindQuery query( uid );
OSQLResult res_noncustom = m_driver->query( &query );
t2needed = t2.elapsed();
OSQLResultItem resItem = res_noncustom.first();
+ QMap<int, QString> nonCustomMap;
QTime t3;
t3.start();
+ nonCustomMap = fillNonCustomMap( resItem );
+ t3needed = t3.elapsed();
+
+
+ // 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
+{
+ // 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;
+
+ odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl;
+
+ QTime t;
+ t.start();
+
+ int t2needed = 0;
+ int t3needed = 0;
+ QTime t2;
+ t2.start();
+ FindQuery query( cachelist );
+ OSQLResult res_noncustom = m_driver->query( &query );
+ t2needed = t2.elapsed();
+
+ QMap<int, QString> nonCustomMap;
+ QTime t3;
+ t3.start();
+ OSQLResultItem resItem = res_noncustom.first();
+ do {
+ OPimContact contact( fillNonCustomMap( resItem ) );
+ contact.setExtraMap( requestCustom( contact.uid() ) );
+ odebug << "Caching uid: " << contact.uid() << oendl;
+ cache( contact );
+ resItem = res_noncustom.next();
+ } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !!
+ t3needed = t3.elapsed();
+
+
+ // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
+ odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
+ << " ms, mapping: " << t3needed << " ms" << oendl;
+
+ return cacheFind( uid );
+}
+
+QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const
+{
+ QMap<int, QString> nonCustomMap;
+
// Now loop through all columns
QStringList fieldList = OPimContactFields::untrfields( false );
QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
// Get data for the selected column and store it with the
// corresponding id into the map..
int id = translate[*it];
- QString value = resItem.data( (*it) );
+ QString value = resultItem.data( (*it) );
// odebug << "Reading " << (*it) << "... found: " << value << "" << oendl;
switch( id ){
case Qtopia::Birthday:
case Qtopia::Anniversary:{
// Birthday and Anniversary are encoded special ( yyyy-mm-dd )
QStringList list = QStringList::split( '-', value );
@@ -811,27 +910,22 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co
break;
case Qtopia::AddressCategory:
odebug << "Category is: " << value << "" << oendl;
default:
nonCustomMap.insert( id, value );
}
}
- // First insert uid
- nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) );
- t3needed = t3.elapsed();
-
- // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
- odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
- << " ms, mapping: " << t3needed << " ms" << oendl;
+ nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) );
return nonCustomMap;
}
+
QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const
{
QTime t;
t.start();
QMap<QString, QString> customMap;
FindCustomQuery query( uid );
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
@@ -68,18 +68,17 @@ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
void clear ();
bool wasChangedExternally();
QArray<int> allRecords() const;
OPimContact find ( int uid ) const;
- // FIXME: Add lookahead-cache support !
- //OPimContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
+ OPimContact find( int uid, const QArray<int>&, uint cur, Frontend::CacheDirection ) const;
QArray<int> queryByExample ( const OPimContact &query, int settings,
const QDateTime& d );
QArray<int> matchRegexp( const QRegExp &r ) const;
const uint querySettings();
@@ -93,16 +92,18 @@ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
bool remove ( int uid );
bool reload();
private:
QArray<int> 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;
Opie::DB::OSQLDriver* m_driver;
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
@@ -91,17 +91,17 @@ public:
/**
* find the OPimRecord with uid @param uid
* returns T and T.isEmpty() if nothing was found
*/
virtual T find(int uid )const = 0;
virtual T find(int uid, const QArray<int>& items,
- uint current, typename Frontend::CacheDirection )const ;
+ uint current, typename Frontend::CacheDirection ) const;
/**
* clear the back end
*/
virtual void clear() = 0;
/**
* add T
*/
@@ -123,18 +123,26 @@ public:
void setFrontend( Frontend* front );
/**
* set the read ahead count
*/
void setReadAhead( uint count );
protected:
int access()const;
+
void cache( const T& t )const;
+ /**
+ * Returns the element with given uid out of the cache.
+ * Returns empty element if nothing was found.
+ * <b>Attention:</b> This just works if we have a frontend which contains the cache !
+ */
+ T cacheFind( int uid ) const;
+
/**
* use a prime number here!
*/
void setSaneCacheSize( int );
uint readAhead()const;
private:
@@ -156,27 +164,39 @@ OPimAccessBackend<T>::~OPimAccessBackend() {
}
template <class T>
void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
m_front = fr;
}
template <class T>
void OPimAccessBackend<T>::cache( const T& t )const {
- if (m_front )
+ if ( m_front )
m_front->cache( t );
}
+
+template <class T>
+T OPimAccessBackend<T>::cacheFind( int uid )const {
+ if ( ! m_front ){
+ qWarning ( "No frontend assigned ! Therefore we cannot access the cache to return the right element!" );
+ return T();
+ }
+
+ return m_front->cacheFind( uid );
+}
+
template <class T>
void OPimAccessBackend<T>::setSaneCacheSize( int size) {
- if (m_front )
+ if ( m_front )
m_front->setSaneCacheSize( size );
}
template <class T>
T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
- uint, typename Frontend::CacheDirection )const {
+ uint, typename Frontend::CacheDirection ) const{
+ qDebug( "*** Lookahead feature not supported. Fallback to default find!" );
return find( uid );
}
template <class T>
void OPimAccessBackend<T>::setReadAhead( uint count ) {
m_read = count;
}
template <class T>
uint OPimAccessBackend<T>::readAhead()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
@@ -30,17 +30,16 @@
#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
#define OPIE_PIM_ACCESS_TEMPLATE_H
/* OPIE */
#include <opie2/opimrecord.h>
#include <opie2/opimaccessbackend.h>
#include <opie2/opimrecordlist.h>
-#include <opie2/opimcache.h>
#include <opie2/opimtemplatebase.h>
#include <opie2/odebug.h>
/* QT */
#include <qarray.h>
namespace Opie {
@@ -123,34 +122,37 @@ public:
virtual T find( int uid )const;
/**
* read ahead cache find method ;)
*/
virtual T find( int uid, const QArray<int>&,
uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const;
+
/* invalidate cache here */
/**
* clears the backend and invalidates the backend
*/
void clear() ;
/**
* add T to the backend
* @param t The item to add.
* @return <i>true</i> if added successfully.
*/
- virtual bool add( const T& t ) ;
+ virtual bool add( const T& t ) ;
+
bool add( const OPimRecord& );
- // Needed for real generic access (eilers)
- // Info: Take this if you are working with OPimRecord, which is a generic base class, and
- // you need to add it into any database, you cannot generate a reference to
- // it and casting may be not approriate, too.
- // But take care that the accessing database is compatible to the real type of OPimRecord !!
+ /**
+ * Add an Opie PimRecord.
+ * Info: Take this if you are working with OPimRecords and you need to add it into any database.
+ * But take care that the accessing database is compatible to the real type of OPimRecord !!
+ * Otherwise this access will be rejected !
+ */
bool add( const OPimRecord* );
/* only the uid matters */
/**
* remove T from the backend
* @param t The item to remove
* @return <i>true</i> if successful.
@@ -171,32 +173,34 @@ public:
* @return <i>true</i> if successful.
*/
virtual bool replace( const T& t) ;
void setReadAhead( uint count );
/**
* @internal
*/
+ virtual T cacheFind( int uid )const;
void cache( const T& )const;
void setSaneCacheSize( int );
QArray<int> records()const;
protected:
/**
* invalidate the cache
*/
void invalidateCache();
void setBackEnd( BackEnd* end );
/**
* returns the backend
*/
BackEnd* backEnd();
BackEnd* m_backEnd;
+
Cache m_cache;
private:
OPimAccessTemplatePrivate *d;
};
template <class T>
@@ -213,17 +217,17 @@ OPimAccessTemplate<T>::~OPimAccessTemplate() {
}
template <class T>
bool OPimAccessTemplate<T>::load() {
invalidateCache();
return m_backEnd->load();
}
template <class T>
bool OPimAccessTemplate<T>::reload() {
- invalidateCache(); // zecke: I think this should be added (se)
+ invalidateCache();
return m_backEnd->reload();
}
template <class T>
bool OPimAccessTemplate<T>::save() {
return m_backEnd->save();
}
template <class T>
typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const {
@@ -246,30 +250,42 @@ typename OPimAccessTemplate<T>::List
OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) {
QArray<int> ints = m_backEnd->queryByExample( t, settings, d );
List lis(ints, this );
return lis;
}
template <class T>
T OPimAccessTemplate<T>::find( int uid ) const{
+ // First search in cache..
+ if ( m_cache.contains( uid ) )
+ return m_cache.find( uid );
+
T t = m_backEnd->find( uid );
cache( t );
+
return t;
}
+
+template <class T>
+T OPimAccessTemplate<T>::cacheFind( int uid ) const
+{
+ return m_cache.find( uid );
+}
+
template <class T>
T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
uint current, typename OTemplateBase<T>::CacheDirection dir )const {
/*
* better do T.isEmpty()
* after a find this way we would
* avoid two finds in QCache...
*/
// owarn << "find it now " << uid << oendl;
- if (m_cache.contains( uid ) ) {
+ if ( m_cache.contains( uid ) ) {
return m_cache.find( uid );
}
T t = m_backEnd->find( uid, ar, current, dir );
cache( t );
return t;
}
template <class T>
@@ -279,33 +295,37 @@ void OPimAccessTemplate<T>::clear() {
}
template <class T>
bool OPimAccessTemplate<T>::add( const T& t ) {
cache( t );
return m_backEnd->add( t );
}
template <class T>
-bool OPimAccessTemplate<T>::add( const OPimRecord& rec) {
+bool OPimAccessTemplate<T>::add( const OPimRecord& rec ) {
/* same type */
T tempInstance;
if ( rec.rtti() == tempInstance.rtti() ) {
const T& t = static_cast<const T&>(rec);
return add(t);
+ } else {
+ owarn << "Adding not possible: Objecttype mismatch" << oendl;
}
return false;
}
template <class T>
bool OPimAccessTemplate<T>::add( const OPimRecord* rec) {
/* same type, but pointer */
T tempInstance;
if ( rec -> rtti() == tempInstance.rtti() ) {
const T* t = static_cast<const T*>(rec);
return add( *t );
+ } else {
+ owarn << "Adding not possible: Objecttype mismatch" << oendl;
}
return false;
}
template <class T>
bool OPimAccessTemplate<T>::remove( const T& t ) {
return remove( t.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
@@ -26,16 +26,17 @@
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef OTEMPLATEBASE_H
#define OTEMPLATEBASE_H
/* OPIE */
#include <opie2/opimrecord.h>
+#include <opie2/opimcache.h>
/* QT */
#include <qarray.h>
namespace Opie {
/**
* Templates do not have a base class, This is why
* we've this class
@@ -65,40 +66,53 @@ struct OPimBase {
* -zecke
*/
private:
OPimBasePrivate* d;
};
/**
* internal template base
- * T needs to implement the copy c'tor!!!
+ * Attention: T needs to implement the copy c'tor!!!
*/
class OTemplateBasePrivate;
template <class T = OPimRecord>
class OTemplateBase : public OPimBase {
public:
+ /** Look ahead direction of cache */
enum CacheDirection { Forward=0, Reverse };
+
OTemplateBase() {
};
virtual ~OTemplateBase() {
}
virtual T find( int uid )const = 0;
/**
* read ahead find
*/
virtual T find( int uid, const QArray<int>& items,
uint current, CacheDirection dir = Forward )const = 0;
+
+ /**
+ * Find in Cache..
+ * Returns empty object if nothing found.
+ */
+ virtual T cacheFind( int uid )const = 0;
+
+ /**
+ * Put element into Cache
+ */
virtual void cache( const T& )const = 0;
virtual void setSaneCacheSize( int ) = 0;
OPimRecord* record()const;
OPimRecord* record(int uid )const;
static T* rec();
+
private:
OTemplateBasePrivate *d;
};
template <class T>
OPimRecord* OTemplateBase<T>::record()const {