feat(repo,project): get by ID and IDs methods
This commit is contained in:
@@ -4,7 +4,10 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/model"
|
||||
"forge.capytal.company/loreddev/x/tinyssert"
|
||||
@@ -82,6 +85,129 @@ func (repo Project) Create(p model.Project) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo Project) GetByID(projectID uuid.UUID) (project model.Project, err error) {
|
||||
repo.assert.NotNil(repo.db)
|
||||
repo.assert.NotNil(repo.ctx)
|
||||
repo.assert.NotNil(repo.log)
|
||||
|
||||
q := `
|
||||
SELECT id, title, created_at, updated_at FROM projects
|
||||
WHERE id = :id
|
||||
`
|
||||
|
||||
log := repo.log.With(slog.String("query", q), slog.String("id", projectID.String()))
|
||||
log.DebugContext(repo.ctx, "Getting project by ID")
|
||||
|
||||
row := repo.db.QueryRowContext(repo.ctx, q, sql.Named("id", projectID))
|
||||
|
||||
var id uuid.UUID
|
||||
var title string
|
||||
var dateCreatedStr, dateUpdatedStr string
|
||||
|
||||
err = row.Scan(&id, &title, &dateCreatedStr, &dateUpdatedStr)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to scan projects with IDs", slog.String("error", err.Error()))
|
||||
return model.Project{}, errors.Join(ErrInvalidOutput, err)
|
||||
}
|
||||
|
||||
dateCreated, err := time.Parse(dateFormat, dateCreatedStr)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to scan projects with IDs", slog.String("error", err.Error()))
|
||||
return model.Project{}, errors.Join(ErrInvalidOutput, err)
|
||||
}
|
||||
|
||||
dateUpdated, err := time.Parse(dateFormat, dateUpdatedStr)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to scan projects with IDs", slog.String("error", err.Error()))
|
||||
return model.Project{}, errors.Join(ErrInvalidOutput, err)
|
||||
}
|
||||
|
||||
return model.Project{
|
||||
ID: id,
|
||||
Title: title,
|
||||
DateCreated: dateCreated,
|
||||
DateUpdated: dateUpdated,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repo Project) GetByIDs(ids []uuid.UUID) (projects []model.Project, err error) {
|
||||
repo.assert.NotNil(repo.db)
|
||||
repo.assert.NotNil(repo.ctx)
|
||||
repo.assert.NotNil(repo.log)
|
||||
|
||||
// Begin tx so we don't read rows as they are being updated
|
||||
tx, err := repo.db.BeginTx(repo.ctx, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Join(ErrDatabaseConn, err)
|
||||
}
|
||||
|
||||
c := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
c[i] = fmt.Sprintf("id = '%s'", id.String())
|
||||
}
|
||||
|
||||
q := fmt.Sprintf(`
|
||||
SELECT id, title, created_at, updated_at FROM projects
|
||||
WHERE %s
|
||||
`, strings.Join(c, " OR "))
|
||||
|
||||
log := repo.log.With(slog.String("query", q))
|
||||
log.DebugContext(repo.ctx, "Getting projects by IDs")
|
||||
|
||||
rows, err := tx.QueryContext(repo.ctx, q)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to get projects by IDs", slog.String("error", err.Error()))
|
||||
return nil, errors.Join(ErrExecuteQuery, err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err = rows.Close()
|
||||
if err != nil {
|
||||
err = errors.Join(ErrCloseConn, err)
|
||||
}
|
||||
}()
|
||||
|
||||
ps := []model.Project{}
|
||||
|
||||
for rows.Next() {
|
||||
var id uuid.UUID
|
||||
var title string
|
||||
var dateCreatedStr, dateUpdatedStr string
|
||||
|
||||
err := rows.Scan(&id, &title, &dateCreatedStr, &dateUpdatedStr)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to scan projects with IDs", slog.String("error", err.Error()))
|
||||
return nil, errors.Join(ErrInvalidOutput, err)
|
||||
}
|
||||
|
||||
dateCreated, err := time.Parse(dateFormat, dateCreatedStr)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to scan projects with IDs", slog.String("error", err.Error()))
|
||||
return nil, errors.Join(ErrInvalidOutput, err)
|
||||
}
|
||||
|
||||
dateUpdated, err := time.Parse(dateFormat, dateUpdatedStr)
|
||||
if err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to scan projects with IDs", slog.String("error", err.Error()))
|
||||
return nil, errors.Join(ErrInvalidOutput, err)
|
||||
}
|
||||
|
||||
ps = append(ps, model.Project{
|
||||
ID: id,
|
||||
Title: title,
|
||||
DateCreated: dateCreated,
|
||||
DateUpdated: dateUpdated,
|
||||
})
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
log.ErrorContext(repo.ctx, "Failed to commit transaction", slog.String("error", err.Error()))
|
||||
return nil, errors.Join(ErrCommitQuery, err)
|
||||
}
|
||||
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func (repo Project) Update(p model.Project) error {
|
||||
repo.assert.NotNil(repo.db)
|
||||
repo.assert.NotNil(repo.ctx)
|
||||
|
||||
Reference in New Issue
Block a user