Gisle Aune
3 years ago
23 changed files with 1831 additions and 348 deletions
-
39api/common.go
-
72api/items.go
-
2api/scope.go
-
1cmd/stufflog3-server.go
-
30internal/database/database.go
-
4internal/database/mysql/database.go
-
354internal/database/mysql/items.go
-
187internal/database/mysql/mysqlcore/db.go
-
791internal/database/mysql/mysqlcore/item.sql.go
-
84internal/database/mysql/mysqlcore/models.go
-
61internal/database/mysql/mysqlcore/project.sql.go
-
78internal/database/mysql/mysqlcore/scope.sql.go
-
12internal/database/mysql/mysqlcore/stats.sql.go
-
105internal/database/mysql/queries/item.sql
-
6internal/database/mysql/queries/project.sql
-
38internal/database/mysql/scopes.go
-
46internal/models/common.go
-
92internal/models/item.go
-
14internal/models/project.go
-
26internal/models/scope.go
-
17internal/models/stat.go
-
46internal/sqltypes/nulldate.go
-
10sqlc.yaml
@ -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 |
||||
|
})) |
||||
|
} |
@ -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 |
||||
|
} |
@ -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 |
||||
|
} |
@ -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 = ?; |
@ -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) |
||||
|
} |
@ -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 |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue