// Package sqliteutil holds small helpers shared by the SQLite repositories: // timestamp conversion and dynamic IN-lists. package sqliteutil import ( "database/sql" "strconv" "strings" "time" ) // TimeLayout matches the SQLite column defaults produced by strftime with %f. const TimeLayout = "2006-01-02T15:04:05.000Z" // FormatTime renders a time in the canonical TEXT format used by the schema. func FormatTime(t time.Time) string { return t.UTC().Format(TimeLayout) } // ParseTime parses a canonical timestamp, tolerating the RFC3339 variants the // driver may return. An empty or unparseable value yields the zero time. func ParseTime(s string) time.Time { if s == "" { return time.Time{} } if t, err := time.Parse(TimeLayout, s); err == nil { return t } if t, err := time.Parse(time.RFC3339Nano, s); err == nil { return t } return time.Time{} } // ParseNullTime converts a nullable TEXT timestamp into *time.Time. func ParseNullTime(ns sql.NullString) *time.Time { if !ns.Valid || ns.String == "" { return nil } t := ParseTime(ns.String) return &t } // Placeholders returns an IN-list placeholder group of n items starting at // index start, e.g. Placeholders(3, 2) -> "$3,$4". func Placeholders(start, n int) string { parts := make([]string, n) for i := 0; i < n; i++ { parts[i] = "$" + strconv.Itoa(start+i) } return strings.Join(parts, ",") }