@@ -64,11 +64,61 @@ struct ReplicationConflictResolverFactory {
6464 }
6565 }
6666
67+ struct MergeDictResolver : AnyConflictResolver {
68+ let property : String
69+
70+ func resolve( peerID: PeerID ? , conflict: Conflict ) -> Document ? {
71+ if conflict. localDocument == nil || conflict. remoteDocument == nil {
72+ return nil
73+ }
74+
75+ let doc = conflict. remoteDocument!. toMutable ( )
76+
77+ guard let localDict = conflict. localDocument!. dictionary ( forKey: property) else {
78+ return doc. setString ( " Both values are not dictionary " , forKey: property)
79+ }
80+
81+ guard let remoteDict = conflict. remoteDocument!. dictionary ( forKey: property) else {
82+ return doc. setString ( " Both values are not dictionary " , forKey: property)
83+ }
84+
85+ let mergedDict = MutableDictionaryObject ( )
86+
87+ for key in localDict {
88+ mergedDict. setValue ( localDict. value ( forKey: key) , forKey: key)
89+ }
90+
91+ for key in remoteDict {
92+ let remoteValue = remoteDict. value ( forKey: key) !
93+ if let curValue = mergedDict. value ( forKey: key) {
94+ if !isEquals( curValue, remoteValue) {
95+ return doc. setString ( " Conflicting values found at key named ' \( key) ' " , forKey: property)
96+ }
97+ }
98+ mergedDict. setValue ( remoteValue, forKey: key)
99+ }
100+
101+ return doc. setValue ( mergedDict, forKey: property)
102+ }
103+
104+ private func isEquals( _ lhs: Any , _ rhs: Any ) -> Bool {
105+ switch ( lhs, rhs) {
106+ case let ( l as String , r as String ) : return l == r
107+ case let ( l as NSNumber , r as NSNumber ) : return l == r
108+ case let ( l as DictionaryObject , r as DictionaryObject ) : return l == r
109+ case let ( l as ArrayObject , r as ArrayObject ) : return l == r
110+ case let ( l as Blob , r as Blob ) : return l == r
111+ default : return false
112+ }
113+ }
114+ }
115+
67116 private enum ConflictResolverType : String {
68117 case localWins = " local-wins "
69118 case removeWins = " remote-wins "
70119 case delete = " delete "
71120 case merge = " merge "
121+ case mergeDict = " merge-dict "
72122 }
73123
74124 static func getResolver(
@@ -90,6 +140,11 @@ struct ReplicationConflictResolverFactory {
90140 throw TestServerError . badRequest ( " The property parameter is missing for the merge conflict resolver " )
91141 }
92142 return ConflictResolver ( MergeResolver ( property: property) )
143+ case . mergeDict:
144+ guard let property = params ? [ " property " ] ? . value as? String else {
145+ throw TestServerError . badRequest ( " The property parameter is missing for the merge-dict conflict resolver " )
146+ }
147+ return ConflictResolver ( MergeDictResolver ( property: property) )
93148 }
94149 }
95150}
0 commit comments