On Jun 22, 2011, at 11:05 , Patrick Ohly wrote:

> On Mi, 2011-06-22 at 09:57 +0200, Lukas Zeller wrote:
>> Hi Patrick,
>> I'm not sure how the "unprocessed" properties should ever be used with
>> this change.
> 
> I agree, they are never exchanged with a peer.
> 
> But they are used locally, which is my main use case right now:
>     1. Parse vCard from EDS, populating XPROPS from X- extensions not
>        mapped to anything else.
>     2. Synchronize with Google (using that as example because its vCard
>        is so woefully incomplete - doesn't even include BDAY, even
>        though the Google web interface does support it): no extensions
>        sent.
>     3. Modify on Google.
>     4. Receive update in next sync: read vCard from EDS, parse it as in
>        step 1, preserve XPROPS (because they are marked "n/a") when
>        applying update, write back with X- extensions.
> 
> That gives me the desirable "no data lost round-trip sync".

Ok I see. However, I don't think the change in 
92d2f367e72eccedb2cd1e103ec7770b6a426ef2 is a good idea. It's basically 
reverting 3529d3cb09 (engine: implemented "unprocessed" wildcard properties to 
allow handling unknown extensions (like X-xxxx properies)), where I added the 
clause to make fields mapped to "unprocessed" properties always available, 
because otherwise they cannot be used at all in sync.

So rather than changing that behaviour in general, I suggest (again) to do it 
by script. To make that possible, I added a new function SETFIELDOPTIONS(). See 
patch suggestion below (as last time - compiled but not functionally tested)

>> There's no way how the "unprocessed" array can become available at all
>> now, even if they are listed in CTCap - there's no match for wildcards
>> in the CTCap scanning (and would not make much sense, IMHO).
> 
> Indeed, tricky. I'm not sure what a solution would look like that works
> in all cases. There's simply no perfect match between "I support X-*"
> and "you support X-FOOBAR".

Exactly.

> For syncing between identical peers (as in
> SyncEvolution<->SyncEvolution, my other use case) I suggest that we
> generate CtCap with a "X-*" entry (yes, with wildcard) and do a strict
> string comparison also for wildcard props when analyzing CtCap.

I guess just implicitly marking the "unprocessed" array field available gives 
the same result, and also has the potential to at least capture extra 
properties from other clients.

> This is something for later. Needs more testing to ensure that we don't
> confuse any of the other peers, for example. At the moment, I have
> show="no" in our config for the "X-*" property.

Makes sense.

Lukas


Here's the suggested patch adding SETFIELDOPTIONS()


>From 25c3e79479542f743b6c64856fb012f63145c55b Mon Sep 17 00:00:00 2001
From: Lukas Zeller <l...@plan44.ch>
Date: Thu, 23 Jun 2011 11:35:56 +0200
Subject: [PATCH] engine: added SETFIELDOPTIONS() function to modify field
 availability.

To implement this, it was required to flag types as local or remote, such that
SETFIELDOPTIONS() can always act on the remote type (the one describing the
capabilities of the peer, not the capabilities of the local types which
are defined by the local config).
---
 sysync/multifielditem.cpp  |   13 +++++++++++++
 sysync/multifielditem.h    |    2 ++
 sysync/remotedatastore.cpp |    4 ++--
 sysync/scriptcontext.cpp   |   36 ++++++++++++++++++++++++++++++++++++
 sysync/syncdatastore.cpp   |    2 +-
 sysync/syncitemtype.cpp    |   20 ++++++++++++--------
 sysync/syncitemtype.h      |    9 +++++++--
 7 files changed, 73 insertions(+), 13 deletions(-)

diff --git a/sysync/multifielditem.cpp b/sysync/multifielditem.cpp
index fcd4348..6c76f5e 100755
--- a/sysync/multifielditem.cpp
+++ b/sysync/multifielditem.cpp
@@ -639,6 +639,19 @@ bool const TMultiFieldItem::isAssigned(const char 
*aFieldName)
 } // TMultiFieldItem::isAssigned
 
 
