item repository and api progress.
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/auth"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/database"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/models"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -29,3 +34,37 @@ func reqInt(c *gin.Context, key string) (int, error) {
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
var scopeIdContextKey = struct{ stuff string }{stuff: "Things"}
|
||||
|
||||
func scopeIDMiddleware(db database.Database) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
scopeID, err := strconv.Atoi(c.Param("scope_id"))
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
Message: "Invalid scope ID in path!",
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
scope, err := db.Scopes().Find(c.Request.Context(), scopeID, c.Request.Method != "GET")
|
||||
if err != nil || !scope.HasMember(auth.UserID(c)) {
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{
|
||||
Code: http.StatusNotFound,
|
||||
Message: "Scope not found or you don't have permission to it!",
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.Request = c.Request.WithContext(
|
||||
context.WithValue(c.Request.Context(), &scopeIdContextKey, scope),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func getScope(c *gin.Context) *models.Scope {
|
||||
return c.Request.Context().Value(&scopeIdContextKey).(*models.Scope)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/auth"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/database"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/models"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Items(g *gin.RouterGroup, db database.Database) {
|
||||
g.Use(scopeIDMiddleware(db))
|
||||
|
||||
g.GET("/:id", handler("item", func(c *gin.Context) (interface{}, error) {
|
||||
id, err := reqInt(c, "id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
item, err := db.Items(getScope(c).ID).Find(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, member := range getScope(c).Members {
|
||||
if member.ID == item.OwnerID {
|
||||
item.Owner = &member
|
||||
}
|
||||
}
|
||||
|
||||
return item, nil
|
||||
}))
|
||||
|
||||
g.POST("/", handler("item", func(c *gin.Context) (interface{}, error) {
|
||||
item := &models.Item{}
|
||||
err := c.BindJSON(item)
|
||||
if err != nil {
|
||||
return nil, slerrors.BadRequest("Invalid JSON input: " + err.Error())
|
||||
}
|
||||
|
||||
item.CreatedTime = time.Now()
|
||||
|
||||
if item.Name == "" {
|
||||
return nil, slerrors.BadRequest("Blank item name not allowed")
|
||||
}
|
||||
if item.OwnerID == "" {
|
||||
item.OwnerID = auth.UserID(c)
|
||||
} else if getScope(c).HasMember(item.OwnerID) {
|
||||
return nil, slerrors.Forbidden("Owner is not part of scope.")
|
||||
}
|
||||
if item.ProjectRequirementID != nil {
|
||||
// TODO: Ensure project requirement exists in scope.
|
||||
return nil, slerrors.Forbidden("TODO: check project requirement ID.")
|
||||
}
|
||||
for _, stat := range item.Stats {
|
||||
if getScope(c).Stat(stat.ID) == nil {
|
||||
return nil, slerrors.Forbidden("One or more stats are not part of scope.")
|
||||
}
|
||||
if stat.Acquired == 0 && stat.Required == 0 {
|
||||
return nil, slerrors.BadRequest("0/0 stats are not allowed when creating items.")
|
||||
}
|
||||
}
|
||||
|
||||
item, err = db.Items(getScope(c).ID).Create(c.Request.Context(), *item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
item.Owner = getScope(c).Member(item.OwnerID)
|
||||
|
||||
return item, err
|
||||
}))
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ func Scopes(g *gin.RouterGroup, db database.Database) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope, err := db.Scopes().Find(c.Request.Context(), id)
|
||||
scope, err := db.Scopes().Find(c.Request.Context(), id, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ func main() {
|
||||
}
|
||||
|
||||
api.Scopes(server.Group("/api/scopes"), db)
|
||||
api.Items(server.Group("/api/scope/:scope_id/items"), db)
|
||||
|
||||
exitSignal := make(chan os.Signal)
|
||||
signal.Notify(exitSignal, os.Interrupt, os.Kill, syscall.SIGTERM)
|
||||
|
||||
@@ -10,10 +10,11 @@ type Database interface {
|
||||
Scopes() ScopeRepository
|
||||
Stats(scopeID int) StatRepository
|
||||
Items(scopeID int) ItemRepository
|
||||
ItemsMultiScope(scopeIDs []int) ItemRepository
|
||||
}
|
||||
|
||||
type ScopeRepository interface {
|
||||
Find(ctx context.Context, id int) (*models.Scope, error)
|
||||
Find(ctx context.Context, id int, full bool) (*models.Scope, error)
|
||||
List(ctx context.Context) ([]models.ScopeEntry, error)
|
||||
ListByUser(ctx context.Context, userID string) ([]models.ScopeEntry, error)
|
||||
Create(ctx context.Context, scope models.ScopeEntry, owner models.ScopeMember) (*models.Scope, error)
|
||||
@@ -33,7 +34,30 @@ type StatRepository interface {
|
||||
|
||||
type ItemRepository interface {
|
||||
Find(ctx context.Context, id int) (*models.Item, error)
|
||||
List(ctx context.Context) ([]models.Item, error)
|
||||
ListCreated(ctx context.Context, from, to time.Time) ([]models.Item, error)
|
||||
ListAcquired(ctx context.Context, from, to time.Time) ([]models.Item, error)
|
||||
Create(ctx context.Context, stat models.Stat) (*models.Item, error)
|
||||
ListScheduled(ctx context.Context, from, to models.Date) ([]models.Item, error)
|
||||
ListLoose(ctx context.Context, from, to time.Time) ([]models.Item, error)
|
||||
Create(ctx context.Context, item models.Item) (*models.Item, error)
|
||||
Update(ctx context.Context, item models.Item, update models.ItemUpdate) (*models.Item, error)
|
||||
Delete(ctx context.Context, item models.Item) error
|
||||
}
|
||||
|
||||
type ItemMultiScopeRepository interface {
|
||||
ListCreated(ctx context.Context, from, to time.Time) ([]models.Item, error)
|
||||
ListAcquired(ctx context.Context, from, to time.Time) ([]models.Item, error)
|
||||
ListScheduled(ctx context.Context, from, to models.Date) ([]models.Item, error)
|
||||
ListLoose(ctx context.Context, from, to time.Time) ([]models.Item, error)
|
||||
}
|
||||
|
||||
type ProjectRepository interface {
|
||||
Find(ctx context.Context, id int) (*models.Project, error)
|
||||
List(ctx context.Context) ([]models.Project, error)
|
||||
Create(ctx context.Context, project models.Project) (*models.Project, error)
|
||||
Update(ctx context.Context, project models.Project) (*models.Project, error)
|
||||
Delete(ctx context.Context, project models.ProjectEntry) error
|
||||
|
||||
AddRequirement(ctx context.Context, project models.ProjectEntry, requirement models.ProjectRequirement)
|
||||
UpdateRequirement(ctx context.Context, project models.ProjectEntry, requirement models.ProjectRequirement, update models.ProjectRequirementUpdate)
|
||||
DeleteRequirement(ctx context.Context, project models.ProjectEntry, requirement models.ProjectRequirement)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ func (d *Database) Stats(scopeID int) database.StatRepository {
|
||||
}
|
||||
|
||||
func (d *Database) Items(scopeID int) database.ItemRepository {
|
||||
return &itemRepository{db: d.db, scopeID: scopeID}
|
||||
}
|
||||
|
||||
func (d *Database) ItemsMultiScope(scopeIDs []int) database.ItemRepository {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/database/mysql/mysqlcore"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/models"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/sqltypes"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type itemRepository struct {
|
||||
db *sql.DB
|
||||
scopeID int
|
||||
}
|
||||
|
||||
func (r *itemRepository) Find(ctx context.Context, id int) (*models.Item, error) {
|
||||
res, err := mysqlcore.New(r.db).GetItem(ctx, id)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, slerrors.NotFound("Item")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if res.ScopeID != r.scopeID {
|
||||
return nil, slerrors.NotFound("Item")
|
||||
}
|
||||
|
||||
item := r.resToItem(mysqlcore.ListItemsAcquiredBetweenRow(res))
|
||||
|
||||
stats, _ := mysqlcore.New(r.db).ListItemStatProgress(ctx, id)
|
||||
for _, stat := range stats {
|
||||
item.Stats = append(item.Stats, models.StatProgressEntry{
|
||||
StatEntry: models.StatEntry{
|
||||
ID: int(stat.ID.Int32),
|
||||
Name: stat.Name.String,
|
||||
Weight: stat.Weight,
|
||||
},
|
||||
Acquired: stat.Acquired,
|
||||
Required: stat.Required,
|
||||
})
|
||||
}
|
||||
|
||||
return &item, nil
|
||||
}
|
||||
|
||||
func (r *itemRepository) ListCreated(ctx context.Context, from, to time.Time) ([]models.Item, error) {
|
||||
rows, err := mysqlcore.New(r.db).ListItemsCreatedBetween(ctx, mysqlcore.ListItemsCreatedBetweenParams{
|
||||
CreatedTime: from,
|
||||
CreatedTime_2: to,
|
||||
ScopeID: r.scopeID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]models.Item, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, r.resToItem(mysqlcore.ListItemsAcquiredBetweenRow(row)))
|
||||
}
|
||||
|
||||
err = r.fillStats(ctx, items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (r *itemRepository) ListAcquired(ctx context.Context, from, to time.Time) ([]models.Item, error) {
|
||||
rows, err := mysqlcore.New(r.db).ListItemsAcquiredBetween(ctx, mysqlcore.ListItemsAcquiredBetweenParams{
|
||||
AcquiredTime: sql.NullTime{Valid: true, Time: from},
|
||||
AcquiredTime_2: sql.NullTime{Valid: true, Time: to},
|
||||
ScopeID: r.scopeID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]models.Item, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, r.resToItem(row))
|
||||
}
|
||||
|
||||
err = r.fillStats(ctx, items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (r *itemRepository) ListScheduled(ctx context.Context, from, to models.Date) ([]models.Item, error) {
|
||||
rows, err := mysqlcore.New(r.db).ListItemsScheduledBetween(ctx, mysqlcore.ListItemsScheduledBetweenParams{
|
||||
ScheduledDate: sqltypes.NullDate{Valid: true, Date: from},
|
||||
ScheduledDate_2: sqltypes.NullDate{Valid: true, Date: to},
|
||||
ScopeID: r.scopeID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]models.Item, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, r.resToItem(mysqlcore.ListItemsAcquiredBetweenRow(row)))
|
||||
}
|
||||
|
||||
err = r.fillStats(ctx, items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (r *itemRepository) ListLoose(ctx context.Context, from, to time.Time) ([]models.Item, error) {
|
||||
rows, err := mysqlcore.New(r.db).ListItemsLooseBetween(ctx, mysqlcore.ListItemsLooseBetweenParams{
|
||||
CreatedTime: from,
|
||||
CreatedTime_2: to,
|
||||
ScopeID: r.scopeID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]models.Item, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, r.resToItem(mysqlcore.ListItemsAcquiredBetweenRow(row)))
|
||||
}
|
||||
|
||||
err = r.fillStats(ctx, items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (r *itemRepository) Create(ctx context.Context, item models.Item) (*models.Item, error) {
|
||||
item.Stats = append(item.Stats[:0:0], item.Stats...)
|
||||
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
q := mysqlcore.New(tx)
|
||||
|
||||
prID, acqTime, schDate := r.generateNullables(item)
|
||||
|
||||
res, err := q.InsertItem(ctx, mysqlcore.InsertItemParams{
|
||||
ScopeID: r.scopeID,
|
||||
ProjectRequirementID: prID,
|
||||
Name: item.Name,
|
||||
Description: item.Description,
|
||||
CreatedTime: time.Now(),
|
||||
CreatedUserID: item.OwnerID,
|
||||
AcquiredTime: acqTime,
|
||||
ScheduledDate: schDate,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, stat := range item.Stats {
|
||||
err = q.ReplaceItemStatProgress(ctx, mysqlcore.ReplaceItemStatProgressParams{
|
||||
ItemID: int(id),
|
||||
StatID: stat.ID,
|
||||
Acquired: stat.Acquired,
|
||||
Required: stat.Required,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Find(ctx, int(id))
|
||||
}
|
||||
|
||||
func (r *itemRepository) generateNullables(item models.Item) (prID sql.NullInt32, acqTime sql.NullTime, schDate sqltypes.NullDate) {
|
||||
if item.ProjectRequirementID != nil {
|
||||
prID.Valid = true
|
||||
prID.Int32 = int32(*item.ProjectRequirementID)
|
||||
}
|
||||
if item.AcquiredTime != nil {
|
||||
acqTime.Valid = true
|
||||
acqTime.Time = *item.AcquiredTime
|
||||
}
|
||||
if item.ScheduledDate != nil {
|
||||
schDate.Valid = true
|
||||
schDate.Date = *item.ScheduledDate
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *itemRepository) Update(ctx context.Context, item models.Item, update models.ItemUpdate) (*models.Item, error) {
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
q := mysqlcore.New(r.db)
|
||||
|
||||
item.ApplyUpdate(update)
|
||||
|
||||
prID, acqTime, schDate := r.generateNullables(item)
|
||||
|
||||
err = q.UpdateItem(ctx, mysqlcore.UpdateItemParams{
|
||||
ID: item.ID,
|
||||
|
||||
ProjectRequirementID: prID,
|
||||
Name: item.Name,
|
||||
Description: item.Description,
|
||||
AcquiredTime: acqTime,
|
||||
ScheduledDate: schDate,
|
||||
CreatedUserID: item.OwnerID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, stat := range update.Stats {
|
||||
if stat.Acquired == 0 && stat.Required == 0 {
|
||||
err = q.DeleteItemStatProgress(ctx, mysqlcore.DeleteItemStatProgressParams{
|
||||
ItemID: item.ID,
|
||||
StatID: stat.ID,
|
||||
})
|
||||
} else {
|
||||
err = q.ReplaceItemStatProgress(ctx, mysqlcore.ReplaceItemStatProgressParams{
|
||||
ItemID: item.ID,
|
||||
StatID: stat.ID,
|
||||
Acquired: stat.Acquired,
|
||||
Required: stat.Required,
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Find(ctx, item.ID)
|
||||
}
|
||||
|
||||
func (r *itemRepository) Delete(ctx context.Context, item models.Item) error {
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
q := mysqlcore.New(r.db)
|
||||
|
||||
err = q.DeleteItem(ctx, item.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = q.ClearItemStatProgress(ctx, item.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (r *itemRepository) resToItem(res mysqlcore.ListItemsAcquiredBetweenRow) models.Item {
|
||||
item := models.Item{
|
||||
ID: res.ID,
|
||||
ScopeID: res.ScopeID,
|
||||
OwnerID: res.CreatedUserID,
|
||||
Name: res.Name,
|
||||
Description: res.Description,
|
||||
CreatedTime: res.CreatedTime.UTC(),
|
||||
}
|
||||
if res.ProjectRequirementID.Valid {
|
||||
projectRequirementID := int(res.ProjectRequirementID.Int32)
|
||||
projectID := int(res.ProjectID.Int32)
|
||||
item.ProjectRequirementID = &projectRequirementID
|
||||
item.ProjectID = &projectID
|
||||
}
|
||||
if res.ScheduledDate.Valid {
|
||||
item.ScheduledDate = &res.ScheduledDate.Date
|
||||
}
|
||||
if res.AcquiredTime.Valid {
|
||||
item.AcquiredTime = &res.AcquiredTime.Time
|
||||
}
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
func (r *itemRepository) fillStats(ctx context.Context, items []models.Item) error {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
ids := make([]interface{}, 0, len(items))
|
||||
for _, item := range items {
|
||||
ids = append(ids, item.ID)
|
||||
}
|
||||
query := `
|
||||
SELECT isp.item_id, isp.required, isp.acquired, s.id, s.name, s.weight FROM item_stat_progress isp
|
||||
LEFT JOIN stat s ON s.id = isp.stat_id
|
||||
WHERE item_id IN (?` + strings.Repeat(",?", len(ids)-1) + `);
|
||||
`
|
||||
|
||||
rows, err := r.db.QueryContext(ctx, query, ids...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var itemID, required, acquired, statID int
|
||||
var statName string
|
||||
var statWeight float64
|
||||
|
||||
err = rows.Scan(&itemID, &required, &acquired, &statID, &statName, &statWeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range items {
|
||||
if items[i].ID == itemID {
|
||||
items[i].Stats = append(items[i].Stats, models.StatProgressEntry{
|
||||
StatEntry: models.StatEntry{
|
||||
ID: statID,
|
||||
Name: statName,
|
||||
Weight: statWeight,
|
||||
},
|
||||
Acquired: acquired,
|
||||
Required: required,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -7,7 +7,6 @@ package mysqlcore
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
@@ -21,198 +20,12 @@ func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
func Prepare(ctx context.Context, db DBTX) (*Queries, error) {
|
||||
q := Queries{db: db}
|
||||
var err error
|
||||
if q.deleteAllScopeMembersStmt, err = db.PrepareContext(ctx, deleteAllScopeMembers); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query DeleteAllScopeMembers: %w", err)
|
||||
}
|
||||
if q.deleteScopeStmt, err = db.PrepareContext(ctx, deleteScope); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query DeleteScope: %w", err)
|
||||
}
|
||||
if q.deleteScopeMemberStmt, err = db.PrepareContext(ctx, deleteScopeMember); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query DeleteScopeMember: %w", err)
|
||||
}
|
||||
if q.getScopeStmt, err = db.PrepareContext(ctx, getScope); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query GetScope: %w", err)
|
||||
}
|
||||
if q.getScopeDisplayNameStmt, err = db.PrepareContext(ctx, getScopeDisplayName); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query GetScopeDisplayName: %w", err)
|
||||
}
|
||||
if q.getScopeWithDisplayNameStmt, err = db.PrepareContext(ctx, getScopeWithDisplayName); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query GetScopeWithDisplayName: %w", err)
|
||||
}
|
||||
if q.insertScopeStmt, err = db.PrepareContext(ctx, insertScope); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query InsertScope: %w", err)
|
||||
}
|
||||
if q.listProjectEntriesStmt, err = db.PrepareContext(ctx, listProjectEntries); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query ListProjectEntries: %w", err)
|
||||
}
|
||||
if q.listScopeMembersStmt, err = db.PrepareContext(ctx, listScopeMembers); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query ListScopeMembers: %w", err)
|
||||
}
|
||||
if q.listScopesStmt, err = db.PrepareContext(ctx, listScopes); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query ListScopes: %w", err)
|
||||
}
|
||||
if q.listScopesByUserStmt, err = db.PrepareContext(ctx, listScopesByUser); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query ListScopesByUser: %w", err)
|
||||
}
|
||||
if q.listStatsStmt, err = db.PrepareContext(ctx, listStats); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query ListStats: %w", err)
|
||||
}
|
||||
if q.updateScopeStmt, err = db.PrepareContext(ctx, updateScope); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query UpdateScope: %w", err)
|
||||
}
|
||||
if q.updateScopeMemberStmt, err = db.PrepareContext(ctx, updateScopeMember); err != nil {
|
||||
return nil, fmt.Errorf("error preparing query UpdateScopeMember: %w", err)
|
||||
}
|
||||
return &q, nil
|
||||
}
|
||||
|
||||
func (q *Queries) Close() error {
|
||||
var err error
|
||||
if q.deleteAllScopeMembersStmt != nil {
|
||||
if cerr := q.deleteAllScopeMembersStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing deleteAllScopeMembersStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.deleteScopeStmt != nil {
|
||||
if cerr := q.deleteScopeStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing deleteScopeStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.deleteScopeMemberStmt != nil {
|
||||
if cerr := q.deleteScopeMemberStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing deleteScopeMemberStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.getScopeStmt != nil {
|
||||
if cerr := q.getScopeStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing getScopeStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.getScopeDisplayNameStmt != nil {
|
||||
if cerr := q.getScopeDisplayNameStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing getScopeDisplayNameStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.getScopeWithDisplayNameStmt != nil {
|
||||
if cerr := q.getScopeWithDisplayNameStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing getScopeWithDisplayNameStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.insertScopeStmt != nil {
|
||||
if cerr := q.insertScopeStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing insertScopeStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.listProjectEntriesStmt != nil {
|
||||
if cerr := q.listProjectEntriesStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing listProjectEntriesStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.listScopeMembersStmt != nil {
|
||||
if cerr := q.listScopeMembersStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing listScopeMembersStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.listScopesStmt != nil {
|
||||
if cerr := q.listScopesStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing listScopesStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.listScopesByUserStmt != nil {
|
||||
if cerr := q.listScopesByUserStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing listScopesByUserStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.listStatsStmt != nil {
|
||||
if cerr := q.listStatsStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing listStatsStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.updateScopeStmt != nil {
|
||||
if cerr := q.updateScopeStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing updateScopeStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
if q.updateScopeMemberStmt != nil {
|
||||
if cerr := q.updateScopeMemberStmt.Close(); cerr != nil {
|
||||
err = fmt.Errorf("error closing updateScopeMemberStmt: %w", cerr)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *Queries) exec(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (sql.Result, error) {
|
||||
switch {
|
||||
case stmt != nil && q.tx != nil:
|
||||
return q.tx.StmtContext(ctx, stmt).ExecContext(ctx, args...)
|
||||
case stmt != nil:
|
||||
return stmt.ExecContext(ctx, args...)
|
||||
default:
|
||||
return q.db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Queries) query(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
switch {
|
||||
case stmt != nil && q.tx != nil:
|
||||
return q.tx.StmtContext(ctx, stmt).QueryContext(ctx, args...)
|
||||
case stmt != nil:
|
||||
return stmt.QueryContext(ctx, args...)
|
||||
default:
|
||||
return q.db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Queries) queryRow(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) *sql.Row {
|
||||
switch {
|
||||
case stmt != nil && q.tx != nil:
|
||||
return q.tx.StmtContext(ctx, stmt).QueryRowContext(ctx, args...)
|
||||
case stmt != nil:
|
||||
return stmt.QueryRowContext(ctx, args...)
|
||||
default:
|
||||
return q.db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
tx *sql.Tx
|
||||
deleteAllScopeMembersStmt *sql.Stmt
|
||||
deleteScopeStmt *sql.Stmt
|
||||
deleteScopeMemberStmt *sql.Stmt
|
||||
getScopeStmt *sql.Stmt
|
||||
getScopeDisplayNameStmt *sql.Stmt
|
||||
getScopeWithDisplayNameStmt *sql.Stmt
|
||||
insertScopeStmt *sql.Stmt
|
||||
listProjectEntriesStmt *sql.Stmt
|
||||
listScopeMembersStmt *sql.Stmt
|
||||
listScopesStmt *sql.Stmt
|
||||
listScopesByUserStmt *sql.Stmt
|
||||
listStatsStmt *sql.Stmt
|
||||
updateScopeStmt *sql.Stmt
|
||||
updateScopeMemberStmt *sql.Stmt
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
tx: tx,
|
||||
deleteAllScopeMembersStmt: q.deleteAllScopeMembersStmt,
|
||||
deleteScopeStmt: q.deleteScopeStmt,
|
||||
deleteScopeMemberStmt: q.deleteScopeMemberStmt,
|
||||
getScopeStmt: q.getScopeStmt,
|
||||
getScopeDisplayNameStmt: q.getScopeDisplayNameStmt,
|
||||
getScopeWithDisplayNameStmt: q.getScopeWithDisplayNameStmt,
|
||||
insertScopeStmt: q.insertScopeStmt,
|
||||
listProjectEntriesStmt: q.listProjectEntriesStmt,
|
||||
listScopeMembersStmt: q.listScopeMembersStmt,
|
||||
listScopesStmt: q.listScopesStmt,
|
||||
listScopesByUserStmt: q.listScopesByUserStmt,
|
||||
listStatsStmt: q.listStatsStmt,
|
||||
updateScopeStmt: q.updateScopeStmt,
|
||||
updateScopeMemberStmt: q.updateScopeMemberStmt,
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,791 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.13.0
|
||||
// source: item.sql
|
||||
|
||||
package mysqlcore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/sqltypes"
|
||||
)
|
||||
|
||||
const clearItemStatProgress = `-- name: ClearItemStatProgress :exec
|
||||
DELETE FROM item_stat_progress WHERE item_id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) ClearItemStatProgress(ctx context.Context, itemID int) error {
|
||||
_, err := q.db.ExecContext(ctx, clearItemStatProgress, itemID)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteItem = `-- name: DeleteItem :exec
|
||||
DELETE FROM item WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteItem(ctx context.Context, id int) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteItem, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteItemStatProgress = `-- name: DeleteItemStatProgress :exec
|
||||
DELETE FROM item_stat_progress WHERE item_id = ? AND stat_id = ?
|
||||
`
|
||||
|
||||
type DeleteItemStatProgressParams struct {
|
||||
ItemID int
|
||||
StatID int
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteItemStatProgress(ctx context.Context, arg DeleteItemStatProgressParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteItemStatProgress, arg.ItemID, arg.StatID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getItem = `-- name: GetItem :one
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.id = ?
|
||||
`
|
||||
|
||||
type GetItemRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) GetItem(ctx context.Context, id int) (GetItemRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, getItem, id)
|
||||
var i GetItemRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getItemStatProgressBetween = `-- name: GetItemStatProgressBetween :one
|
||||
SELECT s.id, s.name, s.weight, SUM(isp.acquired), SUM(isp.required) FROM item i
|
||||
LEFT JOIN item_stat_progress isp on i.id = isp.item_id
|
||||
LEFT JOIN stat s on isp.stat_id = s.id
|
||||
WHERE i.acquired_time >= ?
|
||||
AND i.acquired_time < ?
|
||||
AND i.scope_id = ?
|
||||
GROUP BY stat_id
|
||||
`
|
||||
|
||||
type GetItemStatProgressBetweenParams struct {
|
||||
AcquiredTime sql.NullTime
|
||||
AcquiredTime_2 sql.NullTime
|
||||
ScopeID int
|
||||
}
|
||||
|
||||
type GetItemStatProgressBetweenRow struct {
|
||||
ID sql.NullInt32
|
||||
Name sql.NullString
|
||||
Weight float64
|
||||
Sum interface{}
|
||||
Sum_2 interface{}
|
||||
}
|
||||
|
||||
func (q *Queries) GetItemStatProgressBetween(ctx context.Context, arg GetItemStatProgressBetweenParams) (GetItemStatProgressBetweenRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, getItemStatProgressBetween, arg.AcquiredTime, arg.AcquiredTime_2, arg.ScopeID)
|
||||
var i GetItemStatProgressBetweenRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Weight,
|
||||
&i.Sum,
|
||||
&i.Sum_2,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertItem = `-- name: InsertItem :execresult
|
||||
INSERT INTO item (scope_id, project_requirement_id, name, description, created_time, created_user_id, acquired_time, scheduled_date)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`
|
||||
|
||||
type InsertItemParams struct {
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
}
|
||||
|
||||
func (q *Queries) InsertItem(ctx context.Context, arg InsertItemParams) (sql.Result, error) {
|
||||
return q.db.ExecContext(ctx, insertItem,
|
||||
arg.ScopeID,
|
||||
arg.ProjectRequirementID,
|
||||
arg.Name,
|
||||
arg.Description,
|
||||
arg.CreatedTime,
|
||||
arg.CreatedUserID,
|
||||
arg.AcquiredTime,
|
||||
arg.ScheduledDate,
|
||||
)
|
||||
}
|
||||
|
||||
const listItemStatProgress = `-- name: ListItemStatProgress :many
|
||||
SELECT isp.required, isp.acquired, s.id, s.name, s.weight FROM item_stat_progress isp
|
||||
LEFT JOIN stat s ON s.id = isp.stat_id
|
||||
WHERE item_id = ?
|
||||
`
|
||||
|
||||
type ListItemStatProgressRow struct {
|
||||
Required int
|
||||
Acquired int
|
||||
ID sql.NullInt32
|
||||
Name sql.NullString
|
||||
Weight float64
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemStatProgress(ctx context.Context, itemID int) ([]ListItemStatProgressRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemStatProgress, itemID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemStatProgressRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemStatProgressRow
|
||||
if err := rows.Scan(
|
||||
&i.Required,
|
||||
&i.Acquired,
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Weight,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemStatProgressMulti = `-- name: ListItemStatProgressMulti :many
|
||||
SELECT isp.item_id, isp.required, isp.acquired, s.id, s.name, s.weight FROM item_stat_progress isp
|
||||
LEFT JOIN stat s ON s.id = isp.stat_id
|
||||
WHERE item_id IN (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`
|
||||
|
||||
type ListItemStatProgressMultiParams struct {
|
||||
ItemID int
|
||||
ItemID_2 int
|
||||
ItemID_3 int
|
||||
ItemID_4 int
|
||||
ItemID_5 int
|
||||
ItemID_6 int
|
||||
ItemID_7 int
|
||||
ItemID_8 int
|
||||
}
|
||||
|
||||
type ListItemStatProgressMultiRow struct {
|
||||
ItemID int
|
||||
Required int
|
||||
Acquired int
|
||||
ID sql.NullInt32
|
||||
Name sql.NullString
|
||||
Weight float64
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemStatProgressMulti(ctx context.Context, arg ListItemStatProgressMultiParams) ([]ListItemStatProgressMultiRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemStatProgressMulti,
|
||||
arg.ItemID,
|
||||
arg.ItemID_2,
|
||||
arg.ItemID_3,
|
||||
arg.ItemID_4,
|
||||
arg.ItemID_5,
|
||||
arg.ItemID_6,
|
||||
arg.ItemID_7,
|
||||
arg.ItemID_8,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemStatProgressMultiRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemStatProgressMultiRow
|
||||
if err := rows.Scan(
|
||||
&i.ItemID,
|
||||
&i.Required,
|
||||
&i.Acquired,
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Weight,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsAcquiredBetween = `-- name: ListItemsAcquiredBetween :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.acquired_time >= ?
|
||||
AND i.acquired_time < ?
|
||||
AND i.scope_id = ?
|
||||
`
|
||||
|
||||
type ListItemsAcquiredBetweenParams struct {
|
||||
AcquiredTime sql.NullTime
|
||||
AcquiredTime_2 sql.NullTime
|
||||
ScopeID int
|
||||
}
|
||||
|
||||
type ListItemsAcquiredBetweenRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsAcquiredBetween(ctx context.Context, arg ListItemsAcquiredBetweenParams) ([]ListItemsAcquiredBetweenRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsAcquiredBetween, arg.AcquiredTime, arg.AcquiredTime_2, arg.ScopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsAcquiredBetweenRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsAcquiredBetweenRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsByProject = `-- name: ListItemsByProject :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE pr.project_id = ?
|
||||
`
|
||||
|
||||
type ListItemsByProjectRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsByProject(ctx context.Context, projectID int) ([]ListItemsByProjectRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsByProject, projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsByProjectRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsByProjectRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsCreatedBetween = `-- name: ListItemsCreatedBetween :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
AND i.scope_id = ?
|
||||
`
|
||||
|
||||
type ListItemsCreatedBetweenParams struct {
|
||||
CreatedTime time.Time
|
||||
CreatedTime_2 time.Time
|
||||
ScopeID int
|
||||
}
|
||||
|
||||
type ListItemsCreatedBetweenRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsCreatedBetween(ctx context.Context, arg ListItemsCreatedBetweenParams) ([]ListItemsCreatedBetweenRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsCreatedBetween, arg.CreatedTime, arg.CreatedTime_2, arg.ScopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsCreatedBetweenRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsCreatedBetweenRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsCreatedBetweenNoScope = `-- name: ListItemsCreatedBetweenNoScope :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
`
|
||||
|
||||
type ListItemsCreatedBetweenNoScopeParams struct {
|
||||
CreatedTime time.Time
|
||||
CreatedTime_2 time.Time
|
||||
}
|
||||
|
||||
type ListItemsCreatedBetweenNoScopeRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsCreatedBetweenNoScope(ctx context.Context, arg ListItemsCreatedBetweenNoScopeParams) ([]ListItemsCreatedBetweenNoScopeRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsCreatedBetweenNoScope, arg.CreatedTime, arg.CreatedTime_2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsCreatedBetweenNoScopeRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsCreatedBetweenNoScopeRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsLooseBetween = `-- name: ListItemsLooseBetween :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
AND i.scope_id = ?
|
||||
AND i.scheduled_date IS NULL
|
||||
AND i.acquired_time IS NULL
|
||||
`
|
||||
|
||||
type ListItemsLooseBetweenParams struct {
|
||||
CreatedTime time.Time
|
||||
CreatedTime_2 time.Time
|
||||
ScopeID int
|
||||
}
|
||||
|
||||
type ListItemsLooseBetweenRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsLooseBetween(ctx context.Context, arg ListItemsLooseBetweenParams) ([]ListItemsLooseBetweenRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsLooseBetween, arg.CreatedTime, arg.CreatedTime_2, arg.ScopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsLooseBetweenRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsLooseBetweenRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsLooseBetweenNoScope = `-- name: ListItemsLooseBetweenNoScope :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
AND i.scheduled_date IS NULL
|
||||
AND i.acquired_time IS NULL
|
||||
`
|
||||
|
||||
type ListItemsLooseBetweenNoScopeParams struct {
|
||||
CreatedTime time.Time
|
||||
CreatedTime_2 time.Time
|
||||
}
|
||||
|
||||
type ListItemsLooseBetweenNoScopeRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsLooseBetweenNoScope(ctx context.Context, arg ListItemsLooseBetweenNoScopeParams) ([]ListItemsLooseBetweenNoScopeRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsLooseBetweenNoScope, arg.CreatedTime, arg.CreatedTime_2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsLooseBetweenNoScopeRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsLooseBetweenNoScopeRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsScheduledBetween = `-- name: ListItemsScheduledBetween :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.scheduled_date >= ?
|
||||
AND i.scheduled_date < ?
|
||||
AND i.scope_id = ?
|
||||
`
|
||||
|
||||
type ListItemsScheduledBetweenParams struct {
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ScheduledDate_2 sqltypes.NullDate
|
||||
ScopeID int
|
||||
}
|
||||
|
||||
type ListItemsScheduledBetweenRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsScheduledBetween(ctx context.Context, arg ListItemsScheduledBetweenParams) ([]ListItemsScheduledBetweenRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsScheduledBetween, arg.ScheduledDate, arg.ScheduledDate_2, arg.ScopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsScheduledBetweenRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsScheduledBetweenRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listItemsScheduledBetweenNoScope = `-- name: ListItemsScheduledBetweenNoScope :many
|
||||
SELECT i.id, i.scope_id, i.project_requirement_id, i.name, i.description, i.created_time, i.created_user_id, i.acquired_time, i.scheduled_date, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.scheduled_date >= ?
|
||||
AND i.scheduled_date < ?
|
||||
`
|
||||
|
||||
type ListItemsScheduledBetweenNoScopeParams struct {
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ScheduledDate_2 sqltypes.NullDate
|
||||
}
|
||||
|
||||
type ListItemsScheduledBetweenNoScopeRow struct {
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
ProjectID sql.NullInt32
|
||||
}
|
||||
|
||||
func (q *Queries) ListItemsScheduledBetweenNoScope(ctx context.Context, arg ListItemsScheduledBetweenNoScopeParams) ([]ListItemsScheduledBetweenNoScopeRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listItemsScheduledBetweenNoScope, arg.ScheduledDate, arg.ScheduledDate_2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ListItemsScheduledBetweenNoScopeRow{}
|
||||
for rows.Next() {
|
||||
var i ListItemsScheduledBetweenNoScopeRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectRequirementID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
&i.CreatedUserID,
|
||||
&i.AcquiredTime,
|
||||
&i.ScheduledDate,
|
||||
&i.ProjectID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const replaceItemStatProgress = `-- name: ReplaceItemStatProgress :exec
|
||||
REPLACE INTO item_stat_progress (item_id, stat_id, acquired, required)
|
||||
VALUES (?, ?, ?, ?)
|
||||
`
|
||||
|
||||
type ReplaceItemStatProgressParams struct {
|
||||
ItemID int
|
||||
StatID int
|
||||
Acquired int
|
||||
Required int
|
||||
}
|
||||
|
||||
func (q *Queries) ReplaceItemStatProgress(ctx context.Context, arg ReplaceItemStatProgressParams) error {
|
||||
_, err := q.db.ExecContext(ctx, replaceItemStatProgress,
|
||||
arg.ItemID,
|
||||
arg.StatID,
|
||||
arg.Acquired,
|
||||
arg.Required,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateItem = `-- name: UpdateItem :exec
|
||||
UPDATE item
|
||||
SET project_requirement_id = ?,
|
||||
name = ?,
|
||||
description = ?,
|
||||
acquired_time = ?,
|
||||
scheduled_date = ?,
|
||||
created_user_id = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateItemParams struct {
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
CreatedUserID string
|
||||
ID int
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateItem(ctx context.Context, arg UpdateItemParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateItem,
|
||||
arg.ProjectRequirementID,
|
||||
arg.Name,
|
||||
arg.Description,
|
||||
arg.AcquiredTime,
|
||||
arg.ScheduledDate,
|
||||
arg.CreatedUserID,
|
||||
arg.ID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -12,67 +12,67 @@ import (
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
ID int `json:"id"`
|
||||
ScopeID int `json:"scope_id"`
|
||||
ProjectRequirementID sql.NullInt32 `json:"project_requirement_id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
CreatedTime time.Time `json:"created_time"`
|
||||
CreatedUserID string `json:"created_user_id"`
|
||||
AcquiredTime sql.NullTime `json:"acquired_time"`
|
||||
ScheduledDate sql.NullTime `json:"scheduled_date"`
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectRequirementID sql.NullInt32
|
||||
Name string
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
CreatedUserID string
|
||||
AcquiredTime sql.NullTime
|
||||
ScheduledDate sqltypes.NullDate
|
||||
}
|
||||
|
||||
type ItemStatProgress struct {
|
||||
ItemID int `json:"item_id"`
|
||||
StatID int `json:"stat_id"`
|
||||
Acquired int `json:"acquired"`
|
||||
Required int `json:"required"`
|
||||
ItemID int
|
||||
StatID int
|
||||
Acquired int
|
||||
Required int
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ID int `json:"id"`
|
||||
ScopeID int `json:"scope_id"`
|
||||
AuthorID string `json:"author_id"`
|
||||
Name string `json:"name"`
|
||||
Status int `json:"status"`
|
||||
Description string `json:"description"`
|
||||
CreatedTime time.Time `json:"created_time"`
|
||||
ID int
|
||||
ScopeID int
|
||||
AuthorID string
|
||||
Name string
|
||||
Status int
|
||||
Description string
|
||||
CreatedTime time.Time
|
||||
}
|
||||
|
||||
type ProjectRequirement struct {
|
||||
ID int `json:"id"`
|
||||
ScopeID int `json:"scope_id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Name string `json:"name"`
|
||||
Status int `json:"status"`
|
||||
Description string `json:"description"`
|
||||
ID int
|
||||
ScopeID int
|
||||
ProjectID int
|
||||
Name string
|
||||
Status int
|
||||
Description string
|
||||
}
|
||||
|
||||
type ProjectRequirementStat struct {
|
||||
ProjectRequirementID int `json:"project_requirement_id"`
|
||||
StatID int `json:"stat_id"`
|
||||
Required int `json:"required"`
|
||||
ProjectRequirementID int
|
||||
StatID int
|
||||
Required int
|
||||
}
|
||||
|
||||
type Scope struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
ID int
|
||||
Name string
|
||||
Abbreviation string
|
||||
}
|
||||
|
||||
type ScopeMember struct {
|
||||
ScopeID int `json:"scope_id"`
|
||||
UserID string `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
Owner bool `json:"owner"`
|
||||
ScopeID int
|
||||
UserID string
|
||||
Name string
|
||||
Owner bool
|
||||
}
|
||||
|
||||
type Stat struct {
|
||||
ID int `json:"id"`
|
||||
ScopeID int `json:"scope_id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Weight float64 `json:"weight"`
|
||||
AllowedAmounts sqltypes.NullRawMessage `json:"allowed_amounts"`
|
||||
ID int
|
||||
ScopeID int
|
||||
Name string
|
||||
Description string
|
||||
Weight float64
|
||||
AllowedAmounts sqltypes.NullRawMessage
|
||||
}
|
||||
|
||||
@@ -9,6 +9,25 @@ import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const getProject = `-- name: GetProject :one
|
||||
SELECT id, scope_id, author_id, name, status, description, created_time FROM project WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetProject(ctx context.Context, id int) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, getProject, id)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.AuthorID,
|
||||
&i.Name,
|
||||
&i.Status,
|
||||
&i.Description,
|
||||
&i.CreatedTime,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listProjectEntries = `-- name: ListProjectEntries :many
|
||||
SELECT id, name, status FROM project
|
||||
WHERE scope_id = ?
|
||||
@@ -16,13 +35,13 @@ ORDER BY status, created_time
|
||||
`
|
||||
|
||||
type ListProjectEntriesRow struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status int `json:"status"`
|
||||
ID int
|
||||
Name string
|
||||
Status int
|
||||
}
|
||||
|
||||
func (q *Queries) ListProjectEntries(ctx context.Context, scopeID int) ([]ListProjectEntriesRow, error) {
|
||||
rows, err := q.query(ctx, q.listProjectEntriesStmt, listProjectEntries, scopeID)
|
||||
rows, err := q.db.QueryContext(ctx, listProjectEntries, scopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -43,3 +62,37 @@ func (q *Queries) ListProjectEntries(ctx context.Context, scopeID int) ([]ListPr
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listProjectRequirementsByProjectID = `-- name: ListProjectRequirementsByProjectID :many
|
||||
SELECT id, scope_id, project_id, name, status, description FROM project_requirement WHERE project_id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) ListProjectRequirementsByProjectID(ctx context.Context, projectID int) ([]ProjectRequirement, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listProjectRequirementsByProjectID, projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []ProjectRequirement{}
|
||||
for rows.Next() {
|
||||
var i ProjectRequirement
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.ScopeID,
|
||||
&i.ProjectID,
|
||||
&i.Name,
|
||||
&i.Status,
|
||||
&i.Description,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ DELETE FROM scope_member WHERE scope_id=?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteAllScopeMembers(ctx context.Context, scopeID int) error {
|
||||
_, err := q.exec(ctx, q.deleteAllScopeMembersStmt, deleteAllScopeMembers, scopeID)
|
||||
_, err := q.db.ExecContext(ctx, deleteAllScopeMembers, scopeID)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ DELETE FROM scope WHERE id=?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteScope(ctx context.Context, id int) error {
|
||||
_, err := q.exec(ctx, q.deleteScopeStmt, deleteScope, id)
|
||||
_, err := q.db.ExecContext(ctx, deleteScope, id)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ DELETE FROM scope_member WHERE scope_id=? AND user_id=?
|
||||
`
|
||||
|
||||
type DeleteScopeMemberParams struct {
|
||||
ScopeID int `json:"scope_id"`
|
||||
UserID string `json:"user_id"`
|
||||
ScopeID int
|
||||
UserID string
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteScopeMember(ctx context.Context, arg DeleteScopeMemberParams) error {
|
||||
_, err := q.exec(ctx, q.deleteScopeMemberStmt, deleteScopeMember, arg.ScopeID, arg.UserID)
|
||||
_, err := q.db.ExecContext(ctx, deleteScopeMember, arg.ScopeID, arg.UserID)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetScope(ctx context.Context, id int) (Scope, error) {
|
||||
row := q.queryRow(ctx, q.getScopeStmt, getScope, id)
|
||||
row := q.db.QueryRowContext(ctx, getScope, id)
|
||||
var i Scope
|
||||
err := row.Scan(&i.ID, &i.Name, &i.Abbreviation)
|
||||
return i, err
|
||||
@@ -60,12 +60,12 @@ WHERE user_id = ? AND scope_id = ?
|
||||
`
|
||||
|
||||
type GetScopeDisplayNameParams struct {
|
||||
UserID string `json:"user_id"`
|
||||
ScopeID int `json:"scope_id"`
|
||||
UserID string
|
||||
ScopeID int
|
||||
}
|
||||
|
||||
func (q *Queries) GetScopeDisplayName(ctx context.Context, arg GetScopeDisplayNameParams) (string, error) {
|
||||
row := q.queryRow(ctx, q.getScopeDisplayNameStmt, getScopeDisplayName, arg.UserID, arg.ScopeID)
|
||||
row := q.db.QueryRowContext(ctx, getScopeDisplayName, arg.UserID, arg.ScopeID)
|
||||
var name string
|
||||
err := row.Scan(&name)
|
||||
return name, err
|
||||
@@ -78,19 +78,19 @@ WHERE id = ? AND sm.user_id = ?
|
||||
`
|
||||
|
||||
type GetScopeWithDisplayNameParams struct {
|
||||
ID int `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
ID int
|
||||
UserID string
|
||||
}
|
||||
|
||||
type GetScopeWithDisplayNameRow struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
DisplayName sql.NullString `json:"display_name"`
|
||||
ID int
|
||||
Name string
|
||||
Abbreviation string
|
||||
DisplayName sql.NullString
|
||||
}
|
||||
|
||||
func (q *Queries) GetScopeWithDisplayName(ctx context.Context, arg GetScopeWithDisplayNameParams) (GetScopeWithDisplayNameRow, error) {
|
||||
row := q.queryRow(ctx, q.getScopeWithDisplayNameStmt, getScopeWithDisplayName, arg.ID, arg.UserID)
|
||||
row := q.db.QueryRowContext(ctx, getScopeWithDisplayName, arg.ID, arg.UserID)
|
||||
var i GetScopeWithDisplayNameRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
@@ -107,13 +107,13 @@ VALUES (?, ?, ?)
|
||||
`
|
||||
|
||||
type InsertScopeParams struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
ID int
|
||||
Name string
|
||||
Abbreviation string
|
||||
}
|
||||
|
||||
func (q *Queries) InsertScope(ctx context.Context, arg InsertScopeParams) (sql.Result, error) {
|
||||
return q.exec(ctx, q.insertScopeStmt, insertScope, arg.ID, arg.Name, arg.Abbreviation)
|
||||
return q.db.ExecContext(ctx, insertScope, arg.ID, arg.Name, arg.Abbreviation)
|
||||
}
|
||||
|
||||
const listScopeMembers = `-- name: ListScopeMembers :many
|
||||
@@ -123,13 +123,13 @@ ORDER BY name
|
||||
`
|
||||
|
||||
type ListScopeMembersRow struct {
|
||||
UserID string `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
Owner bool `json:"owner"`
|
||||
UserID string
|
||||
Name string
|
||||
Owner bool
|
||||
}
|
||||
|
||||
func (q *Queries) ListScopeMembers(ctx context.Context, scopeID int) ([]ListScopeMembersRow, error) {
|
||||
rows, err := q.query(ctx, q.listScopeMembersStmt, listScopeMembers, scopeID)
|
||||
rows, err := q.db.QueryContext(ctx, listScopeMembers, scopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -157,7 +157,7 @@ ORDER BY name
|
||||
`
|
||||
|
||||
func (q *Queries) ListScopes(ctx context.Context) ([]Scope, error) {
|
||||
rows, err := q.query(ctx, q.listScopesStmt, listScopes)
|
||||
rows, err := q.db.QueryContext(ctx, listScopes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -187,14 +187,14 @@ ORDER BY s.name
|
||||
`
|
||||
|
||||
type ListScopesByUserRow struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
DisplayName sql.NullString `json:"display_name"`
|
||||
ID int
|
||||
Name string
|
||||
Abbreviation string
|
||||
DisplayName sql.NullString
|
||||
}
|
||||
|
||||
func (q *Queries) ListScopesByUser(ctx context.Context, userID string) ([]ListScopesByUserRow, error) {
|
||||
rows, err := q.query(ctx, q.listScopesByUserStmt, listScopesByUser, userID)
|
||||
rows, err := q.db.QueryContext(ctx, listScopesByUser, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -226,13 +226,13 @@ UPDATE scope SET name = ?, abbreviation = ? WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateScopeParams struct {
|
||||
Name string `json:"name"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
ID int `json:"id"`
|
||||
Name string
|
||||
Abbreviation string
|
||||
ID int
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateScope(ctx context.Context, arg UpdateScopeParams) error {
|
||||
_, err := q.exec(ctx, q.updateScopeStmt, updateScope, arg.Name, arg.Abbreviation, arg.ID)
|
||||
_, err := q.db.ExecContext(ctx, updateScope, arg.Name, arg.Abbreviation, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -242,14 +242,14 @@ VALUES (?, ?, ?, ?)
|
||||
`
|
||||
|
||||
type UpdateScopeMemberParams struct {
|
||||
ScopeID int `json:"scope_id"`
|
||||
UserID string `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
Owner bool `json:"owner"`
|
||||
ScopeID int
|
||||
UserID string
|
||||
Name string
|
||||
Owner bool
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateScopeMember(ctx context.Context, arg UpdateScopeMemberParams) error {
|
||||
_, err := q.exec(ctx, q.updateScopeMemberStmt, updateScopeMember,
|
||||
_, err := q.db.ExecContext(ctx, updateScopeMember,
|
||||
arg.ScopeID,
|
||||
arg.UserID,
|
||||
arg.Name,
|
||||
|
||||
@@ -17,15 +17,15 @@ WHERE scope_id = ?
|
||||
`
|
||||
|
||||
type ListStatsRow struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Weight float64 `json:"weight"`
|
||||
AllowedAmounts sqltypes.NullRawMessage `json:"allowed_amounts"`
|
||||
ID int
|
||||
Name string
|
||||
Description string
|
||||
Weight float64
|
||||
AllowedAmounts sqltypes.NullRawMessage
|
||||
}
|
||||
|
||||
func (q *Queries) ListStats(ctx context.Context, scopeID int) ([]ListStatsRow, error) {
|
||||
rows, err := q.query(ctx, q.listStatsStmt, listStats, scopeID)
|
||||
rows, err := q.db.QueryContext(ctx, listStats, scopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
-- name: GetItem :one
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.id = ?;
|
||||
|
||||
-- name: ListItemsByProject :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE pr.project_id = ?;
|
||||
|
||||
-- name: ListItemsAcquiredBetween :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.acquired_time >= ?
|
||||
AND i.acquired_time < ?
|
||||
AND i.scope_id = ?;
|
||||
|
||||
-- name: ListItemsScheduledBetween :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.scheduled_date >= ?
|
||||
AND i.scheduled_date < ?
|
||||
AND i.scope_id = ?;
|
||||
|
||||
-- name: ListItemsCreatedBetween :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
AND i.scope_id = ?;
|
||||
|
||||
-- name: ListItemsLooseBetween :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
AND i.scope_id = ?
|
||||
AND i.scheduled_date IS NULL
|
||||
AND i.acquired_time IS NULL;
|
||||
|
||||
-- name: ListItemsScheduledBetweenNoScope :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.scheduled_date >= ?
|
||||
AND i.scheduled_date < ?;
|
||||
|
||||
-- name: ListItemsCreatedBetweenNoScope :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?;
|
||||
|
||||
-- name: ListItemsLooseBetweenNoScope :many
|
||||
SELECT i.*, pr.project_id FROM item i
|
||||
LEFT JOIN project_requirement pr ON pr.id = i.project_requirement_id
|
||||
WHERE i.created_time >= ?
|
||||
AND i.created_time < ?
|
||||
AND i.scheduled_date IS NULL
|
||||
AND i.acquired_time IS NULL;
|
||||
|
||||
-- name: GetItemStatProgressBetween :one
|
||||
SELECT s.id, s.name, s.weight, SUM(isp.acquired), SUM(isp.required) FROM item i
|
||||
LEFT JOIN item_stat_progress isp on i.id = isp.item_id
|
||||
LEFT JOIN stat s on isp.stat_id = s.id
|
||||
WHERE i.acquired_time >= ?
|
||||
AND i.acquired_time < ?
|
||||
AND i.scope_id = ?
|
||||
GROUP BY stat_id;
|
||||
|
||||
-- name: ListItemStatProgress :many
|
||||
SELECT isp.required, isp.acquired, s.id, s.name, s.weight FROM item_stat_progress isp
|
||||
LEFT JOIN stat s ON s.id = isp.stat_id
|
||||
WHERE item_id = ?;
|
||||
|
||||
-- name: ListItemStatProgressMulti :many
|
||||
SELECT isp.item_id, isp.required, isp.acquired, s.id, s.name, s.weight FROM item_stat_progress isp
|
||||
LEFT JOIN stat s ON s.id = isp.stat_id
|
||||
WHERE item_id IN (?, ?, ?, ?, ?, ?, ?, ?);
|
||||
|
||||
-- name: InsertItem :execresult
|
||||
INSERT INTO item (scope_id, project_requirement_id, name, description, created_time, created_user_id, acquired_time, scheduled_date)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?);
|
||||
|
||||
-- name: UpdateItem :exec
|
||||
UPDATE item
|
||||
SET project_requirement_id = ?,
|
||||
name = ?,
|
||||
description = ?,
|
||||
acquired_time = ?,
|
||||
scheduled_date = ?,
|
||||
created_user_id = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: DeleteItem :exec
|
||||
DELETE FROM item WHERE id = ?;
|
||||
|
||||
-- name: ReplaceItemStatProgress :exec
|
||||
REPLACE INTO item_stat_progress (item_id, stat_id, acquired, required)
|
||||
VALUES (?, ?, ?, ?);
|
||||
|
||||
-- name: DeleteItemStatProgress :exec
|
||||
DELETE FROM item_stat_progress WHERE item_id = ? AND stat_id = ?;
|
||||
|
||||
-- name: ClearItemStatProgress :exec
|
||||
DELETE FROM item_stat_progress WHERE item_id = ?;
|
||||
@@ -3,3 +3,9 @@ SELECT id, name, status FROM project
|
||||
WHERE scope_id = ?
|
||||
ORDER BY status, created_time;
|
||||
|
||||
-- name: GetProject :one
|
||||
SELECT * FROM project WHERE id = ?;
|
||||
|
||||
-- name: ListProjectRequirementsByProjectID :many
|
||||
SELECT * FROM project_requirement WHERE project_id = ?;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ type scopeRepository struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (r *scopeRepository) Find(ctx context.Context, id int) (*models.Scope, error) {
|
||||
func (r *scopeRepository) Find(ctx context.Context, id int, full bool) (*models.Scope, error) {
|
||||
q := mysqlcore.New(r.db)
|
||||
scope, err := q.GetScope(ctx, id)
|
||||
if err != nil {
|
||||
@@ -37,6 +37,55 @@ func (r *scopeRepository) Find(ctx context.Context, id int) (*models.Scope, erro
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
if full {
|
||||
eg.Go(func() error {
|
||||
projects, err := q.ListProjectEntries(ctx, id)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, project := range projects {
|
||||
res.Projects = append(res.Projects, models.ProjectEntry{
|
||||
ID: project.ID,
|
||||
Name: project.Name,
|
||||
Status: models.Status(project.Status),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
stats, err := q.ListStats(ctx, id)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, stat := range stats {
|
||||
var amounts map[string]int
|
||||
if stat.AllowedAmounts.Valid {
|
||||
amounts = make(map[string]int)
|
||||
err := json.Unmarshal(stat.AllowedAmounts.RawMessage, &amounts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
res.Stats = append(res.Stats, models.Stat{
|
||||
StatEntry: models.StatEntry{
|
||||
ID: stat.ID,
|
||||
Name: stat.Name,
|
||||
Weight: stat.Weight,
|
||||
},
|
||||
Description: stat.Description,
|
||||
AllowedAmounts: amounts,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
eg.Go(func() error {
|
||||
members, err := q.ListScopeMembers(ctx, id)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
@@ -54,53 +103,6 @@ func (r *scopeRepository) Find(ctx context.Context, id int) (*models.Scope, erro
|
||||
return nil
|
||||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
projects, err := q.ListProjectEntries(ctx, id)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, project := range projects {
|
||||
res.Projects = append(res.Projects, models.ProjectEntry{
|
||||
ID: project.ID,
|
||||
Name: project.Name,
|
||||
Status: models.Status(project.Status),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
eg.Go(func() error {
|
||||
stats, err := q.ListStats(ctx, id)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, stat := range stats {
|
||||
var amounts map[string]int
|
||||
if stat.AllowedAmounts.Valid {
|
||||
amounts = make(map[string]int)
|
||||
err := json.Unmarshal(stat.AllowedAmounts.RawMessage, &amounts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
res.Stats = append(res.Stats, models.Stat{
|
||||
StatEntry: models.StatEntry{
|
||||
ID: stat.ID,
|
||||
Name: stat.Name,
|
||||
Weight: stat.Weight,
|
||||
},
|
||||
Description: stat.Description,
|
||||
AllowedAmounts: amounts,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
err = eg.Wait()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Date [3]int
|
||||
|
||||
func ParseDate(s string) (Date, error) {
|
||||
date, err := time.ParseInLocation("2006-01-02", s, time.UTC)
|
||||
if err != nil {
|
||||
return [3]int{}, err
|
||||
}
|
||||
|
||||
y, m, d := date.Date()
|
||||
return Date{y, int(m), d}, nil
|
||||
}
|
||||
|
||||
func (d *Date) UnmarshalJSON(b []byte) error {
|
||||
var str string
|
||||
err := json.Unmarshal(b, &str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*d, err = ParseDate(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d Date) String() string {
|
||||
return fmt.Sprintf("%04d-%02d-%02d", d[0], d[1], d[2])
|
||||
}
|
||||
|
||||
func (d Date) MarshalJSON() ([]byte, error) {
|
||||
return []byte("\"" + d.String() + "\""), nil
|
||||
}
|
||||
|
||||
func (d Date) ToTime() time.Time {
|
||||
return time.Date(d[0], time.Month(d[1]), d[2], 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
+80
-10
@@ -3,15 +3,85 @@ package models
|
||||
import "time"
|
||||
|
||||
type Item struct {
|
||||
ID int
|
||||
ProjectRequirementID *int
|
||||
OwnerID string
|
||||
ID int `json:"id"`
|
||||
ScopeID int `json:"scopeId"`
|
||||
OwnerID string `json:"-"`
|
||||
ProjectID *int `json:"projectId,omitempty"`
|
||||
ProjectRequirementID *int `json:"projectRequirementId,omitempty"`
|
||||
|
||||
Name string
|
||||
Description string
|
||||
OwnerName string
|
||||
CreatedTime time.Time
|
||||
AcquiredTime *time.Time
|
||||
ScheduledDate *time.Time
|
||||
Stats []StatProgressEntry
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
CreatedTime time.Time `json:"createdTime"`
|
||||
AcquiredTime *time.Time `json:"acquiredTime"`
|
||||
ScheduledDate *Date `json:"scheduledDate"`
|
||||
|
||||
Stats []StatProgressEntry `json:"stats,omitempty"`
|
||||
Owner *ScopeMember `json:"owner,omitempty"`
|
||||
}
|
||||
|
||||
func (item *Item) ApplyUpdate(update ItemUpdate) {
|
||||
if update.ProjectRequirementID != nil {
|
||||
item.ProjectRequirementID = update.ProjectRequirementID
|
||||
}
|
||||
if update.OwnerID != nil {
|
||||
item.OwnerID = *update.OwnerID
|
||||
item.Owner = nil
|
||||
}
|
||||
if update.Name != nil {
|
||||
item.Name = *update.Name
|
||||
}
|
||||
if update.Description != nil {
|
||||
item.Description = *update.Description
|
||||
}
|
||||
if update.AcquiredTime != nil {
|
||||
item.AcquiredTime = update.AcquiredTime
|
||||
}
|
||||
if update.ScheduledDate != nil {
|
||||
item.ScheduledDate = update.ScheduledDate
|
||||
}
|
||||
if update.ClearScheduledDate {
|
||||
item.ScheduledDate = nil
|
||||
}
|
||||
if update.ClearProjectRequirementID {
|
||||
item.ProjectRequirementID = nil
|
||||
}
|
||||
if update.ClearAcquiredTime {
|
||||
item.AcquiredTime = nil
|
||||
}
|
||||
|
||||
deleteList := make([]int, 0, len(update.Stats))
|
||||
for i, stat := range update.Stats {
|
||||
if stat.Acquired == 0 && stat.Required == 0 {
|
||||
deleteList = append(deleteList, i-len(deleteList))
|
||||
}
|
||||
|
||||
found := false
|
||||
for j := range item.Stats {
|
||||
if item.Stats[j].ID == stat.ID {
|
||||
item.Stats[j].Required = stat.Required
|
||||
item.Stats[j].Acquired = stat.Acquired
|
||||
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
item.Stats = append(item.Stats, stat)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ItemUpdate struct {
|
||||
ProjectRequirementID *int `json:"projectRequirementId"`
|
||||
OwnerID *string `json:"ownerId"`
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
AcquiredTime *time.Time `json:"acquiredTime"`
|
||||
ScheduledDate *Date `json:"scheduledDate"`
|
||||
|
||||
Stats []StatProgressEntry `json:"stats"`
|
||||
|
||||
ClearProjectRequirementID bool `json:"clearProjectRequirementId"`
|
||||
ClearAcquiredTime bool `json:"clearAcquiredTime"`
|
||||
ClearScheduledDate bool `json:"clearScheduledDate"`
|
||||
}
|
||||
|
||||
@@ -11,5 +11,19 @@ type ProjectRequirement struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Status Status `json:"status"`
|
||||
Stats []StatProgressEntry `json:"stats,omitempty"`
|
||||
Items []Item `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectRequirementUpdate struct {
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
Status *Status `json:"status"`
|
||||
Stats []StatProgressEntry `json:"stats"`
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ProjectEntry
|
||||
Description string
|
||||
Requirements []ProjectRequirement
|
||||
}
|
||||
|
||||
@@ -16,9 +16,19 @@ type Scope struct {
|
||||
ScopeEntry
|
||||
|
||||
DisplayName string `json:"displayName"`
|
||||
Members []ScopeMember `json:"members"`
|
||||
Projects []ProjectEntry `json:"projects"`
|
||||
Stats []Stat `json:"stats"`
|
||||
Members []ScopeMember `json:"members,omitempty"`
|
||||
Projects []ProjectEntry `json:"projects,omitempty"`
|
||||
Stats []Stat `json:"stats,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Scope) Member(id string) *ScopeMember {
|
||||
for _, user := range s.Members {
|
||||
if user.ID == id {
|
||||
return &user
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scope) HasMember(id string) bool {
|
||||
@@ -30,3 +40,13 @@ func (s *Scope) HasMember(id string) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Scope) Stat(id int) *Stat {
|
||||
for _, stat := range s.Stats {
|
||||
if stat.ID == id {
|
||||
return &stat
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -19,3 +19,20 @@ type Stat struct {
|
||||
Description string `json:"description"`
|
||||
AllowedAmounts map[string]int `json:"allowedAmounts"`
|
||||
}
|
||||
|
||||
func (stat *Stat) AllowsAmount(amount int) bool {
|
||||
if stat == nil {
|
||||
return false
|
||||
}
|
||||
if stat.AllowedAmounts == nil || len(stat.AllowedAmounts) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, v := range stat.AllowedAmounts {
|
||||
if v == amount {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package sqltypes
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"git.aiterp.net/stufflog3/stufflog3-api/internal/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NullDate struct {
|
||||
Date models.Date
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func (n *NullDate) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Valid = false
|
||||
return nil
|
||||
}
|
||||
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
date, err := models.ParseDate(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n.Date = date
|
||||
n.Valid = true
|
||||
case time.Time:
|
||||
n.Date = models.Date{value.Year(), int(value.Month()), value.Day()}
|
||||
n.Valid = true
|
||||
default:
|
||||
return errors.New("invalid type")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n NullDate) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return n.Date.String(), nil
|
||||
}
|
||||
@@ -5,17 +5,23 @@ packages:
|
||||
queries: "./internal/database/mysql/queries"
|
||||
schema: "./scripts/goose-mysql"
|
||||
engine: "mysql"
|
||||
emit_prepared_queries: true
|
||||
emit_prepared_queries: false
|
||||
emit_interface: false
|
||||
emit_exact_table_names: false
|
||||
emit_empty_slices: true
|
||||
emit_json_tags: true
|
||||
emit_json_tags: false
|
||||
overrides:
|
||||
- go_type: "git.aiterp.net/stufflog3/stufflog3-api/internal/sqltypes.NullRawMessage"
|
||||
db_type: "json"
|
||||
nullable: true
|
||||
- go_type: "git.aiterp.net/stufflog3/stufflog3-api/internal/sqltypes.NullDate"
|
||||
db_type: "date"
|
||||
nullable: true
|
||||
- go_type: "float64"
|
||||
db_type: "float"
|
||||
- go_type: "float64"
|
||||
db_type: "float"
|
||||
nullable: true
|
||||
- go_type: "int"
|
||||
db_type: "int"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user