add v2 migration: espTimestamp on measurement, firmwareSessionId on session

This commit is contained in:
jess 2026-04-03 07:01:37 -07:00
parent 80dc8ef561
commit 8297773827
1 changed files with 53 additions and 4 deletions

View File

@ -11,6 +11,7 @@ struct Session: Codable, FetchableRecord, MutablePersistableRecord {
var startedAt: Date var startedAt: Date
var label: String? var label: String?
var notes: String? var notes: String?
var firmwareSessionId: Int64?
mutating func didInsert(_ inserted: InsertionSuccess) { mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID id = inserted.rowID
@ -24,6 +25,7 @@ struct Measurement: Codable, FetchableRecord, MutablePersistableRecord {
var startedAt: Date var startedAt: Date
var config: Data? var config: Data?
var resultSummary: Data? var resultSummary: Data?
var espTimestamp: Int64?
mutating func didInsert(_ inserted: InsertionSuccess) { mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID id = inserted.rowID
@ -89,19 +91,34 @@ final class Storage: @unchecked Sendable {
} }
} }
migrator.registerMigration("v2") { db in
try db.alter(table: "measurement") { t in
t.add(column: "espTimestamp", .integer)
}
try db.alter(table: "session") { t in
t.add(column: "firmwareSessionId", .integer)
}
}
try migrator.migrate(dbQueue) try migrator.migrate(dbQueue)
} }
// MARK: - Sessions // MARK: - Sessions
func createSession(label: String? = nil) throws -> Session { func createSession(label: String? = nil, firmwareSessionId: Int64? = nil) throws -> Session {
try dbQueue.write { db in try dbQueue.write { db in
var s = Session(startedAt: Date(), label: label) var s = Session(startedAt: Date(), label: label, firmwareSessionId: firmwareSessionId)
try s.insert(db) try s.insert(db)
return s return s
} }
} }
func fetchSession(_ id: Int64) -> Session? {
try? dbQueue.read { db in
try Session.fetchOne(db, key: id)
}
}
func fetchSessions() throws -> [Session] { func fetchSessions() throws -> [Session] {
try dbQueue.read { db in try dbQueue.read { db in
try Session.order(Column("startedAt").desc).fetchAll(db) try Session.order(Column("startedAt").desc).fetchAll(db)
@ -123,13 +140,43 @@ final class Storage: @unchecked Sendable {
} }
} }
func updateSessionLabel(_ id: Int64, label: String) throws {
try dbQueue.write { db in
try db.execute(
sql: "UPDATE session SET label = ? WHERE id = ?",
arguments: [label, id]
)
}
}
func sessionByFirmwareId(_ fwId: Int64) -> Session? {
try? dbQueue.read { db in
try Session
.filter(Column("firmwareSessionId") == fwId)
.fetchOne(db)
}
}
// MARK: - Measurements // MARK: - Measurements
func measurementExists(sessionId: Int64, espTimestamp: Int64) -> Bool {
(try? dbQueue.read { db in
try Measurement
.filter(Column("sessionId") == sessionId)
.filter(Column("espTimestamp") == espTimestamp)
.fetchCount(db) > 0
}) ?? false
}
func addMeasurement( func addMeasurement(
sessionId: Int64, sessionId: Int64,
type: MeasurementType, type: MeasurementType,
config: (any Encodable)? = nil config: (any Encodable)? = nil,
espTimestamp: Int64? = nil
) throws -> Measurement { ) throws -> Measurement {
if let ts = espTimestamp, measurementExists(sessionId: sessionId, espTimestamp: ts) {
throw StorageError.duplicate
}
let configData: Data? = if let config { let configData: Data? = if let config {
try JSONEncoder().encode(config) try JSONEncoder().encode(config)
} else { } else {
@ -140,7 +187,8 @@ final class Storage: @unchecked Sendable {
sessionId: sessionId, sessionId: sessionId,
type: type.rawValue, type: type.rawValue,
startedAt: Date(), startedAt: Date(),
config: configData config: configData,
espTimestamp: espTimestamp
) )
try m.insert(db) try m.insert(db)
return m return m
@ -460,6 +508,7 @@ final class Storage: @unchecked Sendable {
enum StorageError: Error { enum StorageError: Error {
case notFound case notFound
case duplicate
case parseError(String) case parseError(String)
} }