Documentation
¶
Overview ¶
Package websubpostgres stores hub subscriptions in PostgreSQL.
It talks to postgres through database/sql with the pgx stdlib driver, so a caller that already has a *sql.DB can hand it over rather than opening a second pool.
store, err := websubpostgres.Open(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
return err
}
defer store.Close()
hub, err := websub.NewHub("https://example.com/hub", websub.WithStore(store))
This is the backend for a hub that has to survive a restart and take concurrent writes. See the sqlite backend for single binary deployments, and redis for state that can be lost.
The schema is plain SQL, in migrations/. There is no ORM and no migration framework: one table and one index do not need either.
Index ¶
- Constants
- func Schema(table string) string
- type Option
- type Store
- func (s *Store) Close() error
- func (s *Store) Delete(ctx context.Context, topic, callback string) error
- func (s *Store) Get(ctx context.Context, topic, callback string) (websub.Subscription, error)
- func (s *Store) ListByTopic(ctx context.Context, topic string) ([]websub.Subscription, error)
- func (s *Store) ListExpiring(ctx context.Context, before time.Time) ([]websub.Subscription, error)
- func (s *Store) Save(ctx context.Context, sub websub.Subscription) error
- func (s *Store) Topics(ctx context.Context) ([]string, error)
Constants ¶
const DefaultTable = "websub_subscriptions"
DefaultTable is the table subscriptions live in.
Variables ¶
This section is empty.
Functions ¶
func Schema ¶
Schema returns the statements this backend needs. migrations/0001_init.sql is this output for DefaultTable, and a test keeps the two in step.
The lease is stored in nanoseconds rather than as an interval because a Go time.Duration is nanoseconds and a store must not quietly round what it was handed. The protocol only ever carries whole seconds, but nothing stops a caller setting a finer lease.
Types ¶
type Option ¶
type Option func(*config)
Option configures a Store.
func WithTable ¶
WithTable sets the table name, which defaults to DefaultTable. Useful for sharing a database with an application's own tables, or for isolating tests from each other.
The name is interpolated into SQL, since a table name cannot be a bound parameter, so it is validated as an identifier and rejected otherwise.
func WithoutSchema ¶
func WithoutSchema() Option
WithoutSchema skips creating the table and index, for callers running the migrations in migrations/ themselves. That is the better choice in any deployment where the application does not own DDL privileges.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a websub.SubscriptionStore backed by PostgreSQL.
func Open ¶
Open connects using dsn, which is a postgres connection URL or keyword string, and returns a store that owns the connection pool.
func (*Store) Close ¶
Close releases the pool if this store opened it, and does nothing if the handle was supplied by the caller.
func (*Store) Delete ¶
Delete removes the subscription for topic and callback. Removing one that does not exist is not an error.
func (*Store) Get ¶
Get returns the subscription for topic and callback, or an error matching websub.ErrUnknownSubscription.
func (*Store) ListByTopic ¶
ListByTopic returns every subscription for topic.
func (*Store) ListExpiring ¶
ListExpiring returns every subscription whose lease elapses strictly before the given time. Permanent subscriptions are never returned.