All checks were successful
continuous-integration/drone/push Build is passing
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package storage
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
"github.com/lib/pq"
|
|
)
|
|
|
|
type postgres struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func New(dsn string) (Service, error) {
|
|
pool, err := sql.Open("postgres", dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not open database connection: %v", err)
|
|
}
|
|
return &postgres{pool}, nil
|
|
}
|
|
|
|
func (s *postgres) Close() error {
|
|
return s.db.Close()
|
|
}
|
|
|
|
func (s *postgres) Subscribe(topic string, sub Subscriber) error {
|
|
_, err := s.db.Exec(`
|
|
INSERT INTO "subscribers"
|
|
("topic", "callback", "lease_seconds", "secret", "created", "updated")
|
|
VALUES ($1, $2, $3, $4, now(), now())
|
|
ON CONFLICT (topic, callback)
|
|
DO UPDATE SET lease_seconds = excluded.lease_seconds,
|
|
secret = excluded.secret,
|
|
updated = now(),
|
|
last_subscribed = now()
|
|
`,
|
|
topic,
|
|
sub.Callback,
|
|
sub.LeaseSeconds,
|
|
sub.Secret,
|
|
)
|
|
if e, ok := err.(pq.Error); ok {
|
|
spew.Dump(e)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (s *postgres) RemoveExpiredSubscribers() error {
|
|
_, err := s.db.Exec(`DELETE FROM "subscribers" WHERE "last_subscribed" + "lease_seconds" * interval '1' second < now()`)
|
|
return err
|
|
}
|
|
|
|
func (s *postgres) Unsubscribe(topic, callback string) error {
|
|
_, err := s.db.Exec(
|
|
`DELETE FROM "subscribers" WHERE "topic" = $1 AND "callback" = $2`,
|
|
topic,
|
|
callback,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (s *postgres) Subscribers(topic string) ([]Subscriber, error) {
|
|
rows, err := s.db.Query(`SELECT callback, lease_seconds, secret, created FROM "subscribers" WHERE "topic" = $1`, topic)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var subscribers []Subscriber
|
|
for rows.Next() {
|
|
var sub Subscriber
|
|
err := rows.Scan(&sub.Callback, &sub.LeaseSeconds, &sub.Secret, &sub.Created)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
subscribers = append(subscribers, sub)
|
|
}
|
|
return subscribers, nil
|
|
}
|