[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    PATCH: Multiple backends for libkabc
From:       Cornelius Schumacher <schumacher () kde ! org>
Date:       2002-03-03 23:16:19
[Download RAW message or body]

The attached patch adds the option to libkabc to attach different backends, 
e.g. a SQL database or a LDAP directory. The patch moves dependencies on the 
file backend behind an additional layer of Resource classes. There is an 
example class ResourceSql, which accesses data from an SQL database. It's not 
really useful at the moment, but it serves as a second case for testing the 
design.

It would be good to add the patch before the 3.0 release, because otherwise we 
wouldn't be able to add it before the next binary incompatible release.

Comments?

-- 
Cornelius Schumacher <schumacher@kde.org>
>
["kabc.patch" (text/x-diff)]

? a.out
? kabc.patch
? my.kabc
? mytest.cpp
? out.diff
? out.txt
? resource.cpp
? resource.h
? resourcefile.cpp
? resourcefile.h
? resourcesql.cpp
? resourcesql.h
? testdb
? testdb.cpp
Index: Makefile.am
===================================================================
RCS file: /home/kde/kdelibs/kabc/Makefile.am,v
retrieving revision 1.12
diff -u -p -r1.12 Makefile.am
--- Makefile.am	2002/02/27 10:18:57	1.12
+++ Makefile.am	2002/03/03 23:06:32
@@ -11,12 +11,13 @@ libkabc_la_SOURCES = \
   addressbook.cpp addressee.cpp phonenumber.cpp simpleformat.cpp \
   stdaddressbook.cpp vcardformat.cpp address.cpp geo.cpp timezone.cpp \
   vcardformatimpl.cpp addresseedialog.cpp distributionlist.cpp \
-  distributionlisteditor.cpp
+  distributionlisteditor.cpp resource.cpp resourcefile.cpp resourcesql.cpp
 
 kabcincludedir = $(includedir)/kabc
 kabcinclude_HEADERS = address.h addressbook.h addressee.h addresseedialog.h \
   distributionlist.h distributionlisteditor.h format.h geo.h phonenumber.h \
-  simpleformat.h stdaddressbook.h timezone.h vcardformat.h
+  simpleformat.h stdaddressbook.h timezone.h vcardformat.h resource.h \
+  resourcefile.h
 
 METASOURCES = AUTO
 
@@ -26,7 +27,7 @@ kab2kabc_LDFLAGS = $(all_libraries) $(KD
 kab2kabc_LDADD = libkabc.la $(LIB_KAB)
 kab2kabc_SOURCES = kab2kabc.cpp
 
-check_PROGRAMS = testkabc testkabcdlg testdistlist bigread bigwrite
+check_PROGRAMS = testkabc testkabcdlg testdistlist bigread bigwrite testdb
 
 testkabc_LDFLAGS = $(all_libraries) $(KDE_RPATH)
 testkabc_LDADD = libkabc.la
@@ -47,6 +48,10 @@ bigread_SOURCES = bigread.cpp
 bigwrite_LDFLAGS = $(all_libraries) $(KDE_RPATH)
 bigwrite_LDADD = libkabc.la
 bigwrite_SOURCES = bigwrite.cpp
+
+testdb_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+testdb_LDADD = libkabc.la
+testdb_SOURCES = testdb.cpp
 
 autostart_DATA = kab2kabc.desktop
 autostartdir = $(prefix)/share/autostart
Index: addressbook.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/addressbook.cpp,v
retrieving revision 1.13
diff -u -p -r1.13 addressbook.cpp
--- addressbook.cpp	2002/03/01 09:55:29	1.13
+++ addressbook.cpp	2002/03/03 23:06:32
@@ -18,10 +18,6 @@
     Boston, MA 02111-1307, USA.
 */
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
 #include <qtimer.h>
 #include <qfile.h>
 #include <qregexp.h>
@@ -32,79 +28,247 @@
 
 #include "simpleformat.h"
 #include "vcardformat.h"
+#include "resource.h"
 
 #include "addressbook.h"
 #include "addressbook.moc"
 
 using namespace KABC;
 
-AddressBook::AddressBook( Format *format )
+struct AddressBook::AddressBookData
 {
-  if ( !format ) {
-    mFormat = new VCardFormat();
-  } else {
-    mFormat = format;
-  }
+  Addressee::List mAddressees;
+};
+
+struct AddressBook::Iterator::IteratorData
+{
+  Addressee::List::Iterator mIt;
+};
+
+struct AddressBook::ConstIterator::ConstIteratorData
+{
+  Addressee::List::ConstIterator mIt;
+};
+
+AddressBook::Iterator::Iterator()
+{
+  d = new IteratorData;
+}
+
+AddressBook::Iterator::Iterator( const AddressBook::Iterator &i )
+{
+  d = new IteratorData;
+  d->mIt = i.d->mIt;
+}
+
+AddressBook::Iterator &AddressBook::Iterator::operator=( const AddressBook::Iterator &i )
+{
+  d = new IteratorData;
+  d->mIt = i.d->mIt;
+  return *this;
+}
+
+AddressBook::Iterator::~Iterator()
+{
+  delete d;
+}
+
+const Addressee &AddressBook::Iterator::operator*() const
+{
+  return *(d->mIt);
+}
+
+Addressee &AddressBook::Iterator::operator*()
+{
+  return *(d->mIt);
+}
+
+AddressBook::Iterator &AddressBook::Iterator::operator++()
+{
+  (d->mIt)++;
+  return *this;
+}
+
+AddressBook::Iterator &AddressBook::Iterator::operator++(int)
+{
+  (d->mIt)++;
+  return *this;
+}
+
+AddressBook::Iterator &AddressBook::Iterator::operator--()
+{
+  (d->mIt)--;
+  return *this;
+}
+
+AddressBook::Iterator &AddressBook::Iterator::operator--(int)
+{
+  (d->mIt)--;
+  return *this;
+}
+
+bool AddressBook::Iterator::operator==( const Iterator &it )
+{
+  return ( d->mIt == it.d->mIt );
+}
+
+bool AddressBook::Iterator::operator!=( const Iterator &it )
+{
+  return ( d->mIt != it.d->mIt );
+}
+
+
+AddressBook::ConstIterator::ConstIterator()
+{
+  d = new ConstIteratorData;
+}
+
+AddressBook::ConstIterator::ConstIterator( const AddressBook::ConstIterator &i )
+{
+  d = new ConstIteratorData;
+  d->mIt = i.d->mIt;
+}
+
+AddressBook::ConstIterator &AddressBook::ConstIterator::operator=( const AddressBook::ConstIterator &i )
+{
+  d = new ConstIteratorData;
+  d->mIt = i.d->mIt;
+  return *this;
+}
+
+AddressBook::ConstIterator::~ConstIterator()
+{
+  delete d;
+}
+
+const Addressee & AddressBook::ConstIterator::operator*() const
+{
+  return *(d->mIt);
+}
+AddressBook::ConstIterator &AddressBook::ConstIterator::operator++()
+{
+  (d->mIt)++;
+  return *this;
+}
+
+AddressBook::ConstIterator &AddressBook::ConstIterator::operator++(int)
+{
+  (d->mIt)++;
+  return *this;
+}
+
+AddressBook::ConstIterator &AddressBook::ConstIterator::operator--()
+{
+  (d->mIt)--;
+  return *this;
+}
 
-  mFileCheckTimer = new QTimer( this );
-  connect( mFileCheckTimer, SIGNAL( timeout() ), SLOT( checkFile() ) );
+AddressBook::ConstIterator &AddressBook::ConstIterator::operator--(int)
+{
+  (d->mIt)--;
+  return *this;
 }
 
+bool AddressBook::ConstIterator::operator==( const ConstIterator &it )
+{
+  return ( d->mIt == it.d->mIt );
+}
+
+bool AddressBook::ConstIterator::operator!=( const ConstIterator &it )
+{
+  return ( d->mIt != it.d->mIt );
+}
+
+
+AddressBook::AddressBook()
+{
+  d = new AddressBookData;
+}
+
 AddressBook::~AddressBook()
+{
+  delete d;
+}
+
+bool AddressBook::addResource( Resource *resource )
 {
-  delete mFormat;
+  if ( !resource->open() ) return false;
+  mResources.append( resource );
+  return true;
 }
 
-bool AddressBook::load( const QString &fileName )
+bool AddressBook::load()
 {
-  setFileName( fileName );
+  kdDebug(5700) << "AddressBook::load()" << endl;
+
+  clear();
 
-  mAddressees.clear();
+  Resource *r;
+  for( r = mResources.first(); r; r = mResources.next() ) {
+    kdDebug() << " Tick" << endl;
+    if ( !r->load( this ) ) return false;
+  }
 
-  return mFormat->load( this, fileName );
+  return true;
 }
 
 bool AddressBook::save( Ticket *ticket )
 {
-  kdDebug(5700) << "AddressBook::save() '" << ticket->fileName << "'" << endl;
-  
-  bool success = mFormat->save( this, ticket->fileName );
+  kdDebug(5700) << "AddressBook::save()"<< endl;
 
-  setFileName( ticket->fileName );
-
-  delete ticket;
-  unlock( mFileName );
+  if ( ticket->resource() ) {
+    return ticket->resource()->save( ticket );
+  }
 
-  return success;
+  return false;
 }
 
-bool AddressBook::reload()
+AddressBook::Iterator AddressBook::begin()
 {
-  if ( fileName().isEmpty() ) return false;
+  Iterator it = Iterator();
+  it.d->mIt = d->mAddressees.begin();
+  return it;
+}
 
-  return load( fileName() );
+AddressBook::ConstIterator AddressBook::begin() const
+{
+  ConstIterator it = ConstIterator();
+  it.d->mIt = d->mAddressees.begin();
+  return it;
 }
 
-void AddressBook::clear()
+AddressBook::Iterator AddressBook::end()
 {
-  mAddressees.clear();
+  Iterator it = Iterator();
+  it.d->mIt = d->mAddressees.end();
+  return it;
 }
 
-AddressBook::Ticket *AddressBook::requestSaveTicket( const QString &fn )
+AddressBook::ConstIterator AddressBook::end() const
 {
-  kdDebug(5700) << "AddressBook::requestSaveTicket(): '" << fn << "'" << endl; 
+  ConstIterator it = ConstIterator();
+  it.d->mIt = d->mAddressees.end();
+  return it;
+}
 
-  QString saveFileName;
+void AddressBook::clear()
+{
+  d->mAddressees.clear();
+}
 
-  if ( fn.isEmpty() ) saveFileName = fileName();
-  else saveFileName = fn;
+Ticket *AddressBook::requestSaveTicket( Resource *resource )
+{
+  kdDebug(5700) << "AddressBook::requestSaveTicket()" << endl; 
 
-  if ( !lock( saveFileName ) ) {
-    kdDebug() << "AddressBook::requestSaveTicket(): Can't lock file '"
-              << saveFileName << "'" << endl;
+  if ( !resource ) {
+    resource = mResources.first();
+  }
+  
+  if ( mResources.find( resource ) < 0 ) {
     return 0;
+  } else {
+    return resource->requestSaveTicket();
   }
-  return new Ticket( saveFileName );
 }
 
 void AddressBook::insertAddressee( const Addressee &a )
@@ -116,7 +280,7 @@ void AddressBook::insertAddressee( const
       return;
     }
   }
-  mAddressees.append( a );
+  d->mAddressees.append( a );
 }
 
 void AddressBook::removeAddressee( const Addressee &a )
@@ -132,7 +296,7 @@ void AddressBook::removeAddressee( const
 
 void AddressBook::removeAddressee( const Iterator &it )
 {
-  mAddressees.remove( it.mIt );
+  d->mAddressees.remove( it.d->mIt );
 }
 
 AddressBook::Iterator AddressBook::find( const Addressee &a )
@@ -199,90 +363,6 @@ Addressee::List AddressBook::findByCateg
   return results;
 }
 
-bool AddressBook::lock( const QString &fileName )
-{
-  kdDebug(5700) << "AddressBook::lock()" << endl;
-
-  QString fn = fileName;
-  fn.replace( QRegExp("/"), "_" );
-
-  QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
-  kdDebug(5700) << "-- lock name: " << lockName << endl;
-
-  if (QFile::exists( lockName )) return false;
-
-  QString lockUniqueName;
-  lockUniqueName = fn + kapp->randomString(8);
-  mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
-  kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
-
-  // Create unique file
-  QFile file( mLockUniqueName );
-  file.open( IO_WriteOnly );
-  file.close();
-
-  // Create lock file
-  int result = ::link( QFile::encodeName( mLockUniqueName ),
-                       QFile::encodeName( lockName ) );
-
-  if ( result == 0 ) {
-    emit addressBookLocked( this );
-    return true;
-  }
-
-  // TODO: check stat
-
-  return false;
-}
-
-void AddressBook::unlock( const QString &fileName )
-{
-  QString fn = fileName;
-  fn.replace( QRegExp( "/" ), "_" );
-
-  QString lockName = locate( "data", "kabc/lock/" + fn + ".lock" );
-  ::unlink( QFile::encodeName( lockName ) );
-  QFile::remove( mLockUniqueName );
-  emit addressBookUnlocked( this );
-}
-
-void AddressBook::setFileName( const QString &fileName )
-{
-  mFileName = fileName;
-
-  struct stat s;
-  int result = stat( QFile::encodeName( mFileName ), &s );
-  if ( result == 0 ) {
-    mChangeTime  = s.st_ctime;
-  }
-
-  mFileCheckTimer->start( 500 );
-}
-
-QString AddressBook::fileName() const
-{
-  return mFileName;
-}
-
-void AddressBook::checkFile()
-{
-  struct stat s;
-  int result = stat( QFile::encodeName( mFileName ), &s );
-
-#if 0
-  kdDebug(5700) << "AddressBook::checkFile() result: " << result
-            << " new ctime: " << s.st_ctime
-            << " old ctime: " << mChangeTime
-            << endl;
-#endif
-
-  if ( result == 0 && ( mChangeTime != s.st_ctime ) ) {
-    mChangeTime  = s.st_ctime;
-    load( mFileName );
-    emit addressBookChanged( this );
-  }
-}
-
 void AddressBook::dump() const
 {
   kdDebug(5700) << "AddressBook::dump() --- begin ---" << endl;
@@ -293,4 +373,9 @@ void AddressBook::dump() const
   }
 
   kdDebug(5700) << "AddressBook::dump() ---  end  ---" << endl;
+}
+
+QString AddressBook::identifier()
+{
+  return "NoIdentifier";
 }
