Loggest thine Stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

193 lines
4.6 KiB

package mysql
import (
"context"
"database/sql"
"encoding/json"
"git.aiterp.net/stufflog3/stufflog3/entities"
"git.aiterp.net/stufflog3/stufflog3/internal/genutils"
"git.aiterp.net/stufflog3/stufflog3/models"
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore"
"github.com/Masterminds/squirrel"
)
type statsRepository struct {
db *sql.DB
q *mysqlcore.Queries
}
func (r *statsRepository) Find(ctx context.Context, scopeID, statID int) (*entities.Stat, error) {
row, err := r.q.GetStat(ctx, mysqlcore.GetStatParams{ScopeID: scopeID, ID: statID})
if err != nil {
if err == sql.ErrNoRows {
return nil, models.NotFoundError("Stat")
}
return nil, err
}
var allowedAmounts []models.StatAllowedAmount
if row.AllowedAmounts.Valid {
allowedAmounts = make([]models.StatAllowedAmount, 0, 8)
_ = json.Unmarshal(row.AllowedAmounts.RawMessage, &allowedAmounts)
if len(allowedAmounts) == 0 {
allowedAmounts = nil
}
}
return &entities.Stat{
ID: row.ID,
ScopeID: row.ScopeID,
Name: row.Name,
Weight: row.Weight,
Description: row.Description,
AllowedAmounts: allowedAmounts,
Primary: row.IsPrimary,
}, nil
}
func (r *statsRepository) List(ctx context.Context, scopeIDs ...int) ([]entities.Stat, error) {
if len(scopeIDs) == 0 {
return []entities.Stat{}, nil
} else if len(scopeIDs) == 1 {
rows, err := r.q.ListStats(ctx, scopeIDs[0])
if err != nil {
if err == sql.ErrNoRows {
return nil, models.NotFoundError("Stat")
}
return nil, err
}
res := make([]entities.Stat, 0, len(rows))
for _, row := range rows {
var allowedAmounts []models.StatAllowedAmount
if row.AllowedAmounts.Valid {
allowedAmounts = make([]models.StatAllowedAmount, 0, 8)
_ = json.Unmarshal(row.AllowedAmounts.RawMessage, &allowedAmounts)
if len(allowedAmounts) == 0 {
allowedAmounts = nil
}
}
res = append(res, entities.Stat{
ID: row.ID,
ScopeID: row.ScopeID,
Name: row.Name,
Weight: row.Weight,
Description: row.Description,
AllowedAmounts: allowedAmounts,
Primary: row.IsPrimary,
})
}
return res, nil
}
rows, err := squirrel.
Select("id, scope_id, name, description, weight, allowed_amounts, is_primary").
From("stat").
Where(squirrel.Eq{"scope_id": scopeIDs}).
RunWith(r.db).
Query()
if err == sql.ErrNoRows {
return []entities.Stat{}, nil
} else if err != nil {
return nil, err
}
stats := make([]entities.Stat, 0, 16)
for rows.Next() {
var row mysqlcore.Stat
if err := rows.Scan(
&row.ID,
&row.ScopeID,
&row.Name,
&row.Description,
&row.Weight,
&row.AllowedAmounts,
&row.IsPrimary,
); err != nil {
return nil, err
}
stats = append(stats, entities.Stat{
ID: row.ID,
ScopeID: row.ScopeID,
Name: row.Name,
Weight: row.Weight,
Description: row.Description,
Primary: row.IsPrimary,
AllowedAmounts: genutils.ParseJSONArray[models.StatAllowedAmount](row.AllowedAmounts.RawMessage),
})
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return stats, nil
}
func (r *statsRepository) Insert(ctx context.Context, stat entities.Stat) (*entities.Stat, error) {
res, err := r.q.InsertStat(ctx, mysqlcore.InsertStatParams{
ScopeID: stat.ScopeID,
Name: stat.Name,
Description: stat.Description,
Weight: stat.Weight,
IsPrimary: stat.Primary,
AllowedAmounts: sqlJsonPtr(stat.AllowedAmounts),
})
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
stat.ID = int(id)
return &stat, nil
}
func (r *statsRepository) Update(ctx context.Context, stat entities.Stat, update models.StatUpdate) error {
stat.Update(update)
return r.q.UpdateStat(ctx, mysqlcore.UpdateStatParams{
Name: stat.Name,
Description: stat.Description,
Weight: stat.Weight,
AllowedAmounts: sqlJsonPtr(stat.AllowedAmounts),
IsPrimary: stat.Primary,
ID: stat.ID,
ScopeID: stat.ScopeID,
})
}
func (r *statsRepository) Delete(ctx context.Context, stat entities.Stat) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
q := r.q.WithTx(tx)
err = q.ClearItemStatProgressByStat(ctx, stat.ID)
if err != nil {
return err
}
err = q.ClearProjectRequirementStatsByStat(ctx, stat.ID)
if err != nil {
return err
}
err = q.DeleteStat(ctx, mysqlcore.DeleteStatParams{ScopeID: stat.ScopeID, ID: stat.ID})
if err != nil {
return err
}
return tx.Commit()
}