87 lines
1.9 KiB
Go
87 lines
1.9 KiB
Go
package storage
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
// DB wraps sql.DB
|
|
type DB struct {
|
|
conn *sql.DB
|
|
}
|
|
|
|
// Default is the package-level DB used by handlers
|
|
var Default *DB
|
|
|
|
// Init opens the sqlite database at path and ensures the table exists
|
|
func Init(path string) (*DB, error) {
|
|
conn, err := sql.Open("sqlite3", path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// set reasonable pragmas
|
|
if _, err := conn.Exec("PRAGMA journal_mode=WAL;"); err != nil {
|
|
// ignore
|
|
}
|
|
schema := `CREATE TABLE IF NOT EXISTS messages (
|
|
message TEXT NOT NULL,
|
|
timestamp TEXT NOT NULL
|
|
);`
|
|
if _, err := conn.Exec(schema); err != nil {
|
|
conn.Close()
|
|
return nil, err
|
|
}
|
|
return &DB{conn: conn}, nil
|
|
}
|
|
|
|
// SetDefault sets the package default DB
|
|
func SetDefault(d *DB) {
|
|
Default = d
|
|
}
|
|
|
|
// Close closes the underlying connection
|
|
func (d *DB) Close() error {
|
|
if d == nil || d.conn == nil {
|
|
return nil
|
|
}
|
|
return d.conn.Close()
|
|
}
|
|
|
|
// InsertMessage inserts a message with timestamp into the DB
|
|
func (d *DB) InsertMessage(msg string, ts time.Time) error {
|
|
if d == nil || d.conn == nil {
|
|
return nil
|
|
}
|
|
_, err := d.conn.Exec("INSERT INTO messages(message, timestamp) VALUES(?, ?)", msg, ts.Format(time.RFC3339))
|
|
return err
|
|
}
|
|
|
|
// Message is the returned message shape
|
|
type Message struct {
|
|
Message string `json:"message"`
|
|
Timestamp string `json:"timestamp"`
|
|
}
|
|
|
|
// QueryMessages returns messages ordered by newest first
|
|
func (d *DB) QueryMessages(limit, offset int) ([]Message, error) {
|
|
if d == nil || d.conn == nil {
|
|
return nil, nil
|
|
}
|
|
rows, err := d.conn.Query("SELECT message, timestamp FROM messages ORDER BY rowid DESC LIMIT ? OFFSET ?", limit, offset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
res := []Message{}
|
|
for rows.Next() {
|
|
var m Message
|
|
if err := rows.Scan(&m.Message, &m.Timestamp); err != nil {
|
|
return nil, err
|
|
}
|
|
res = append(res, m)
|
|
}
|
|
return res, nil
|
|
}
|