Index: addressbook.h
===================================================================
RCS file: /home/kde/kdelibs/kabc/addressbook.h,v
retrieving revision 1.8
diff -u -p -r1.8 addressbook.h
--- addressbook.h	2002/01/27 23:04:48	1.8
+++ addressbook.h	2002/03/03 23:06:32
@@ -21,18 +21,15 @@
 #define KABC_ADDRESSBOOK_H
 // $Id: addressbook.h,v 1.8 2002/01/27 23:04:48 cschumac Exp $
 
-#include <sys/types.h>
-
 #include <qobject.h>
+#include <qptrlist.h>
 
 #include "addressee.h"
 
-class QTimer;
-
 namespace KABC {
 
-class Format;
-class AddressBookPrivate;
+class Resource;
+class Ticket;
 
 /**
   @short Address Book
@@ -51,21 +48,24 @@ class AddressBook : public QObject
     class Iterator
     {
       public:
-        Iterator() {}
-        Iterator( const Addressee::List::Iterator &it ) : mIt( it ) {}
-      
-        const Addressee & operator*() const { return *mIt; }
-        Addressee &operator*() { return *mIt; }
-        Iterator &operator++() { mIt++; return *this; }
-        Iterator &operator++(int) { mIt++; return *this; }
-        Iterator &operator--() { mIt--; return *this; }
-        Iterator &operator--(int) { mIt--; return *this; }
-        bool operator==( const Iterator &it ) { return ( mIt == it.mIt ); }
-        bool operator!=( const Iterator &it ) { return ( mIt != it.mIt ); }
+        Iterator();
+        Iterator( const Iterator & );
+      	~Iterator();
+
+      	Iterator &operator=( const Iterator & );
+        const Addressee & operator*() const;
+        Addressee &operator*();
+        Iterator &operator++();
+        Iterator &operator++(int);
+        Iterator &operator--();
+        Iterator &operator--(int);
+        bool operator==( const Iterator &it );
+        bool operator!=( const Iterator &it );
 
-        Addressee::List::Iterator mIt;
+      	struct IteratorData;
+	IteratorData *d;
     };
-    
+
     /**
       @short Address Book Const Iterator
       
@@ -74,41 +74,29 @@ class AddressBook : public QObject
     class ConstIterator
     {
       public:
-        ConstIterator() {}
-        ConstIterator( const Addressee::List::ConstIterator &it ) : mIt( it ) {}
-      
-        const Addressee & operator*() const { return *mIt; }
-        ConstIterator &operator++() { mIt++; return *this; }
-        ConstIterator &operator++(int) { mIt++; return *this; }
-        ConstIterator &operator--() { mIt--; return *this; }
-        ConstIterator &operator--(int) { mIt--; return *this; }
-        bool operator==( const ConstIterator &it ) { return ( mIt == it.mIt ); }
-        bool operator!=( const ConstIterator &it ) { return ( mIt != it.mIt ); }
+        ConstIterator();
+        ConstIterator( const ConstIterator & );
+      	~ConstIterator();
+      
+      	ConstIterator &operator=( const ConstIterator & );
+        const Addressee & operator*() const;
+        ConstIterator &operator++();
+        ConstIterator &operator++(int);
+        ConstIterator &operator--();
+        ConstIterator &operator--(int);
+        bool operator==( const ConstIterator &it );
+        bool operator!=( const ConstIterator &it );
 
-        Addressee::List::ConstIterator mIt;
+      	struct ConstIteratorData;
+	ConstIteratorData *d;
     };
     
     /**
-      @short Helper class for handling coordinated save of address books.
-      
-      This class is used as helper class for saving address book. @See
-      requestSaveTicket(), save().
-    */
-    class Ticket
-    {
-        friend class AddressBook;
-    
-        Ticket( const QString &_fileName ) : fileName( _fileName ) {}
-        
-        QString fileName;
-    };
-
-    /**
       Construct address book object.
       
       @param format File format class.
     */
-    AddressBook( Format *format=0 );
+    AddressBook();
     virtual ~AddressBook();
 
     /**
@@ -117,20 +105,19 @@ class AddressBook : public QObject
       locked the function returns 0. You need the returned @ref Ticket object
       for calling the @ref save() function.
       
-      @param fileName The file name the addres book is to be saved. If this
-                      parameter is omitted or null, the file is used, the
-                      address book has been loaded from.
-    
       @see save()
+    */
+    Ticket *requestSaveTicket( Resource *resource=0 );
+    
+    /**
+      Add address book resource.
     */
-    Ticket *requestSaveTicket( const QString &fileName = QString::null );
+    bool addResource( Resource * );
     
     /**
       Load address book from file.
-      
-      @param fileName name of file to be loaded.
     */
-    bool load( const QString &fileName );
+    bool load();
     /**
       Save address book. The address book is saved to the file, the Ticket
       object has been requested for by @ref requestSaveTicket().
@@ -138,28 +125,23 @@ class AddressBook : public QObject
       @param ticket a ticket object returned by @ref requestSaveTicket()
     */
     bool save( Ticket *ticket );
-
-    /**
-      Reload currently loaded addressbook.
-    */
-    bool reload();
     
     /**
       Return iterator for first entry of address book.
     */
-    Iterator begin() { return Iterator( mAddressees.begin() ); }
+    Iterator begin();
     /**
       Return const iterator for first entry of address book.
     */
-    ConstIterator begin() const { return ConstIterator( mAddressees.begin() ); }
+    ConstIterator begin() const;
     /**
       Return iterator for first entry of address book.
     */
-    Iterator end() { return Iterator( mAddressees.end() ); }
+    Iterator end();
     /**
       Return const iterator for first entry of address book.
     */
-    ConstIterator end() const { return ConstIterator( mAddressees.end() ); }
+    ConstIterator end() const;
     
     /**
       Remove all entries from address book.
@@ -209,20 +191,20 @@ class AddressBook : public QObject
     */
     Addressee::List findByCategory( const QString & );
 
-    /**
-      Set name of file to be used for saving.
-    */
-    void setFileName( const QString & );
     /**
-      Return name of file used for loading and saving the address book.
+      Return a string identifying this addressbook.
     */
-    QString fileName() const;
+    virtual QString identifier();
 
     /**
       Debug output.
     */
     void dump() const;
 
+    void emitAddressBookLocked() { emit addressBookLocked( this ); }
+    void emitAddressBookUnlocked() { emit addressBookUnlocked( this ); }
+    void emitAddressBookChanged() { emit addressBookChanged( this ); }
+
   signals:
     /**
       Emitted, when the address book has changed on disk.
@@ -237,26 +219,11 @@ class AddressBook : public QObject
     */
     void addressBookUnlocked( AddressBook * );
 
-  protected slots:
-    void checkFile();
-
-  protected:
-    bool lock( const QString &fileName );
-    void unlock( const QString &fileName );
-
   private:
-    Addressee::List mAddressees;
-
-    Format *mFormat;
-
-    QString mFileName;
-    
-    QString mLockUniqueName;
-    
-    QTimer *mFileCheckTimer;
-    time_t mChangeTime;
+    QPtrList<Resource> mResources;
 
-    AddressBookPrivate *d;
+    struct AddressBookData;
+    AddressBookData *d;
 };
 
 }
