// // 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("red") static let columnGreen = Expression("green") static let columnBlue = Expression("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 { 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 { 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) } }