cleaned up EvolutionSyncSource interface+implementation

git-svn-id: https://zeitsenke.de/svn/SyncEvolution/trunk@664 15ad00c4-1369-45f4-8270-35d70d36bdcd
This commit is contained in:
Patrick Ohly 2008-07-10 19:17:42 +00:00
parent 0d580b83bc
commit ca390a7743
12 changed files with 124 additions and 140 deletions

View file

@ -1213,11 +1213,11 @@ AddressBookSource::AddressBookSource(const AddressBookSource &other) :
m_modNodeName(other.m_modNodeName)
{}
EvolutionSyncSource::sources AddressBookSource::getSyncBackends()
EvolutionSyncSource::Databases AddressBookSource::getDatabases()
{
EvolutionSyncSource::sources result;
Databases result;
result.push_back(EvolutionSyncSource::source("<<system>>", ""));
result.push_back(Database("<<system>>", ""));
return result;
}

View file

@ -169,7 +169,7 @@ class AddressBookSource : public EvolutionSyncSource
//
// implementation of EvolutionSyncSource
//
virtual sources getSyncBackends();
virtual Databases getDatabases();
virtual void open();
virtual void close();
virtual void exportData(ostream &out);

View file

@ -83,11 +83,11 @@ EvolutionCalendarSource::EvolutionCalendarSource( const EvolutionCalendarSource
}
}
EvolutionSyncSource::sources EvolutionCalendarSource::getSyncBackends()
EvolutionSyncSource::Databases EvolutionCalendarSource::getDatabases()
{
ESourceList *sources = NULL;
GError *gerror = NULL;
EvolutionSyncSource::sources result;
Databases result;
if (!e_cal_get_sources(&sources, m_type, &gerror)) {
// ignore unspecific errors (like on Maemo with no support for memos)
@ -104,9 +104,9 @@ EvolutionSyncSource::sources EvolutionCalendarSource::getSyncBackends()
for (GSList *s = e_source_group_peek_sources (group); s; s = s->next) {
ESource *source = E_SOURCE (s->data);
eptr<char> uri(e_source_get_uri(source));
result.push_back(EvolutionSyncSource::source(e_source_peek_name(source),
uri ? uri.get() : "",
first));
result.push_back(Database(e_source_peek_name(source),
uri ? uri.get() : "",
first));
first = false;
}
}

View file

@ -53,7 +53,7 @@ class EvolutionCalendarSource : public TrackingSyncSource
//
// implementation of EvolutionSyncSource
//
virtual sources getSyncBackends();
virtual Databases getDatabases();
virtual void open();
virtual void close();
virtual void exportData(ostream &out);

View file

@ -72,7 +72,7 @@ EvolutionContactSource::EvolutionContactSource( const EvolutionContactSource &ot
{
}
EvolutionSyncSource::sources EvolutionContactSource::getSyncBackends()
EvolutionSyncSource::Databases EvolutionContactSource::getDatabases()
{
ESourceList *sources = NULL;
@ -80,14 +80,14 @@ EvolutionSyncSource::sources EvolutionContactSource::getSyncBackends()
EvolutionSyncClient::throwError("unable to access address books");
}
EvolutionSyncSource::sources result;
Databases result;
bool first = true;
for (GSList *g = e_source_list_peek_groups (sources); g; g = g->next) {
ESourceGroup *group = E_SOURCE_GROUP (g->data);
for (GSList *s = e_source_group_peek_sources (group); s; s = s->next) {
ESource *source = E_SOURCE (s->data);
eptr<char> uri(e_source_get_uri(source));
result.push_back(EvolutionSyncSource::source(e_source_peek_name(source),
result.push_back(Database(e_source_peek_name(source),
uri ? uri.get() : "",
first));
first = false;
@ -111,7 +111,7 @@ EvolutionSyncSource::sources EvolutionContactSource::getSyncBackends()
if (book) {
const char *uri = e_book_get_uri (book);
result.push_back (EvolutionSyncSource::source (name, uri, true));
result.push_back(Database(name, uri, true));
}
}

View file

@ -48,7 +48,7 @@ class EvolutionContactSource : public EvolutionSyncSource
//
// implementation of EvolutionSyncSource
//
virtual sources getSyncBackends();
virtual Databases getDatabases();
virtual void open();
virtual void close();
virtual void exportData(ostream &out);

View file

@ -23,6 +23,7 @@
#include <common/base/Log.h>
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <list>
using namespace std;
@ -67,6 +68,7 @@ void EvolutionSyncSource::throwError( const string &action
#endif
gerrorstr = ": failure";
setFailed(true);
EvolutionSyncClient::throwError(string(getName()) + ": " + action + gerrorstr);
}
@ -79,19 +81,6 @@ void EvolutionSyncSource::resetItems()
m_deletedItems.clear();
}
string EvolutionSyncSource::getPropertyValue(ManagementNode &node, const string &property)
{
char *value = node.readPropertyValue(property.c_str());
string res;
if (value) {
res = value;
delete [] value;
}
return res;
}
void EvolutionSyncSource::handleException()
{
try {
@ -100,6 +89,7 @@ void EvolutionSyncSource::handleException()
setErrorF(getLastErrorCode() == ERR_NONE ? ERR_UNSPECIFIED : getLastErrorCode(),
"%s", ex.what());
LOG.error("%s", getLastErrorMsg());
setFailed(true);
}
}
@ -226,7 +216,7 @@ EvolutionSyncSource *EvolutionSyncSource::createTestingSource(const string &name
return createSource(params, error);
}
int EvolutionSyncSource::beginSync()
int EvolutionSyncSource::beginSync() throw()
{
string buffer;
buffer += getName();
@ -301,19 +291,17 @@ int EvolutionSyncSource::beginSync()
beginSyncThrow(needAll, needPartial, deleteLocal);
} catch( ... ) {
handleException();
setFailed(true);
return 1;
}
return 0;
}
int EvolutionSyncSource::endSync()
int EvolutionSyncSource::endSync() throw()
{
try {
endSyncThrow();
} catch ( ... ) {
handleException();
setFailed(true);
}
// Do _not_ tell the caller (SyncManager) if an error occurred
@ -323,49 +311,45 @@ int EvolutionSyncSource::endSync()
return 0;
}
void EvolutionSyncSource::setItemStatus(const char *key, int status)
void EvolutionSyncSource::setItemStatus(const char *key, int status) throw()
{
try {
// TODO: logging
setItemStatusThrow(key, status);
} catch (...) {
handleException();
setFailed(true);
}
}
int EvolutionSyncSource::addItem(SyncItem& item)
int EvolutionSyncSource::addItem(SyncItem& item) throw()
{
return processItem("add", &EvolutionSyncSource::addItemThrow, item, true);
}
int EvolutionSyncSource::updateItem(SyncItem& item)
int EvolutionSyncSource::updateItem(SyncItem& item) throw()
{
return processItem("update", &EvolutionSyncSource::updateItemThrow, item, true);
}
int EvolutionSyncSource::deleteItem(SyncItem& item)
int EvolutionSyncSource::deleteItem(SyncItem& item) throw()
{
return processItem("delete", &EvolutionSyncSource::deleteItemThrow, item, false);
}
int EvolutionSyncSource::removeAllItems()
int EvolutionSyncSource::removeAllItems() throw()
{
int status = 0;
try {
for (itemList::const_iterator it = m_allItems.begin();
it != m_allItems.end();
++it) {
BOOST_FOREACH(const string &key, m_allItems) {
SyncItem item;
item.setKey(it->c_str());
item.setKey(key.c_str());
logItem(item, "delete all items");
deleteItemThrow(item);
m_isModified = true;
}
} catch (...) {
handleException();
setFailed(true);
status = 1;
}
return status;
@ -374,7 +358,7 @@ int EvolutionSyncSource::removeAllItems()
int EvolutionSyncSource::processItem(const char *action,
int (EvolutionSyncSource::*func)(SyncItem& item),
SyncItem& item,
bool needData)
bool needData) throw()
{
int status = STC_COMMAND_FAILED;
@ -392,7 +376,6 @@ int EvolutionSyncSource::processItem(const char *action,
m_isModified = true;
} catch (...) {
handleException();
setFailed(true);
}
return status;
}
@ -411,3 +394,48 @@ void EvolutionSyncSource::setItemStatusThrow(const char *key, int status)
}
}
}
SyncItem *EvolutionSyncSource::Items::start()
{
m_it = begin();
LOG.debug("start scanning %s items", m_type.c_str());
return iterate();
}
SyncItem *EvolutionSyncSource::Items::iterate()
{
if (m_it != end()) {
const string &uid( *m_it );
LOG.debug("next %s item: %s", m_type.c_str(), uid.c_str());
++m_it;
if (&m_source.m_deletedItems == this) {
// just tell caller the uid of the deleted item
// and the type that it probably had
SyncItem *item = new SyncItem( uid.c_str() );
item->setDataType(m_source.getMimeType());
return item;
} else {
// retrieve item with all its data
try {
cxxptr<SyncItem> item(m_source.createItem(uid));
if (item) {
item->setState(m_state);
}
return item.release();
} catch(...) {
m_source.handleException();
return NULL;
}
}
} else {
return NULL;
}
}
bool EvolutionSyncSource::Items::addItem(const string &uid) {
pair<iterator, bool> res = insert(uid);
if (res.second) {
m_source.logItem(uid, m_type, true);
}
return res.second;
}

View file

@ -213,20 +213,20 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
*/
static SourceRegistry &getSourceRegistry();
struct source {
source( const string &name, const string &uri, bool isDefault = false ) :
struct Database {
Database(const string &name, const string &uri, bool isDefault = false) :
m_name( name ), m_uri( uri ), m_isDefault(isDefault) {}
string m_name;
string m_uri;
bool m_isDefault;
};
typedef vector<source> sources;
typedef vector<Database> Databases;
/**
* returns a list of all know sources for the kind of items
* returns a list of all know data sources for the kind of items
* supported by this sync source
*/
virtual sources getSyncBackends() = 0;
virtual Databases getDatabases() = 0;
/**
* Actually opens the data source specified in the constructor,
@ -302,18 +302,12 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
void setFailed(bool failed) { m_hasFailed = failed; }
/**
* convenience function: gets property as string class
*
* @return empty string if property not found, otherwise its value
* Convenience function, to be called inside a catch() block of
* the sync source.
* Rethrows the exception to determine what it is, then logs it
* as an error and sets the state of the sync source to failed.
*/
static string getPropertyValue(ManagementNode &node, const string &property);
/**
* convenience function, to be called inside a catch() block:
* rethrows the exception to determine what it is, then logs it
* as an error
*/
static void handleException();
void handleException();
/**
* factory function for a EvolutionSyncSource that provides the
@ -353,23 +347,23 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
// their own position marker, but as they are never called in
// parallel that's okay.
//
virtual SyncItem* getFirstItem() { return m_allItems.start(); }
virtual SyncItem* getNextItem() { return m_allItems.iterate(); }
virtual SyncItem* getFirstNewItem() { return m_newItems.start(); }
virtual SyncItem* getNextNewItem() { return m_newItems.iterate(); }
virtual SyncItem* getFirstUpdatedItem() { return m_updatedItems.start(); }
virtual SyncItem* getNextUpdatedItem() { return m_updatedItems.iterate(); }
virtual SyncItem* getFirstDeletedItem() { return m_deletedItems.start(); }
virtual SyncItem* getNextDeletedItem() { return m_deletedItems.iterate(); }
virtual SyncItem* getFirstItemKey() { return getFirstItem(); }
virtual SyncItem* getNextItemKey() { return getNextItem(); }
virtual SyncItem* getFirstItem() throw() { return m_allItems.start(); }
virtual SyncItem* getNextItem() throw() { return m_allItems.iterate(); }
virtual SyncItem* getFirstNewItem() throw() { return m_newItems.start(); }
virtual SyncItem* getNextNewItem() throw() { return m_newItems.iterate(); }
virtual SyncItem* getFirstUpdatedItem() throw() { return m_updatedItems.start(); }
virtual SyncItem* getNextUpdatedItem() throw() { return m_updatedItems.iterate(); }
virtual SyncItem* getFirstDeletedItem() throw() { return m_deletedItems.start(); }
virtual SyncItem* getNextDeletedItem() throw() { return m_deletedItems.iterate(); }
virtual SyncItem* getFirstItemKey() throw() { return getFirstItem(); }
virtual SyncItem* getNextItemKey() throw() { return getNextItem(); }
virtual int beginSync();
virtual int endSync();
virtual void setItemStatus(const char *key, int status);
virtual int addItem(SyncItem& item);
virtual int updateItem(SyncItem& item);
virtual int deleteItem(SyncItem& item);
virtual int beginSync() throw();
virtual int endSync() throw();
virtual void setItemStatus(const char *key, int status) throw();
virtual int addItem(SyncItem& item) throw();
virtual int updateItem(SyncItem& item) throw();
virtual int deleteItem(SyncItem& item) throw();
/**
* The client library invokes this call to delete all local
@ -382,13 +376,13 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
*
* @return 0 for success, non-zero for failure
*/
virtual int removeAllItems();
virtual int removeAllItems() throw();
/**
* Disambiguate getName(): we have inherited it from both SyncSource and
* AbstractSyncSourceConfig. Both must return the same string.
*/
const char *getName() { return SyncSource::getName(); }
const char *getName() throw() { return SyncSource::getName(); }
/**
* source specific part of beginSync() - throws exceptions in case of error
@ -424,7 +418,7 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
#endif
/**
* throw an exception after a Gnome action failed and
* throw an exception after an operation failed and
* remember that this instance has failed
*
* @param action a string describing what was attempted
@ -443,18 +437,19 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
const string m_changeId;
class itemList : public set<string> {
class Items : public set<string> {
const_iterator m_it;
EvolutionSyncSource &m_source;
const string m_type;
const SyncState m_state;
public:
itemList( EvolutionSyncSource &source, const string &type, SyncState state ) :
Items( EvolutionSyncSource &source, const string &type, SyncState state ) :
m_source( source ),
m_type( type ),
m_state( state )
{}
/**
* start iterating, return first item if available
*
@ -464,58 +459,21 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
* for parent items and thus they appear in the list before
* their children.
*/
SyncItem *start() {
m_it = begin();
LOG.debug("start scanning %s items", m_type.c_str());
return iterate();
}
SyncItem *start();
/** return current item if available, step to next one */
SyncItem *iterate() {
if (m_it != end()) {
const string &uid( *m_it );
LOG.debug("next %s item: %s", m_type.c_str(), uid.c_str());
++m_it;
if (&m_source.m_deletedItems == this) {
// just tell caller the uid of the deleted item
// and the type that it probably had
SyncItem *item = new SyncItem( uid.c_str() );
item->setDataType(m_source.getMimeType());
return item;
} else {
// retrieve item with all its data
try {
cxxptr<SyncItem> item(m_source.createItem(uid));
if (item) {
item->setState(m_state);
}
return item.release();
} catch(...) {
EvolutionSyncSource::handleException();
m_source.setFailed(true);
return NULL;
}
}
} else {
return NULL;
}
}
SyncItem *iterate();
/**
* add to list, with logging
*
* @return true if the item had not been added before
*/
bool addItem(const string &uid) {
pair<iterator, bool> res = insert(uid);
if (res.second) {
m_source.logItem(uid, m_type, true);
}
return res.second;
}
bool addItem(const string &uid);
};
/** UIDs of all/all new/all updated/all deleted items */
itemList m_allItems,
Items m_allItems,
m_newItems,
m_updatedItems,
m_deletedItems;
@ -535,7 +493,7 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig
int processItem(const char *action,
int (EvolutionSyncSource::*func)(SyncItem& item),
SyncItem& item,
bool needData);
bool needData) throw();
/** keeps track of failure state */
bool m_hasFailed;

