121 lines
2.6 KiB
Go
121 lines
2.6 KiB
Go
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()
|
|
}
|