--------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8bit 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 > --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-diff; charset="us-ascii"; name="kabc.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kabc.patch" ? 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 -#include -#include - #include #include #include @@ -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 - #include +#include #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 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 entryMap = cfg.entryMap( mAddressBook->fileName() ); + QMap 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::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 #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 ); --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-chdr; charset="us-ascii"; name="resource.h" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="resource.h" #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 --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-c++src; charset="us-ascii"; name="resource.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="resource.cpp" #include #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; } --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-chdr; charset="us-ascii"; name="resourcefile.h" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="resourcefile.h" #ifndef KABC_RESOURCEFILE_H #define KABC_RESOURCEFILE_H #include #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 --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-c++src; charset="us-ascii"; name="resourcefile.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="resourcefile.cpp" #include #include #include #include #include #include #include #include #include #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(); } } --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-chdr; charset="us-ascii"; name="resourcesql.h" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="resourcesql.h" #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 --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS Content-Type: text/x-c++src; charset="us-ascii"; name="resourcesql.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="resourcesql.cpp" #include #include #include #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; } --------------Boundary-00=_7B7F6JIMCCTDIBMK8XIS--