Merge pull request '(FIX): Some ORM things and an attempt to fix CI/CD' (#91) from feature/orm into master
Some checks failed
Deploy application with Docker / build_and_deploy (push) Failing after 57s

Reviewed-on: #91
This commit is contained in:
Hayden Hargreaves 2026-02-07 23:42:03 -07:00
commit eb2ebff0ae
3 changed files with 60 additions and 54 deletions

View File

@ -2,6 +2,9 @@ FROM golang:1.25-alpine
WORKDIR /app WORKDIR /app
# Solution t IP block?
ENV GOPROXY=https://goproxy.io,https://athens.azurefd.net,direct
COPY go.mod go.sum ./ COPY go.mod go.sum ./
RUN go mod download RUN go mod download

View File

@ -237,7 +237,10 @@ func (r *RecipeRepository) GetRecipe(id int, userId *int) (*domain.Recipe, error
&recipe.Created, &recipe.Created,
&recipe.Deleted, &recipe.Deleted,
); err != nil { ); err != nil {
return nil, fmt.Errorf("Failed to location recipe in database: %s", err.Error()) if err == sql.ErrNoRows {
return nil, err
}
return nil, fmt.Errorf("Failed to location recipe (id: %d) in database: %s", id, err.Error())
} }
// Parse duration // Parse duration
@ -300,7 +303,7 @@ func (r *RecipeRepository) GetRecipes(ids []int, userId *int) ([]domain.Recipe,
for _, id := range ids { for _, id := range ids {
recipe, err := r.GetRecipe(id, userId) recipe, err := r.GetRecipe(id, userId)
if err != nil { if err != nil && err != sql.ErrNoRows {
return nil, err return nil, err
} }

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
sq "github.com/Masterminds/squirrel"
domain "github.com/haydenhargreaves/Potion/internal/domain/user" domain "github.com/haydenhargreaves/Potion/internal/domain/user"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
_ "github.com/lib/pq" _ "github.com/lib/pq"
@ -31,42 +32,37 @@ func NewUserRepository(db *sqlx.DB) domain.UserRepository {
// best results, pair this function with the GetGoogleUser which will return the user if it can find // best results, pair this function with the GetGoogleUser which will return the user if it can find
// it. // it.
func (r *UserRepository) CreateGoogleUser(googleUserInfo *domain.GoogleUserInfo, googleRefreshToken string) (domain.User, error) { func (r *UserRepository) CreateGoogleUser(googleUserInfo *domain.GoogleUserInfo, googleRefreshToken string) (domain.User, error) {
tx, err := r.db.Begin()
if err != nil {
return domain.User{}, err
}
if googleUserInfo == nil { if googleUserInfo == nil {
return domain.User{}, fmt.Errorf("Google user info provided was nil") return domain.User{}, fmt.Errorf("Google user info provided was nil")
} }
var user domain.User psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := `INSERT INTO users
(GoogleId, Name, Email, ImageUrl, GoogleRefreshToken)
VALUES ($1, $2, $3, $4, $5) RETURNING *;`
if err := tx.QueryRow( query := psql.
query, Insert("users").
Columns(
"googleid",
"name",
"email",
"imageurl",
"googlerefreshtoken").
Values(
googleUserInfo.Id, googleUserInfo.Id,
googleUserInfo.Name, googleUserInfo.Name,
googleUserInfo.Email, googleUserInfo.Email,
googleUserInfo.Picture, googleUserInfo.Picture,
googleRefreshToken, googleRefreshToken,
).Scan( ).
&user.Id, Suffix("RETURNING *")
&user.GoogleId,
&user.Name, _sql, args, err := query.ToSql()
&user.Email, if err != nil {
&user.ImageUrl, return domain.User{}, fmt.Errorf("Failed to construct sql query: %w", err)
&user.GoogleRefreshToken,
&user.Created,
); err != nil {
tx.Rollback()
return domain.User{}, err
} }
if err := tx.Commit(); err != nil { var user domain.User
return domain.User{}, err if err := r.db.Get(&user, _sql, args...); err != nil {
return domain.User{}, fmt.Errorf("Failed to create user: %w", err)
} }
return user, nil return user, nil
@ -76,23 +72,26 @@ func (r *UserRepository) CreateGoogleUser(googleUserInfo *domain.GoogleUserInfo,
// function is used when a user logs in with Google to prevent duplicate entries from being made. If // function is used when a user logs in with Google to prevent duplicate entries from being made. If
// no user is found, this function will return a null pointer but not an error. // no user is found, this function will return a null pointer but not an error.
func (r *UserRepository) GetGoogleUser(googleId string) (*domain.User, error) { func (r *UserRepository) GetGoogleUser(googleId string) (*domain.User, error) {
var user domain.User psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := `SELECT * FROM users WHERE GoogleId = $1`
if err := r.db.QueryRow(query, googleId).Scan( query := psql.
&user.Id, Select("*").
&user.GoogleId, From("users").
&user.Name, Where(sq.Eq{
&user.Email, "GoogleId": googleId,
&user.ImageUrl, })
&user.GoogleRefreshToken,
&user.Created, _sql, args, err := query.ToSql()
); err != nil { if err != nil {
// If no user was found, don't error, just return return nil, fmt.Errorf("Failed to construct sql query: %w", err)
}
var user domain.User
if err := r.db.Get(&user, _sql, args...); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return nil, nil return nil, nil
} }
return nil, err return nil, fmt.Errorf("Failed to get Google user: %w", err)
} }
return &user, nil return &user, nil
@ -103,18 +102,19 @@ func (r *UserRepository) GetGoogleUser(googleId string) (*domain.User, error) {
// Callers are responsible for protecting against double nil results. Any errors will be bubbled // Callers are responsible for protecting against double nil results. Any errors will be bubbled
// to the caller. // to the caller.
func (r *UserRepository) GetUser(id int) (*domain.User, error) { func (r *UserRepository) GetUser(id int) (*domain.User, error) {
query := "SELECT * FROM users WHERE id = $1" psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := psql.
Select("*").
From("users").
Where(sq.Eq{"id": id})
_sql, args, err := query.ToSql()
if err != nil {
return nil, fmt.Errorf("Failed to construct sql query: %w", err)
}
var user domain.User var user domain.User
if err := r.db.QueryRow(query, id).Scan( if err := r.db.Get(&user, _sql, args...); err != nil {
&user.Id,
&user.GoogleId,
&user.Name,
&user.Email,
&user.ImageUrl,
&user.GoogleRefreshToken,
&user.Created,
); err != nil {
// If no user was found, don't error, just return // If no user was found, don't error, just return
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return nil, nil return nil, nil