diff options
| author | Fuwn <[email protected]> | 2026-01-23 21:11:09 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-23 21:11:09 -0800 |
| commit | 388bccd24b97758c2f815044c2b17eaecde5e00a (patch) | |
| tree | 3532d405a28a93670fb7c4a1b35ffa8f3cf23a59 | |
| parent | feat: Switch to libsql driver for Turso compatibility (diff) | |
| download | kaze-388bccd24b97758c2f815044c2b17eaecde5e00a.tar.xz kaze-388bccd24b97758c2f815044c2b17eaecde5e00a.zip | |
fix: Handle libsql string-based time values
| -rw-r--r-- | internal/storage/sqlite.go | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/internal/storage/sqlite.go b/internal/storage/sqlite.go index 5fcc9b3..2341db4 100644 --- a/internal/storage/sqlite.go +++ b/internal/storage/sqlite.go @@ -11,6 +11,29 @@ import ( _ "github.com/tursodatabase/go-libsql" ) +var timeFormats = []string{ + time.RFC3339Nano, + time.RFC3339, + "2006-01-02 15:04:05.999999999-07:00", + "2006-01-02 15:04:05.999999999", + "2006-01-02 15:04:05", + "2006-01-02T15:04:05.999999999Z07:00", + "2006-01-02T15:04:05Z07:00", + "2006-01-02T15:04:05", +} + +func parseTime(s string) (time.Time, error) { + if s == "" { + return time.Time{}, nil + } + for _, format := range timeFormats { + if t, err := time.Parse(format, s); err == nil { + return t, nil + } + } + return time.Time{}, fmt.Errorf("unable to parse time: %s", s) +} + // Storage handles all database operations type Storage struct { db *sql.DB @@ -352,18 +375,22 @@ func (s *Storage) GetAllMonitorStats(ctx context.Context) (map[string]*MonitorSt for rows.Next() { var ms MonitorStats + var lastCheck, sslExpiry sql.NullString var lastError sql.NullString - var sslExpiry sql.NullTime - err := rows.Scan(&ms.MonitorName, &ms.CurrentStatus, &ms.LastCheck, + err := rows.Scan(&ms.MonitorName, &ms.CurrentStatus, &lastCheck, &ms.LastResponseTime, &lastError, &sslExpiry, &ms.SSLDaysLeft) if err != nil { return nil, fmt.Errorf("failed to scan monitor state: %w", err) } + if lastCheck.Valid { + ms.LastCheck, _ = parseTime(lastCheck.String) + } if lastError.Valid { ms.LastError = lastError.String } if sslExpiry.Valid { - ms.SSLExpiry = &sslExpiry.Time + t, _ := parseTime(sslExpiry.String) + ms.SSLExpiry = &t } stats[ms.MonitorName] = &ms } @@ -417,13 +444,16 @@ func (s *Storage) GetAllMonitorStats(ctx context.Context) (map[string]*MonitorSt for rows.Next() { var name string - var timestamp time.Time + var timestampStr sql.NullString var errorMsg sql.NullString - if err := rows.Scan(&name, ×tamp, &errorMsg); err != nil { + if err := rows.Scan(&name, ×tampStr, &errorMsg); err != nil { return nil, fmt.Errorf("failed to scan last failure: %w", err) } if ms, ok := stats[name]; ok { - ms.LastFailure = ×tamp + if timestampStr.Valid { + t, _ := parseTime(timestampStr.String) + ms.LastFailure = &t + } if errorMsg.Valid { ms.LastFailureError = errorMsg.String } @@ -581,9 +611,13 @@ func (s *Storage) GetRecentPings(ctx context.Context, monitorName string, limit var results []PingResult for rows.Next() { var p PingResult - if err := rows.Scan(&p.Status, &p.ResponseTime, &p.Timestamp); err != nil { + var timestampStr sql.NullString + if err := rows.Scan(&p.Status, &p.ResponseTime, ×tampStr); err != nil { return nil, fmt.Errorf("failed to scan ping: %w", err) } + if timestampStr.Valid { + p.Timestamp, _ = parseTime(timestampStr.String) + } results = append(results, p) } |