View file

@ -165,13 +165,13 @@ void SQLiteContactSource::close()
m_sqlite.close();
}
SQLiteContactSource::sources SQLiteContactSource::getSyncBackends()
SQLiteContactSource::Databases SQLiteContactSource::getDatabases()
{
sources res;
Databases result;
res.push_back(EvolutionSyncSource::source("select database via file path",
"file:///<absolute path>"));
return res;
result.push_back(Database("select database via file path",
"file:///<absolute path>"));
return result;
}
void SQLiteContactSource::listAllItems(RevisionMap_t &revisions)

View file

@ -57,7 +57,7 @@ class SQLiteContactSource : public TrackingSyncSource
/* implementation of EvolutionSyncSource interface */
virtual void open();
virtual void close();
virtual sources getSyncBackends();
virtual Databases getDatabases();
virtual SyncItem *createItem(const string &uid);
virtual string fileSuffix() { return "vcf"; }
virtual const char *getMimeType() const { return "text/x-vcard"; }

View file

@ -308,8 +308,8 @@ bool SyncEvolutionCmdline::run() {
disable = "no backend available";
} else {
try {
EvolutionSyncSource::sources datasources = syncSource->getSyncBackends();
if (datasources.empty()) {
EvolutionSyncSource::Databases databases = syncSource->getDatabases();
if (databases.empty()) {
disable = "no database to synchronize";
}
} catch (...) {
@ -481,13 +481,11 @@ bool SyncEvolutionCmdline::listProperties(const ConfigPropertyRegistry &validPro
void SyncEvolutionCmdline::listSources(EvolutionSyncSource &syncSource, const string &header)
{
m_out << header << ":\n";
EvolutionSyncSource::sources sources = syncSource.getSyncBackends();
EvolutionSyncSource::Databases databases = syncSource.getDatabases();
for (EvolutionSyncSource::sources::const_iterator it = sources.begin();
it != sources.end();
it++) {
m_out << " " << it->m_name << " (" << it->m_uri << ")";
if (it->m_isDefault) {
BOOST_FOREACH(const EvolutionSyncSource::Database &database, databases) {
m_out << " " << database.m_name << " (" << database.m_uri << ")";
if (database.m_isDefault) {
m_out << " <default>";
}
m_out << endl;

View file

@ -70,7 +70,7 @@ class TrackingSyncSource : public EvolutionSyncSource
* returns a list of all know sources for the kind of items
* supported by this sync source
*/
virtual sources getSyncBackends() = 0;
virtual Databases getDatabases() = 0;
/**
* Actually opens the data source specified in the constructor,