diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS.xcodeproj/project.pbxproj b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS.xcodeproj/project.pbxproj index 0f2d4dfa..c855b46c 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS.xcodeproj/project.pbxproj +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS.xcodeproj/project.pbxproj @@ -881,6 +881,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSTests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -906,6 +907,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSTests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -930,6 +932,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -954,6 +957,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1079,6 +1083,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSTests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1103,6 +1108,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1214,6 +1220,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSTests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1238,6 +1245,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "CBLTestServer-iOSUITests/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DataSourceRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DataSourceRequestHandler.swift index f300c3aa..4526709f 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DataSourceRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DataSourceRequestHandler.swift @@ -20,7 +20,8 @@ public class DataSourceRequestHandler { //////////////// case "datasource_database": let database: Database = args.get(name: "database")! - return DataSource.database(database) + let defaultCol = try database.defaultCollection() + return DataSource.collection(defaultCol) default: throw RequestHandlerError.MethodNotFound(method) diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DatabaseRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DatabaseRequestHandler.swift index e066f807..91a1056b 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DatabaseRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DatabaseRequestHandler.swift @@ -45,23 +45,25 @@ public class DatabaseRequestHandler { case "database_delete": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let document: Document = (args.get(name:"document"))! do { - try database.deleteDocument(document) + try defaultCol.delete(document: document) } catch { return error } case "database_deleteBulkDocs": let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() let doc_ids: Array = args.get(name: "doc_ids")! try database.inBatch { for id in doc_ids { - let document: Document = database.document(withID: id)! + let document: Document = try defaultCol.document(id: id)! do { - try! database.deleteDocument(document) + try! defaultCol.delete(document: document) } } } @@ -78,9 +80,10 @@ public class DatabaseRequestHandler { case "database_deleteIndex": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let name: String = (args.get(name: "name"))! - try database.deleteIndex(forName: name) + try defaultCol.deleteIndex(forName: name) case "database_getName": let database: Database = args.get(name:"database")! @@ -89,16 +92,19 @@ public class DatabaseRequestHandler { case "database_getDocument": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let id: String? = args.get(name: "id") - return try database.document(withID: id!) + return try defaultCol.document(id: id!) case "database_save": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let document: MutableDocument = args.get(name:"document")! - try database.saveDocument(document) + try defaultCol.save(document: document) case "database_saveWithConcurrency": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let document: MutableDocument = args.get(name:"document")! let concurrencyControlType : String? = args.get(name:"concurrencyControlType")! var concurrencyType = ConcurrencyControl.lastWriteWins @@ -110,10 +116,12 @@ public class DatabaseRequestHandler { concurrencyType = .lastWriteWins } } - try! database.saveDocument(document, concurrencyControl: concurrencyType) + + return try defaultCol.save(document: document, concurrencyControl: concurrencyType) case "database_deleteWithConcurrency": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let document: Document = (args.get(name:"document"))! let concurrencyControlType : String? = args.get(name:"concurrencyControlType")! var concurrencyType = ConcurrencyControl.lastWriteWins @@ -125,26 +133,24 @@ public class DatabaseRequestHandler { concurrencyType = .lastWriteWins } } - do { - try database.deleteDocument(document, concurrencyControl: concurrencyType) - } catch { - return error - } + return try defaultCol.delete(document: document, concurrencyControl: concurrencyType) - case "database_purge": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let document: MutableDocument = args.get(name:"document")! - try! database.purgeDocument(document) + try! defaultCol.purge(document: document) case "database_contains": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let id: String = (args.get(name: "id"))! - return try database.document(withID: id) != nil + return try defaultCol.document(id: id) != nil case "database_getCount": let database: Database = (args.get(name:"database"))! - return try database.count + let defaultCol = try database.defaultCollection() + return defaultCol.count case "database_compact": let database: Database = (args.get(name:"database"))! @@ -152,14 +158,15 @@ public class DatabaseRequestHandler { case "database_addChangeListener": let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() var token: ListenerToken? = nil let docId: String? = (args.get(name:"docId")) if (docId != nil) { let changeListener = MyDocumentChangeListener() - token = try database.addDocumentChangeListener(withID: docId!, listener: changeListener.listener) + token = defaultCol.addDocumentChangeListener(id: docId!, listener: changeListener.listener) } else { let changeListener = MyDatabaseChangeListener() - token = database.addChangeListener(changeListener.listener) + token = defaultCol.addChangeListener(listener: changeListener.listener) } return token @@ -167,8 +174,7 @@ public class DatabaseRequestHandler { case "database_removeChangeListener": let database: Database = (args.get(name:"database"))! let changeListener: ListenerToken = (args.get(name: "changeListener"))! - - database.removeChangeListener(withToken: changeListener) + changeListener.remove() case "database_databaseChangeListenerChangesCount": let changeListener: MyDatabaseChangeListener = (args.get(name: "changeListener"))! @@ -186,7 +192,7 @@ public class DatabaseRequestHandler { return changeListener.getChanges() case "database_databaseChangeGetDocumentId": - let change: DatabaseChange = (args.get(name: "change"))! + let change: CollectionChange = (args.get(name: "change"))! return change.documentIDs @@ -201,6 +207,7 @@ public class DatabaseRequestHandler { case "database_saveDocuments": let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() let documents: Dictionary> = args.get(name: "documents")! try database.inBatch { for doc in documents { @@ -212,13 +219,14 @@ public class DatabaseRequestHandler { } let new_data: Dictionary = setDataBlob(data) let document = MutableDocument(id: id, data: new_data) - try! database.saveDocument(document) + try! defaultCol.save(document: document) } } case "database_updateDocuments": let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() let documents: Dictionary> = args.get(name: "documents")! try database.inBatch { for doc in documents { @@ -228,32 +236,33 @@ public class DatabaseRequestHandler { data["id"] = id data.removeValue(forKey: "_id") } - let updated_doc = database.document(withID: id)!.toMutable() + let updated_doc = try! defaultCol.document(id: id)!.toMutable() let new_data: Dictionary = setDataBlob(data) updated_doc.setData(new_data) - try database.saveDocument(updated_doc) + try defaultCol.save(document: updated_doc) } } case "database_updateDocument": - let database: Database = (args.get(name:"database"))! + let defaultCol = try database.defaultCollection() let data: Dictionary = args.get(name: "data")! let docId: String = args.get(name: "id")! - let updated_doc = database.document(withID: docId)!.toMutable() + let updated_doc = try! defaultCol.document(id: docId)!.toMutable() let new_data: Dictionary = setDataBlob(data) updated_doc.setData(new_data) - try! database.saveDocument(updated_doc) + try! defaultCol.save(document: updated_doc) case "database_getDocIds": let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() let limit: Int = args.get(name:"limit")! let offset: Int = args.get(name:"offset")! let query = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .limit(Expression.int(limit), offset:Expression.int(offset)) var result: [String] = [] @@ -267,11 +276,12 @@ public class DatabaseRequestHandler { case "database_getDocuments": let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() let ids: [String] = args.get(name:"ids")! var documents = [String: [String: Any]]() for id in ids { - let document: Document? = database.document(withID: id) + let document: Document? = try! defaultCol.document(id: id) if document != nil{ var dict = document!.toDictionary() for (key, value) in dict { @@ -320,9 +330,10 @@ public class DatabaseRequestHandler { case "database_queryAllDocuments": let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() let searchQuery = QueryBuilder .select(SelectResult.all()) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) return searchQuery default: @@ -361,13 +372,13 @@ private extension DatabaseRequestHandler { } class MyDatabaseChangeListener { - var changes: [DatabaseChange] = [] + var changes: [CollectionChange] = [] - lazy var listener: (DatabaseChange) -> Void = { (change: DatabaseChange) in + lazy var listener: (CollectionChange) -> Void = { (change: CollectionChange) in self.changes.append(change) } - public func getChanges() -> [DatabaseChange] { + public func getChanges() -> [CollectionChange] { return changes } } diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DocumentRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DocumentRequestHandler.swift index eae1df8a..1db1fa00 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DocumentRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/DocumentRequestHandler.swift @@ -201,9 +201,10 @@ public class DocumentRequestHandler { case "document_delete": let database: Database = (args.get(name:"database"))! + let defaultCol = try! database.defaultCollection() let document: MutableDocument = args.get(name:"document")! - try! database.deleteDocument(document) + try! defaultCol.delete(document: document) case "document_getId": let document: Document = args.get(name: "document")! diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FileLoggingRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FileLoggingRequestHandler.swift index 85107ada..79080f3e 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FileLoggingRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FileLoggingRequestHandler.swift @@ -15,79 +15,65 @@ public class FileLoggingRequestHandler { fileprivate var _pushPullReplListener:NSObjectProtocol? public func handleRequest(method: String, args: Args) throws -> Any? { + let max_rotate_count: Int = args.get(name: "max_rotate_count")! + let max_file_size: UInt64 = UInt64(truncating: args.get(name: "max_size")!) + + let log_level: String = args.get(name: "log_level")! + let level = parseLogLevel(log_level) + + let plain_text: Bool = args.get(name: "plain_text")! + var directory: String = args.get(name: "directory")! + if (directory.isEmpty) { + let cacheDir = try FileManager.default.url(for: .cachesDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: false) + directory = cacheDir.appendingPathComponent("logs_\(Date().timeIntervalSince1970)").path + print("File logging configured at : " + directory) + } switch method { ///////////////// // CBL Logging // ///////////////// case "logging_configure": - let max_rotate_count: Int = args.get(name: "max_rotate_count")! - let max_size_temp: NSNumber = args.get(name: "max_size")! - let max_size: UInt64 = UInt64(truncating: max_size_temp) - let log_level: String = args.get(name: "log_level")! - let plain_text: Bool = args.get(name: "plain_text")! - var directory: String = args.get(name: "directory")! - if (directory.isEmpty) { - let cacheDir = try FileManager.default.url(for: .cachesDirectory, - in: .userDomainMask, - appropriateFor: nil, - create: false) - directory = cacheDir.appendingPathComponent("logs_\(Date().timeIntervalSince1970)").path - print("File logging configured at : " + directory) - } - - let config: LogFileConfiguration = LogFileConfiguration.init(directory: directory) - if (max_rotate_count > 1) { - config.maxRotateCount = max_rotate_count - } - if (max_size > 512000) { - config.maxSize = max_size - } - config.usePlainText = plain_text - Database.log.file.config = config - switch log_level { - case "debug": - Database.log.file.level = LogLevel.debug - break - case "verbose": - Database.log.file.level = LogLevel.verbose - break - case "error": - Database.log.file.level = LogLevel.error - break - case "info": - Database.log.file.level = LogLevel.info - break - case "warning": - Database.log.file.level = LogLevel.warning - break - default: - Database.log.file.level = LogLevel.none - } - return config + LogSinks.file = FileLogSink( + level: level, + directory: directory, + usePlainText: plain_text, + maxKeptFiles: max_rotate_count + 1, + maxFileSize: max_file_size + ) + return serializeConfig(LogSinks.file!) case "logging_getPlainTextStatus": - return Database.log.file.config?.usePlainText + guard let fileSink = LogSinks.file else { return nil } + return fileSink.usePlaintext case "logging_getMaxRotateCount": - return Database.log.file.config?.maxRotateCount - + guard let fileSink = LogSinks.file else { return nil } + return fileSink.maxKeptFiles - 1 + case "logging_getMaxSize": - return Database.log.file.config?.maxSize + guard let fileSink = LogSinks.file else { return nil } + return fileSink.maxFileSize case "logging_getDirectory": - return Database.log.file.config?.directory + guard let fileSink = LogSinks.file else { return nil } + return fileSink.directory case "logging_getLogLevel": - return Database.log.file.level.rawValue + guard let fileSink = LogSinks.file else { return nil } + return fileSink.level case "logging_getConfig": - return Database.log.file.config + guard let fileSink = LogSinks.file else { return nil } + return serializeConfig(fileSink) case "logging_getLogsInZip": - guard let path = Database.log.file.config?.directory else { + guard let fileSink = LogSinks.file else { fatalError("failed to get the config directory") } - + let path = fileSink.directory do { let dirURL = URL(fileURLWithPath: path) let zipFilePath = try Zip.quickZipFiles([dirURL], @@ -100,60 +86,98 @@ public class FileLoggingRequestHandler { return nil case "logging_setPlainTextStatus": - let config: LogFileConfiguration = args.get(name: "config")! - let plain_text: Bool = args.get(name: "plain_text")! - config.usePlainText = plain_text - return config + if let sink = LogSinks.file { + LogSinks.file = FileLogSink( + level: sink.level, + directory: sink.directory, + usePlainText: plain_text, + maxKeptFiles: sink.maxKeptFiles, + maxFileSize: sink.maxFileSize + ) + return serializeConfig(LogSinks.file!) + } + return nil case "logging_setMaxRotateCount": - let config: LogFileConfiguration = args.get(name: "config")! - let max_rotate_count: Int = args.get(name: "max_rotate_count")! - config.maxRotateCount = max_rotate_count - return config + if let sink = LogSinks.file { + LogSinks.file = FileLogSink( + level: sink.level, + directory: sink.directory, + usePlainText: sink.usePlaintext, + maxKeptFiles: max_rotate_count + 1, + maxFileSize: sink.maxFileSize + ) + return serializeConfig(LogSinks.file!) + } + return nil case "logging_setMaxSize": - let config: LogFileConfiguration = args.get(name: "config")! - let max_size_temp: NSNumber = args.get(name: "max_size")! - let max_size: UInt64 = UInt64(truncating: max_size_temp) - config.maxSize = max_size - return config + if let sink = LogSinks.file { + LogSinks.file = FileLogSink( + level: sink.level, + directory: sink.directory, + usePlainText: sink.usePlaintext, + maxKeptFiles: sink.maxKeptFiles, + maxFileSize: max_file_size + ) + return serializeConfig(LogSinks.file!) + } + return nil - case "logging_setConfig": - var directory: String = args.get(name: "directory")! - if (directory.isEmpty) { - directory = NSHomeDirectory() + "/logs" + String(Date().timeIntervalSince1970) - print("File logging configured at : " + directory) + case "logging_setDirectory": + if let sink = LogSinks.file { + LogSinks.file = FileLogSink( + level: sink.level, + directory: directory, + usePlainText: sink.usePlaintext, + maxKeptFiles: sink.maxKeptFiles, + maxFileSize: sink.maxFileSize + ) + return serializeConfig(LogSinks.file!) + } else { + LogSinks.file = FileLogSink(level: level, directory: directory) + return serializeConfig(LogSinks.file!) } - let config: LogFileConfiguration = LogFileConfiguration.init(directory: directory) - Database.log.file.config = config - return config case "logging_setLogLevel": - let config: LogFileConfiguration = args.get(name: "config")! - let log_level: String = args.get(name: "log_level")! - switch log_level { - case "debug": - Database.log.file.level = LogLevel.debug - break - case "verbose": - Database.log.file.level = LogLevel.verbose - break - case "error": - Database.log.file.level = LogLevel.error - break - case "info": - Database.log.file.level = LogLevel.info - break - case "warning": - Database.log.file.level = LogLevel.warning - break - default: - Database.log.file.level = LogLevel.none + let level = parseLogLevel(log_level) + if let sink = LogSinks.file { + LogSinks.file = FileLogSink( + level: level, + directory: sink.directory, + usePlainText: sink.usePlaintext, + maxKeptFiles: sink.maxKeptFiles, + maxFileSize: sink.maxFileSize + ) + return serializeConfig(LogSinks.file!) + } else { + LogSinks.file = FileLogSink(level: level, directory: directory) + return serializeConfig(LogSinks.file!) } - return config default: throw RequestHandlerError.MethodNotFound(method) } } + + func parseLogLevel(_ s: String) -> LogLevel { + switch s.lowercased() { + case "debug": return .debug + case "verbose": return .verbose + case "error": return .error + case "info": return .info + case "warning": return .warning + default: return .none + } + } + + func serializeConfig(_ sink: FileLogSink) -> [String: Any] { + return [ + "usePlaintext": sink.usePlaintext, + "maxFileSize": sink.maxFileSize, + "maxKeptFiles": sink.maxKeptFiles, + "level": sink.level.rawValue, + "directory": sink.directory + ] + } } diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FunctionRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FunctionRequestHandler.swift index 18459781..dedcab06 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FunctionRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/FunctionRequestHandler.swift @@ -171,7 +171,7 @@ public class FunctionRequestHandler { case "function_rank": let indexName: String = args.get(name: "expression")! - return FullTextFunction.rank(indexName) + return FullTextFunction.rank(Expression.fullTextIndex(indexName)) default: throw RequestHandlerError.MethodNotFound(method) diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PeerToPeerRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PeerToPeerRequestHandler.swift index 1a135874..3d0243b6 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PeerToPeerRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PeerToPeerRequestHandler.swift @@ -73,7 +73,8 @@ public class PeerToPeerRequestHandler { config = URLEndpointListenerConfiguration(collections: collections!) } else if database != nil { - config = URLEndpointListenerConfiguration.init(database: [database][0]!) + let defaultCol = try database!.defaultCollection() + config = URLEndpointListenerConfiguration.init(collections: [defaultCol]) } else { throw RequestHandlerError.InvalidArgument("Provide collections or database") @@ -103,7 +104,7 @@ public class PeerToPeerRequestHandler { } else if tlsAuthType == "self_signed_create" { try! TLSIdentity.deleteIdentity(withLabel: "CBL-Cert") - let id = try! TLSIdentity.createIdentity(forServer: true , attributes: [certAttrCommonName: "CBL-Server"], expiration: nil, label: "CBL-Cert") + let id = try! TLSIdentity.createIdentity(for: .serverAuth, attributes: [certAttrCommonName: "CBL-Server"], expiration: nil, label: "CBL-Cert") config.tlsIdentity = id print("========== Setting CreateIdentity =========") } @@ -147,6 +148,24 @@ public class PeerToPeerRequestHandler { var wsPort: String? let maxRetries: String? = args.get(name: "max_retries") let maxRetryWaitTime: String? = args.get(name: "max_timeout") + + var finalConfigs: [CollectionConfiguration] = [] + + if let cols = collections { + if let colConfig = collectionConfigurations { + if colConfig.count == 1 { + finalConfigs = cols.map { _ in colConfig[0] } + } else { + assert(colConfig.count == cols.count) + finalConfigs = colConfig + } + } else { + finalConfigs = cols.map { col in CollectionConfiguration(collection: col) } + } + } else { + throw RequestHandlerError.InvalidArgument("No collections provided") + } + if let type = replication_type { if type == "push" { replicatorType = .push @@ -167,11 +186,11 @@ public class PeerToPeerRequestHandler { if endPointType == "URLEndPoint"{ let urlEndPoint: URLEndpoint = URLEndpoint(url: url) print(urlEndPoint) - replicatorConfig = ReplicatorConfiguration(target: urlEndPoint) + replicatorConfig = ReplicatorConfiguration(collections: finalConfigs, target: urlEndPoint) } else{ let endpoint = MessageEndpoint(uid: url.absoluteString, target: url, protocolType: ProtocolType.byteStream, delegate: self) - replicatorConfig = ReplicatorConfiguration(target: endpoint) + replicatorConfig = ReplicatorConfiguration(collections: finalConfigs, target: endpoint) } if auth != nil { @@ -209,22 +228,7 @@ public class PeerToPeerRequestHandler { replicatorConfig.maxAttemptWaitTime = maxRetryWaitTimeDouble } replicatorConfig.replicatorType = replicatorType - if let col = collections { - if let colConfig = collectionConfigurations { - if colConfig.count == 1 { - replicatorConfig.addCollections(col, config: colConfig[0]) - } - else { - assert(colConfig.count == col.count) - for (i, j) in colConfig.enumerated() { - replicatorConfig.addCollection(col[i], config: j) - } - } - } - else { - replicatorConfig.addCollections(col) - } - } + let replicator: Replicator = Replicator(config: replicatorConfig) return replicator @@ -233,6 +237,9 @@ public class PeerToPeerRequestHandler { let port: Int = args.get(name:"port")! let serverDBName: String = args.get(name:"serverDBName")! let database: Database = args.get(name:"database")! + let defaultCol = try database.defaultCollection() + var colConfig = CollectionConfiguration(collection: defaultCol) + let continuous: Bool? = args.get(name:"continuous")! let replication_type: String? = args.get(name: "replicationType")! let documentIDs: [String]? = args.get(name: "documentIDs") @@ -253,6 +260,7 @@ public class PeerToPeerRequestHandler { var wsPort: String? let maxRetries: String? = args.get(name: "max_retries") let maxRetryWaitTime: String? = args.get(name: "max_timeout") + if let type = replication_type { if type == "push" { @@ -269,93 +277,94 @@ public class PeerToPeerRequestHandler { } else { wsPort = "ws" } - - let url = URL(string: "\(wsPort ?? "ws")://\(host):\(port)/\(serverDBName)")! - if endPointType == "URLEndPoint"{ - let urlEndPoint: URLEndpoint = URLEndpoint(url: url) - replicatorConfig = ReplicatorConfiguration(database: database, target: urlEndPoint) - } - else{ - let endpoint = MessageEndpoint(uid: url.absoluteString, target: url, protocolType: ProtocolType.byteStream, delegate: self) - replicatorConfig = ReplicatorConfiguration(database: database, target: endpoint) - } - - if auth != nil { - replicatorConfig.authenticator = auth - } - if serverVerificationMode != false { - replicatorConfig.acceptOnlySelfSignedServerCertificate = true - } - if tlsAuthType == "self_signed" { - let certData = try! dataFromResource(name: "identity/certs", ofType: "p12") - try! TLSIdentity.deleteIdentity(withLabel: "CBL-Cert") - let identity = try! TLSIdentity.importIdentity(withData: certData, password: "123", label: "CBL-Cert") - replicatorConfig.pinnedServerCertificate = identity.certs[0] - print("======= pinned the certs to Replicator ============") - } - if tlsAuthenticator != false { - let clientCertData = try dataFromResource(name: "identity/client", ofType: "p12") - try! TLSIdentity.deleteIdentity(withLabel: "CBL-Cert") - let identity = try TLSIdentity.importIdentity(withData: clientCertData, password: "123", label: "CBL-Cert") - replicatorConfig.authenticator = ClientCertificateAuthenticator(identity: identity) - print("====== Added Autheticator to Replicator ========") - } - - if continuous != nil { - replicatorConfig.continuous = continuous! - } if documentIDs != nil { - replicatorConfig.documentIDs = documentIDs + colConfig.documentIDs = documentIDs } if pull_filter != false { if filter_callback_func == "boolean" { - replicatorConfig.pullFilter = _replicatorBooleanFilterCallback; + colConfig.pullFilter = _replicatorBooleanFilterCallback; } else if filter_callback_func == "deleted" { - replicatorConfig.pullFilter = _replicatorDeletedFilterCallback; + colConfig.pullFilter = _replicatorDeletedFilterCallback; } else if filter_callback_func == "access_revoked" { - replicatorConfig.pullFilter = _replicatorAccessRevokedCallback; + colConfig.pullFilter = _replicatorAccessRevokedCallback; } else { - replicatorConfig.pullFilter = _defaultReplicatorFilterCallback; + colConfig.pullFilter = _defaultReplicatorFilterCallback; } } if push_filter != false { if filter_callback_func == "boolean" { - replicatorConfig.pushFilter = _replicatorBooleanFilterCallback; + colConfig.pushFilter = _replicatorBooleanFilterCallback; } else if filter_callback_func == "deleted" { - replicatorConfig.pushFilter = _replicatorDeletedFilterCallback; + colConfig.pushFilter = _replicatorDeletedFilterCallback; } else if filter_callback_func == "access_revoked" { - replicatorConfig.pushFilter = _replicatorAccessRevokedCallback; + colConfig.pushFilter = _replicatorAccessRevokedCallback; } else { - replicatorConfig.pushFilter = _defaultReplicatorFilterCallback; + colConfig.pushFilter = _defaultReplicatorFilterCallback; } } switch conflict_resolver { case "local_wins": - replicatorConfig.conflictResolver = LocalWinCustomConflictResolver(); + colConfig.conflictResolver = LocalWinCustomConflictResolver(); break case "remote_wins": - replicatorConfig.conflictResolver = RemoteWinCustomConflictResolver(); + colConfig.conflictResolver = RemoteWinCustomConflictResolver(); break; case "null": - replicatorConfig.conflictResolver = NullWinCustomConflictResolver(); + colConfig.conflictResolver = NullWinCustomConflictResolver(); break; case "merge": - replicatorConfig.conflictResolver = MergeWinCustomConflictResolver(); + colConfig.conflictResolver = MergeWinCustomConflictResolver(); break; case "incorrect_doc_id": - replicatorConfig.conflictResolver = IncorrectDocIdCustomConflictResolver(); + colConfig.conflictResolver = IncorrectDocIdCustomConflictResolver(); break; case "delayed_local_win": - replicatorConfig.conflictResolver = DelayedLocalWinCustomConflictResolver(); + colConfig.conflictResolver = DelayedLocalWinCustomConflictResolver(); break; case "exception_thrown": - replicatorConfig.conflictResolver = ExceptionThrownCustomConflictResolver(); + colConfig.conflictResolver = ExceptionThrownCustomConflictResolver(); break; default: - replicatorConfig.conflictResolver = ConflictResolver.default + colConfig.conflictResolver = ConflictResolver.default break; } + + let url = URL(string: "\(wsPort ?? "ws")://\(host):\(port)/\(serverDBName)")! + if endPointType == "URLEndPoint"{ + let urlEndPoint: URLEndpoint = URLEndpoint(url: url) + replicatorConfig = ReplicatorConfiguration(collections: [colConfig], target: urlEndPoint) + } + else{ + let endpoint = MessageEndpoint(uid: url.absoluteString, target: url, protocolType: ProtocolType.byteStream, delegate: self) + replicatorConfig = ReplicatorConfiguration(collections: [colConfig], target: endpoint) + } + + if auth != nil { + replicatorConfig.authenticator = auth + } + if serverVerificationMode != false { + replicatorConfig.acceptOnlySelfSignedServerCertificate = true + } + + if tlsAuthType == "self_signed" { + let certData = try! dataFromResource(name: "identity/certs", ofType: "p12") + try! TLSIdentity.deleteIdentity(withLabel: "CBL-Cert") + let identity = try! TLSIdentity.importIdentity(withData: certData, password: "123", label: "CBL-Cert") + replicatorConfig.pinnedServerCertificate = identity.certs[0] + print("======= pinned the certs to Replicator ============") + } + if tlsAuthenticator != false { + let clientCertData = try dataFromResource(name: "identity/client", ofType: "p12") + try! TLSIdentity.deleteIdentity(withLabel: "CBL-Cert") + let identity = try TLSIdentity.importIdentity(withData: clientCertData, password: "123", label: "CBL-Cert") + replicatorConfig.authenticator = ClientCertificateAuthenticator(identity: identity) + print("====== Added Autheticator to Replicator ========") + } + + if continuous != nil { + replicatorConfig.continuous = continuous! + } if let heartbeat = heartbeat, let heartbeatDouble = Double(heartbeat) { replicatorConfig.heartbeat = heartbeatDouble } @@ -384,7 +393,7 @@ public class PeerToPeerRequestHandler { case "peerToPeer_removeReplicatorEventListener": let replication_obj: Replicator = args.get(name: "replicator")! let changeListener : MyDocumentReplicationListener = (args.get(name: "changeListener"))! - replication_obj.removeChangeListener(withToken: changeListener.listenerToken!) + changeListener.listenerToken!.remove() case "peerToPeer_replicatorEventChangesCount": let changeListener: MyDocumentReplicationListener = (args.get(name: "changeListener"))! @@ -408,7 +417,9 @@ public class PeerToPeerRequestHandler { default: throw RequestHandlerError.MethodNotFound(method) } + return PeerToPeerRequestHandler.VOID + } } #if COUCHBASE_ENTERPRISE diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PredictiveQueriesRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PredictiveQueriesRequestHandler.swift index 10366281..941c526f 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PredictiveQueriesRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/PredictiveQueriesRequestHandler.swift @@ -32,11 +32,12 @@ public class PredictiveQueriesRequestHandler { let model: EchoModel = args.get(name: "model")! let dict: [String: Any] = args.get(name: "dictionary")! let database: Database = args.get(name: "database")! + let defaultCol = try database.defaultCollection() let input = Expression.value(dict) let prediction = Function.prediction(model: model.name, input: input) let queryResult = QueryBuilder .select(SelectResult.expression(prediction)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) var resultArray = [Any]() @@ -50,11 +51,12 @@ public class PredictiveQueriesRequestHandler { let model: EchoModel = args.get(name: "model")! let text: String = args.get(name: "nonDictionary")! let database: Database = args.get(name: "database")! + let defaultCol = try database.defaultCollection() let input = Expression.value(text) let prediction = Function.prediction(model: model.name, input: input) let queryResult = QueryBuilder .select(SelectResult.expression(prediction)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) // return try queryResult.execute() do{ try queryResult.execute(); @@ -69,13 +71,14 @@ public class PredictiveQueriesRequestHandler { case "predictiveQuery_getEuclideanDistance": let database: Database = args.get(name: "database")! + let defaultCol = try database.defaultCollection() let key1: String = args.get(name: "key1")! let key2: String = args.get(name: "key2")! let key3_distance = Function.euclideanDistance(between: Expression.property(key1), and: Expression.property(key2)) let queryResult = QueryBuilder .select(SelectResult.expression(key3_distance)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) var resultArray = [Any]() for row in try queryResult.execute() { @@ -86,13 +89,14 @@ public class PredictiveQueriesRequestHandler { case "predictiveQuery_getSquaredEuclideanDistance": let database: Database = args.get(name: "database")! + let defaultCol = try database.defaultCollection() let key1: String = args.get(name: "key1")! let key2: String = args.get(name: "key2")! let distance = Function.squaredEuclideanDistance(between: Expression.property(key1), and: Expression.property(key2)) let queryResult = QueryBuilder .select(SelectResult.expression(distance)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) var resultArray = [Any]() for row in try queryResult.execute() { @@ -103,13 +107,14 @@ public class PredictiveQueriesRequestHandler { case "predictiveQuery_getCosineDistance": let database: Database = args.get(name: "database")! + let defaultCol = try database.defaultCollection() let key1: String = args.get(name: "key1")! let key2: String = args.get(name: "key2")! let distance = Function.cosineDistance(between: Expression.property(key1), and: Expression.property(key2)) let queryResult = QueryBuilder .select(SelectResult.expression(distance)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) var resultArray = [Any]() for row in try queryResult.execute() { diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/QueryRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/QueryRequestHandler.swift index aed6adc3..0a371903 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/QueryRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/QueryRequestHandler.swift @@ -9,6 +9,8 @@ import Foundation import CouchbaseLiteSwift +typealias Expression = CouchbaseLiteSwift.Expression + public class QueryRequestHandler { public static let VOID: String? = nil @@ -104,11 +106,12 @@ public class QueryRequestHandler { case "query_getDoc": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let doc_id: String = args.get(name: "doc_id")! let searchQuery = QueryBuilder .select(SelectResult.all()) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where((Meta.id).equalTo(Expression.string(doc_id))) var resultArray = [Any]() @@ -121,12 +124,13 @@ public class QueryRequestHandler { case "query_docsLimitOffset": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let limit: Int = args.get(name: "limit")! let offset: Int = args.get(name: "offset")! let searchQuery = QueryBuilder .select(SelectResult.all()) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .limit(Expression.int(limit), offset: Expression.int(offset)) var resultArray = [Any]() @@ -139,6 +143,7 @@ public class QueryRequestHandler { case "query_multipleSelects": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let whr_key: String = args.get(name: "whr_key")! @@ -147,7 +152,7 @@ public class QueryRequestHandler { .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1)), SelectResult.expression(Expression.property(select_property2))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where((Expression.property(whr_key)).equalTo(Expression.string(whr_val))) var resultArray = [Any]() @@ -159,6 +164,7 @@ public class QueryRequestHandler { case "query_multipleSelectsDoubleValue": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let whr_key: String = args.get(name: "whr_key")! @@ -167,7 +173,7 @@ public class QueryRequestHandler { .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1)), SelectResult.expression(Expression.property(select_property2))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where((Expression.property(whr_key)).equalTo(Expression.double(whr_val))) var resultArray = [Any]() @@ -179,6 +185,7 @@ public class QueryRequestHandler { case "query_multipleSelectsOrderByLocaleValue": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let whr_key: String = args.get(name: "whr_key")! @@ -189,7 +196,7 @@ public class QueryRequestHandler { .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1)), SelectResult.expression(Expression.property(select_property2))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .orderBy(Ordering.expression(key.collate(with_locale))) var resultArray = [Any]() @@ -201,6 +208,7 @@ public class QueryRequestHandler { case "query_whereAndOr": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let whr_key1: String = args.get(name: "whr_key1")! let whr_val1: String = args.get(name: "whr_val1")! let whr_key2: String = args.get(name: "whr_key2")! @@ -212,7 +220,7 @@ public class QueryRequestHandler { let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(whr_key1).equalTo(Expression.string(whr_val1)) .and(Expression.property(whr_key2).equalTo(Expression.string(whr_val2)) .or(Expression.property(whr_key3).equalTo(Expression.string(whr_val3)))) @@ -223,15 +231,16 @@ public class QueryRequestHandler { for row in try searchQuery.execute() { resultArray.append(row.toDictionary()) } - + return resultArray case "query_arthimetic": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property("number1").modulo(Expression.int(2)).equalTo(Expression.int(0))) var resultArray = [Any]() @@ -244,6 +253,7 @@ public class QueryRequestHandler { case "query_like": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let whr_key: String = args.get(name: "whr_key")! let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! @@ -255,7 +265,7 @@ public class QueryRequestHandler { .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1)), SelectResult.expression(Expression.property(select_property2))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(whr_key).equalTo(Expression.string(whr_val)) .and(Expression.property(like_key).like(Expression.string(like_val)))) @@ -269,6 +279,7 @@ public class QueryRequestHandler { case "query_regex": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let whr_key: String = args.get(name: "whr_key")! let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! @@ -280,7 +291,7 @@ public class QueryRequestHandler { .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1)), SelectResult.expression(Expression.property(select_property2))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(whr_key).equalTo(Expression.string(whr_val)) .and(Expression.property(regex_key).regex(Expression.string(regex_val)))) @@ -294,14 +305,15 @@ public class QueryRequestHandler { case "query_isNullOrMissing": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let limit: Int = args.get(name: "limit")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1))) - .from(DataSource.database(database)) - .where(Expression.property(select_property1).isNullOrMissing()) + .from(DataSource.collection(defaultCol)) + .where(Expression.property(select_property1).isNotValued()) .orderBy(Ordering.expression(Meta.id).ascending()) .limit(Expression.int(limit)) @@ -315,6 +327,7 @@ public class QueryRequestHandler { case "query_ordering": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let whr_key: String = args.get(name: "whr_key")! let whr_val: String = args.get(name: "whr_val")! @@ -323,7 +336,7 @@ public class QueryRequestHandler { .select( SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(whr_key).equalTo(Expression.string(whr_val))) .orderBy(Ordering.property(select_property1).ascending()) @@ -337,6 +350,7 @@ public class QueryRequestHandler { case "query_substring": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let substring: String = args.get(name: "substring")! @@ -345,7 +359,7 @@ public class QueryRequestHandler { .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1)), SelectResult.expression(Function.upper(Expression.property(select_property2)))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Function.contains(Expression.property(select_property1), substring: Expression.string(substring))) var resultArray = [Any]() @@ -358,6 +372,7 @@ public class QueryRequestHandler { case "query_collation": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let whr_key1: String = args.get(name: "whr_key1")! let whr_val1: String = args.get(name: "whr_val1")! @@ -372,7 +387,7 @@ public class QueryRequestHandler { let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(select_property1))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(whr_key1).equalTo(Expression.string(whr_val1)) .and(Expression.property(whr_key2).equalTo(Expression.string(whr_val2))) .and(Expression.property(select_property1).collate(collator).equalTo(Expression.string(equal_to)))) @@ -387,6 +402,7 @@ public class QueryRequestHandler { case "query_join": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let select_property3: String = args.get(name: "select_property3")! @@ -408,8 +424,8 @@ public class QueryRequestHandler { SelectResult.expression(Expression.property(select_property3).from(main)), SelectResult.expression(Expression.property(select_property4).from(main)), SelectResult.expression(Expression.property(select_property5).from(main))) - .from(DataSource.database(database).as(main)) - .join(Join.join(DataSource.database(database).as(secondary)) + .from(DataSource.collection(defaultCol).as(main)) + .join(Join.join(DataSource.collection(defaultCol).as(secondary)) .on(Meta.id.from(secondary).equalTo(Expression.property(join_key).from(main)))) .where(Expression.property(whr_key1).from(main).equalTo(Expression.string(whr_val1)) .and(Expression.property(whr_key2).from(secondary).equalTo(Expression.string(whr_val2))) @@ -424,6 +440,7 @@ public class QueryRequestHandler { case "query_leftJoin": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop: String = args.get(name: "select_property")! let limit: Int = args.get(name: "limit")! let main: String = "airline" @@ -432,8 +449,8 @@ public class QueryRequestHandler { let searchQuery = QueryBuilder .select(SelectResult.all().from(main), SelectResult.all().from((secondary))) - .from(DataSource.database(database).as(main)) - .join(Join.leftJoin(DataSource.database(database).as(secondary)) + .from(DataSource.collection(defaultCol).as(main)) + .join(Join.leftJoin(DataSource.collection(defaultCol).as(secondary)) .on(Meta.id.from(main).equalTo(Expression.property(prop).from(secondary)))) //.orderBy(Ordering.expression(Expression.property(prop).from(secondary)).ascending()) .limit(Expression.int(limit)) @@ -448,6 +465,7 @@ public class QueryRequestHandler { case "query_leftOuterJoin": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop: String = args.get(name: "select_property")! let limit: Int = args.get(name: "limit")! let main: String = "airline" @@ -456,8 +474,8 @@ public class QueryRequestHandler { let searchQuery = QueryBuilder .select(SelectResult.all().from(main), SelectResult.all().from((secondary))) - .from(DataSource.database(database).as(main)) - .join(Join.leftOuterJoin(DataSource.database(database).as(secondary)) + .from(DataSource.collection(defaultCol).as(main)) + .join(Join.leftOuterJoin(DataSource.collection(defaultCol).as(secondary)) .on(Meta.id.from(main).equalTo(Expression.property(prop).from(secondary)))) //.orderBy(Ordering.expression(Expression.property(prop).from(secondary)).ascending()) .limit(Expression.int(limit)) @@ -483,6 +501,7 @@ public class QueryRequestHandler { AND departmentDS.type = "department" */ let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let select_property3: String = args.get(name: "select_property3")! @@ -500,8 +519,8 @@ public class QueryRequestHandler { .select(SelectResult.expression(Expression.property(select_property1).from(main)), SelectResult.expression(Expression.property(select_property2).from(main)), SelectResult.expression(Expression.property(select_property3).from(secondary))) - .from(DataSource.database(database).as(main)) - .join(Join.innerJoin(DataSource.database(database).as(secondary)) + .from(DataSource.collection(defaultCol).as(main)) + .join(Join.innerJoin(DataSource.collection(defaultCol).as(secondary)) .on(Expression.property(join_key1).from(secondary).equalTo(Expression.property(join_key2).from(main)) .and(Expression.property(whr_key1).from(secondary).equalTo(Expression.string(whr_val1))) .and(Expression.property(whr_key2).from(main).equalTo(Expression.int(whr_val2))))) @@ -527,6 +546,7 @@ public class QueryRequestHandler { departmentDS.type = "department" */ let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let select_property1: String = args.get(name: "select_property1")! let select_property2: String = args.get(name: "select_property2")! let whr_key1: String = args.get(name: "whr_key1")! @@ -543,8 +563,8 @@ public class QueryRequestHandler { .select(SelectResult.expression(Expression.property(select_property1).from(main)).as(first_name), SelectResult.expression(Expression.property(select_property1).from(secondary)).as(second_name), SelectResult.expression(Expression.property(select_property2).from(secondary))) - .from(DataSource.database(database).as(main)) - .join(Join.crossJoin(DataSource.database(database).as(secondary))) + .from(DataSource.collection(defaultCol).as(main)) + .join(Join.crossJoin(DataSource.collection(defaultCol).as(secondary))) .where(Expression.property(whr_key1).from(main).equalTo(Expression.string(whr_val1)) .and(Expression.property(whr_key2).from(secondary).equalTo(Expression.string(whr_val2)))) .limit(Expression.int(limit)) @@ -558,12 +578,13 @@ public class QueryRequestHandler { case "query_equalTo": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val: String = args.get(name: "val")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).equalTo(Expression.string(val))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -576,12 +597,13 @@ public class QueryRequestHandler { case "query_notEqualTo": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val: String = args.get(name: "val")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).notEqualTo(Expression.string(val))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -594,12 +616,13 @@ public class QueryRequestHandler { case "query_greaterThan": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val: Int = args.get(name: "val")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).greaterThan(Expression.int(val))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -612,12 +635,13 @@ public class QueryRequestHandler { case "query_greaterThanOrEqualTo": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val: Int = args.get(name: "val")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).greaterThanOrEqualTo(Expression.int(val))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -630,12 +654,13 @@ public class QueryRequestHandler { case "query_lessThan": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val: Int = args.get(name: "val")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).lessThan(Expression.int(val))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -648,12 +673,13 @@ public class QueryRequestHandler { case "query_lessThanOrEqualTo": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val: Int = args.get(name: "val")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).lessThanOrEqualTo(Expression.int(val))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -666,13 +692,14 @@ public class QueryRequestHandler { case "query_between": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val1: Int = args.get(name: "val1")! let val2: Int = args.get(name: "val2")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).between(Expression.int(val1), and: Expression.int(val2))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -685,13 +712,14 @@ public class QueryRequestHandler { case "query_in": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val1: String = args.get(name: "val1")! let val2: String = args.get(name: "val2")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).in([Expression.string(val1), Expression.string(val2)])) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -704,11 +732,12 @@ public class QueryRequestHandler { case "query_is": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).is(Expression.string(nil))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -721,6 +750,7 @@ public class QueryRequestHandler { case "query_anyOperator": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let schedule: String = args.get(name: "schedule")! let departure: String = args.get(name: "departure")! let departure_prop: String = args.get(name: "departure_prop")! @@ -732,7 +762,7 @@ public class QueryRequestHandler { let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(whr_prop).equalTo(Expression.value(whr_val)) .and(ArrayExpression.any(dep_schedule).in(Expression.property(schedule)) .satisfies(departure_utc.greaterThan(Expression.value(departure_val))))) @@ -747,13 +777,14 @@ public class QueryRequestHandler { case "query_not": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let val1: Int = args.get(name: "val1")! let val2: Int = args.get(name: "val2")! let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.not(Expression.property(prop).between(Expression.int(val1), and: Expression.int(val2)))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -766,12 +797,13 @@ public class QueryRequestHandler { case "query_isNot": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop: String = args.get(name: "prop")! let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(prop))) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) .where(Expression.property(prop).isNot(Expression.string(nil))) .orderBy(Ordering.expression(Meta.id).ascending()) var resultArray = [Any]() @@ -784,27 +816,27 @@ public class QueryRequestHandler { case "query_singlePropertyFTS": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop: String = args.get(name: "prop")! let val: String = args.get(name: "val")! let doc_type: String = args.get(name: "doc_type")! let limit: Int = args.get(name: "limit")! let stemming: Bool = args.get(name: "stemming")! let index: String = "singlePropertyIndex" - let ftsIndex:FullTextIndex + let ftsIndex: FullTextIndex if stemming{ ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(prop)) } else { ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(prop)).language(nil) } - try database.createIndex(ftsIndex, withName: index) - let ftsExpression = FullTextExpression.index(index) + try defaultCol.createIndex(ftsIndex, name: index) let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(prop))) - .from(DataSource.database(database)) - .where(Expression.property("type").equalTo(Expression.string(doc_type)).and(ftsExpression.match(val))) + .from(DataSource.collection(defaultCol)) + .where(Expression.property("type").equalTo(Expression.string(doc_type)).and(FullTextFunction.match(Expression.fullTextIndex(index), query: val))) .limit(Expression.int(limit)) var resultArray = [Any]() @@ -817,6 +849,7 @@ public class QueryRequestHandler { case "query_multiplePropertyFTS": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop1: String = args.get(name: "prop1")! let prop2: String = args.get(name: "prop2")! let val: String = args.get(name: "val")! @@ -831,15 +864,14 @@ public class QueryRequestHandler { } else { ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(prop1), FullTextIndexItem.property(prop2)).language(nil) } - try database.createIndex(ftsIndex, withName: index) - let ftsExpression = FullTextExpression.index(index) + try defaultCol.createIndex(ftsIndex, name: index) let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(prop1)), SelectResult.expression(Expression.property(prop2))) - .from(DataSource.database(database)) - .where(Expression.property("type").equalTo(Expression.string(doc_type)).and(ftsExpression.match(val))) + .from(DataSource.collection(defaultCol)) + .where(Expression.property("type").equalTo(Expression.string(doc_type)).and(FullTextFunction.match(Expression.fullTextIndex(index), query: val))) .limit(Expression.int(limit)) var resultArray = [Any]() @@ -852,6 +884,7 @@ public class QueryRequestHandler { case "query_ftsWithRanking": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let prop: String = args.get(name: "prop")! let val: String = args.get(name: "val")! let doc_type: String = args.get(name: "doc_type")! @@ -859,15 +892,14 @@ public class QueryRequestHandler { let index: String = "singlePropertyIndex" let ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(prop)).language(nil) - try database.createIndex(ftsIndex, withName: index) - let ftsExpression = FullTextExpression.index(index) + try defaultCol.createIndex(ftsIndex, name: index) let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property(prop))) - .from(DataSource.database(database)) - .where(Expression.property("type").equalTo(Expression.string(doc_type)).and(ftsExpression.match(val))) - .orderBy(Ordering.expression(FullTextFunction.rank(index)).descending()) + .from(DataSource.collection(defaultCol)) + .where(Expression.property("type").equalTo(Expression.string(doc_type)).and(FullTextFunction.match(Expression.fullTextIndex(index), query: val))) + .orderBy(Ordering.expression(FullTextFunction.rank(Expression.fullTextIndex(index))).descending()) .limit(Expression.int(limit)) var resultArray = [Any]() @@ -888,17 +920,17 @@ public class QueryRequestHandler { case "query_removeChangeListener": let query_obj: Query = args.get(name: "query")! let changeListener : MyQueryChangeListener = (args.get(name: "changeListener"))! - query_obj.removeChangeListener(withToken: changeListener.listenerToken!) + changeListener.listenerToken!.remove() return query_obj case "query_selectAll": let database: Database = args.get(name: "database")! + let defaultCol: Collection = try database.defaultCollection() let query = QueryBuilder .select(SelectResult.all()) - .from(DataSource.database(database)) + .from(DataSource.collection(defaultCol)) return query - default: throw RequestHandlerError.MethodNotFound(method) } diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorConfigurationRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorConfigurationRequestHandler.swift index c058998b..ce8b3e71 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorConfigurationRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorConfigurationRequestHandler.swift @@ -29,7 +29,8 @@ public class ReplicatorConfigurationRequestHandler { let filter_callback_func: String? = args.get(name: "filter_callback_func") let channels: [String]? = args.get(name: "channels") let documentIDs: [String]? = args.get(name: "documentIDs") - var config = CollectionConfiguration() + let collection: Collection? = args.get(name: "collection") + var config = CollectionConfiguration(collection: collection!) let filter1 = { (doc: Document, flags: DocumentFlags) in return false } config.conflictResolver = conflictResolver if (pull_filter != false) { @@ -59,45 +60,19 @@ public class ReplicatorConfigurationRequestHandler { config.documentIDs = documentIDs return config - case "replicatorConfiguration_addCollection": - var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "replicatorConfiguration")! - let collection: Collection = args.get(name: "collections")! - let collectionConfiguration: CollectionConfiguration? = args.get(name: "configuration") - if(collectionConfiguration != nil) { - replicatorConfiguration.addCollection((collection), config: collectionConfiguration) - } - else { - replicatorConfiguration.addCollection(collection) - } - - case "replicatorConfiguration_addCollections": - var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "replicatorConfiguration")! - let collection: [Collection] = args.get(name: "collections")! - let collectionConfiguration: CollectionConfiguration? = args.get(name: "configuration") - replicatorConfiguration.addCollections((collection), config: collectionConfiguration) - - case "replicatorConfiguration_removeCollection": - let collection: Collection = args.get(name: "collection")! - var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "replicatorConfiguration")! - replicatorConfiguration.removeCollection(collection) - - case "replicatorConfiguration_collectionConfig": - let collection: Collection = args.get(name: "collection")! - let replicatorConfiguration: ReplicatorConfiguration = args.get(name: "replicator")! - return replicatorConfiguration.collectionConfig(collection) - case "replicatorConfiguration_collectionNames": let replicatorConfiguration: ReplicatorConfiguration = args.get(name: "replicator")! let collectionNames = replicatorConfiguration.collections var names = [String]() for collection in collectionNames { - let collectionObject: Collection = collection + let collectionObject: Collection = collection.collection names.append(collectionObject.name) } return names case "replicatorConfiguration_create": let sourceDb: Database = args.get(name: "sourceDb")! + let defaulCol = try sourceDb.defaultCollection() let targetURI: String? = args.get(name: "targetURI")! let targetDb: Database? = args.get(name: "targetDb")! var target: Endpoint? @@ -116,11 +91,11 @@ public class ReplicatorConfigurationRequestHandler { throw RequestHandlerError.InvalidArgument("Target database or URL should be provided.") } - return ReplicatorConfiguration(database: sourceDb, target: target!) - + let colConfig = CollectionConfiguration(collection: defaulCol) + return ReplicatorConfiguration(collections: [colConfig], target: target!) + case "replicatorConfiguration_configureCollection": - Database.log.console.domains = .all - Database.log.console.level = .verbose + LogSinks.console = ConsoleLogSink(level: .verbose, domains: .all) let target_url: String? = args.get(name: "target_url") let replication_type: String? = args.get(name: "replication_type") let continuous: Bool? = args.get(name: "continuous") @@ -164,14 +139,18 @@ public class ReplicatorConfigurationRequestHandler { let targetDatabase: Database? = args.get(name: "target_db") if (targetDatabase != nil) { target = DatabaseEndpoint(database: targetDatabase!) - config = ReplicatorConfiguration(target: target!) + let defaultCol = try targetDatabase!.defaultCollection() + let colConfig = CollectionConfiguration(collection: defaultCol) + config = ReplicatorConfiguration(collections: [colConfig], target: target!) } #endif if (target == nil) { throw RequestHandlerError.InvalidArgument("target url or database should be provided.") } - config = ReplicatorConfiguration(target: target!) + + config = ReplicatorConfiguration(collections: collectionConfigurations!, target: target!) + config.replicatorType = replicatorType config.authenticator = authenticator if continuous != nil { @@ -202,26 +181,11 @@ public class ReplicatorConfigurationRequestHandler { config.enableAutoPurge = auto_purge.lowercased() == "enabled" } - if let col = collections { - if let colConfig = collectionConfigurations { - if colConfig.count == 1 { - config.addCollections(col, config: colConfig[0]) - } - else { - assert(colConfig.count == col.count) - for (i, j) in colConfig.enumerated() { - config.addCollection(col[i], config: j) - } - } - } - else { - config.addCollections(col) - } - } return Replicator(config: config) case "replicatorConfiguration_configure": let source_db: Database? = args.get(name: "source_db") + let defaultCol = try source_db?.defaultCollection() let target_url: String? = args.get(name: "target_url") let replication_type: String? = args.get(name: "replication_type")! let continuous: Bool? = args.get(name: "continuous") @@ -276,87 +240,96 @@ public class ReplicatorConfigurationRequestHandler { let targetDatabase: Database? = args.get(name: "target_db") if (targetDatabase != nil) { target = DatabaseEndpoint(database: targetDatabase!) - config = ReplicatorConfiguration(database: source_db!, target: target!) + let defaultCol = try targetDatabase!.defaultCollection() + let colConfig = CollectionConfiguration(collection: defaultCol) + config = ReplicatorConfiguration(collections: [colConfig], target: target!) } #endif if (target == nil) { throw RequestHandlerError.InvalidArgument("target url or database should be provided.") } - config = ReplicatorConfiguration(database: source_db!, target: target!) - config.replicatorType = replicatorType - if continuous != nil { - config.continuous = continuous! - } else { - config.continuous = false - } - if headers != nil { - config.headers = headers - } - config.authenticator = authenticator + + var colConfig = CollectionConfiguration(collection: defaultCol!) if channels != nil { - config.channels = channels + colConfig.channels = channels } if documentIDs != nil { - config.documentIDs = documentIDs - } - if pinnedservercert != nil { - let path = Bundle(for: type(of:self)).path(forResource: pinnedservercert, ofType: "cer") - let data = try! NSData(contentsOfFile: path!, options: []) - let certificate = SecCertificateCreateWithData(nil, data) - config.pinnedServerCertificate = certificate + colConfig.documentIDs = documentIDs } if pull_filter != false { if filter_callback_func == "boolean" { - config.pullFilter = _replicatorBooleanFilterCallback; + colConfig.pullFilter = _replicatorBooleanFilterCallback; } else if filter_callback_func == "deleted" { - config.pullFilter = _replicatorDeletedFilterCallback; + colConfig.pullFilter = _replicatorDeletedFilterCallback; } else if filter_callback_func == "access_revoked" { - config.pullFilter = _replicatorAccessRevokedCallback; + colConfig.pullFilter = _replicatorAccessRevokedCallback; } else { - config.pullFilter = _defaultReplicatorFilterCallback; + colConfig.pullFilter = _defaultReplicatorFilterCallback; } } if push_filter != false { if filter_callback_func == "boolean" { - config.pushFilter = _replicatorBooleanFilterCallback; + colConfig.pushFilter = _replicatorBooleanFilterCallback; } else if filter_callback_func == "deleted" { - config.pushFilter = _replicatorDeletedFilterCallback; + colConfig.pushFilter = _replicatorDeletedFilterCallback; } else if filter_callback_func == "access_revoked" { - config.pushFilter = _replicatorAccessRevokedCallback; + colConfig.pushFilter = _replicatorAccessRevokedCallback; } else { - config.pushFilter = _defaultReplicatorFilterCallback; + colConfig.pushFilter = _defaultReplicatorFilterCallback; } } switch conflict_resolver { case "local_wins": - config.conflictResolver = LocalWinCustomConflictResolver(); + colConfig.conflictResolver = LocalWinCustomConflictResolver(); break case "remote_wins": - config.conflictResolver = RemoteWinCustomConflictResolver(); + colConfig.conflictResolver = RemoteWinCustomConflictResolver(); break; case "null": - config.conflictResolver = NullWinCustomConflictResolver(); + colConfig.conflictResolver = NullWinCustomConflictResolver(); break; case "merge": - config.conflictResolver = MergeWinCustomConflictResolver(); + colConfig.conflictResolver = MergeWinCustomConflictResolver(); break; case "incorrect_doc_id": - config.conflictResolver = IncorrectDocIdCustomConflictResolver(); + colConfig.conflictResolver = IncorrectDocIdCustomConflictResolver(); break; case "delayed_local_win": - config.conflictResolver = DelayedLocalWinCustomConflictResolver(); + colConfig.conflictResolver = DelayedLocalWinCustomConflictResolver(); break; case "delete_not_win": - config.conflictResolver = DeleteDocCustomConflictResolver(); + colConfig.conflictResolver = DeleteDocCustomConflictResolver(); break case "exception_thrown": - config.conflictResolver = ExceptionThrownCustomConflictResolver(); + colConfig.conflictResolver = ExceptionThrownCustomConflictResolver(); break; default: - config.conflictResolver = ConflictResolver.default + colConfig.conflictResolver = ConflictResolver.default break; } + + config = ReplicatorConfiguration(collections: [colConfig], target: target!) + config.replicatorType = replicatorType + + if continuous != nil { + config.continuous = continuous! + } else { + config.continuous = false + } + if headers != nil { + config.headers = headers + } + + config.authenticator = authenticator + + if pinnedservercert != nil { + let path = Bundle(for: type(of:self)).path(forResource: pinnedservercert, ofType: "cer") + let data = try! NSData(contentsOfFile: path!, options: []) + let certificate = SecCertificateCreateWithData(nil, data) + config.pinnedServerCertificate = certificate + } + if let heartbeat = heartbeat, let heartbeatDouble = Double(heartbeat) { config.heartbeat = heartbeatDouble } @@ -377,16 +350,16 @@ public class ReplicatorConfigurationRequestHandler { return replicatorConfiguration.authenticator case "replicatorConfiguration_getChannels": - let replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! - return replicatorConfiguration.channels + let colConfiguration: CollectionConfiguration = args.get(name: "configuration")! + return colConfiguration.channels case "replicatorConfiguration_getDatabase": - let replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! - return replicatorConfiguration.database + let colConfiguration: CollectionConfiguration = args.get(name: "configuration")! + return colConfiguration.collection.database case "replicatorConfiguration_getDocumentIDs": - let replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! - return replicatorConfiguration.documentIDs + let colConfiguration: CollectionConfiguration = args.get(name: "configuration")! + return colConfiguration.documentIDs case "replicatorConfiguration_getPinnedServerCertificate": let replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! @@ -411,10 +384,10 @@ public class ReplicatorConfigurationRequestHandler { return replicatorConfiguration case "replicatorConfiguration_setChannels": - var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! + var colConfiguration: CollectionConfiguration = args.get(name: "configuration")! let channels: [String] = args.get(name: "channels")! - replicatorConfiguration.channels = channels - return replicatorConfiguration + colConfiguration.channels = channels + return colConfiguration case "replicatorConfiguration_setContinuous": var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! @@ -423,10 +396,10 @@ public class ReplicatorConfigurationRequestHandler { return replicatorConfiguration case "replicatorConfiguration_setDocumentIDs": - var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! + var colConfiguration: CollectionConfiguration = args.get(name: "configuration")! let documentIds: [String] = args.get(name: "documentIds")! - replicatorConfiguration.documentIDs = documentIds - return replicatorConfiguration + colConfiguration.documentIDs = documentIds + return colConfiguration case "replicatorConfiguration_setAutoPurge": var replicatorConfiguration: ReplicatorConfiguration = args.get(name: "configuration")! @@ -460,7 +433,6 @@ public class ReplicatorConfigurationRequestHandler { default: throw RequestHandlerError.MethodNotFound(method) } - return ReplicatorConfigurationRequestHandler.VOID } diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorRequestHandler.swift index 41f1b927..fb881934 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorRequestHandler.swift @@ -67,7 +67,7 @@ public class ReplicatorRequestHandler { case "replicator_removeReplicatorEventListener": let replication_obj: Replicator = args.get(name: "replicator")! let changeListener : MyDocumentReplicationListener = (args.get(name: "changeListener"))! - replication_obj.removeChangeListener(withToken: changeListener.listenerToken!) + changeListener.listenerToken!.remove() case "replicator_replicatorEventChangesCount": let changeListener: MyDocumentReplicationListener = (args.get(name: "changeListener"))! @@ -98,7 +98,7 @@ public class ReplicatorRequestHandler { case "replicator_removeChangeListener": let replication_obj: Replicator = args.get(name: "replicator")! let changeListener : MyReplicationChangeListener = (args.get(name: "changeListener"))! - replication_obj.removeChangeListener(withToken: changeListener.listenerToken!) + changeListener.listenerToken!.remove() case "replicator_changeListenerChangesCount": let changeListener: MyReplicationChangeListener = (args.get(name: "changeListener"))! diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorTcpListener.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorTcpListener.swift index c3104faf..85089db7 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorTcpListener.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/ReplicatorTcpListener.swift @@ -68,7 +68,7 @@ public final class ReplicatorTcpListener: NSObject { public init(databases: [Database], port: UInt32) { for db in databases { let config = MessageEndpointListenerConfiguration( - database: db, protocolType: .byteStream) + collections: [try! db.defaultCollection()], protocolType: .byteStream) listeners[db.name] = MessageEndpointListener(config: config) } self.port = port diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/Server.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/Server.swift index 9b3a48d4..324cdf46 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/Server.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/Server.swift @@ -59,7 +59,7 @@ public class Server { let memory = Memory() public init() { - Database.log.console.level = .debug + LogSinks.console = ConsoleLogSink(level: .debug) dictionaryRequestHandler = DictionaryRequestHandler() queryRequestHandler = QueryRequestHandler() databaseRequestHandler = DatabaseRequestHandler() @@ -89,7 +89,7 @@ public class Server { vectorSearchRequestHandler = VectorSearchRequestHandler() #endif server = GCDWebServer() - Database.log.console.level = LogLevel.verbose + LogSinks.console = ConsoleLogSink(level: .verbose) @Sendable func handlePostRequest (request: GCDWebServerRequest, completion: @escaping GCDWebServerCompletionBlock) async throws { var rawArgs = [String: Any]() @@ -98,7 +98,7 @@ public class Server { if request.path.hasPrefix("/") { let start = request.path.index(request.path.startIndex, offsetBy: 1) - method = request.path.substring(from: start) + method = String(request.path[start...]) } else { method = request.path } @@ -260,4 +260,4 @@ public class Server { #endif server.start(withPort: kPort, bonjourName: nil) } -} \ No newline at end of file +} diff --git a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/VectorSearchRequestHandler.swift b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/VectorSearchRequestHandler.swift index 56096054..bea26d0f 100644 --- a/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/VectorSearchRequestHandler.swift +++ b/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/VectorSearchRequestHandler.swift @@ -177,7 +177,6 @@ public class VectorSearchRequestHandler { } -@available(iOS 16.0, *) public class vectorModel: PredictiveModel { // key is the field name in the doc // to create embeddings on @@ -307,4 +306,4 @@ private extension VectorSearchRequestHandler { } } } -#endif \ No newline at end of file +#endif