// Fetch exchange rates from Frankfurter API (free, ECB rates) // Usage: go run scripts/fetch_rates.go package main import ( "database/sql" "encoding/json" "fmt" "log" "net/http" "time" _ "github.com/mattn/go-sqlite3" ) const frankfurterAPI = "https://api.frankfurter.app/latest?from=USD" type RatesResponse struct { Amount float64 `json:"amount"` Base string `json:"base"` Date string `json:"date"` Rates map[string]float64 `json:"rates"` } func main() { db, err := sql.Open("sqlite3", "corporate.db") if err != nil { log.Fatal(err) } defer db.Close() fmt.Println("Fetching exchange rates from Frankfurter API (ECB rates)...") // Fetch rates from API resp, err := http.Get(frankfurterAPI) if err != nil { log.Fatalf("Failed to fetch rates: %v", err) } defer resp.Body.Close() var ratesData RatesResponse if err := json.NewDecoder(resp.Body).Decode(&ratesData); err != nil { log.Fatalf("Failed to decode response: %v", err) } fmt.Printf("Base: %s, Date: %s\n", ratesData.Base, ratesData.Date) fmt.Printf("Got rates for %d currencies\n", len(ratesData.Rates)) // Update database now := time.Now().Unix() updated := 0 notFound := []string{} for currency, rate := range ratesData.Rates { result, err := db.Exec( "UPDATE currencies SET exchange_rate = ?, rate_fetched_at = ? WHERE code = ?", rate, now, currency, ) if err != nil { log.Printf("Error updating %s: %v", currency, err) continue } rows, _ := result.RowsAffected() if rows > 0 { updated++ } else { notFound = append(notFound, currency) } } // Always set USD to 1.0 db.Exec("UPDATE currencies SET exchange_rate = 1.0, rate_fetched_at = ? WHERE code = 'USD'", now) updated++ fmt.Printf("\nUpdated %d currencies in database\n", updated) if len(notFound) > 0 { fmt.Printf("Rates not in our DB (consider adding): %v\n", notFound) } // Show sample rates fmt.Println("\n--- Sample Rates (1 USD = X units) ---") rows, _ := db.Query(` SELECT code, name, exchange_rate, decimals FROM currencies WHERE exchange_rate IS NOT NULL ORDER BY code LIMIT 15 `) defer rows.Close() for rows.Next() { var code, name string var rate float64 var decimals int rows.Scan(&code, &name, &rate, &decimals) fmt.Printf(" %s (%s): %.4f (%d decimals)\n", code, name, rate, decimals) } }