+TMultiFieldItemType *TMultiFieldItem::getLocalItemType(void)
+{
+  return fItemTypeP && fItemTypeP->isRemoteType() ? fTargetItemTypeP : 
fItemTypeP;
+} // TMultiFieldItem::getLocalItemType
+
+
+TMultiFieldItemType *TMultiFieldItem::getRemoteItemType(void)
+{
+  return fItemTypeP && fItemTypeP->isRemoteType() ? fItemTypeP : 
fTargetItemTypeP;
+} // TMultiFieldItem::getRemoteItemType
+
+
+
 // check if field is assigned (exists and has a value)
 bool const TMultiFieldItem::isAssigned(sInt16 aFieldIndex)
 {
diff --git a/sysync/multifielditem.h b/sysync/multifielditem.h
index 4c7aec5..0582f66 100755
--- a/sysync/multifielditem.h
+++ b/sysync/multifielditem.h
@@ -298,6 +298,8 @@ public:
   // get associated MultiFieldItemType
   TMultiFieldItemType *getItemType(void) { return fItemTypeP; };
   TMultiFieldItemType *getTargetItemType(void) { return fTargetItemTypeP; };
+  TMultiFieldItemType *getLocalItemType(void);
+  TMultiFieldItemType *getRemoteItemType(void);
   // field availability (combined source & target)
   bool isAvailable(sInt16 aFieldIndex);
   bool isAvailable(const char *aFieldName);
diff --git a/sysync/remotedatastore.cpp b/sysync/remotedatastore.cpp
index 72dc8b2..6283e78 100755
--- a/sysync/remotedatastore.cpp
+++ b/sysync/remotedatastore.cpp
@@ -223,11 +223,11 @@ bool TRemoteDataStore::setDatastoreDevInf(
     } // if >=DS1.2
     // - analyze supported rx types
     TSyncDataStore *relDsP = getSession()->getSyncMLVersion()>=syncml_vers_1_2 
? this : NULL;
-    
fRxPrefItemTypeP=TSyncItemType::registerType(fSessionP,aDataStoreDevInfP->rxpref,aLocalItemTypes,aNewItemTypes,relDsP);
+    
fRxPrefItemTypeP=TSyncItemType::registerRemoteType(fSessionP,aDataStoreDevInfP->rxpref,aLocalItemTypes,aNewItemTypes,relDsP);
     fRxItemTypes.push_back(fRxPrefItemTypeP);
     
registerTypes(fRxItemTypes,aDataStoreDevInfP->rx,aLocalItemTypes,aNewItemTypes,relDsP);
     // - analyze supported tx types
-    
fTxPrefItemTypeP=TSyncItemType::registerType(fSessionP,aDataStoreDevInfP->txpref,aLocalItemTypes,aNewItemTypes,relDsP);
+    
fTxPrefItemTypeP=TSyncItemType::registerRemoteType(fSessionP,aDataStoreDevInfP->txpref,aLocalItemTypes,aNewItemTypes,relDsP);
     fTxItemTypes.push_back(fTxPrefItemTypeP);
     
registerTypes(fTxItemTypes,aDataStoreDevInfP->tx,aLocalItemTypes,aNewItemTypes,relDsP);
     // - Datastore Memory
diff --git a/sysync/scriptcontext.cpp b/sysync/scriptcontext.cpp
index cc0f0ea..0d2c4db 100644
--- a/sysync/scriptcontext.cpp
+++ b/sysync/scriptcontext.cpp
@@ -1596,6 +1596,40 @@ public:
   }; // func_IsAvailable
 
 
