81 lines
2.2 KiB
Swift
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)
|
|
}
|
|
}
|
|
}
|