Caps-iOS/Caps/Data/Colors.swift
2022-04-28 15:54:13 +02:00

133 lines
3.9 KiB
Swift

//
// Colors.swift
// CapCollector
//
// Created by Christoph on 26.05.20.
// Copyright © 2020 CH. All rights reserved.
//
import UIKit
import SQLite
extension Database {
enum Colors {
static let table = Table("colors")
static let columnRed = Expression<Double>("red")
static let columnGreen = Expression<Double>("green")
static let columnBlue = Expression<Double>("blue")
static var createQuery: String {
table.create(ifNotExists: true) { t in
t.column(Cap.columnId, primaryKey: true)
t.column(columnRed)
t.column(columnGreen)
t.column(columnBlue)
}
}
}
var colors: [Int : UIColor] {
do {
let rows = try db.prepare(Database.Colors.table)
return rows.reduce(into: [:]) { dict, row in
let id = row[Cap.columnId]
let r = CGFloat(row[Database.Colors.columnRed])
let g = CGFloat(row[Database.Colors.columnGreen])
let b = CGFloat(row[Database.Colors.columnBlue])
dict[id] = UIColor(red: r, green: g, blue: b, alpha: 1.0)
}
} catch {
log("Failed to load cap colors: \(error)")
return [:]
}
}
var capsWithColors: Set<Int> {
do {
let rows = try db.prepare(Database.Colors.table.select(Cap.columnId))
return Set(rows.map { $0[Cap.columnId]})
} catch {
log("Failed to load caps with colors: \(error)")
return []
}
}
var capsWithoutColors: Set<Int> {
Set(1...capCount).subtracting(capsWithColors)
}
func removeColor(for cap: Int) -> Bool {
do {
try db.run(Colors.table.filter(Cap.columnId == cap).delete())
return true
} catch {
log("Failed to delete cap color \(cap): \(error)")
return false
}
}
func set(color: UIColor, for cap: Int) -> Bool {
guard let _ = row(for: cap) else {
return insert(color: color, for: cap)
}
return update(color: color, for: cap)
}
private func insert(color: UIColor, for cap: Int) -> Bool {
let (red, green, blue) = color.rgb
let query = Database.Colors.table.insert(
Cap.columnId <- cap,
Database.Colors.columnRed <- red,
Database.Colors.columnGreen <- green,
Database.Colors.columnBlue <- blue)
do {
try db.run(query)
return true
} catch {
log("Failed to insert color for cap \(cap): \(error)")
return false
}
}
private func update(color: UIColor, for cap: Int) -> Bool {
let (red, green, blue) = color.rgb
let query = Database.Colors.table.filter(Cap.columnId == cap).update(
Database.Colors.columnRed <- red,
Database.Colors.columnGreen <- green,
Database.Colors.columnBlue <- blue)
do {
try db.run(query)
return true
} catch {
log("Failed to update color for cap \(cap): \(error)")
return false
}
}
private func row(for cap: Int) -> Row? {
do {
return try db.pluck(Database.Colors.table.filter(Cap.columnId == cap))
} catch {
log("Failed to get color for cap \(cap): \(error)")
return nil
}
}
func color(for cap: Int) -> UIColor? {
guard let row = self.row(for: cap) else {
return nil
}
let r = CGFloat(row[Database.Colors.columnRed])
let g = CGFloat(row[Database.Colors.columnGreen])
let b = CGFloat(row[Database.Colors.columnBlue])
return UIColor(red: r, green: g, blue: b, alpha: 1.0)
}
}