summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2010-05-17 15:49:52 +0200
committerPatrick Ohly <patrick.ohly@intel.com>2010-08-24 15:16:50 +0200
commitc831ee6ef892990a1f9cde5a0fc0032943fdcf3a (patch)
treeca47ebb22f0d9967fa388202acef66fc98d1238e
parent74ee93d2fb0b057eed63a9b3b1babbe6fd3a5e51 (diff)
FileSyncSource: use "raw" datatype (experimental)raw-sync-source
This patch uses an inofficial change to libsynthesis which was never merged. It doesn't work because that change does not fully support reading/writing items via the DB API. The official support for raw data access is described here: http://meego.gitorious.org/meego-middleware/libsynthesis/commit/ae884ae56479e1a82ac845a26599559c37272dc1 This is what this patch should use instead.
-rw-r--r--src/backends/file/FileSyncSource.cpp71
-rw-r--r--src/backends/file/FileSyncSource.h12
-rw-r--r--src/syncevo/SyncSource.h34
-rw-r--r--src/syncevo/SynthesisDBPlugin.cpp121
4 files changed, 219 insertions, 19 deletions
diff --git a/src/backends/file/FileSyncSource.cpp b/src/backends/file/FileSyncSource.cpp
index de43c455..9b419b23 100644
--- a/src/backends/file/FileSyncSource.cpp
+++ b/src/backends/file/FileSyncSource.cpp
@@ -43,6 +43,8 @@
#include <sstream>
#include <fstream>
+#include <boost/bind.hpp>
+
#include <syncevo/SyncContext.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
@@ -50,8 +52,19 @@ SE_BEGIN_CXX
FileSyncSource::FileSyncSource(const SyncSourceParams &params,
const string &dataformat) :
TrackingSyncSource(params),
+ m_raw(true),
m_entryCounter(0)
{
+ if (m_raw) {
+ // replace default operations from TrackingSyncSource/SyncSourceSerialize
+ m_operations.m_readItemAsKey = 0;
+ m_operations.m_insertItemAsKey = 0;
+ m_operations.m_updateItemAsKey = 0;
+ m_operations.m_readItem = boost::bind(&FileSyncSource::readItemDirect, this, _1, _2);
+ m_operations.m_insertItem = boost::bind(&FileSyncSource::insertItemDirect, this, _1, _2);
+ m_operations.m_updateItem = boost::bind(&FileSyncSource::updateItemDirect, this, _1, _2, _3);
+ }
+
if (dataformat.empty()) {
throwError("a data format must be specified");
}
@@ -74,6 +87,29 @@ const char *FileSyncSource::getMimeVersion() const
return m_mimeVersion.c_str();
}
+void FileSyncSource::getSynthesisInfo(SynthesisInfo &info,
+ XMLConfigFragments &fragments)
+{
+ if (m_raw) {
+ // use a new datatype whose name is composed from mime type and version
+ info.m_native = string("file:") + info.m_native + m_mimeType + ":" + m_mimeVersion;
+ info.m_fieldlist = "";
+ info.m_profile = "";
+ info.m_datatypes =
+ string(" <use datatype='") + info.m_native + "' mode='rw' preferred='yes'/>\n";
+ fragments.m_datatypes[info.m_native] =
+ StringPrintf("<datatype name='%s' basetype=\"simple\">\n"
+ " <typestring>%s</typestring>\n"
+ " <versionstring>%s</versionstring>\n"
+ "</datatype>\n",
+ info.m_native.c_str(),
+ m_mimeType.c_str(),
+ m_mimeVersion.c_str());
+ } else {
+ TrackingSyncSource::getSynthesisInfo(info, fragments);
+ }
+}
+
void FileSyncSource::open()
{
const string &database = getDatabaseID();
@@ -261,6 +297,41 @@ string FileSyncSource::createFilename(const string &entry)
return filename;
}
+sysync::TSyError FileSyncSource::readItemDirect(sysync::cItemID aID, char *&data) throw()
+{
+ sysync::TSyError res = sysync::LOCERR_OK;
+ try {
+ string buffer;
+ res = readItem(aID->item, buffer, true);
+ data = strdup(buffer.c_str());
+ } catch (...) {
+ res = handleException();
+ }
+ return res;
+}
+
+sysync::TSyError FileSyncSource::insertItemDirect(const char *data, sysync::ItemID newID) throw()
+{
+ sysync::TSyError res = sysync::LOCERR_OK;
+ try {
+ res = insertItem("", data, true);
+ } catch (...) {
+ res = handleException();
+ }
+ return res;
+}
+
+sysync::TSyError FileSyncSource::updateItemDirect(const char *data, sysync::cItemID aID, sysync::ItemID updID) throw()
+{
+ sysync::TSyError res = sysync::LOCERR_OK;
+ try {
+ res = insertItem(aID->item, data, true);
+ } catch (...) {
+ res = handleException();
+ }
+ return res;
+}
+
SE_END_CXX
#endif /* ENABLE_FILE */
diff --git a/src/backends/file/FileSyncSource.h b/src/backends/file/FileSyncSource.h
index 7bf9f78e..e6c302ac 100644
--- a/src/backends/file/FileSyncSource.h
+++ b/src/backends/file/FileSyncSource.h
@@ -69,6 +69,8 @@ class FileSyncSource : public TrackingSyncSource, private boost::noncopyable
virtual Databases getDatabases();
virtual const char *getMimeType() const;
virtual const char *getMimeVersion() const;
+ virtual void getSynthesisInfo(SynthesisInfo &info,
+ XMLConfigFragments &fragments);
/* implementation of TrackingSyncSource interface */
virtual void listAllItems(RevisionMap_t &revisions);
@@ -78,6 +80,11 @@ class FileSyncSource : public TrackingSyncSource, private boost::noncopyable
private:
/**
+ * if true, then don't use the Synthesis data conversion code
+ */
+ bool m_raw;
+
+ /**
* @name values obtained from the source's type property
*
* Other sync sources only support one hard-coded type and
@@ -104,6 +111,11 @@ class FileSyncSource : public TrackingSyncSource, private boost::noncopyable
* create full filename from basedir and entry name
*/
string createFilename(const string &entry);
+
+ /* implementation of Synthesis Update/Insert/ReadItem variant with direct access to SyncML data */
+ sysync::TSyError readItemDirect(sysync::cItemID aID, char *&data) throw();
+ sysync::TSyError insertItemDirect(const char *data, sysync::ItemID newID) throw();
+ sysync::TSyError updateItemDirect(const char *data, sysync::cItemID aID, sysync::ItemID updID) throw();
};
SE_END_CXX
diff --git a/src/syncevo/SyncSource.h b/src/syncevo/SyncSource.h
index 5d66ee5d..4185fb7c 100644
--- a/src/syncevo/SyncSource.h
+++ b/src/syncevo/SyncSource.h
@@ -940,12 +940,44 @@ class SyncSource : virtual public SyncSourceBase, public SyncSourceConfig, publi
typedef sysync::TSyError (EndDataWrite_t)(bool success, char **newToken);
boost::function<EndDataWrite_t> m_endDataWrite;
+
/** the SynthesisDBPlugin is configured so that this operation
doesn't have to (and cannot) return the item data */
typedef sysync::TSyError (ReadNextItem_t)(sysync::ItemID aID,
sysync::sInt32 *aStatus, bool aFirst);
boost::function<ReadNextItem_t> m_readNextItem;
+
+ typedef sysync::TSyError (DeleteItem_t)(sysync::cItemID aID);
+ boost::function<DeleteItem_t> m_deleteItem;
+
+ /*
+ * A sync source can choose between using either the *AsKey
+ * variant or the plain version, but cannot mix and match.
+ * If m_readItem is set, then the plain versions are used.
+ *
+ * The normal versions exchange data as a C string. Therefore
+ * payload must not contain nul bytes. Strings allocated by
+ * the plugin in m_readItem will be freed with free() by the
+ * caller.
+ *
+ * The MIME type and version is defined via the data type
+ * definition selected by the source.
+ */
+ typedef sysync::TSyError (ReadItem_t)(sysync::cItemID aID, char *&data);
+ boost::function<ReadItem_t> m_readItem;
+
+ typedef sysync::TSyError (InsertItem_t)(const char *data, sysync::ItemID newID);
+ boost::function<InsertItem_t> m_insertItem;
+ typedef sysync::TSyError (UpdateItem_t)(const char *data, sysync::cItemID aID, sysync::ItemID updID);
+ boost::function<UpdateItem_t> m_updateItem;
+
+ /*
+ * The *AsKey versions get an item handle and can read
+ * individual fields. SyncSourceSerialize uses that handle to
+ * generate a specific string again, formatted for the local
+ * data backend.
+ */
typedef sysync::TSyError (ReadItemAsKey_t)(sysync::cItemID aID, sysync::KeyH aItemKey);
boost::function<ReadItemAsKey_t> m_readItemAsKey;
@@ -955,8 +987,6 @@ class SyncSource : virtual public SyncSourceBase, public SyncSourceConfig, publi
typedef sysync::TSyError (UpdateItemAsKey_t)(sysync::KeyH aItemKey, sysync::cItemID aID, sysync::ItemID updID);
boost::function<UpdateItemAsKey_t> m_updateItemAsKey;
- typedef sysync::TSyError (DeleteItem_t)(sysync::cItemID aID);
- boost::function<DeleteItem_t> m_deleteItem;
/**@}*/
diff --git a/src/syncevo/SynthesisDBPlugin.cpp b/src/syncevo/SynthesisDBPlugin.cpp
index 089a6870..d0c30bbd 100644
--- a/src/syncevo/SynthesisDBPlugin.cpp
+++ b/src/syncevo/SynthesisDBPlugin.cpp
@@ -108,11 +108,17 @@ TSyError SyncEvolution_Module_Capabilities( CContext mContext, appCharP *mCapabi
<< DLL_Info << "\n"
<< CA_MinVersion << ":V1.0.6.0\n" /* must not be changed */
<< CA_Manufacturer << ":SyncEvolution\n"
- << CA_Description << ":SyncEvolution Synthesis DB Plugin\n"
- << Plugin_DS_Data_Str << ":no\n"
- << Plugin_DS_Data_Key << ":yes\n"
- << CA_ItemAsKey << ":yes\n"
- << Plugin_DS_Blob <<
+ << CA_Description << ":SyncEvolution Synthesis DB Plugin\n";
+ if (source->getOperations().m_readItem) {
+ s << Plugin_DS_Data_Str << ":yes\n"
+ << Plugin_DS_Data_Key << ":no\n"
+ << CA_ItemAsKey << ":no\n";
+ } else {
+ s << Plugin_DS_Data_Str << ":no\n"
+ << Plugin_DS_Data_Key << ":yes\n"
+ << CA_ItemAsKey << ":yes\n";
+ }
+ s << Plugin_DS_Blob <<
((source && source->getOperations().m_readBlob) ?
":yes\n" :
":no\n");
@@ -121,7 +127,7 @@ TSyError SyncEvolution_Module_Capabilities( CContext mContext, appCharP *mCapabi
s << Plugin_DS_Admin << ":yes\n";
}
- *mCapabilities= StrAlloc(s.str().c_str());
+ *mCapabilities= strdup(s.str().c_str());
SE_LOG_DEBUG(NULL, NULL, "Module_Capabilities:\n%s", *mCapabilities);
return LOCERR_OK;
} /* Module_Capabilities */
@@ -145,7 +151,7 @@ TSyError SyncEvolution_Module_PluginParams( CContext mContext,
extern "C"
void SyncEvolution_Module_DisposeObj( CContext mContext, void* memory )
{
- StrDispose(memory);
+ free(memory);
}
extern "C"
@@ -222,8 +228,8 @@ TSyError SyncEvolution_Session_CheckDevice( CContext sContext,
res = DB_Forbidden;
}
- *sDevKey= StrAlloc(aDeviceID);
- *nonce = StrAlloc(sc->getNonce().c_str());
+ *sDevKey= strdup(aDeviceID);
+ *nonce = strdup(sc->getNonce().c_str());
SE_LOG_DEBUG(NULL, NULL, "Session_CheckDevice dev='%s' nonce='%s' res=%d",
*sDevKey, *nonce, res);
return res;
@@ -317,7 +323,7 @@ TSyError SyncEvolution_Session_Login( CContext sContext, cAppCharP sUsername, ap
// nothing to check, accept peer
res = LOCERR_OK;
} else if (user == sUsername) {
- *sPassword=StrAlloc(password.c_str());
+ *sPassword=strdup(password.c_str());
res = LOCERR_OK;
}
@@ -340,7 +346,7 @@ TSyError SyncEvolution_Session_Logout( CContext sContext )
extern "C"
void SyncEvolution_Session_DisposeObj( CContext sContext, void* memory )
{
- StrDispose ( memory );
+ free(memory);
} /* Session_DisposeObj */
@@ -660,12 +666,14 @@ TSyError SyncEvolution_StartDataRead( CContext aContext, cAppCharP lastToken,
return res;
}
-
-extern "C"
-TSyError SyncEvolution_ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aItemKey,
- sInt32* aStatus, bool aFirst )
+/**
+ * Common implementation of ReadNextItem() and ReadNextItemAsKey(): in both cases
+ * no data is returned.
+ */
+static
+TSyError ReadNextItem( CContext aContext, ItemID aID,
+ sInt32* aStatus, bool aFirst )
{
- /**** CAN BE ADAPTED BY USER ****/
SyncSource *source = DBC( aContext );
if (!source) {
return LOCERR_WRONGUSAGE;
@@ -681,12 +689,47 @@ TSyError SyncEvolution_ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aI
}
}
- SE_LOG_DEBUG(source, NULL, "ReadNextItemAsKey aStatus=%d aID=(%s,%s) res=%d",
+ SE_LOG_DEBUG(source, NULL, "ReadNextItem aStatus=%d aID=(%s,%s) res=%d",
*aStatus, aID->item, aID->parent, res);
return res;
}
extern "C"
+TSyError SyncEvolution_ReadNextItem( CContext aContext, ItemID aID, appCharP *aItemData,
+ sInt32* aStatus, bool aFirst )
+{
+ return ReadNextItem(aContext, aID, aStatus, aFirst);
+}
+
+extern "C"
+TSyError SyncEvolution_ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aItemKey,
+ sInt32* aStatus, bool aFirst )
+{
+ return ReadNextItem(aContext, aID, aStatus, aFirst);
+}
+
+extern "C"
+TSyError SyncEvolution_ReadItem( CContext aContext, cItemID aID, appCharP *aItemData )
+{
+ SyncSource *source = DBC( aContext );
+ if (!source) {
+ return LOCERR_WRONGUSAGE;
+ }
+ TSyError res = LOCERR_OK;
+ if (source->getOperations().m_readItem) {
+ try {
+ res = source->getOperations().m_readItem(aID, *aItemData);
+ } catch (...) {
+ res = source->handleException();
+ }
+ }
+
+ SE_LOG_DEBUG(source, NULL, "ReadItem aID=(%s,%s) res=%d",
+ aID->item, aID->parent, res);
+ return res;
+}
+
+extern "C"
TSyError SyncEvolution_ReadItemAsKey( CContext aContext, cItemID aID, KeyH aItemKey )
{
SyncSource *source = DBC( aContext );
@@ -773,6 +816,27 @@ TSyError SyncEvolution_StartDataWrite( CContext aContext )
}
extern "C"
+TSyError SyncEvolution_InsertItem( CContext aContext, cAppCharP aItemData, ItemID newID )
+{
+ /**** CAN BE ADAPTED BY USER ****/
+ SyncSource *source = DBC( aContext );
+ if (!source) {
+ return LOCERR_WRONGUSAGE;
+ }
+ TSyError res = LOCERR_OK;
+ if (source->getOperations().m_insertItem) {
+ try {
+ res = source->getOperations().m_insertItem(aItemData, newID);
+ } catch (...) {
+ res = source->handleException();
+ }
+ }
+
+ SE_LOG_DEBUG(source, NULL, "InsertItem res=%d\n", res);
+ return res;
+}
+
+extern "C"
TSyError SyncEvolution_InsertItemAsKey( CContext aContext, KeyH aItemKey, ItemID newID )
{
/**** CAN BE ADAPTED BY USER ****/
@@ -795,6 +859,29 @@ TSyError SyncEvolution_InsertItemAsKey( CContext aContext, KeyH aItemKey, ItemID
extern "C"
+TSyError SyncEvolution_UpdateItem( CContext aContext, cAppCharP aItemData, cItemID aID,
+ ItemID updID )
+{
+ SyncSource *source = DBC( aContext );
+ if (!source) {
+ return LOCERR_WRONGUSAGE;
+ }
+ TSyError res = LOCERR_OK;
+ if (source->getOperations().m_updateItem) {
+ try {
+ res = source->getOperations().m_updateItem(aItemData, aID, updID);
+ } catch (...) {
+ res = source->handleException();
+ }
+ }
+
+
+ SE_LOG_DEBUG(source, NULL, "UpdateItem aID=(%s,%s) res=%d",
+ aID->item,aID->parent, res);
+ return res;
+}
+
+extern "C"
TSyError SyncEvolution_UpdateItemAsKey( CContext aContext, KeyH aItemKey, cItemID aID,
ItemID updID )
{