Index: bigread.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/bigread.cpp,v
retrieving revision 1.1
diff -u -p -r1.1 bigread.cpp
--- bigread.cpp	2002/02/27 10:18:57	1.1
+++ bigread.cpp	2002/03/03 23:06:32
@@ -8,6 +8,8 @@
 
 #include "addressbook.h"
 #include "vcardformat.h"
+#include "resourcefile.h"
+#include "resourcesql.h"
 
 using namespace KABC;
 
@@ -18,7 +20,13 @@ int main(int argc,char **argv)
 
   KApplication app;
   
-  AddressBook ab( new VCardFormat );
+  AddressBook ab; 
+   
+  ResourceFile r( &ab, "my.kabc" );
+  ab.addResource( &r );
+  
+  ResourceSql rsql( &ab, "root", "kde4ever", "localhost" );
+  ab.addResource( &rsql );
 
   struct tms start;
 
@@ -32,7 +40,7 @@ int main(int argc,char **argv)
 #endif
 	    
   kdDebug() << "Start load" << endl;
-  ab.load( "my.kabc" );
+  ab.load();
   kdDebug() << "Finished load" << endl;
 
   struct tms end;
@@ -48,4 +56,6 @@ int main(int argc,char **argv)
 
   kdDebug() << "UTime: " << int( end.tms_utime ) - int( start.tms_utime ) << endl; 
   kdDebug() << "STime: " << int( end.tms_stime ) - int( start.tms_stime ) << endl; 
