conversations-classic-ios/ConversationsClassic/AppData/Model/Roster.swift
2024-08-11 23:55:45 +02:00

81 lines
2.2 KiB
Swift

import Foundation
import GRDB
import Martin
struct RosterVersion: DBStorable {
static let databaseTableName = "rosterVersions"
var bareJid: String
var version: String
var id: String { bareJid }
}
struct Roster: DBStorable {
static let databaseTableName = "rosters"
var bareJid: String = ""
var contactBareJid: String
var name: String?
var subscription: String
var ask: Bool
var data: DBRosterData
var locallyDeleted: Bool = false
var id: String { "\(bareJid)-\(contactBareJid)" }
}
struct DBRosterData: Codable, DatabaseValueConvertible {
let groups: [String]
let annotations: [RosterItemAnnotation]
public var databaseValue: DatabaseValue {
let encoder = JSONEncoder()
// swiftlint:disable:next force_try
let data = try! encoder.encode(self)
return data.databaseValue
}
public static func fromDatabaseValue(_ dbValue: DatabaseValue) -> Self? {
guard let data = Data.fromDatabaseValue(dbValue) else {
return nil
}
let decoder = JSONDecoder()
// swiftlint:disable:next force_try
return try! decoder.decode(Self.self, from: data)
}
static func == (lhs: DBRosterData, rhs: DBRosterData) -> Bool {
lhs.groups == rhs.groups && lhs.annotations == rhs.annotations
}
}
extension RosterItemAnnotation: Equatable {
public static func == (lhs: RosterItemAnnotation, rhs: RosterItemAnnotation) -> Bool {
lhs.type == rhs.type && lhs.values == rhs.values
}
}
extension Roster: Equatable {
static func == (lhs: Roster, rhs: Roster) -> Bool {
lhs.bareJid == rhs.bareJid && lhs.contactBareJid == rhs.contactBareJid
}
}
extension Roster {
mutating func setLocallyDeleted(_ value: Bool) async throws {
locallyDeleted = value
let copy = self
try? await Database.shared.dbQueue.write { db in
try copy.save(db)
}
}
}
extension Roster {
static func fetchDeletedLocally() async throws -> [Roster] {
try await Database.shared.dbQueue.read { db in
try Roster.filter(Column("locallyDeleted") == true).fetchAll(db)
}
}
}