package store import ( "database/sql" "git.espin.casa/albert/whippet/proto" _ "github.com/mattn/go-sqlite3" ) type Storage struct { db *sql.DB } func NewStorage(path string) *Storage { db, err := sql.Open("sqlite3", path) if err != nil { return nil } s := &Storage{db: db} if err := s.initSchema(); err != nil { return nil } return s } func (s *Storage) initSchema() error { schema := ` CREATE TABLE IF NOT EXISTS messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, topic TEXT, msg_id TEXT, payload BLOB, timestamp INTEGER );` _, err := s.db.Exec(schema) return err } // Save guarda un mensaje en la base de datos func (s *Storage) Save(topic string, msg *proto.DataMessage) error { _, err := s.db.Exec(` INSERT INTO messages (topic, msg_id, payload, timestamp) VALUES (?, ?, ?, ?)`, topic, string(msg.Id()), msg.PayloadBytes(), msg.Timestamp(), ) return err } // LoadSince carga mensajes desde un timestamp específico func (s *Storage) LoadSince(topic string, sinceTimestamp uint64, max int) ([]*proto.DataMessage, error) { rows, err := s.db.Query(` SELECT msg_id, payload, timestamp FROM messages WHERE topic = ? AND timestamp > ? ORDER BY timestamp ASC LIMIT ?`, topic, sinceTimestamp, max, ) if err != nil { return nil, err } defer rows.Close() var result []*proto.DataMessage for rows.Next() { var id string var payload []byte var timestamp uint64 err := rows.Scan(&id, &payload, ×tamp) if err != nil { return nil, err } // Reensamblar el FlatBuffer msg := proto.GetRootAsDataMessage(payload, 0) // Cuidado: esto apunta a datos en `payload` directamente // Alternativa: clonar si necesitas preservar después result = append(result, msg) } return result, nil } // LoadAll carga todos los mensajes de un tema específico func (s *Storage) LoadAll(topic string) ([]*proto.DataMessage, error) { rows, err := s.db.Query(` SELECT msg_id, payload, timestamp FROM messages WHERE topic = ? ORDER BY timestamp ASC `, topic) if err != nil { return nil, err } defer rows.Close() var result []*proto.DataMessage for rows.Next() { var id string var payload []byte var timestamp uint64 err := rows.Scan(&id, &payload, ×tamp) if err != nil { return nil, err } // Reensamblar el FlatBuffer msg := proto.GetRootAsDataMessage(payload, 0) // Cuidado: esto apunta a datos en `payload` directamente // Alternativa: clonar si necesitas preservar después result = append(result, msg) } return result, nil } // LoadAllTopics carga todos los temas disponibles func (s *Storage) Close() error { return s.db.Close() }