+
+  ab.dump();
 }
Index: bigwrite.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/bigwrite.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 bigwrite.cpp
--- bigwrite.cpp	2002/02/27 11:04:39	1.2
+++ bigwrite.cpp	2002/03/03 23:06:32
@@ -6,6 +6,7 @@
 
 #include "addressbook.h"
 #include "vcardformat.h"
+#include "resourcefile.h"
 
 using namespace KABC;
 
@@ -15,8 +16,10 @@ int main(int argc,char **argv)
   KCmdLineArgs::init(argc,argv,&aboutData);
 
   KApplication app;
-  
-  AddressBook ab( new VCardFormat );
+
+  AddressBook ab;
+  ResourceFile r( &ab, "my.kabc" );
+  ab.addResource( &r );
   
   for( int i = 0; i < 1000; ++i ) {
     Addressee a;
@@ -28,7 +31,7 @@ int main(int argc,char **argv)
   }
   printf( "\n" );
   
-  AddressBook::Ticket *t = ab.requestSaveTicket( "my.kabc" );
+  Ticket *t = ab.requestSaveTicket( &r );
   if ( t ) {
     if ( !ab.save( t ) ) {
       kdDebug() << "Can't save." << endl;
Index: distributionlist.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/distributionlist.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 distributionlist.cpp
--- distributionlist.cpp	2001/11/12 23:08:10	1.2
+++ distributionlist.cpp	2002/03/03 23:06:32
@@ -150,13 +150,13 @@ bool DistributionListManager::load()
 {
   KSimpleConfig cfg( locateLocal( "data", "kabc/distlists" ) );
 
-  QMap<QString,QString> entryMap = cfg.entryMap( mAddressBook->fileName() );
+  QMap<QString,QString> entryMap = cfg.entryMap( mAddressBook->identifier() );
   if ( entryMap.isEmpty() ) {
-    kdDebug() << "No distlists for '" << mAddressBook->fileName() << "'" << endl;
+    kdDebug() << "No distlists for '" << mAddressBook->identifier() << "'" << endl;
     return false;
   }
 
-  cfg.setGroup( mAddressBook->fileName() );
+  cfg.setGroup( mAddressBook->identifier() );
 
   QMap<QString,QString>::ConstIterator it;
   for( it = entryMap.begin(); it != entryMap.end(); ++it ) {
@@ -193,7 +193,7 @@ bool DistributionListManager::save()
 
   KSimpleConfig cfg( locateLocal( "data", "kabc/distlists" ) );
 
-  cfg.setGroup( mAddressBook->fileName() );
+  cfg.setGroup( mAddressBook->identifier() );
   
   DistributionList *list;
   for( list = mLists.first(); list; list = mLists.next() ) {
Index: kab2kabc.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/kab2kabc.cpp,v
retrieving revision 1.11
diff -u -p -r1.11 kab2kabc.cpp
--- kab2kabc.cpp	2002/03/01 18:45:59	1.11
+++ kab2kabc.cpp	2002/03/03 23:06:33
@@ -463,5 +463,5 @@ int main(int argc,char **argv)
 
   StdAddressBook::save();
   
-  kdDebug(5700) << "Saved kabc addressbook to '" << kabcBook->fileName() << "'" << endl;
+  kdDebug(5700) << "Saved kabc addressbook to '" << kabcBook->identifier() << "'" << endl;
 }
Index: stdaddressbook.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/stdaddressbook.cpp,v
retrieving revision 1.6
diff -u -p -r1.6 stdaddressbook.cpp
--- stdaddressbook.cpp	2002/03/01 09:55:29	1.6
+++ stdaddressbook.cpp	2002/03/03 23:06:33
@@ -22,6 +22,8 @@
 #include <kdebug.h>
 
 #include "stdaddressbook.h"
+#include "resourcefile.h"
+#include "resourcesql.h"
 
 using namespace KABC;
 
@@ -56,10 +58,17 @@ bool StdAddressBook::save()
 
 StdAddressBook::StdAddressBook()
 {
-  load( fileName() );
+  addResource( new ResourceFile( this, fileName() ) );
+  addResource( new ResourceSql( this, "root", "kde4ever", "localhost" ) );
+  load();
 }
 
 StdAddressBook::~StdAddressBook()
 {
   save();
+}
+
+QString StdAddressBook::identifier()
+{
+  return fileName();
 }
Index: stdaddressbook.h
===================================================================
RCS file: /home/kde/kdelibs/kabc/stdaddressbook.h,v
retrieving revision 1.3
diff -u -p -r1.3 stdaddressbook.h
--- stdaddressbook.h	2002/03/01 09:55:29	1.3
+++ stdaddressbook.h	2002/03/03 23:06:33
@@ -51,6 +51,8 @@ class StdAddressBook : public AddressBoo
     */
     static QString fileName();
     
+    QString identifier();
+    
   protected:
     StdAddressBook();
     ~StdAddressBook();
Index: testkabc.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/testkabc.cpp,v
retrieving revision 1.8
diff -u -p -r1.8 testkabc.cpp
--- testkabc.cpp	2002/02/21 11:38:51	1.8
+++ testkabc.cpp	2002/03/03 23:06:33
@@ -6,6 +6,7 @@
 
 #include "addressbook.h"
 #include "vcardformat.h"
+#include "resourcefile.h"
 
 using namespace KABC;
 
@@ -16,11 +17,17 @@ int main(int argc,char **argv)
 
 //  KApplication app( false, false );
   KApplication app;
+
+  AddressBook ab;
+  
+  ResourceFile r( &ab, "my.kabc", new VCardFormat );
   
-  AddressBook ab( new VCardFormat );
+  if ( !ab.addResource( &r ) ) {
+    kdDebug() << "Can't add Resource." << endl;
+  }
   
-  ab.load( "/home/cs/kdecvs/kdepim/kabc/my.kabc" );
-  kdDebug() << "Read addressbook from: " << ab.fileName() << endl;
+  ab.load();
+  kdDebug() << "Read addressbook from: " << r.fileName() << endl;
   ab.dump();
   
   ab.clear();
@@ -59,10 +66,10 @@ int main(int argc,char **argv)
   AddressBook::Iterator it = ab.find( c );
   (*it).insertEmail( "neueemail@woauchimmer" );
   
-  kdDebug() << "Write addressbook to: " << ab.fileName() << endl;
+  kdDebug() << "Write addressbook to: " << ab.identifier() << endl;
   ab.dump();
   
-  AddressBook::Ticket *t = ab.requestSaveTicket( "/home/cs/kdecvs/kdepim/kabc/my.kabc" );
+  Ticket *t = ab.requestSaveTicket( &r );
   if ( t ) {
     ab.save( t );
   } else {
Index: testkabcdlg.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/testkabcdlg.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 testkabcdlg.cpp
--- testkabcdlg.cpp	2001/11/12 23:08:10	1.2
+++ testkabcdlg.cpp	2002/03/03 23:06:33
@@ -18,7 +18,7 @@ static const KCmdLineOptions options[] =
 
 int main(int argc,char **argv)
 {
-  KAboutData aboutData("testkabc",I18N_NOOP("TestKabc"),"0.1");
+  KAboutData aboutData("testkabcdlg",I18N_NOOP("TestKabc"),"0.1");
   KCmdLineArgs::init(argc,argv,&aboutData);
   KCmdLineArgs::addCmdLineOptions( options );
 

["resource.h" (text/x-chdr)]

#ifndef KABC_RESOURCE_H
#define KABC_RESOURCE_H

#include "addressbook.h"

namespace KABC {

/**
  @short Helper class for handling coordinated save of address books.
  
  This class is used as helper class for saving address book. @See
  requestSaveTicket(), save().
*/
class Ticket
{
    friend class Resource;
  public:
    Resource *resource() { return mResource; }

  private:    
    Ticket( Resource *resource ) : mResource( resource ) {}
    
    Resource *mResource;
};


class Resource {
  public:
    Resource( AddressBook * );
    virtual ~Resource();
  
    virtual bool open();
    virtual void close();
  
    virtual Ticket *requestSaveTicket();
  
    virtual bool load( AddressBook * );
    virtual bool save( Ticket * );

    void setAddressBook( AddressBook * );
    AddressBook *addressBook() { return mAddressBook; }

  protected:
    Ticket *createTicket( Resource * );

  private:
    AddressBook *mAddressBook;
};

}

#endif

["resource.cpp" (text/x-c++src)]

#include <kdebug.h>

#include "resource.h"

using namespace KABC;

Resource::Resource( AddressBook *ab ) :
  mAddressBook( ab )
{
}

Resource::~Resource()
{
}

bool Resource::open()
{
  return true;
}

void Resource::close()
{
}

Ticket *Resource::requestSaveTicket()
{
  return 0;
}

bool Resource::load( AddressBook *ab )
{
  mAddressBook = ab;
  return true;
}

bool Resource::save( Ticket * )
{
  return false;
}

Ticket *Resource::createTicket( Resource *resource )
{
  return new Ticket( resource );
}

void Resource::setAddressBook( AddressBook *ab )
{
  mAddressBook = ab;
}

["resourcefile.h" (text/x-chdr)]

#ifndef KABC_RESOURCEFILE_H
#define KABC_RESOURCEFILE_H

#include <sys/types.h>

#include "resource.h"

class QTimer;

namespace KABC {

class Format;

class ResourceFile : public QObject, public Resource {
    Q_OBJECT
  public:
    ResourceFile( AddressBook *, const QString &filename, Format *format=0 );
    ~ResourceFile();
  
    bool open();
    void close();
  
    Ticket *requestSaveTicket();

    bool load( AddressBook * );
    bool save( Ticket * );

    /**
      Set name of file to be used for saving.
    */
    void setFileName( const QString & );
    /**
      Return name of file used for loading and saving the address book.
    */
    QString fileName() const;

  protected slots:
    void checkFile();

  protected:
    bool lock( const QString &fileName );
    void unlock( const QString &fileName );


  private:
    QString mFileName;
    Format *mFormat;

    QString mLockUniqueName;
    
    QTimer *mFileCheckTimer;
    time_t mChangeTime;
};

}

#endif

["resourcefile.cpp" (text/x-c++src)]

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <qtimer.h>
#include <qregexp.h>
#include <qfile.h>

#include <kdebug.h>
#include <kstandarddirs.h>
#include <kapplication.h>

#include "vcardformat.h"
#include "addressbook.h"

#include "resourcefile.h"
#include "resourcefile.moc"

using namespace KABC;

ResourceFile::ResourceFile( AddressBook *addressBook, const QString &filename,
                            Format *format ) :
  Resource( addressBook )      
{
  if ( !format ) {
    mFormat = new VCardFormat();
  } else {
    mFormat = format;
  }

  mFileCheckTimer = new QTimer( this );

  setFileName( filename );

  connect( mFileCheckTimer, SIGNAL( timeout() ), SLOT( checkFile() ) );
}

ResourceFile::~ResourceFile()
{
  delete mFormat;
}

Ticket *ResourceFile::requestSaveTicket()
{
  kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;

  if ( !addressBook() ) return 0;

  if ( !lock( mFileName ) ) {
    kdDebug() << "ResourceFile::requestSaveTicket(): Can't lock file '"
              << mFileName << "'" << endl;
    return 0;
  }
  return createTicket( this );
}


bool ResourceFile::open()
{
  return true;
}

void ResourceFile::close()
{
}

bool ResourceFile::load( AddressBook *ab )
{
  kdDebug() << "ResourceFile::load(): '" << mFileName << "'" << endl;

  setAddressBook( ab );
  
  return mFormat->load( ab, mFileName );
}

bool ResourceFile::save( Ticket *ticket )
{
  kdDebug(5700) << "ResourceFile::save()" << endl;
  
  bool success = mFormat->save( addressBook(), mFileName );

  delete ticket;
  unlock( mFileName );

  return success;
}

bool ResourceFile::lock( const QString &fileName )
{
  kdDebug(5700) << "ResourceFile::lock()" << endl;

  QString fn = fileName;
  fn.replace( QRegExp("/"), "_" );

  QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
  kdDebug(5700) << "-- lock name: " << lockName << endl;

  if (QFile::exists( lockName )) return false;

  QString lockUniqueName;
  lockUniqueName = fn + kapp->randomString(8);
  mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
  kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;

  // Create unique file
  QFile file( mLockUniqueName );
  file.open( IO_WriteOnly );
  file.close();

  // Create lock file
  int result = ::link( QFile::encodeName( mLockUniqueName ),
                       QFile::encodeName( lockName ) );

  if ( result == 0 ) {
    addressBook()->emitAddressBookLocked();
    return true;
  }

  // TODO: check stat

  return false;
}

void ResourceFile::unlock( const QString &fileName )
{
  QString fn = fileName;
  fn.replace( QRegExp( "/" ), "_" );

  QString lockName = locate( "data", "kabc/lock/" + fn + ".lock" );
  ::unlink( QFile::encodeName( lockName ) );
  QFile::remove( mLockUniqueName );
  addressBook()->emitAddressBookUnlocked();
}

void ResourceFile::setFileName( const QString &fileName )
{
  mFileName = fileName;

  struct stat s;
  int result = stat( QFile::encodeName( mFileName ), &s );
  if ( result == 0 ) {
    mChangeTime  = s.st_ctime;
  }

  mFileCheckTimer->start( 500 );
}

QString ResourceFile::fileName() const
{
  return mFileName;
}

void ResourceFile::checkFile()
{
  struct stat s;
  int result = stat( QFile::encodeName( mFileName ), &s );

#if 0
  kdDebug(5700) << "AddressBook::checkFile() result: " << result
            << " new ctime: " << s.st_ctime
            << " old ctime: " << mChangeTime
            << endl;
#endif

  if ( result == 0 && ( mChangeTime != s.st_ctime ) ) {
    mChangeTime  = s.st_ctime;
    load( addressBook() );
    addressBook()->emitAddressBookChanged();
  }
}

["resourcesql.h" (text/x-chdr)]

#ifndef KABC_RESOURCESQL_H
#define KABC_RESOURCESQL_H

#include "addressbook.h"
#include "resource.h"

class QSqlDatabase;

namespace KABC {

class ResourceSql : public Resource {
  public:
    ResourceSql( AddressBook *ab, const QString &user, const QString &password,
                 const QString &host );
  
    bool open();
    void close();
  
    bool load( AddressBook * );
    bool save();

    enum EntryKind { FamilyName = 1, GivenName , Email };
    
  private:
    QString mUser;
    QString mPassword;
    QString mHost;
  
    QSqlDatabase *mDb;
};

}

#endif

["resourcesql.cpp" (text/x-c++src)]

#include <qsqldatabase.h>
#include <qsqlcursor.h>

#include <kdebug.h>

#include "resourcesql.h"

using namespace KABC;

ResourceSql::ResourceSql( AddressBook *ab, const QString &user,
                          const QString &password, const QString &host ) :
  Resource( ab ), mUser( user ), mPassword( password ), mHost( host ), mDb( 0 )
{
}

bool ResourceSql::open()
{
  QStringList drivers = QSqlDatabase::drivers();
  for ( QStringList::Iterator it = drivers.begin(); it != drivers.end(); ++it ) {
    kdDebug() << "Driver: " << (*it) << endl;
  }

  mDb = QSqlDatabase::addDatabase( "QMYSQL3" );

  if ( !mDb ) {
    kdDebug() << "Error. Can't connect to database." << endl;
    return false;
  }

  mDb->setDatabaseName( "address" );
  mDb->setUserName( mUser );
  mDb->setPassword( mPassword );
  mDb->setHostName( mHost );

  if ( !mDb->open() ) {
    kdDebug() << "Error. Can't open database." << endl;
    return false;
  }

  return true;
}

void ResourceSql::close()
{
  mDb->close();
}

bool ResourceSql::load( AddressBook *ab )
{
  QSqlCursor cur( "addresses" ); // Specify the table/view name
  cur.select(); // We'll retrieve every record
  while ( cur.next() ) {
    kdDebug() << cur.value( "entry" ).toString() << endl;
  }

  QSqlQuery query( "select distinct addressId from addresses" );
  while ( query.next() ) {
    QString id = query.value(0).toString();
    kdDebug() << "id: " << id << endl;

    Addressee a;
    a.setUid( id );

    QSqlQuery entryQuery( "select * from addresses where addressId = " + id );
    while ( entryQuery.next() ) {
      int entryKind = entryQuery.value(1).toInt();
      QString entry = entryQuery.value(2).toString();
      kdDebug() << "  " << QString::number( entryKind ) << ": " << entry << endl;
      switch ( entryKind ) {
      	case GivenName:
	  a.setGivenName( entry );
	  break;
	case FamilyName:
	  a.setFamilyName( entry );
	  break;
	case Email:
	  a.insertEmail( entry );
	  break;
	default:
	  break;
      }
    }
    
    ab->insertAddressee( a );
  }
 
  setAddressBook( ab );
  
  return true;
}

bool ResourceSql::save()
{
  return false;
}


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic