go-waku/waku/persistence/store.go

129 lines
2.7 KiB
Go
Raw Normal View History

2021-04-13 18:52:57 +00:00
package persistence
2021-04-12 17:59:41 +00:00
import (
"database/sql"
"log"
2021-04-22 00:09:37 +00:00
"github.com/status-im/go-waku/waku/v2/protocol/pb"
"github.com/status-im/go-waku/waku/v2/protocol/store"
2021-04-12 17:59:41 +00:00
)
2021-04-22 18:49:52 +00:00
// DBStore is a MessageProvider that has a *sql.DB connection
2021-04-12 17:59:41 +00:00
type DBStore struct {
store.MessageProvider
db *sql.DB
}
2021-04-13 18:52:57 +00:00
type DBOption func(*DBStore) error
2021-04-22 18:49:52 +00:00
// WithDB is a DBOption that lets you use any custom *sql.DB with a DBStore.
2021-04-13 18:52:57 +00:00
func WithDB(db *sql.DB) DBOption {
return func(d *DBStore) error {
d.db = db
return nil
}
}
2021-04-22 18:49:52 +00:00
// WithDriver is a DBOption that will open a *sql.DB connection
2021-04-13 18:52:57 +00:00
func WithDriver(driverName string, datasourceName string) DBOption {
return func(d *DBStore) error {
db, err := sql.Open(driverName, datasourceName)
if err != nil {
return err
}
d.db = db
return nil
}
}
2021-04-22 18:49:52 +00:00
// Creates a new DB store using the db specified via options.
// It will create a messages table if it does not exist
2021-04-13 18:52:57 +00:00
func NewDBStore(opt DBOption) (*DBStore, error) {
result := new(DBStore)
err := opt(result)
2021-04-12 17:59:41 +00:00
if err != nil {
return nil, err
}
err = result.createTable()
if err != nil {
return nil, err
}
return result, nil
}
func (d *DBStore) createTable() error {
sqlStmt := `CREATE TABLE IF NOT EXISTS messages (
id BLOB PRIMARY KEY,
timestamp INTEGER NOT NULL,
contentTopic BLOB NOT NULL,
payload BLOB,
version INTEGER NOT NULL DEFAULT 0
) WITHOUT ROWID;`
_, err := d.db.Exec(sqlStmt)
if err != nil {
return err
}
return nil
}
2021-04-22 18:49:52 +00:00
// Closes a DB connection
2021-04-12 17:59:41 +00:00
func (d *DBStore) Stop() {
d.db.Close()
}
2021-04-22 18:49:52 +00:00
// Inserts a WakuMessage into the DB
2021-04-22 00:09:37 +00:00
func (d *DBStore) Put(cursor *pb.Index, message *pb.WakuMessage) error {
2021-04-12 17:59:41 +00:00
stmt, err := d.db.Prepare("INSERT INTO messages (id, timestamp, contentTopic, payload, version) VALUES (?, ?, ?, ?, ?)")
if err != nil {
return err
}
_, err = stmt.Exec(cursor.Digest, uint64(message.Timestamp), message.ContentTopic, message.Payload, message.Version)
if err != nil {
return err
}
return nil
}
2021-04-22 18:49:52 +00:00
// Returns all the stored WakuMessages
2021-04-22 00:09:37 +00:00
func (d *DBStore) GetAll() ([]*pb.WakuMessage, error) {
2021-04-12 17:59:41 +00:00
rows, err := d.db.Query("SELECT timestamp, contentTopic, payload, version FROM messages ORDER BY timestamp ASC")
if err != nil {
return nil, err
}
2021-04-22 00:09:37 +00:00
var result []*pb.WakuMessage
2021-04-12 17:59:41 +00:00
defer rows.Close()
for rows.Next() {
var timestamp int64
var contentTopic string
var payload []byte
var version uint32
err = rows.Scan(&timestamp, &contentTopic, &payload, &version)
if err != nil {
log.Fatal(err)
}
2021-04-22 00:09:37 +00:00
msg := new(pb.WakuMessage)
2021-04-12 17:59:41 +00:00
msg.ContentTopic = contentTopic
msg.Payload = payload
msg.Timestamp = float64(timestamp)
msg.Version = version
result = append(result, msg)
}
err = rows.Err()
if err != nil {
return nil, err
}
return result, nil
}