+  // SETFIELDOPTIONS(variant &fieldvar, bool available [[[, int maxsize=0 ], 
int maxoccur=0 ], int notruncate=FALSE])
+  // set field options (override what might have been set by reading devInf)
+  // - fieldvar must be a field contained in the primary item of the caller, 
else function is NOP
+  static void func_SetFieldOptions(TItemField *&aTermP, TScriptContext 
*aFuncContextP)
+  {
+    if (aFuncContextP->fParentContextP) {
+      // get item to find field in
+      TMultiFieldItem *checkItemP = 
aFuncContextP->fParentContextP->fTargetItemP;
+      // modify options on the "remote" type
+      TMultiFieldItemType *mfitP = checkItemP->getRemoteItemType();
+      // - get index of field by field pointer (passed by reference)
+      sInt16 fid = checkItemP->getIndexOfField(aFuncContextP->getLocalVar(0));
+      if (mfitP && fid!=FID_NOT_SUPPORTED) {
+        // field exists, we can set availability
+        // - get params
+        bool available = aFuncContextP->getLocalVar(1)->getAsBoolean();
+        sInt32 maxsize = FIELD_OPT_MAXSIZE_NONE;
+        if (aFuncContextP->getLocalVar(2)->isAssigned())
+          maxsize = aFuncContextP->getLocalVar(2)->getAsInteger();
+        sInt32 maxoccur = aFuncContextP->getLocalVar(3)->getAsInteger(); // 
returns 0 if not specified
+        bool notruncate = aFuncContextP->getLocalVar(4)->getAsBoolean();
+        // - now set options
+        TFieldOptions *fo = mfitP->getFieldOptions(fid);
+        if (fo) {
+          fo->available=available;
+          fo->maxsize=maxsize;
+          fo->maxoccur=maxoccur;
+          fo->notruncate=notruncate;
+        }
+      }
+    }
+  }; // func_SetFieldOptions
+
+
   // string ITEMDATATYPE()
   // returns the type's internal name (like "vcard21")
   static void func_ItemDataType(TItemField *&aTermP, TScriptContext 
*aFuncContextP)
@@ -2126,6 +2160,7 @@ const uInt8 param_contains[] = { REF(fty_none), 
VAL(fty_none), OPTVAL(fty_intege
 const uInt8 param_append[] = { REF(fty_none), VAL(fty_none) };
 const uInt8 param_swap[] = { REF(fty_none), REF(fty_none) };
 const uInt8 param_isAvailable[] = { REF(fty_none) };
+const uInt8 param_setFieldOptions[] = { REF(fty_none), VAL(fty_integer), 
OPTVAL(fty_integer), OPTVAL(fty_integer), OPTVAL(fty_integer) };
 const uInt8 param_typename[] = { VAL(fty_none) };
 const uInt8 param_SetSessionVar[] = { VAL(fty_string), VAL(fty_none) };
 const uInt8 param_SetDebugOptions[] = { VAL(fty_string), VAL(fty_integer) };
@@ -2158,6 +2193,7 @@ const TBuiltInFuncDef BuiltInFuncDefs[] = {
   { "NUMFORMAT", TBuiltinStdFuncs::func_NumFormat, fty_string, 4, 
param_NumFormat },
   { "NORMALIZED", TBuiltinStdFuncs::func_Normalized, fty_string, 1, 
param_Normalized },
   { "ISAVAILABLE", TBuiltinStdFuncs::func_IsAvailable, fty_integer, 1, 
param_isAvailable },
+  { "SETFIELDOPTIONS", TBuiltinStdFuncs::func_SetFieldOptions, fty_none, 5, 
param_setFieldOptions },
   { "ITEMDATATYPE", TBuiltinStdFuncs::func_ItemDataType, fty_string, 0, NULL },
   { "ITEMTYPENAME", TBuiltinStdFuncs::func_ItemTypeName, fty_string, 0, NULL },
   { "ITEMTYPEVERS", TBuiltinStdFuncs::func_ItemTypeVers, fty_string, 0, NULL },
diff --git a/sysync/syncdatastore.cpp b/sysync/syncdatastore.cpp
index f44a796..1f9dbc2 100755
--- a/sysync/syncdatastore.cpp
+++ b/sysync/syncdatastore.cpp
@@ -325,7 +325,7 @@ void TSyncDataStore::registerTypes(
     if (aXmitTypeListP->data) {
       // register
       TSyncItemType *itemtypeP =
-        
TSyncItemType::registerType(fSessionP,aXmitTypeListP->data,aLocalItemTypes,aNewItemTypes,aRelatedDatastoreP);
+        
TSyncItemType::registerRemoteType(fSessionP,aXmitTypeListP->data,aLocalItemTypes,aNewItemTypes,aRelatedDatastoreP);
       // add to list
       aSupportedXmitTypes.push_back(itemtypeP);
     }
diff --git a/sysync/syncitemtype.cpp b/sysync/syncitemtype.cpp
index 75cfb56..14e1fbc 100755
--- a/sysync/syncitemtype.cpp
+++ b/sysync/syncitemtype.cpp
@@ -51,6 +51,8 @@ void TSyncItemType::init(
   if (aVerCT) fTypeVers=aVerCT;
   // set relation to a specific datastore (if any)
   fRelatedDatastoreP=aRelatedDatastoreP;
+  // assume local
+  fIsRemoteType = false;
 
   #if defined(ZIPPED_BINDATA_SUPPORT) && defined(SYDEBUG)
   // data compression accounting
@@ -275,7 +277,7 @@ TSyncItemType *TSyncItemType::findTypeInList(
 
 
 // - static function to add new or copied ItemType to passed list
-TSyncItemType *TSyncItemType::registerType(
+TSyncItemType *TSyncItemType::registerRemoteType(
   TSyncSession *aSessionP,
   SmlDevInfXmitPtr_t aXmitTypeP,              // name and version of type
   TSyncItemTypePContainer &aLocalItemTypes,   // list to look up local types 
(for reference)
@@ -284,7 +286,7 @@ TSyncItemType *TSyncItemType::registerType(
 )
 {
   return (
-    registerType(
+    registerRemoteType(
       aSessionP,
       smlPCDataToCharP(aXmitTypeP->cttype),
       smlPCDataToCharP(aXmitTypeP->verct),
@@ -293,12 +295,12 @@ TSyncItemType *TSyncItemType::registerType(
       aRelatedDatastoreP
     )
   );
-} // static TSyncItemType::registerType
+} // static TSyncItemType::registerRemoteType
 
 
 // - static function to add new or copied ItemType to passed list
 //   If type is already in aNewItemTypes, nothing will be added
-TSyncItemType *TSyncItemType::registerType(
+TSyncItemType *TSyncItemType::registerRemoteType(
   TSyncSession *aSessionP,
   const char *aName, const char *aVers,       // name and version of type
   TSyncItemTypePContainer &aLocalItemTypes,   // list to look up local types 
(for reference) - aRelatedDatastoreP does NOT relate to the types here, as 
these are local ones
@@ -346,6 +348,8 @@ TSyncItemType *TSyncItemType::registerType(
       //   (but without handling abilities)
       newitemtypeP = new 
TSyncItemType(aSessionP,NULL,aName,aVers,aRelatedDatastoreP);
     }
+    // this is a remote type!
+    newitemtypeP->defineAsRemoteType();
     // add item to list
     aNewItemTypes.push_back(newitemtypeP);
     POBJDEBUGPRINTFX(aSessionP,DBG_REMOTEINFO+DBG_HOT,(
@@ -365,7 +369,7 @@ TSyncItemType *TSyncItemType::registerType(
     }
   } // if not already in list
   return newitemtypeP;
-} // static TSyncItemType::registerType
+} // static TSyncItemType::registerRemoteType
 
 
 /// @brief static function to analyze CTCap and add entries to passed list
@@ -393,7 +397,7 @@ bool TSyncItemType::analyzeCTCapAndCreateItemTypes(
       #endif
       // valenum shows version supported
       TSyncItemType *newitemtypeP =
-        registerType(
+        registerRemoteType(
           aSessionP,
           name,vers,         // name and version of type
           aLocalItemTypes,   // list to look up local types (for reference)
@@ -425,7 +429,7 @@ bool TSyncItemType::analyzeCTCapAndCreateItemTypes(
               #endif
               // valenum shows version supported
               TSyncItemType *newitemtypeP =
-                registerType(
+                registerRemoteType(
                   aSessionP,
                   name,vers,         // name and version of type
                   aLocalItemTypes,   // list to look up local types (for 
reference)
@@ -452,7 +456,7 @@ bool TSyncItemType::analyzeCTCapAndCreateItemTypes(
       if (aSessionP) { 
PLOGDEBUGBLOCKFMT(aSessionP->getDbgLogger(),("RemoteCTCap", "Registering remote 
Type w/o version from CTCap", "type=%s|version=[none]", name)); }
       #endif
       TSyncItemType *newitemtypeP =
-        registerType(
+        registerRemoteType(
           aSessionP,
           name,NULL,         // name, but no version
           aLocalItemTypes,   // list to look up local types (for reference)
diff --git a/sysync/syncitemtype.h b/sysync/syncitemtype.h
index 6206e41..0a4bfce 100755
--- a/sysync/syncitemtype.h
+++ b/sysync/syncitemtype.h
@@ -83,6 +83,9 @@ public:
   virtual bool isBasedOn(uInt16 aItemTypeID) const { return 
aItemTypeID==ity_syncitem; };
   // differentiation between implemented and just descriptive TSyncTypeItems
   virtual bool isImplemented(void) { return false; }; // base class is 
descriptive only
+  // differentiation between type describing local and remote items
+  bool isRemoteType(void) { return fIsRemoteType; };
+  void defineAsRemoteType(void) { fIsRemoteType = true; };
   // compatibility (=assignment compatibility between items based on these 
types)
   virtual bool isCompatibleWith(TSyncItemType *aReferenceType) { return 
this==aReferenceType; } // compatible if same type
   // get session pointer
@@ -177,14 +180,14 @@ public:
     TSyncItemTypePContainer &aNewItemTypes      // list to add analyzed types 
if not already there
   );
   // - static function to add new or copied ItemType to passed list
-  static TSyncItemType *registerType(
+  static TSyncItemType *registerRemoteType(
     TSyncSession *aSessionP,
     const char *aName, const char *aVers,       // name and version of type
     TSyncItemTypePContainer &aLocalItemTypes,   // list to look up local types 
(for reference)
     TSyncItemTypePContainer &aNewItemTypes,     // list to add analyzed types 
if not already there
     TSyncDataStore *aRelatedDatastoreP
   );
-  static TSyncItemType *registerType(
+  static TSyncItemType *registerRemoteType(
     TSyncSession *aSessionP,
     SmlDevInfXmitPtr_t aXmitTypeP,              // name and version of type
     TSyncItemTypePContainer &aLocalItemTypes,   // list to look up local types 
(for reference)
@@ -252,6 +255,8 @@ private:
   sInt32 fRawDataBytes;
   sInt32 fZippedDataBytes;
   #endif
+  // flag if this is a remote type
+  bool fIsRemoteType;
 }; // TSyncItemType
 
 
-- 
1.7.4.4+GitX
_______________________________________________
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis

Reply via email to