Skip to content

Commit 8633894

Browse files
committed
updated to fix replication issues with configuration deserization
1 parent 8071b4f commit 8633894

File tree

3 files changed

+100
-89
lines changed

3 files changed

+100
-89
lines changed

CbliteSwiftJsLib/Classes/CollectionManager.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@
88
import Foundation
99
import CouchbaseLiteSwift
1010

11-
enum CollectionError: Error {
11+
public struct CollectionConfigItem: Codable {
12+
let collections: [CollectionDtoWrapper]
13+
let config: ConfigDto
14+
}
15+
16+
public struct CollectionDtoWrapper: Codable {
17+
let collection: CollectionDto
18+
}
19+
20+
public struct CollectionDto: Codable {
21+
let name: String
22+
let scopeName: String
23+
let databaseName: String
24+
}
25+
26+
public struct ConfigDto: Codable {
27+
let channels: [String]
28+
let documentIds: [String]
29+
}
30+
31+
public enum CollectionError: Error {
1232
case unableToFindCollection(collectionName: String, scopeName: String, databaseName: String)
1333
case getCollection(message: String, collectionName: String, scopeName: String, databaseName: String)
1434
case cannotCreateIndex(indexName: String)

CbliteSwiftJsLib/Classes/ReplicatorHelper.swift

Lines changed: 77 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,124 +6,119 @@
66
//
77

88
import Foundation
9+
import JavaScriptCore
910
import CouchbaseLiteSwift
1011

1112
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],
1616
let url = target["url"] as? String,
1717
let replicatorType = data["replicatorType"] as? String,
18-
let continuous = data["continuous"] as? Bool,
19-
let collectionConfig = data["collectionConfig"] as? [String: Any] else {
18+
let continuous = data["continuous"] as? Bool else {
2019
throw ReplicatorError.fatalError(message: "Invalid JSON data")
2120
}
22-
21+
2322
let endpoint = URLEndpoint(url: URL(string: url)!)
2423
var replConfig = ReplicatorConfiguration(target: endpoint)
25-
24+
25+
if let authenticatorData = data["authenticator"], !(authenticatorData is String && authenticatorData as! String == "") {
26+
if let authenticatorConfig = authenticatorData as? [String: Any] {
27+
if let authenticator = ReplicatorHelper.replicatorAuthenticatorFromConfig(authenticatorConfig) {
28+
replConfig.authenticator = authenticator
29+
}
30+
}
31+
32+
}
33+
34+
try ReplicatorHelper.replicatorCollectionConfigFromJson(collectionConfiguration, replicationConfig: &replConfig)
35+
2636
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")
37+
case "PUSH_AND_PULL":
38+
replConfig.replicatorType = .pushAndPull
39+
case "PULL":
40+
replConfig.replicatorType = .pull
41+
case "PUSH":
42+
replConfig.replicatorType = .push
43+
default:
44+
throw ReplicatorError.fatalError(message: "Invalid replicatorType")
3545
}
36-
46+
3747
replConfig.continuous = continuous
38-
39-
if let authenticator = ReplicatorHelper.replicatorAuthenticatorFromConfig(authenticatorData) {
40-
replConfig.authenticator = authenticator
41-
}
4248

43-
//setup collections
44-
let (collections, colConfig) = try ReplicatorHelper.replicatorCollectionConfigFromJson(collectionConfig)
45-
replConfig.addCollections(Array(collections), config: colConfig)
4649

4750
return replConfig
4851
}
49-
50-
private static func replicatorCollectionConfigFromJson(_ data: [String: Any]) throws -> (Set<Collection>, CollectionConfiguration) {
52+
53+
public static func replicatorCollectionConfigFromJson(_ data: [CollectionConfigItem], replicationConfig: inout ReplicatorConfiguration) throws {
5154

5255
//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")
56+
for item in data {
57+
58+
var collections: [Collection] = []
59+
60+
for col in item.collections {
61+
62+
guard let collection = try CollectionManager.shared.getCollection(col.collection.name, scopeName: col.collection.scopeName, databaseName: col.collection.databaseName) else {
63+
throw CollectionError.unableToFindCollection(collectionName: col.collection.name, scopeName: col.collection.scopeName, databaseName: col.collection.databaseName)
64+
}
65+
collections.append(collection)
6866
}
69-
guard let collection = try CollectionManager.shared.getCollection(collectionName, scopeName: scopeName, databaseName: databaseName) else {
70-
throw CollectionError.unableToFindCollection(collectionName: collectionName, scopeName: scopeName, databaseName: databaseName)
67+
68+
//process the config part of the data
69+
var collectionConfig = CollectionConfiguration()
70+
71+
//get the channels and documentIds to filter for the collections
72+
//these are optional
73+
if item.config.channels.count > 0 {
74+
collectionConfig.channels = item.config.channels
7175
}
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
76+
if item.config.documentIds.count > 0 {
77+
collectionConfig.documentIDs = item.config.documentIds
78+
}
79+
replicationConfig.addCollections(collections, config: collectionConfig)
8480
}
85-
return (collections, collectionConfig)
8681
}
87-
82+
8883
private static func replicatorAuthenticatorFromConfig(_ config: [String: Any]?) -> Authenticator? {
8984
guard let type = config?["type"] as? String,
9085
let data = config?["data"] as? [String: Any] else {
9186
return nil
9287
}
93-
88+
9489
switch type {
95-
case "session":
96-
guard let sessionID = data["sessionID"] as? String,
97-
let cookieName = data["cookieName"] as? String else {
90+
case "session":
91+
guard let sessionID = data["sessionID"] as? String,
92+
let cookieName = data["cookieName"] as? String else {
93+
return nil
94+
}
95+
return SessionAuthenticator(sessionID: sessionID, cookieName: cookieName)
96+
97+
case "basic":
98+
guard let username = data["username"] as? String,
99+
let password = data["password"] as? String else {
100+
return nil
101+
}
102+
return BasicAuthenticator(username: username, password: password)
103+
104+
default:
98105
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 {
105-
return nil
106-
}
107-
return BasicAuthenticator(username: username, password: password)
108-
109-
default:
110-
return nil
111106
}
112107
}
113-
108+
114109
public static func generateReplicatorStatusJson(_ status: Replicator.Status) -> [String: Any] {
115110
var errorJson: [String: Any]?
116111
if let error = status.error {
117112
errorJson = [
118113
"message": error.localizedDescription
119114
]
120115
}
121-
116+
122117
let progressJson: [String: Any] = [
123118
"completed": status.progress.completed,
124119
"total": status.progress.total
125120
]
126-
121+
127122
if let errorJson = errorJson {
128123
return [
129124
"activityLevel": status.activity.rawValue,
@@ -137,10 +132,10 @@ public struct ReplicatorHelper {
137132
]
138133
}
139134
}
140-
135+
141136
public static func generateReplicationJson(_ replication: [ReplicatedDocument], isPush: Bool) -> [String: Any] {
142137
var docs = [[String: Any]]()
143-
138+
144139
for document in replication {
145140
var flags = [String]()
146141
if document.flags.contains(.deleted) {
@@ -150,20 +145,20 @@ public struct ReplicatorHelper {
150145
flags.append("ACCESS_REMOVED")
151146
}
152147
var documentDictionary: [String: Any] = ["id": document.id, "flags": flags]
153-
148+
154149
if let error = document.error {
155150
documentDictionary["error"] = [
156151
"message": error.localizedDescription
157152
]
158153
}
159-
154+
160155
docs.append(documentDictionary)
161156
}
162-
157+
163158
return [
164159
"direction": isPush ? "PUSH" : "PULL",
165160
"documents": docs
166161
]
167162
}
168-
163+
169164
}

CbliteSwiftJsLib/Classes/ReplicatorManager.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,12 @@ public class ReplicatorManager {
4040

4141
// MARK: Replicator Functions
4242

43-
public func replicator(_ replicatorConfig: [String: Any]) throws -> String {
44-
do {
43+
public func replicator(_ replicatorConfig: [String: Any], collectionConfiguration: [CollectionConfigItem]) throws -> String {
4544
let id = UUID().uuidString
46-
let config = try ReplicatorHelper.replicatorConfigFromJson(replicatorConfig)
45+
let config = try ReplicatorHelper.replicatorConfigFromJson(replicatorConfig, collectionConfiguration: collectionConfiguration)
4746
let replicator = Replicator(config: config)
4847
replicators[id] = replicator
4948
return id
50-
} catch {
51-
throw ReplicatorError.fatalError(message: error.localizedDescription)
52-
}
5349
}
5450

5551
public func start(_ replicatorId: String) throws {

0 commit comments

Comments
 (0)