Documentation ¶
Index ¶
- Constants
- Variables
- func ValidateEmail(v *validator.Validator, email string)
- func ValidateFilters(v *validator.Validator, f Filters)
- func ValidateMovie(v *validator.Validator, movie *Movie)
- func ValidatePasswordPlaintext(v *validator.Validator, password string)
- func ValidateTokenPlaintext(v *validator.Validator, tokenPlaintext string)
- func ValidateUser(v *validator.Validator, user *User)
- type Filters
- type Metadata
- type Models
- type Movie
- type MovieModel
- type PermissionModel
- type Permissions
- type Runtime
- type Token
- type TokenModel
- type User
- type UserModel
Constants ¶
const ( ScopeActivation = "activation" ScopeAuthentication = "authentication" )
ScopeActivation defines the "activate" scope for scope in the tokens table.
Variables ¶
var ( // ErrRecordNotFound is returned when a movie record doesn't exist in database. ErrRecordNotFound = errors.New("record not found") // ErrEditConflict is returned when a there is a data race, and we have an edit conflict. ErrEditConflict = errors.New("edit conflict") )
var AnonymousUser = &User{}
var (
ErrDuplicateEmail = errors.New("duplicate email")
)
var ErrInvalidRuntimeFormat = errors.New("invalid runtime format")
ErrInvalidRuntimeFormat returns error when we are unable to parse or convert a JSON string successfully. This is used in our Runtime.UnmarshalJSON() method.
Functions ¶
func ValidateEmail ¶
ValidateEmail checks that the Email field is not an empty string and that it matches the regex for email addresses, validator.EmailRX.
func ValidateFilters ¶
ValidateFilters runs validation checks on the Filters type.
func ValidateMovie ¶
ValidateMovie runs validation checks on the Movie type.
func ValidatePasswordPlaintext ¶
ValidatePasswordPlaintext validtes that the password is not an empty string and is between 8 and 72 bytes long.
func ValidateTokenPlaintext ¶
func ValidateUser ¶
Types ¶
type Metadata ¶
type Metadata struct { CurrentPage int `json:"current_page,omitempty"` PageSize int `json:"page_size,omitempty"` FirstPage int `json:"first_page,omitempty"` LastPage int `json:"last_page,omitempty"` TotalRecords int `json:"total_records,omitempty"` }
Metadata holds pagination metadata.
type Models ¶
type Models struct { Movies MovieModel Users UserModel Tokens TokenModel Permissions PermissionModel }
Models struct is a single convenient container to hold and represent all our database models.
type Movie ¶
type Movie struct { ID int64 `json:"id"` // Unique integer ID for the movie CreatedAt time.Time `json:"-"` // Use the - directive to never export in JSON output Title string `json:"title"` Year int32 `json:"year,omitempty"` // Movie release year0 Runtime Runtime `json:"runtime,omitempty"` Genres []string `json:"genres,omitempty"` Version int32 `json:"version"` // The version number starts at 1 and is incremented each }
Movie type whose fields describe the movie. Note that the Runtime type uses a custom Runtime type instead of int32. Furthermore, the omitempty directive on the Runtime type will still work on this: if the Runtime field has the underlying value 0, then it will be considered empty and omitted -- and the MarshalJSON() method won't be called.
type MovieModel ¶
MovieModel struct wraps a sql.DB connection pool and allows us to work with Movie struct type and the movies table in our database.
func (MovieModel) Delete ¶
func (m MovieModel) Delete(id int64) error
Delete is a placeholder method for deleting a specific record in the movies table.
func (MovieModel) Get ¶
func (m MovieModel) Get(id int64) (*Movie, error)
Get fetches a record from the movies table and returns the corresponding Movie struct. It cancels the query call if the SQL query does not finish within 3 seconds.
func (MovieModel) GetAll ¶
func (m MovieModel) GetAll(title string, genres []string, filters Filters) ([]*Movie, Metadata, error)
GetAll returns a list of movies in the form of a string of Movie type based on a set of provided filters.
func (MovieModel) Insert ¶
func (m MovieModel) Insert(movie *Movie) error
Insert accepts a pointer to a movie struct, which should contain the data for the new record and inserts the record into the movies table.
func (MovieModel) Update ¶
func (m MovieModel) Update(movie *Movie) error
Update updates a specific movie in the movies table.
type PermissionModel ¶
func (PermissionModel) AddForUser ¶
func (m PermissionModel) AddForUser(userID int64, codes ...string) error
AddForUser adds the provided codes for a specific user.
func (PermissionModel) GetAllForUser ¶
func (m PermissionModel) GetAllForUser(userID int64) (Permissions, error)
GetAllForUser returns all permission codes for a specific user in a Permissions slice.
type Permissions ¶
type Permissions []string
Permissions holds the permission codes for a single user.
func (Permissions) Include ¶
func (p Permissions) Include(code string) bool
Include checks whether the Permissions slice contains a specific permission code.
type Runtime ¶
type Runtime int32
func (Runtime) MarshalJSON ¶
MarshalJSON method on the Runtime type so that it satisfies the json.Marshaler interface. This should return the JSON-encoded string for the movie runtime in the format "<runtime> mins".
func (*Runtime) UnmarshalJSON ¶
UnmarshalJSON ensures that Runtime satisfies the json.Unmarshaler interface. IMPORTANT: because UnmarshalJSON() needs to modify the receiver (our Runtime type), we must use a pointer receiver for this to work correctly. Otherwise, we will only be modifying a copy (which is then discarded when this method returns).
type Token ¶
type Token struct { Plaintext string `json:"token"` Hash []byte `json:"-"` UserID int64 `json:"-"` Expiry time.Time `json:"expiry"` Scope string `json:"-"` }
Token represents a token record in our tokens table. Note, it includes plaintext and hashed version of the token.
type TokenModel ¶
TokenModel struct wraps a sql.DB connection pool and allows us to work with the Token struct type and the tokens table in our database.
func (TokenModel) DeleteAllForUser ¶
func (m TokenModel) DeleteAllForUser(scope string, userID int64) error
DeleteAllForUser deletes all tokens for a specific user and scope.
func (TokenModel) Insert ¶
func (m TokenModel) Insert(token *Token) error
Insert inserts a new token record into the tokens table.
type User ¶
type User struct { ID int64 `json:"id"` CreatedAt time.Time `json:"created_at"` Name string `json:"name"` Email string `json:"email"` Password password `json:"-"` Activated bool `json:"activated"` Version int `json:"-"` }
User type whose fields describe a user. Note, that we use the json:"-" struct tag to prevent the Password and Version fields from appearing in any output when we encode it to JSON. Also, notice that the Password field uses the custom password type defined below.
func (*User) IsAnonymous ¶
type UserModel ¶
UserModel struct wraps a sql.DB connection pool and allows us to work with the User struct type and the users table in our database.
func (UserModel) GetByEmail ¶
GetByEmail retrieves the User details from the database based on the user's email address. Because we have a UNIQUE constraint on the email column, this query will only return one record, or none at all, upon which we return a ErrRecordNotFound error).
func (UserModel) GetForToken ¶
GetForToken retrieves a user record from the users table for an associated token and token scope.
func (UserModel) Insert ¶
Insert inserts a new record in the users table in our database for the user. Note, that the id, created_at, and version fields are all automatically generated by our database, so we use use the RETURNING clause to read them into the User struct after the insert. Also, we check if our table already contains the same email address and if so return ErrDuplicateEmail error.