package queries import ( "bssapp-backend/models" "database/sql" "fmt" "github.com/google/uuid" "log" "strings" "time" ) // ============================================================ // πŸ”₯ UNIVERSAL DATETIME PARSER // ============================================================ func parseDateTime(str string) (time.Time, error) { layouts := []string{ "2006-01-02 15:04:05", // "2025-11-21 12:37:21" time.RFC3339, // "2025-11-21T12:37:21Z" "2006-01-02", // "2025-11-21" } for _, layout := range layouts { if t, err := time.Parse(layout, str); err == nil { return t, nil } } return time.Time{}, fmt.Errorf("datetime parse edilemedi: %s", str) } // ============================================================ // πŸ“Œ DATE (YYYY-MM-DD) β†’ sql.NullTime // ============================================================ func nullableDateString(ns models.NullString) sql.NullTime { if ns.Valid && strings.TrimSpace(ns.String) != "" { t, err := time.Parse("2006-01-02", ns.String) if err == nil { return sql.NullTime{Valid: true, Time: t} } } return sql.NullTime{} } // ============================================================ // πŸ“Œ TIME (HH:mm:ss) β†’ sql.NullString // ============================================================ func nullableTimeString(ns models.NullString) sql.NullString { if ns.Valid && strings.TrimSpace(ns.String) != "" { return sql.NullString{String: ns.String, Valid: true} } return sql.NullString{} } // ============================================================ // πŸ“Œ DATETIME (CustomTime β†’ sql.NullTime) // ============================================================ func nullableDateTime(ct models.CustomTime, fallback time.Time) sql.NullTime { if ct.Valid && !ct.Time.IsZero() { return sql.NullTime{Valid: true, Time: ct.Time} } return sql.NullTime{Valid: true, Time: fallback} } // ============================================================ // πŸ“Œ DATETIME (NullTime β†’ sql.NullTime) // ============================================================ func nullableTime(nt models.NullTime, fallback time.Time) sql.NullTime { if nt.Valid && !nt.Time.IsZero() { return sql.NullTime{Valid: true, Time: nt.Time} } return sql.NullTime{Valid: true, Time: fallback} } // ============================================================ // πŸ“Œ DATETIME (NullString β†’ sql.NullTime) // ============================================================ func nullableDateTimeString(ns models.NullString, fallback time.Time) sql.NullTime { if !ns.Valid || strings.TrimSpace(ns.String) == "" { return sql.NullTime{Time: fallback, Valid: true} } t, err := parseDateTime(ns.String) if err != nil { return sql.NullTime{Time: fallback, Valid: true} } return sql.NullTime{Time: t, Valid: true} } // ============================================================ // πŸ“Œ STRING β†’ sql.NullString // ============================================================ func nullableString(val models.NullString, fallback string) sql.NullString { if val.Valid && strings.TrimSpace(val.String) != "" { return sql.NullString{String: val.String, Valid: true} } return sql.NullString{String: fallback, Valid: true} } // ============================================================ // πŸ“Œ GUID (UNIQUEIDENTIFIER) β†’ interface{} // ============================================================ func nullableUUID(v interface{}) interface{} { switch x := v.(type) { // 1️⃣ models.NullUUID β†’ direkt geri dΓΆn case models.NullUUID: if !x.Valid { return nil } return x.UUID // 2️⃣ models.NullString β†’ GUID parse et case models.NullString: if !x.Valid || strings.TrimSpace(x.String) == "" { return nil } id, err := uuid.Parse(x.String) if err != nil { return nil } return id // 3️⃣ string β†’ GUID parse et case string: id, err := uuid.Parse(x) if err != nil { return nil } return id } return nil } // ============================================================ // πŸ“Œ NUMERIC β†’ sql.NullX // ============================================================ func nullableFloat64(val models.NullFloat64, fallback float64) sql.NullFloat64 { if val.Valid { return sql.NullFloat64{Float64: val.Float64, Valid: true} } return sql.NullFloat64{Float64: fallback, Valid: true} } func nullableInt16(val models.NullInt16, fallback int16) sql.NullInt16 { if val.Valid { return sql.NullInt16{Int16: val.Int16, Valid: true} } return sql.NullInt16{Int16: fallback, Valid: true} } func nullableInt32(val models.NullInt32, fallback int32) sql.NullInt32 { if val.Valid { return sql.NullInt32{Int32: val.Int32, Valid: true} } return sql.NullInt32{Int32: fallback, Valid: true} } func nullableInt32ToInt16(val models.NullInt32, fallback int16) sql.NullInt16 { if val.Valid { return sql.NullInt16{Int16: int16(val.Int32), Valid: true} } return sql.NullInt16{Int16: fallback, Valid: true} } // ============================================================ // πŸ“Œ BOOL β†’ sql.NullBool // ============================================================ func nullableBool(val models.NullBool, fallback bool) sql.NullBool { if val.Valid { return sql.NullBool{Bool: val.Bool, Valid: true} } return sql.NullBool{Bool: fallback, Valid: true} } var logger = log.Default()