summaryrefslogtreecommitdiff
path: root/src/sysync/syncitem.h
blob: 682a4ca58576ef4387c10f7d70634d0104fbbcb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
 *  File:         SyncItem.h
 *
 *  Author:			  Lukas Zeller (luz@synthesis.ch)
 *
 *  TSyncItem
 *    Abstract Base class of all data containing items.
 *    TSyncItems always correspond to a TSyncItemType
 *    which holds type information and conversion
 *    features.
 *
 *  Copyright (c) 2001-2009 by Synthesis AG (www.synthesis.ch)
 *
 *  2001-06-18 : luz : created
 *
 */

#ifndef SyncItem_H
#define SyncItem_H

// includes
#include "syncitemtype.h"


namespace sysync {


// default command size
#define DEFAULTITEMSIZE 50;


// equality relevance / mode
typedef enum {    // RELEVANCE                        COMPARE MODE
  eqm_none,       // not relevant at all (*)          compares ALL fields, even not-relevant ones
  eqm_scripted,   // relevant, handled in script      n/a
  eqm_conflict,   // relevant for conflicts only      compares all somehow relevant fields for conflict comparison
  eqm_slowsync,   // relevant for slow sync           compares only fields relevant for slow sync
  eqm_always,     // always relevant (e.g firsttime)  compares only always-relevant fields (first time slowsync)
  eqm_nocompare,  // n/a                              prevent equality test in compareWith totally
  numEQmodes
} TEqualityMode;
// (*) Note: eqm_none fields will be silently merged in mergeWith(), that is, if no other
//     fields are merged, mergeWith will report "nothing merged" even if eqm_none field might
//     be modified
//     Fields with eqm_none will also not be included in CRC calculations for detecting changes.

extern const char * const compareRelevanceNames[numEQmodes];


// merge options
#define mem_none          -1   // do not merge at all
#define mem_fillempty     -2   // fill empty fields of winning item with loosig item's field contents
#define mem_addunassigned -3   // add fields of loosing item to winning item if it has this field not yet assigned (not just empty)
#define mem_concat         0   // simply concatenate field contents
// NOTE: any positive char constant means intelligent merge using given char as separator

// forward
class TLocalEngineDS;
class TSyncAppBase;

class TSyncItem
{
public:
  TSyncItem(TSyncItemType *aItemType=NULL);
  virtual ~TSyncItem();
  // access to type
  virtual uInt16 getTypeID(void) const { return ity_syncitem; };
  virtual bool isBasedOn(uInt16 aItemTypeID) const { return aItemTypeID==ity_syncitem; };
  // get session pointer
  TSyncSession *getSession(void) { return fSyncItemTypeP ? fSyncItemTypeP->getSession() : NULL; };
  // get session zones pointer
  GZones *getSessionZones(void);
  // assignment (IDs and contents)
  virtual TSyncItem& operator=(TSyncItem &aSyncItem);
  // access to IDs
  // - remote ID
  const char *getRemoteID(void) { return fRemoteID.c_str(); };
  void setRemoteID(const char *aRemoteID) { fRemoteID = aRemoteID; };
  bool hasRemoteID(void) { return !fRemoteID.empty(); };
  void clearRemoteID(void) { fRemoteID.erase(); };
  // - local ID
  const char *getLocalID(void) { return fLocalID.c_str(); };
  void setLocalID(const char *aLocalID) { fLocalID = aLocalID; };
  bool hasLocalID(void) { return !fLocalID.empty(); };
  void clearLocalID(void) { fLocalID.erase(); };
  virtual void updateLocalIDDependencies(void) { /* nop here */ }
  // - changelog support
  #ifdef CHECKSUM_CHANGELOG
  virtual uInt16 getDataCRC(uInt16 crc=0, bool /* aEQRelevantOnly */=false) { return crc; /* always empty */ };
  #endif
  // access to operation
  TSyncOperation getSyncOp(void) { return fSyncOp; };
  void setSyncOp(TSyncOperation aSyncOp) { fSyncOp=aSyncOp; };
  // access to visibility
  // object filtering
  #ifdef OBJECT_FILTERING
  // New style generic filtering
  // - check if item passes filter and probably apply some modifications to it
  virtual bool postFetchFiltering(TLocalEngineDS *aDatastoreP) { return true; } // without filters, just pass everything
  // Old style filter expressions
  // - test if item passes filter
  virtual bool testFilter(const char *aFilterString)
    { return (!aFilterString || *aFilterString==0); }; // without real test, only empty filterstring pass
  // - make item pass filter
  virtual bool makePassFilter(const char *aFilterString)
    { return (!aFilterString || *aFilterString==0); }; // without real implementation, works only with no filter string
  #endif
  // compare abilities
  // - test if comparable at all (correct types)
  virtual bool comparable(TSyncItem & /* aItem */) { return false; };
  // - test if comparison can find out newer (greater) item
  //   NOTE: this should reflect the actually possible sorting state
  //   related to current contents of the item (for example, a vCard
  //   that COULD be sorted if it HAD a REV date may not return true
  //   if the actual item does not have a REV property included.
  virtual bool sortable(TSyncItem & /* aItem */) { return false; };
  // clear item data (means not only empty values, but NO VALUES assigned)
  virtual void cleardata(void) {};
  // replace data contents from specified item (returns false if not possible)
  // - aAvailable only: only replace contents actually available in aItem, leave rest untouched
  // - aDetectCutOffs: handle case where aItem could have somhow cut-off data and prevent replacing
  //   complete data with cut-off version (e.g. mobiles like T39m with limited name string capacity)
  virtual bool replaceDataFrom(TSyncItem & /* aItem */, bool /* aAvailableOnly */=false, bool /* aDetectCutoffs */=false, bool /* aAssignedOnly */=false, bool /* aTransferUnassigned */=false) { return true; }; // no data -> nop
  // check item before processing it
  virtual bool checkItem(TLocalEngineDS * /* aDatastoreP */) { return true; }; // default is: ok
  // merge this item with specified item.
  // Notes:
  // - specified item is treated as loosing item, this item is winning item
  // - also updates other item to make sure it is equal to the winning after the merge
  // sets (but does not reset) change status of this and other item.
  // Note that changes of non-relevant fields are not reported here.
  virtual void mergeWith(TSyncItem & /* aItem */, bool &aChangedThis, bool &aChangedOther, TLocalEngineDS * /* aDatastoreP */) { aChangedThis=false; aChangedOther=false; }; // nop by default
  // remote and local ID
  string fRemoteID; // ID in remote party (if this is a server: LUID, GUID otherwise)
  string fLocalID;  // ID in this party (if this is a server: GUID, LUID otherwise)
  // compare: returns 0 if equal, 1 if this > aItem, -1 if this < aItem
  // SYSYNC_NOT_COMPARABLE if not equal and no ordering known
  virtual sInt16 compareWith(
    TSyncItem & /* aItem */,
    TEqualityMode /* aEqMode */,
    TLocalEngineDS * /* aDatastoreP */
    #ifdef SYDEBUG
    ,bool /* aDebugShow */=false
    #endif
  ) { return SYSYNC_NOT_COMPARABLE; };
  #ifdef SYDEBUG
  // show item contents for debug
  virtual void debugShowItem(uInt32 aDbgMask=DBG_DATA) { /* nop */ };
  // get debug channel
  TDebugLogger *getDbgLogger(void);
  uInt32 getDbgMask(void);
  #endif
  // - get session owner (dispatcher/clientbase)
  TSyncAppBase *getSyncAppBase(void);  
protected:
  // operation to be performed with this item at its destination
  TSyncOperation fSyncOp;
  TSyncItemType *fSyncItemTypeP;
private:
  // cast pointer to same type, returns NULL if incompatible
  TSyncItem *castToSameTypeP(TSyncItem *aItemP) { return aItemP; } // all are compatible TSyncItem
}; // TSyncItem

}	// namespace sysync

#endif	// SyncItem_H

// eof