Files
chat/internal/models/model.go

70 lines
1.9 KiB
Go

// Package models defines the data models used by the chat application.
// All model structs embed Base, which provides database access for
// relation-fetching methods directly on model instances.
package models
import (
"context"
"database/sql"
"errors"
)
var (
// ErrUserLookupNotAvailable is returned when the user lookup interface is not set.
ErrUserLookupNotAvailable = errors.New("user lookup not available")
// ErrChannelLookupNotAvailable is returned when the channel lookup interface is not set.
ErrChannelLookupNotAvailable = errors.New("channel lookup not available")
)
// DB is the interface that models use to query the database.
// This avoids a circular import with the db package.
type DB interface {
GetDB() *sql.DB
}
// UserLookup provides user lookup by ID without circular imports.
type UserLookup interface {
GetUserByID(ctx context.Context, id string) (*User, error)
}
// ChannelLookup provides channel lookup by ID without circular imports.
type ChannelLookup interface {
GetChannelByID(ctx context.Context, id string) (*Channel, error)
}
// Base is embedded in all model structs to provide database access.
type Base struct {
db DB
}
// SetDB injects the database reference into a model.
func (b *Base) SetDB(d DB) {
b.db = d
}
// GetDB returns the database interface for use in model methods.
func (b *Base) GetDB() *sql.DB {
return b.db.GetDB()
}
// GetUserLookup returns the DB as a UserLookup if it implements the interface.
func (b *Base) GetUserLookup() UserLookup { //nolint:ireturn // intentional interface return for dependency inversion
if ul, ok := b.db.(UserLookup); ok {
return ul
}
return nil
}
// GetChannelLookup returns the DB as a ChannelLookup
// if it implements the interface.
//
//nolint:ireturn // intentional interface return for dependency inversion
func (b *Base) GetChannelLookup() ChannelLookup {
if cl, ok := b.db.(ChannelLookup); ok {
return cl
}
return nil
}