On Tue, 2009-08-04 at 16:10 +0100, Patrick Ohly wrote:
The interfaces must be pure virtual to allow multiple inheritance.
Default implementations of them provide the current functionality (for
example, EvolutionSyncSource: iterate over fixed lists of changes,
import/export items as blobs) and hook that up with the Synthesis DB
Interface. An implementor can put all of his code in one class which is
derived from the appropriate base classes.
I've implemented that concept and committed it to the "backend-api"
branch. Warning, the code is not stable. Be prepared for a somewhat
volatile branch and forced updates when pulling it.
The code currently is complete enough to run sync sessions with the
command line. The GUI and syncevo-dbus-server also compile. What is
missing is the adaption of ClientTest.cpp to the updated API. Therefore
it doesn't compile yet, which prevented more intensive tests today.
The current EvolutionSyncSource and TrackingSyncSource would do that
to
preserve the current, rather simple to implement API, and to avoid
rewriting existing backends. I would rename EvolutionSyncSource though
and move the remaining Evolution specific code into a common class in
src/backend/evolution.
The equivalent of the former EvolutionSyncSource is now SyncSource.
EvolutionSyncSource made a comeback as base class for all EDS sync
sources.
TrackingSyncSource documents the whole API, just as it did before, even
for those methods which are inherited from base classes. The goal is
that someone can copy/paste that class, fill out the pure virtual
functions and be done with his work (okay, after registering his
backend).
Bob, for your purposes (reusing change tracking via revision string, but
accessing field lists directly), you would compose a class roughly like
this (untested):
#include <boost/bind.hpp>
class FieldListSyncSource : public SyncSource,
public SyncSourceSession,
public SyncSourceRevisions,
public SyncSourceDelete {
public:
FieldListSyncSource(const SyncSourceParams ¶ms) :
SyncSource(params)
{
SyncSourceSession::init(m_operations);
SyncSourceRevisions::init(NULL, NULL, m_operations); // APIs for backup/restore
not available
SyncSourceDelete::init(m_operations);
m_operations.m_readItemAsKey =
boost::bind(&FieldListSyncSource::readItemAsKey,
this, _1, _2);
m_operations.m_insertItemAsKey =
boost::bind(&FieldListSyncSource::insertItemAsKey,
this, _1, _2);
m_operations.m_updateItemAsKey =
boost::bind(&FieldListSyncSource::updateItemAsKey,
this, _1, _2, _3);
}
sysync::TSyError readItemAsKey(sysync::cItemID aID, sysync::KeyH aItemKey);
sysync::TSyError insertItemAsKey(sysync::KeyH aItemKey, sysync::ItemID newID);
sysync::TSyError updateItemAsKey(sysync::KeyH aItemKey, sysync::cItemID aID,
sysync::ItemID updID);
};
See sysync_dbapi.h for information about the *AsKey() Synthesis calls. I
can imagine that some C++ glue code like in SyncEvolution's
SynthesisEngine.h will make it easier to work with that API.
I won't have much time to work on this tomorrow, I have to catch up with
my other work first. At least I should get client-test compiled and
running again.
The next steps would be to get the SQLiteContactSource working with the
new API and direct field list access. It was meant as a coding example
that works on all platforms, but due to bit rot and neglect during the
0.9 release cycle it currently doesn't compile (same problem as in Mac
OS X, dependency on removed VOCL vCard parse/encoder).
Yongsheng, perhaps you want to have a look at that? It would be a good
check for the new API if someone else could go through it, check whether
the comments all make sense/are up-to-date, and then uses it in a new
way.
--
Best Regards, Patrick Ohly
The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.