parent
63f4327e8c
commit
a60750ce97
@ -0,0 +1,102 @@ |
||||
// |
||||
// Model+CSV.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 29/11/2023. |
||||
// |
||||
|
||||
import Foundation |
||||
import CoreData |
||||
|
||||
protocol CSVField { |
||||
associatedtype T: CSVRepresentable |
||||
var header: String { get } |
||||
} |
||||
|
||||
protocol CSVRepresentable: NSFetchRequestResult { |
||||
|
||||
associatedtype F: CSVField |
||||
|
||||
func toCSV() -> String |
||||
|
||||
static var fields: [F] { get } |
||||
|
||||
func value(field: F) -> String? |
||||
} |
||||
|
||||
extension CSVRepresentable { |
||||
|
||||
static func toCSV() -> String { |
||||
var csv: String = "" |
||||
|
||||
let context: NSManagedObjectContext = PersistenceController.shared.container.viewContext |
||||
|
||||
let request = NSFetchRequest<Self>(entityName: String(describing: self)) |
||||
|
||||
csv = self.fields.map { "\"\($0.header)\"" }.joined(separator: ",") |
||||
csv.append("\n") |
||||
|
||||
do { |
||||
let entities = try context.fetch(request) |
||||
for entity in entities { |
||||
let entityCSV = entity.toCSV() |
||||
csv.append("\(entityCSV)\n") |
||||
} |
||||
|
||||
|
||||
} catch { |
||||
Logger.error(error) |
||||
} |
||||
|
||||
return csv |
||||
} |
||||
|
||||
func toCSV() -> String { |
||||
let values: [String?] = Self.fields.map { field in |
||||
self.value(field: field) |
||||
} |
||||
return values.map { "\"\($0 ?? "")\"" }.joined(separator: ",") |
||||
} |
||||
|
||||
} |
||||
|
||||
extension Record : CSVRepresentable { |
||||
|
||||
static var fields: [RecordCSVField] { |
||||
return RecordCSVField.allCases |
||||
} |
||||
|
||||
func value(field: RecordCSVField) -> String? { |
||||
switch field { |
||||
case .activity: |
||||
return self.activity?.name |
||||
case .start: |
||||
return self.start?.formattedDateTime |
||||
case .end: |
||||
return self.end?.formattedDateTime |
||||
case .cancelled: |
||||
return self.cancelled.description |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
enum RecordCSVField: CSVField, CaseIterable { |
||||
|
||||
typealias T = Record |
||||
|
||||
case activity |
||||
case start |
||||
case end |
||||
case cancelled |
||||
|
||||
var header: String { |
||||
switch self { |
||||
case .activity: return "Activity" |
||||
case .start: return "Start" |
||||
case .end: return "End" |
||||
case .cancelled: return "Cancelled" |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,62 @@ |
||||
// |
||||
// Patcher.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 29/11/2023. |
||||
// |
||||
|
||||
import Foundation |
||||
import CoreData |
||||
|
||||
enum Patch: String, CaseIterable { |
||||
case interval |
||||
|
||||
var key: String { |
||||
return "patch." + self.rawValue |
||||
} |
||||
} |
||||
|
||||
class Patcher { |
||||
|
||||
static func patch() { |
||||
|
||||
let context = PersistenceController.shared.container.viewContext |
||||
for patch in Patch.allCases { |
||||
|
||||
if true { |
||||
Logger.log("PATCH!!!") |
||||
// if !UserDefaults.standard.bool(forKey: patch.key) { |
||||
|
||||
do { |
||||
switch patch { |
||||
case .interval: |
||||
try self._patchIntervals(context: context) |
||||
} |
||||
|
||||
try context.save() |
||||
UserDefaults.standard.set(true, forKey: patch.key) |
||||
} catch { |
||||
Logger.error(error) |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
static fileprivate func _patchIntervals(context: NSManagedObjectContext) throws { |
||||
|
||||
let countdowns: [Countdown] = try context.fetch(Countdown.fetchRequest()) |
||||
for countdown in countdowns { |
||||
if let ranges = countdown.timeRanges, ranges.count == 0 { |
||||
let range = TimeRange(context: context) |
||||
range.duration = countdown.duration |
||||
range.name = countdown.name |
||||
range.order = 0 |
||||
countdown.addToTimeRanges(range) |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue