package store import ( "context" "database/sql" "errors" "time" ) var ( QueryTimeout = 5 * time.Second ErrNotFound = errors.New("resource not found") ErrConflict = errors.New("resource already exists") ErrDuplicateEmail = errors.New("email already exists") ErrDuplicateUsername = errors.New("username already exists") ErrPasswordNotSet = errors.New("password is empty") ) type Storage struct { Posts interface { Create(context.Context, *Post) error GetByID(context.Context, int64) (*Post, error) GetUserFeed(context.Context, int64, PaginatedFeedQuery) ([]PostWithMetadata, error) Update(context.Context, *Post) error Delete(context.Context, int64) error } Users interface { Create(context.Context, *sql.Tx, *User) error Activate(context.Context, string) error GetByID(context.Context, int64) (*User, error) GetByEmail(context.Context, string) (*User, error) Update(context.Context, *User) error CreateAndInvite(context.Context, *User, string, time.Duration) error PasswordResetRequest(context.Context, int64, string, time.Duration) error Delete(context.Context, int64) error DeleteUser(context.Context, int64) error } Comments interface { Create(context.Context, *Comment) error GetByPostID(context.Context, int64) ([]Comment, error) } Followers interface { Follow(context.Context, int64, int64) error Unfollow(context.Context, int64, int64) error } Roles interface { GetByName(context.Context, string) (*Role, error) } } func NewStorage(db *sql.DB) (Storage, error) { userStore, roleStore, err := initStores(db) if err != nil { return Storage{}, err } return Storage{ Posts: &PostStore{db}, Users: userStore, Comments: &CommentStore{db}, Followers: &FollowerStore{db}, Roles: roleStore, }, nil } func withTx(db *sql.DB, ctx context.Context, f func(*sql.Tx) error) error { tx, err := db.BeginTx(ctx, nil) if err != nil { return err } if err := f(tx); err != nil { _ = tx.Rollback() return err } return tx.Commit() } func initStores(db *sql.DB) (*UserStore, *RoleStore, error) { userStore, err := NewUserStore(db) if err != nil { return &UserStore{}, &RoleStore{}, err } roleStore, err := NewRoleStore(db) if err != nil { return &UserStore{}, &RoleStore{}, err } return userStore, roleStore, nil }