6
6
//
7
7
8
8
import Foundation
9
+ import JavaScriptCore
9
10
import CouchbaseLiteSwift
10
11
11
12
public struct ReplicatorHelper {
12
-
13
- public static func replicatorConfigFromJson( _ data: [ String : Any ] ) throws -> ReplicatorConfiguration {
14
- guard let authenticatorData = data [ " authenticator " ] as? [ String : Any ] ,
15
- let target = data [ " target " ] as? [ String : Any ] ,
13
+
14
+ public static func replicatorConfigFromJson( _ data: [ String : Any ] , collectionConfiguration: [ CollectionConfigItem ] ) throws -> ReplicatorConfiguration {
15
+ guard let target = data [ " target " ] as? [ String : Any ] ,
16
16
let url = target [ " url " ] as? String ,
17
17
let replicatorType = data [ " replicatorType " ] as? String ,
18
18
let continuous = data [ " continuous " ] as? Bool ,
19
- let collectionConfig = data [ " collectionConfig " ] as? [ String : Any ] else {
19
+ let acceptParentDomainCookies = data [ " acceptParentDomainCookies " ] as? Bool ,
20
+ let acceptSelfSignedCerts = data [ " acceptSelfSignedCerts " ] as? Bool ,
21
+ let allowReplicationInBackground = data [ " allowReplicationInBackground " ] as? Bool ,
22
+ let autoPurgeEnabled = data [ " autoPurgeEnabled " ] as? Bool ,
23
+ let heartbeat = data [ " heartbeat " ] as? NSNumber ,
24
+ let maxAttempts = data [ " maxAttempts " ] as? NSNumber ,
25
+ let maxAttemptWaitTime = data [ " maxAttemptWaitTime " ] as? NSNumber
26
+ else {
20
27
throw ReplicatorError . fatalError ( message: " Invalid JSON data " )
21
28
}
22
-
29
+
23
30
let endpoint = URLEndpoint ( url: URL ( string: url) !)
31
+
32
+ //set values from data
24
33
var replConfig = ReplicatorConfiguration ( target: endpoint)
25
-
26
- switch replicatorType {
27
- case " PUSH_AND_PULL " :
28
- replConfig. replicatorType = . pushAndPull
29
- case " PULL " :
30
- replConfig. replicatorType = . pull
31
- case " PUSH " :
32
- replConfig. replicatorType = . push
33
- default :
34
- throw ReplicatorError . fatalError ( message: " Invalid replicatorType " )
35
- }
36
-
34
+ replConfig. acceptParentDomainCookie = acceptSelfSignedCerts
35
+ replConfig. acceptParentDomainCookie = acceptParentDomainCookies
36
+ replConfig. allowReplicatingInBackground = allowReplicationInBackground
37
37
replConfig. continuous = continuous
38
-
39
- if let authenticator = ReplicatorHelper . replicatorAuthenticatorFromConfig ( authenticatorData) {
40
- replConfig. authenticator = authenticator
38
+ replConfig. enableAutoPurge = autoPurgeEnabled
39
+
40
+ replConfig. heartbeat = TimeInterval ( exactly: heartbeat. int64Value) ?? 300
41
+ replConfig. maxAttemptWaitTime = TimeInterval ( exactly: maxAttemptWaitTime. int64Value) ?? 0
42
+ replConfig. maxAttempts = maxAttempts. uintValue
43
+
44
+ //check for headers
45
+ if let headers = data [ " headers " ] as? [ String : String ] {
46
+ replConfig. headers = headers
41
47
}
42
48
43
- //setup collections
44
- let ( collections, colConfig) = try ReplicatorHelper . replicatorCollectionConfigFromJson ( collectionConfig)
45
- replConfig. addCollections ( Array ( collections) , config: colConfig)
49
+ if let authenticatorData = data [ " authenticator " ] , !( authenticatorData is String && authenticatorData as! String == " " ) {
50
+ if let authenticatorConfig = authenticatorData as? [ String : Any ] {
51
+ if let authenticator = ReplicatorHelper . replicatorAuthenticatorFromConfig ( authenticatorConfig) {
52
+ replConfig. authenticator = authenticator
53
+ }
54
+ }
55
+
56
+ }
46
57
58
+ try ReplicatorHelper . replicatorCollectionConfigFromJson ( collectionConfiguration, replicationConfig: & replConfig)
59
+
60
+ switch replicatorType {
61
+ case " PUSH_AND_PULL " :
62
+ replConfig. replicatorType = . pushAndPull
63
+ case " PULL " :
64
+ replConfig. replicatorType = . pull
65
+ case " PUSH " :
66
+ replConfig. replicatorType = . push
67
+ default :
68
+ throw ReplicatorError . fatalError ( message: " Invalid replicatorType " )
69
+ }
47
70
return replConfig
48
71
}
49
-
50
- private static func replicatorCollectionConfigFromJson( _ data: [ String : Any ] ) throws -> ( Set < Collection > , CollectionConfiguration ) {
72
+
73
+ public static func replicatorCollectionConfigFromJson( _ data: [ CollectionConfigItem ] , replicationConfig : inout ReplicatorConfiguration ) throws {
51
74
52
75
//work on the collections sent in as part of the configuration with an array of collectionName, scopeName, and databaseName
53
- guard let collectionData = data [ " collections " ] as? [ [ String : String ] ] else {
54
- throw ReplicatorError . configurationError ( message: " collections doesn't include collections in the proper format " )
55
- }
56
- guard let config = data [ " config " ] as? [ String : Any ] else {
57
- throw ReplicatorError . configurationError ( message: " ReplicationConfig collection config is incorrect format " )
58
- }
59
-
60
- var collections : Set < Collection > = [ ]
61
-
62
- for collectionItem in collectionData {
63
- guard let collectionName = collectionItem [ " collectionName " ] ,
64
- let scopeName = collectionItem [ " scopeName " ] ,
65
- let databaseName = collectionItem [ " databaseName " ] else {
66
- // Handle the case where any required key is missing
67
- throw ReplicatorError . configurationError ( message: " Error: collections missing required key in collection data - collectionName, scopeName, or databaseName " )
76
+ for item in data {
77
+
78
+ var collections : [ Collection ] = [ ]
79
+
80
+ for col in item. collections {
81
+
82
+ guard let collection = try CollectionManager . shared. getCollection ( col. collection. name, scopeName: col. collection. scopeName, databaseName: col. collection. databaseName) else {
83
+ throw CollectionError . unableToFindCollection ( collectionName: col. collection. name, scopeName: col. collection. scopeName, databaseName: col. collection. databaseName)
84
+ }
85
+ collections. append ( collection)
68
86
}
69
- guard let collection = try CollectionManager . shared. getCollection ( collectionName, scopeName: scopeName, databaseName: databaseName) else {
70
- throw CollectionError . unableToFindCollection ( collectionName: collectionName, scopeName: scopeName, databaseName: databaseName)
87
+
88
+ //process the config part of the data
89
+ var collectionConfig = CollectionConfiguration ( )
90
+
91
+ //get the channels and documentIds to filter for the collections
92
+ //these are optional
93
+ if item. config. channels. count > 0 {
94
+ collectionConfig. channels = item. config. channels
71
95
}
72
- collections. insert ( collection)
73
- }
74
- //process the config part of the data
75
- var collectionConfig = CollectionConfiguration ( )
76
-
77
- //get the channels and documentIds to filter for the collections
78
- //these are optional
79
- if let channels = config [ " channels " ] as? [ String ] {
80
- collectionConfig. channels = channels
81
- }
82
- if let documentIds = config [ " documentIds " ] as? [ String ] {
83
- collectionConfig. documentIDs = documentIds
96
+ if item. config. documentIds. count > 0 {
97
+ collectionConfig. documentIDs = item. config. documentIds
98
+ }
99
+ replicationConfig. addCollections ( collections, config: collectionConfig)
84
100
}
85
- return ( collections, collectionConfig)
86
101
}
87
-
102
+
88
103
private static func replicatorAuthenticatorFromConfig( _ config: [ String : Any ] ? ) -> Authenticator ? {
89
104
guard let type = config ? [ " type " ] as? String ,
90
105
let data = config ? [ " data " ] as? [ String : Any ] else {
91
106
return nil
92
107
}
93
-
108
+
94
109
switch type {
95
- case " session " :
96
- guard let sessionID = data [ " sessionID " ] as? String ,
97
- let cookieName = data [ " cookieName " ] as? String else {
98
- return nil
99
- }
100
- return SessionAuthenticator ( sessionID: sessionID, cookieName: cookieName)
101
-
102
- case " basic " :
103
- guard let username = data [ " username " ] as? String ,
104
- let password = data [ " password " ] as? String else {
110
+ case " session " :
111
+ guard let sessionID = data [ " sessionID " ] as? String ,
112
+ let cookieName = data [ " cookieName " ] as? String else {
113
+ return nil
114
+ }
115
+ return SessionAuthenticator ( sessionID: sessionID, cookieName: cookieName)
116
+
117
+ case " basic " :
118
+ guard let username = data [ " username " ] as? String ,
119
+ let password = data [ " password " ] as? String else {
120
+ return nil
121
+ }
122
+ return BasicAuthenticator ( username: username, password: password)
123
+
124
+ default :
105
125
return nil
106
- }
107
- return BasicAuthenticator ( username: username, password: password)
108
-
109
- default :
110
- return nil
111
126
}
112
127
}
113
-
128
+
114
129
public static func generateReplicatorStatusJson( _ status: Replicator . Status ) -> [ String : Any ] {
115
130
var errorJson : [ String : Any ] ?
116
131
if let error = status. error {
117
132
errorJson = [
118
133
" message " : error. localizedDescription
119
134
]
120
135
}
121
-
136
+
122
137
let progressJson : [ String : Any ] = [
123
138
" completed " : status. progress. completed,
124
139
" total " : status. progress. total
125
140
]
126
-
141
+
127
142
if let errorJson = errorJson {
128
143
return [
129
144
" activityLevel " : status. activity. rawValue,
@@ -137,10 +152,10 @@ public struct ReplicatorHelper {
137
152
]
138
153
}
139
154
}
140
-
155
+
141
156
public static func generateReplicationJson( _ replication: [ ReplicatedDocument ] , isPush: Bool ) -> [ String : Any ] {
142
157
var docs = [ [ String: Any] ] ( )
143
-
158
+
144
159
for document in replication {
145
160
var flags = [ String] ( )
146
161
if document. flags. contains ( . deleted) {
@@ -149,21 +164,21 @@ public struct ReplicatorHelper {
149
164
if document. flags. contains ( . accessRemoved) {
150
165
flags. append ( " ACCESS_REMOVED " )
151
166
}
152
- var documentDictionary : [ String : Any ] = [ " id " : document. id, " flags " : flags]
153
-
167
+ var documentDictionary : [ String : Any ] = [ " id " : document. id, " flags " : flags, " scopeName " : document . scope , " collectionName " : document . collection ]
168
+
154
169
if let error = document. error {
155
170
documentDictionary [ " error " ] = [
156
171
" message " : error. localizedDescription
157
172
]
158
173
}
159
-
174
+
160
175
docs. append ( documentDictionary)
161
176
}
162
-
177
+
163
178
return [
164
- " direction " : isPush ? " PUSH " : " PULL " ,
179
+ " isPush " : isPush ? true : false ,
165
180
" documents " : docs
166
181
]
167
182
}
168
-
183
+
169
184
}
0 commit comments