diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2010-05-17 15:49:52 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2010-08-24 15:16:50 +0200 |
commit | c831ee6ef892990a1f9cde5a0fc0032943fdcf3a (patch) | |
tree | ca47ebb22f0d9967fa388202acef66fc98d1238e | |
parent | 74ee93d2fb0b057eed63a9b3b1babbe6fd3a5e51 (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.cpp | 71 | ||||
-rw-r--r-- | src/backends/file/FileSyncSource.h | 12 | ||||
-rw-r--r-- | src/syncevo/SyncSource.h | 34 | ||||
-rw-r--r-- | src/syncevo/SynthesisDBPlugin.cpp | 121 |
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 ¶ms, 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 ) { |