package storage import ( "database/sql" "encoding/json" "time" "3588AdminBackend/internal/models" ) type DevicesRepo struct { db *sql.DB } func NewDevicesRepo(db *sql.DB) *DevicesRepo { return &DevicesRepo{db: db} } func (r *DevicesRepo) Upsert(dev *models.Device) error { if r == nil || r.db == nil || dev == nil { return nil } graphs, err := json.Marshal(dev.Graphs) if err != nil { return err } if string(graphs) == "null" { graphs = []byte(`{}`) } _, err = r.db.Exec(` INSERT INTO devices(device_id, hostname, ip, agent_port, media_port, alias, device_name, version, git_sha, build_id, last_seen_ms, online, graphs_json, updated_at) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(device_id) DO UPDATE SET hostname=excluded.hostname, ip=excluded.ip, agent_port=excluded.agent_port, media_port=excluded.media_port, alias=excluded.alias, device_name=excluded.device_name, version=excluded.version, git_sha=excluded.git_sha, build_id=excluded.build_id, last_seen_ms=excluded.last_seen_ms, online=excluded.online, graphs_json=excluded.graphs_json, updated_at=excluded.updated_at `, dev.DeviceID, dev.Hostname, dev.IP, dev.AgentPort, dev.MediaPort, dev.DeviceAlias, dev.DeviceName, dev.Version, dev.GitSha, dev.BuildID, dev.LastSeenMs, boolToInt(dev.Online), string(graphs), time.Now().Format(time.RFC3339)) return err } func (r *DevicesRepo) List() ([]*models.Device, error) { if r == nil || r.db == nil { return nil, nil } rows, err := r.db.Query(` SELECT device_id, hostname, ip, agent_port, media_port, alias, device_name, version, git_sha, build_id, last_seen_ms, online, graphs_json FROM devices ORDER BY updated_at DESC, device_id ASC `) if err != nil { return nil, err } defer rows.Close() var out []*models.Device for rows.Next() { var ( dev models.Device onlineInt int graphsJSON string ) if err := rows.Scan(&dev.DeviceID, &dev.Hostname, &dev.IP, &dev.AgentPort, &dev.MediaPort, &dev.DeviceAlias, &dev.DeviceName, &dev.Version, &dev.GitSha, &dev.BuildID, &dev.LastSeenMs, &onlineInt, &graphsJSON); err != nil { return nil, err } dev.Online = onlineInt == 1 if graphsJSON != "" && graphsJSON != "{}" { var graphs any if err := json.Unmarshal([]byte(graphsJSON), &graphs); err != nil { return nil, err } dev.Graphs = graphs } out = append(out, &dev) } return out, rows.Err() } func boolToInt(v bool) int { if v { return 1 } return 0 }