133 lines
3.2 KiB
Swift
133 lines
3.2 KiB
Swift
import CoreData
|
|
import Foundation
|
|
|
|
protocol ServersDatabase {
|
|
var viewContext: NSManagedObjectContext { get }
|
|
|
|
func server(url: URL) -> Server?
|
|
func user(id: String) -> LoggedUser?
|
|
func servers() -> [Server]
|
|
|
|
func remove(_ server: Server)
|
|
|
|
func save()
|
|
|
|
func process(updatedServer: WatchMessage.Server)
|
|
}
|
|
|
|
final class DefaultDatabase: ServersDatabase {
|
|
private let container: NSPersistentContainer
|
|
|
|
var viewContext: NSManagedObjectContext {
|
|
container.viewContext
|
|
}
|
|
|
|
private static let model: NSManagedObjectModel = {
|
|
guard let url = Bundle.main.url(forResource: "Default", withExtension: "momd"),
|
|
let managedObjectModel = NSManagedObjectModel(contentsOf: url) else {
|
|
fatalError("Can't find Core Data Model")
|
|
}
|
|
|
|
return managedObjectModel
|
|
}()
|
|
|
|
init() {
|
|
container = NSPersistentContainer(name: "default", managedObjectModel: Self.model)
|
|
|
|
container.loadPersistentStores { _, error in
|
|
if let error { fatalError("Can't load persistent stores: \(error)") }
|
|
}
|
|
|
|
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
|
}
|
|
|
|
func save() {
|
|
guard container.viewContext.hasChanges else {
|
|
return
|
|
}
|
|
|
|
try? container.viewContext.save()
|
|
}
|
|
|
|
func server(url: URL) -> Server? {
|
|
let request = Server.fetchRequest()
|
|
request.predicate = NSPredicate(format: "url == %@", url.absoluteString.removeTrailingSlash())
|
|
|
|
return try? viewContext.fetch(request).first
|
|
}
|
|
|
|
func user(id: String) -> LoggedUser? {
|
|
let request = LoggedUser.fetchRequest()
|
|
request.predicate = NSPredicate(format: "id == %@", id)
|
|
|
|
return try? viewContext.fetch(request).first
|
|
}
|
|
|
|
func servers() -> [Server] {
|
|
let request = Server.fetchRequest()
|
|
|
|
return (try? viewContext.fetch(request)) ?? []
|
|
}
|
|
|
|
func remove(_ server: Server) {
|
|
viewContext.delete(server)
|
|
|
|
save()
|
|
}
|
|
|
|
func process(updatedServer: WatchMessage.Server) {
|
|
if let server = server(url: updatedServer.url) {
|
|
server.url = updatedServer.url
|
|
server.name = updatedServer.name
|
|
server.iconURL = updatedServer.iconURL
|
|
server.useRealName = updatedServer.useRealName
|
|
server.loggedUser = user(from: updatedServer.loggedUser)
|
|
server.certificate = updatedServer.clientSSL?.certificate
|
|
server.password = updatedServer.clientSSL?.password
|
|
server.version = updatedServer.version
|
|
} else {
|
|
Server(
|
|
context: viewContext,
|
|
iconURL: updatedServer.iconURL,
|
|
name: updatedServer.name,
|
|
url: updatedServer.url,
|
|
useRealName: updatedServer.useRealName,
|
|
loggedUser: user(from: updatedServer.loggedUser),
|
|
certificate: updatedServer.clientSSL?.certificate,
|
|
password: updatedServer.clientSSL?.password,
|
|
version: updatedServer.version
|
|
)
|
|
}
|
|
|
|
save()
|
|
}
|
|
|
|
private func user(from updatedUser: WatchMessage.Server.LoggedUser) -> LoggedUser {
|
|
if let user = user(id: updatedUser.id) {
|
|
user.name = updatedUser.name
|
|
user.username = updatedUser.username
|
|
user.token = updatedUser.token
|
|
|
|
return user
|
|
}
|
|
|
|
return LoggedUser(
|
|
context: viewContext,
|
|
id: updatedUser.id,
|
|
name: updatedUser.name,
|
|
token: updatedUser.token,
|
|
username: updatedUser.username
|
|
)
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func removeTrailingSlash() -> String {
|
|
var url = self
|
|
if (url.last == "/") {
|
|
url.removeLast()
|
|
}
|
|
return url
|
|
}
|
|
}
|