Gisle Aune
2 years ago
commit
e2d098e03f
60 changed files with 4832 additions and 0 deletions
-
2.gitignore
-
104cmd/stufflog3-local/main.go
-
57entities/item.go
-
58entities/project.go
-
15entities/scope.go
-
59entities/sprint.go
-
42entities/stat.go
-
8go.mod
-
51go.sum
-
46models/date.go
-
47models/errors.go
-
15models/item.go
-
14models/project.go
-
6models/scope.go
-
23models/sprint.go
-
13models/stat.go
-
29models/status.go
-
71ports/httpapi/auth.go
-
68ports/httpapi/common.go
-
21ports/httpapi/projects.go
-
104ports/httpapi/scopes.go
-
90ports/mysql/db.go
-
125ports/mysql/items.go
-
598ports/mysql/mysqlcore/db.go
-
805ports/mysql/mysqlcore/items.sql.go
-
100ports/mysql/mysqlcore/models.go
-
323ports/mysql/mysqlcore/projects.sql.go
-
278ports/mysql/mysqlcore/scopes.sql.go
-
155ports/mysql/mysqlcore/stats.sql.go
-
246ports/mysql/projects.go
-
114ports/mysql/queries/items.sql
-
60ports/mysql/queries/projects.sql
-
43ports/mysql/queries/scopes.sql
-
26ports/mysql/queries/stats.sql
-
197ports/mysql/scopes.go
-
55ports/mysql/sqltypes/nulldate.go
-
36ports/mysql/sqltypes/nullrawmessage.go
-
91ports/mysql/stats.go
-
14scripts/goose-mysql/20220313115117_scope.sql
-
17scripts/goose-mysql/20220313115122_scope_member.sql
-
18scripts/goose-mysql/20220326173144_stat.sql
-
18scripts/goose-mysql/20220326174046_project.sql
-
16scripts/goose-mysql/20220404144911_project_requirement.sql
-
19scripts/goose-mysql/20220404144914_item.sql
-
17scripts/goose-mysql/20220404144947_item_stat_progress.sql
-
15scripts/goose-mysql/20220404184237_project_requirement_stat.sql
-
9scripts/goose-mysql/20220411190154_project_created_time.sql
-
22scripts/goose-mysql/20220502181149_sprint.sql
-
16scripts/goose-mysql/20220502181235_sprint_part.sql
-
30sqlc.yaml
-
22usecases/auth/service.go
-
22usecases/items/repository.go
-
28usecases/items/service.go
-
21usecases/projects/repository.go
-
143usecases/projects/result.go
-
65usecases/projects/service.go
-
20usecases/scopes/repository.go
-
73usecases/scopes/service.go
-
15usecases/stats/repository.go
-
17usecases/stats/service.go
@ -0,0 +1,2 @@ |
|||
/.idea |
|||
.env |
@ -0,0 +1,104 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/httpapi" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/auth" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/items" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/projects" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/stats" |
|||
"github.com/gin-gonic/gin" |
|||
"log" |
|||
"os" |
|||
"os/signal" |
|||
"strconv" |
|||
"syscall" |
|||
) |
|||
|
|||
func main() { |
|||
db, err := mysql.Connect( |
|||
os.Getenv("STUFFLOG3_MYSQL_HOST"), |
|||
envInt("STUFFLOG3_MYSQL_PORT"), |
|||
os.Getenv("STUFFLOG3_MYSQL_USERNAME"), |
|||
os.Getenv("STUFFLOG3_MYSQL_PASSWORD"), |
|||
os.Getenv("STUFFLOG3_MYSQL_SCHEMA"), |
|||
) |
|||
if err != nil { |
|||
log.Println("Failed to open database:", err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
authService := &auth.Service{} |
|||
scopesService := &scopes.Service{ |
|||
Auth: authService, |
|||
Repository: db.Scopes(), |
|||
} |
|||
statsSerice := &stats.Service{ |
|||
Scopes: scopesService, |
|||
Repository: db.Stats(), |
|||
} |
|||
itemsService := &items.Service{ |
|||
Scopes: scopesService, |
|||
Stats: statsSerice, |
|||
Repository: db.Items(), |
|||
} |
|||
projectsService := &projects.Service{ |
|||
Scopes: scopesService, |
|||
Stats: statsSerice, |
|||
Items: itemsService, |
|||
Repository: db.Projects(), |
|||
} |
|||
|
|||
server := gin.New() |
|||
apiV1 := server.Group("/api/v1") |
|||
if os.Getenv("STUFFLOG3_USE_DUMMY_USER") != "" { |
|||
log.Println("Using dummy UUID") |
|||
apiV1.Use(httpapi.DummyMiddleware(authService, "c11230be-4912-4313-83b0-410a248b5bd1")) |
|||
} else { |
|||
apiV1.Use(httpapi.TrustingJwtParserMiddleware(authService)) |
|||
} |
|||
apiV1Scopes := apiV1.Group("/scopes") |
|||
apiV1ScopesSub := apiV1Scopes.Group("/:scope_id") |
|||
apiV1ScopesSub.Use(httpapi.ScopeMiddleware(scopesService)) |
|||
httpapi.Scopes(apiV1Scopes, scopesService) |
|||
httpapi.Projects(apiV1ScopesSub.Group("/projects"), projectsService) |
|||
|
|||
exitSignal := make(chan os.Signal) |
|||
signal.Notify(exitSignal, os.Interrupt, os.Kill, syscall.SIGTERM) |
|||
|
|||
errCh := make(chan error) |
|||
go func() { |
|||
err := server.Run(":8239") |
|||
if err != nil { |
|||
errCh <- err |
|||
} |
|||
}() |
|||
|
|||
select { |
|||
case sig := <-exitSignal: |
|||
{ |
|||
log.Println("Received signal", sig) |
|||
os.Exit(0) |
|||
} |
|||
case err := <-errCh: |
|||
{ |
|||
log.Println("Server run failed:", err) |
|||
os.Exit(2) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func envInt(key string) int { |
|||
value := os.Getenv(key) |
|||
if value == "" { |
|||
return 0 |
|||
} |
|||
|
|||
intValue, err := strconv.Atoi(value) |
|||
if err != nil { |
|||
return 0 |
|||
} |
|||
|
|||
return intValue |
|||
} |
@ -0,0 +1,57 @@ |
|||
package entities |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"time" |
|||
) |
|||
|
|||
type Item struct { |
|||
ID int `json:"id"` |
|||
ScopeID int `json:"scopeId"` |
|||
OwnerID string `json:"ownerId"` |
|||
ProjectID *int `json:"projectId,omitempty"` |
|||
ProjectRequirementID *int `json:"projectRequirementId,omitempty"` |
|||
Name string `json:"name"` |
|||
Description string `json:"description"` |
|||
CreatedTime time.Time `json:"createdTime"` |
|||
AcquiredTime *time.Time `json:"acquiredTime"` |
|||
ScheduledDate *models.Date `json:"scheduledDate"` |
|||
} |
|||
|
|||
type ItemProgress struct { |
|||
ItemID int `json:"itemId"` |
|||
StatID int `json:"statId"` |
|||
Acquired int `json:"acquired"` |
|||
Required int `json:"required"` |
|||
} |
|||
|
|||
func (item *Item) ApplyUpdate(update models.ItemUpdate) { |
|||
if update.ProjectRequirementID != nil { |
|||
if *update.ProjectRequirementID <= 0 { |
|||
item.ProjectRequirementID = nil |
|||
} else { |
|||
item.ProjectRequirementID = update.ProjectRequirementID |
|||
} |
|||
} |
|||
if update.OwnerID != nil { |
|||
item.OwnerID = *update.OwnerID |
|||
} |
|||
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.ClearAcquiredTime { |
|||
item.AcquiredTime = nil |
|||
} |
|||
} |
@ -0,0 +1,58 @@ |
|||
package entities |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"time" |
|||
) |
|||
|
|||
type Project struct { |
|||
ID int `json:"id"` |
|||
ScopeID int `json:"scopeId"` |
|||
OwnerID string `json:"ownerId"` |
|||
CreatedTime time.Time `json:"createdTime"` |
|||
Name string `json:"name"` |
|||
Description string `json:"description"` |
|||
Status models.Status `json:"status"` |
|||
} |
|||
|
|||
func (project *Project) Update(update models.ProjectUpdate) { |
|||
if update.OwnerID != nil { |
|||
project.OwnerID = *update.OwnerID |
|||
} |
|||
if update.Name != nil { |
|||
project.Name = *update.Name |
|||
} |
|||
if update.Description != nil { |
|||
project.Description = *update.Description |
|||
} |
|||
if update.Status != nil { |
|||
project.Status = *update.Status |
|||
} |
|||
} |
|||
|
|||
type Requirement struct { |
|||
ID int `json:"id"` |
|||
ScopeID int `json:"scopeId"` |
|||
ProjectID int `json:"projectId"` |
|||
Name string `json:"name"` |
|||
Description string `json:"description"` |
|||
Status models.Status `json:"status"` |
|||
} |
|||
|
|||
func (requirement Requirement) Update(update models.RequirementUpdate) { |
|||
if update.Name != nil { |
|||
requirement.Name = *update.Name |
|||
} |
|||
if update.Description != nil { |
|||
requirement.Description = *update.Description |
|||
} |
|||
if update.Status != nil { |
|||
requirement.Status = *update.Status |
|||
} |
|||
} |
|||
|
|||
type RequirementStat struct { |
|||
RequirementID int `json:"requirementId"` |
|||
StatID int `json:"statId"` |
|||
Required int `json:"required"` |
|||
} |
@ -0,0 +1,15 @@ |
|||
package entities |
|||
|
|||
type Scope struct { |
|||
ID int `json:"id"` |
|||
Name string `json:"name"` |
|||
Abbreviation string `json:"abbreviation"` |
|||
CustomLabels map[string]string `json:"customLabels"` |
|||
} |
|||
|
|||
type ScopeMember struct { |
|||
ScopeID int `json:"scopeId"` |
|||
UserID string `json:"userId"` |
|||
Name string `json:"name"` |
|||
Owner bool `json:"owner"` |
|||
} |
@ -0,0 +1,59 @@ |
|||
package entities |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"time" |
|||
) |
|||
|
|||
type Sprint struct { |
|||
ID int `json:"id"` |
|||
ScopeID int `json:"scopeId"` |
|||
Name string `json:"name"` |
|||
Description string `json:"description"` |
|||
Kind models.SprintKind `json:"kind"` |
|||
|
|||
FromTime time.Time `json:"fromTime"` |
|||
ToTime time.Time `json:"toTime"` |
|||
|
|||
IsTimed bool `json:"isTimed"` |
|||
IsCoarse bool `json:"isCoarse"` |
|||
IsUnweighted bool `json:"isUnweighted"` |
|||
|
|||
AggregateName string `json:"aggregateName"` |
|||
AggregateAcquired float64 `json:"aggregateAcquired"` |
|||
AggregateRequired int `json:"aggregateRequired"` |
|||
} |
|||
|
|||
// SprintPart is not meant for the frontend, but it can be submitted.
|
|||
type SprintPart struct { |
|||
SprintID int `json:"sprintId"` |
|||
PartID int `json:"partId"` |
|||
Required int `json:"required,omitempty"` |
|||
} |
|||
|
|||
func (sprint *Sprint) ApplyUpdate(update models.SprintUpdate) { |
|||
if update.Name != nil { |
|||
sprint.Name = *update.Name |
|||
} |
|||
if update.Description != nil { |
|||
sprint.Description = *update.Description |
|||
} |
|||
if update.FromTime != nil { |
|||
sprint.FromTime = *update.FromTime |
|||
} |
|||
if update.ToTime != nil { |
|||
sprint.ToTime = *update.ToTime |
|||
} |
|||
if update.IsTimed != nil { |
|||
sprint.IsTimed = *update.IsTimed |
|||
} |
|||
if update.IsCoarse != nil { |
|||
sprint.IsCoarse = *update.IsCoarse |
|||
} |
|||
if update.AggregateName != nil { |
|||
sprint.AggregateName = *update.AggregateName |
|||
} |
|||
if update.AggregateRequired != nil { |
|||
sprint.AggregateRequired = *update.AggregateRequired |
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
package entities |
|||
|
|||
import "git.aiterp.net/stufflog3/stufflog3/models" |
|||
|
|||
type Stat struct { |
|||
ID int `json:"id"` |
|||
Name string `json:"name"` |
|||
Weight float64 `json:"weight"` |
|||
Description string `json:"description"` |
|||
AllowedAmounts []models.StatAllowedAmount `json:"allowedAmounts"` |
|||
} |
|||
|
|||
func (stat *Stat) Update(update models.StatUpdate) { |
|||
if update.Name != nil { |
|||
stat.Name = *update.Name |
|||
} |
|||
if update.Weight != nil { |
|||
stat.Weight = *update.Weight |
|||
} |
|||
if update.Description != nil { |
|||
stat.Description = *update.Description |
|||
} |
|||
for _, amount := range update.AllowedAmounts { |
|||
found := false |
|||
for i, existing := range stat.AllowedAmounts { |
|||
if existing.Label == amount.Label { |
|||
if amount.Value <= 0 { |
|||
stat.AllowedAmounts = append(stat.AllowedAmounts[:i], stat.AllowedAmounts[i+1:]...) |
|||
} else { |
|||
stat.AllowedAmounts[i].Value = amount.Value |
|||
} |
|||
|
|||
found = true |
|||
break |
|||
} |
|||
} |
|||
|
|||
if !found && amount.Value > 0 { |
|||
stat.AllowedAmounts = append(stat.AllowedAmounts, amount) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
module git.aiterp.net/stufflog3/stufflog3 |
|||
|
|||
go 1.13 |
|||
|
|||
require ( |
|||
github.com/gin-gonic/gin v1.7.7 |
|||
github.com/go-sql-driver/mysql v1.6.0 |
|||
) |
@ -0,0 +1,51 @@ |
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
|||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= |
|||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= |
|||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= |
|||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= |
|||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= |
|||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= |
|||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= |
|||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= |
|||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= |
|||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= |
|||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= |
|||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= |
|||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= |
|||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= |
|||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= |
|||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= |
|||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= |
|||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= |
|||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= |
|||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= |
|||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= |
|||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= |
|||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= |
|||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
|||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= |
|||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= |
|||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= |
|||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= |
|||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= |
|||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= |
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= |
|||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= |
|||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= |
|||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
|||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
|||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
|||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
|||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= |
|||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
@ -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,47 @@ |
|||
package models |
|||
|
|||
import "fmt" |
|||
|
|||
type NotFoundError string |
|||
|
|||
func (e NotFoundError) Error() string { |
|||
return fmt.Sprintf("%s not found or inaccessible", string(e)) |
|||
} |
|||
|
|||
func (e NotFoundError) HttpStatus() (int, string, interface{}) { |
|||
return 404, e.Error(), nil |
|||
} |
|||
|
|||
type PermissionDeniedError struct{} |
|||
|
|||
func (e PermissionDeniedError) Error() string { |
|||
return "Permission denied" |
|||
} |
|||
|
|||
func (e PermissionDeniedError) HttpStatus() (int, string, interface{}) { |
|||
return 403, "Permission denied", nil |
|||
} |
|||
|
|||
type BadInputError struct { |
|||
Object string |
|||
Field string |
|||
Problem string |
|||
Min interface{} |
|||
Max interface{} |
|||
} |
|||
|
|||
func (e BadInputError) Error() string { |
|||
if e.Min != nil && e.Max != nil { |
|||
return fmt.Sprintf("%s.%s: %s (min: %v, max: %v)", e.Object, e.Field, e.Problem, e.Min, e.Max) |
|||
} else if e.Min != nil { |
|||
return fmt.Sprintf("%s.%s: %s (min: %v)", e.Object, e.Field, e.Problem, e.Min) |
|||
} else if e.Max != nil { |
|||
return fmt.Sprintf("%s.%s: %s (max: %v)", e.Object, e.Field, e.Problem, e.Max) |
|||
} else { |
|||
return fmt.Sprintf("%s.%s: %s", e.Object, e.Field, e.Problem) |
|||
} |
|||
} |
|||
|
|||
func (e BadInputError) HttpStatus() (int, string, interface{}) { |
|||
return 400, e.Error(), &e |
|||
} |
@ -0,0 +1,15 @@ |
|||
package models |
|||
|
|||
import "time" |
|||
|
|||
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"` |
|||
|
|||
ClearAcquiredTime bool `json:"clearAcquiredTime"` |
|||
ClearScheduledDate bool `json:"clearScheduledDate"` |
|||
} |
@ -0,0 +1,14 @@ |
|||
package models |
|||
|
|||
type ProjectUpdate struct { |
|||
Name *string `json:"name,omitempty"` |
|||
OwnerID *string `json:"ownerId,omitempty"` |
|||
Status *Status `json:"status,omitempty"` |
|||
Description *string `json:"description,omitempty"` |
|||
} |
|||
|
|||
type RequirementUpdate struct { |
|||
Name *string `json:"name"` |
|||
Description *string `json:"description"` |
|||
Status *Status `json:"status"` |
|||
} |
@ -0,0 +1,6 @@ |
|||
package models |
|||
|
|||
type ScopeUpdate struct { |
|||
Name *string |
|||
Abbreviation *string |
|||
} |
@ -0,0 +1,23 @@ |
|||
package models |
|||
|
|||
import "time" |
|||
|
|||
type SprintUpdate struct { |
|||
Name *string `json:"name"` |
|||
Description *string `json:"description"` |
|||
FromTime *time.Time `json:"fromTime"` |
|||
ToTime *time.Time `json:"toTime"` |
|||
IsTimed *bool `json:"isTimed"` |
|||
IsCoarse *bool `json:"isCoarse"` |
|||
AggregateName *string `json:"aggregateName"` |
|||
AggregateRequired *int `json:"aggregateRequired"` |
|||
} |
|||
|
|||
type SprintKind int |
|||
|
|||
const ( |
|||
SprintKindItems SprintKind = iota |
|||
SprintKindRequirements |
|||
SprintKindStats |
|||
SprintKindScope |
|||
) |
@ -0,0 +1,13 @@ |
|||
package models |
|||
|
|||
type StatUpdate struct { |
|||
Name *string `json:"name"` |
|||
Weight *float64 `json:"weight"` |
|||
Description *string `json:"description"` |
|||
AllowedAmounts []StatAllowedAmount `json:"allowedAmounts"` |
|||
} |
|||
|
|||
type StatAllowedAmount struct { |
|||
Label string `json:"label"` |
|||
Value int `json:"value"` |
|||
} |
@ -0,0 +1,29 @@ |
|||
package models |
|||
|
|||
type Status int |
|||
|
|||
func (s Status) Valid() bool { |
|||
return s >= 0 && s < maxStatus |
|||
} |
|||
|
|||
const ( |
|||
Blocked Status = iota |
|||
Available |
|||
Background |
|||
Active |
|||
Completed |
|||
Failed |
|||
Dropped |
|||
|
|||
maxStatus |
|||
) |
|||
|
|||
var StatusLabels = map[Status]string{ |
|||
Blocked: "Blocked", |
|||
Available: "Available", |
|||
Background: "Background", |
|||
Active: "Active", |
|||
Completed: "Completed", |
|||
Failed: "Failed", |
|||
Dropped: "Dropped", |
|||
} |
@ -0,0 +1,71 @@ |
|||
package httpapi |
|||
|
|||
import ( |
|||
"context" |
|||
"encoding/base64" |
|||
"encoding/json" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/auth" |
|||
"github.com/gin-gonic/gin" |
|||
"net/http" |
|||
"strings" |
|||
) |
|||
|
|||
var contextKey = struct{}{} |
|||
|
|||
func UserID(ctx context.Context) string { |
|||
if c, ok := ctx.(*gin.Context); ok { |
|||
return UserID(c.Request.Context()) |
|||
} |
|||
|
|||
return ctx.Value(&contextKey).(string) |
|||
} |
|||
|
|||
func DummyMiddleware(auth *auth.Service, uuid string) gin.HandlerFunc { |
|||
return func(c *gin.Context) { |
|||
c.Request = c.Request.WithContext( |
|||
auth.ContextWithUser(c.Request.Context(), uuid), |
|||
) |
|||
} |
|||
} |
|||
|
|||
func abortRequest(c *gin.Context) { |
|||
c.AbortWithStatusJSON(http.StatusUnauthorized, Error{ |
|||
Code: http.StatusUnauthorized, |
|||
Message: "You're not supposed to be here!", |
|||
}) |
|||
} |
|||
|
|||
// TrustingJwtParserMiddleware is meant to be put behind an AWS API gateway that has already
|
|||
// verified this token.
|
|||
func TrustingJwtParserMiddleware(auth *auth.Service) gin.HandlerFunc { |
|||
return func(c *gin.Context) { |
|||
authHeader := c.GetHeader("Authorization") |
|||
split := strings.Split(authHeader, ".") |
|||
|
|||
if len(split) >= 3 { |
|||
data, err := base64.RawStdEncoding.DecodeString(split[1]) |
|||
if err != nil { |
|||
abortRequest(c) |
|||
return |
|||
} |
|||
|
|||
fields := make(map[string]interface{}) |
|||
err = json.Unmarshal(data, &fields) |
|||
if err != nil { |
|||
abortRequest(c) |
|||
return |
|||
} |
|||
|
|||
if sub, ok := fields["sub"].(string); ok { |
|||
c.Request = c.Request.WithContext( |
|||
auth.ContextWithUser(c.Request.Context(), sub), |
|||
) |
|||
} else { |
|||
abortRequest(c) |
|||
return |
|||
} |
|||
} else { |
|||
abortRequest(c) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
package httpapi |
|||
|
|||
import ( |
|||
"crypto/rand" |
|||
"encoding/hex" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"github.com/gin-gonic/gin" |
|||
"log" |
|||
"strconv" |
|||
) |
|||
|
|||
type statusError interface { |
|||
HttpStatus() (int, string, interface{}) |
|||
} |
|||
|
|||
func handler(key string, callback func(c *gin.Context) (interface{}, error)) gin.HandlerFunc { |
|||
return func(c *gin.Context) { |
|||
res, err := callback(c) |
|||
if err != nil { |
|||
if statusError, ok := err.(statusError); ok { |
|||
code, msg, data := statusError.HttpStatus() |
|||
c.JSON(code, Error{ |
|||
Code: code, |
|||
Message: msg, |
|||
Data: data, |
|||
}) |
|||
} else { |
|||
id := make([]byte, 16) |
|||
_, _ = rand.Read(id) |
|||
idHex := hex.EncodeToString(id) |
|||
|
|||
log.Println("Internal server error", idHex, "triggered by:", err) |
|||
|
|||
c.JSON(500, Error{ |
|||
Code: 500, |
|||
Message: "Internal server error (" + idHex + ")", |
|||
Data: nil, |
|||
}) |
|||
} |
|||
|
|||
return |
|||
} |
|||
|
|||
resJson := make(map[string]interface{}, 1) |
|||
resJson[key] = res |
|||
|
|||
c.JSON(200, resJson) |
|||
} |
|||
} |
|||
|
|||
type Error struct { |
|||
Code int `json:"statusCode"` |
|||
Message string `json:"statusMessage"` |
|||
Data interface{} `json:"errorData,omitempty"` |
|||
} |
|||
|
|||
func reqInt(c *gin.Context, key string) (int, error) { |
|||
v, err := strconv.Atoi(c.Param(key)) |
|||
if err != nil { |
|||
return 0, models.BadInputError{ |
|||
Object: "query", |
|||
Field: key, |
|||
Problem: "Value for " + key + " must be numeric", |
|||
} |
|||
} |
|||
|
|||
return v, nil |
|||
} |
@ -0,0 +1,21 @@ |
|||
package httpapi |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/projects" |
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
func Projects(g *gin.RouterGroup, projects *projects.Service) { |
|||
g.GET("", handler("projects", func(c *gin.Context) (interface{}, error) { |
|||
return projects.List(c.Request.Context()) |
|||
})) |
|||
|
|||
g.GET("/:project_id", handler("project", func(c *gin.Context) (interface{}, error) { |
|||
id, err := reqInt(c, "project_id") |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return projects.Find(c.Request.Context(), id) |
|||
})) |
|||
} |
@ -0,0 +1,104 @@ |
|||
package httpapi |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
"github.com/gin-gonic/gin" |
|||
"net/http" |
|||
) |
|||
|
|||
type scopeResult struct { |
|||
entities.Scope |
|||
|
|||
Members []scopeResultMember `json:"members"` |
|||
} |
|||
|
|||
type scopeResultMember struct { |
|||
ID string `json:"id"` |
|||
Name string `json:"name"` |
|||
Owner bool `json:"owner"` |
|||
} |
|||
|
|||
func ScopeMiddleware(scopes *scopes.Service) gin.HandlerFunc { |
|||
return func(c *gin.Context) { |
|||
id, err := reqInt(c, "scope_id") |
|||
if err != nil { |
|||
c.AbortWithStatusJSON(http.StatusUnauthorized, Error{ |
|||
Code: http.StatusBadRequest, |
|||
Message: "Invalid scope ID in path!", |
|||
Data: models.BadInputError{ |
|||
Object: "params", |
|||
Field: "scopeid", |
|||
Problem: "Not a number", |
|||
}, |
|||
}) |
|||
} |
|||
|
|||
scope, _, err := scopes.Find(c.Request.Context(), id) |
|||
if err != nil { |
|||
c.AbortWithStatusJSON(http.StatusUnauthorized, Error{ |
|||
Code: http.StatusNotFound, |
|||
Message: "Scope not found or inaccessible", |
|||
}) |
|||
} |
|||
|
|||
c.Request = c.Request.WithContext(scopes.ContextWithScope(c.Request.Context(), *scope)) |
|||
} |
|||
} |
|||
|
|||
func Scopes(g *gin.RouterGroup, scopes *scopes.Service) { |
|||
g.GET("", handler("scopes", func(c *gin.Context) (interface{}, error) { |
|||
scopes, members, err := scopes.List(c.Request.Context()) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
results := make([]scopeResult, 0, len(scopes)) |
|||
for _, scope := range scopes { |
|||
resMembers := make([]scopeResultMember, 0, len(members)/2) |
|||
for _, member := range members { |
|||
if member.ScopeID == scope.ID { |
|||
resMembers = append(resMembers, scopeResultMember{ |
|||
ID: member.UserID, |
|||
Name: member.Name, |
|||
Owner: member.Owner, |
|||
}) |
|||
} |
|||
} |
|||
|
|||
results = append(results, scopeResult{ |
|||
Scope: scope, |
|||
Members: resMembers, |
|||
}) |
|||
} |
|||
|
|||
return results, nil |
|||
})) |
|||
|
|||
g.GET("/:scope_id", handler("scope", func(c *gin.Context) (interface{}, error) { |
|||
id, err := reqInt(c, "scope_id") |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
scope, members, err := scopes.Find(c.Request.Context(), id) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
resMembers := make([]scopeResultMember, 0, len(members)/2) |
|||
for _, member := range members { |
|||
resMembers = append(resMembers, scopeResultMember{ |
|||
ID: member.UserID, |
|||
Name: member.Name, |
|||
Owner: member.Owner, |
|||
}) |
|||
} |
|||
|
|||
return scopeResult{ |
|||
Scope: *scope, |
|||
Members: resMembers, |
|||
}, nil |
|||
})) |
|||
} |
@ -0,0 +1,90 @@ |
|||
package mysql |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"fmt" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/items" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/projects" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/stats" |
|||
"time" |
|||
|
|||
_ "github.com/go-sql-driver/mysql" |
|||
) |
|||
|
|||
type Database struct { |
|||
db *sql.DB |
|||
q *mysqlcore.Queries |
|||
} |
|||
|
|||
func (db *Database) Scopes() scopes.Repository { |
|||
return &scopeRepository{ |
|||
db: db.db, |
|||
q: db.q, |
|||
} |
|||
} |
|||
|
|||
func (db *Database) Projects() projects.Repository { |
|||
return &projectRepository{ |
|||
db: db.db, |
|||
q: db.q, |
|||
} |
|||
} |
|||
|
|||
func (db *Database) Stats() stats.Repository { |
|||
return &statsRepository{ |
|||
db: db.db, |
|||
q: db.q, |
|||
} |
|||
} |
|||
|
|||
func (db *Database) Items() items.Repository { |
|||
return &itemRepository{ |
|||
db: db.db, |
|||
q: db.q, |
|||
} |
|||
} |
|||
|
|||
func Connect(host string, port int, username, password, database string) (*Database, error) { |
|||
db, err := sql.Open("mysql", fmt.Sprintf( |
|||
"%s:%s@(%s:%d)/%s?parseTime=true", username, password, host, port, database, |
|||
)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
db.SetMaxOpenConns(10) |
|||
db.SetMaxIdleConns(10) |
|||
db.SetConnMaxIdleTime(time.Minute) |
|||
|
|||
err = db.Ping() |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
q, err := mysqlcore.Prepare(context.Background(), db) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return &Database{db: db, q: q}, nil |
|||
} |
|||
|
|||
func timePtr(nullTime sql.NullTime) *time.Time { |
|||
if nullTime.Valid { |
|||
return &nullTime.Time |
|||
} else { |
|||
return nil |
|||
} |
|||
} |
|||
|
|||
func intPtr(nullInt32 sql.NullInt32) *int { |
|||
if nullInt32.Valid { |
|||
v := int(nullInt32.Int32) |
|||
return &v |
|||
} else { |
|||
return nil |
|||
} |
|||
} |
@ -0,0 +1,125 @@ |
|||
package mysql |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore" |
|||
"strings" |
|||
"time" |
|||
) |
|||
|
|||
type itemRepository struct { |
|||
db *sql.DB |
|||
q *mysqlcore.Queries |
|||
} |
|||
|
|||
func (r *itemRepository) Find(ctx context.Context, scopeID, itemID int) (*entities.Item, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) ListCreated(ctx context.Context, scopeID int, from, to time.Time) ([]entities.Item, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) ListAcquired(ctx context.Context, scopeID int, from, to time.Time) ([]entities.Item, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) ListScheduled(ctx context.Context, scopeID int, from, to models.Date) ([]entities.Item, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) ListRequirement(ctx context.Context, requirementID int) ([]entities.Item, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) ListProject(ctx context.Context, projectID int) ([]entities.Item, error) { |
|||
rows, err := r.q.ListItemsByProject(ctx, projectID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
res := make([]entities.Item, 0, len(rows)) |
|||
for _, row := range rows { |
|||
res = append(res, entities.Item{ |
|||
ID: row.ID, |
|||
ScopeID: row.ScopeID, |
|||
OwnerID: row.OwnerID, |
|||
ProjectID: intPtr(row.ProjectID), |
|||
ProjectRequirementID: intPtr(row.ProjectRequirementID), |
|||
Name: row.Name, |
|||
Description: row.Description, |
|||
CreatedTime: row.CreatedTime, |
|||
AcquiredTime: timePtr(row.AcquiredTime), |
|||
ScheduledDate: row.ScheduledDate.AsPtr(), |
|||
}) |
|||
} |
|||
|
|||
return res, nil |
|||
} |
|||
|
|||
func (r *itemRepository) Insert(ctx context.Context, item entities.Item) (*entities.Item, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) Update(ctx context.Context, item entities.Item, update models.ItemUpdate) error { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) Delete(ctx context.Context, item entities.Item) error { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *itemRepository) ListProgress(ctx context.Context, items ...entities.Item) ([]entities.ItemProgress, error) { |
|||
if len(items) == 0 { |
|||
return []entities.ItemProgress{}, nil |
|||
} |
|||
|
|||
ids := make([]interface{}, 0, 64) |
|||
for _, item := range items { |
|||
ids = append(ids, item.ID) |
|||
} |
|||
|
|||
query := ` |
|||
SELECT item_id, stat_id, acquired, required FROM item_stat_progress |
|||
WHERE item_id IN (?` + strings.Repeat(",?", len(ids)-1) + `); |
|||
` |
|||
|
|||
rows, err := r.db.QueryContext(ctx, query, ids...) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return []entities.ItemProgress{}, nil |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
res := make([]entities.ItemProgress, 0, 8) |
|||
for rows.Next() { |
|||
progress := entities.ItemProgress{} |
|||
|
|||
err = rows.Scan(&progress.ItemID, &progress.StatID, &progress.Acquired, &progress.Required) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
res = append(res, progress) |
|||
} |
|||
|
|||
return res, nil |
|||
} |
|||
|
|||
func (r *itemRepository) UpdateProgress(ctx context.Context, item entities.ItemProgress) error { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
@ -0,0 +1,598 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
|
|||
package mysqlcore |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"fmt" |
|||
) |
|||
|
|||
type DBTX interface { |
|||
ExecContext(context.Context, string, ...interface{}) (sql.Result, error) |
|||
PrepareContext(context.Context, string) (*sql.Stmt, error) |
|||
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) |
|||
QueryRowContext(context.Context, string, ...interface{}) *sql.Row |
|||
} |
|||
|
|||
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.clearItemProjectRequirementStmt, err = db.PrepareContext(ctx, clearItemProjectRequirement); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ClearItemProjectRequirement: %w", err) |
|||
} |
|||
if q.clearItemStatProgressStmt, err = db.PrepareContext(ctx, clearItemStatProgress); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ClearItemStatProgress: %w", err) |
|||
} |
|||
if q.deleteAllItemStatProgressByStatIdStmt, err = db.PrepareContext(ctx, deleteAllItemStatProgressByStatId); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteAllItemStatProgressByStatId: %w", err) |
|||
} |
|||
if q.deleteAllProjectRequirementStatByStatIdStmt, err = db.PrepareContext(ctx, deleteAllProjectRequirementStatByStatId); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteAllProjectRequirementStatByStatId: %w", err) |
|||
} |
|||
if q.deleteAllProjectRequirementStatsStmt, err = db.PrepareContext(ctx, deleteAllProjectRequirementStats); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteAllProjectRequirementStats: %w", err) |
|||
} |
|||
if q.deleteAllProjectRequirementsStmt, err = db.PrepareContext(ctx, deleteAllProjectRequirements); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteAllProjectRequirements: %w", err) |
|||
} |
|||
if q.deleteAllScopeMembersStmt, err = db.PrepareContext(ctx, deleteAllScopeMembers); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteAllScopeMembers: %w", err) |
|||
} |
|||
if q.deleteItemStmt, err = db.PrepareContext(ctx, deleteItem); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteItem: %w", err) |
|||
} |
|||
if q.deleteItemForRequirementStmt, err = db.PrepareContext(ctx, deleteItemForRequirement); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteItemForRequirement: %w", err) |
|||
} |
|||
if q.deleteItemStatProgressStmt, err = db.PrepareContext(ctx, deleteItemStatProgress); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteItemStatProgress: %w", err) |
|||
} |
|||
if q.deleteProjectStmt, err = db.PrepareContext(ctx, deleteProject); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteProject: %w", err) |
|||
} |
|||
if q.deleteProjectRequirementStmt, err = db.PrepareContext(ctx, deleteProjectRequirement); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteProjectRequirement: %w", err) |
|||
} |
|||
if q.deleteProjectRequirementStatStmt, err = db.PrepareContext(ctx, deleteProjectRequirementStat); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteProjectRequirementStat: %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.deleteStatStmt, err = db.PrepareContext(ctx, deleteStat); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteStat: %w", err) |
|||
} |
|||
if q.getItemStmt, err = db.PrepareContext(ctx, getItem); err != nil { |
|||
return nil, fmt.Errorf("error preparing query GetItem: %w", err) |
|||
} |
|||
if q.getItemStatProgressBetweenStmt, err = db.PrepareContext(ctx, getItemStatProgressBetween); err != nil { |
|||
return nil, fmt.Errorf("error preparing query GetItemStatProgressBetween: %w", err) |
|||
} |
|||
if q.getProjectStmt, err = db.PrepareContext(ctx, getProject); err != nil { |
|||
return nil, fmt.Errorf("error preparing query GetProject: %w", err) |
|||
} |
|||
if q.getScopeStmt, err = db.PrepareContext(ctx, getScope); err != nil { |
|||
return nil, fmt.Errorf("error preparing query GetScope: %w", err) |
|||
} |
|||
if q.getStatStmt, err = db.PrepareContext(ctx, getStat); err != nil { |
|||
return nil, fmt.Errorf("error preparing query GetStat: %w", err) |
|||
} |
|||
if q.insertItemStmt, err = db.PrepareContext(ctx, insertItem); err != nil { |
|||
return nil, fmt.Errorf("error preparing query InsertItem: %w", err) |
|||
} |
|||
if q.insertProjectStmt, err = db.PrepareContext(ctx, insertProject); err != nil { |
|||
return nil, fmt.Errorf("error preparing query InsertProject: %w", err) |
|||
} |
|||
if q.insertProjectRequirementStmt, err = db.PrepareContext(ctx, insertProjectRequirement); err != nil { |
|||
return nil, fmt.Errorf("error preparing query InsertProjectRequirement: %w", err) |
|||
} |
|||
if q.insertScopeStmt, err = db.PrepareContext(ctx, insertScope); err != nil { |
|||
return nil, fmt.Errorf("error preparing query InsertScope: %w", err) |
|||
} |
|||
if q.insertStatStmt, err = db.PrepareContext(ctx, insertStat); err != nil { |
|||
return nil, fmt.Errorf("error preparing query InsertStat: %w", err) |
|||
} |
|||
if q.listItemStatProgressStmt, err = db.PrepareContext(ctx, listItemStatProgress); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemStatProgress: %w", err) |
|||
} |
|||
if q.listItemStatProgressMultiStmt, err = db.PrepareContext(ctx, listItemStatProgressMulti); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemStatProgressMulti: %w", err) |
|||
} |
|||
if q.listItemsAcquiredBetweenStmt, err = db.PrepareContext(ctx, listItemsAcquiredBetween); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsAcquiredBetween: %w", err) |
|||
} |
|||
if q.listItemsByProjectStmt, err = db.PrepareContext(ctx, listItemsByProject); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsByProject: %w", err) |
|||
} |
|||
if q.listItemsCreatedBetweenStmt, err = db.PrepareContext(ctx, listItemsCreatedBetween); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsCreatedBetween: %w", err) |
|||
} |
|||
if q.listItemsCreatedBetweenNoScopeStmt, err = db.PrepareContext(ctx, listItemsCreatedBetweenNoScope); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsCreatedBetweenNoScope: %w", err) |
|||
} |
|||
if q.listItemsLooseBetweenStmt, err = db.PrepareContext(ctx, listItemsLooseBetween); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsLooseBetween: %w", err) |
|||
} |
|||
if q.listItemsLooseBetweenNoScopeStmt, err = db.PrepareContext(ctx, listItemsLooseBetweenNoScope); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsLooseBetweenNoScope: %w", err) |
|||
} |
|||
if q.listItemsScheduledBetweenStmt, err = db.PrepareContext(ctx, listItemsScheduledBetween); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsScheduledBetween: %w", err) |
|||
} |
|||
if q.listItemsScheduledBetweenNoScopeStmt, err = db.PrepareContext(ctx, listItemsScheduledBetweenNoScope); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListItemsScheduledBetweenNoScope: %w", err) |
|||
} |
|||
if q.listProjectRequirementsStmt, err = db.PrepareContext(ctx, listProjectRequirements); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListProjectRequirements: %w", err) |
|||
} |
|||
if q.listProjectRequirementsStatsStmt, err = db.PrepareContext(ctx, listProjectRequirementsStats); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListProjectRequirementsStats: %w", err) |
|||
} |
|||
if q.listProjectsStmt, err = db.PrepareContext(ctx, listProjects); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListProjects: %w", err) |
|||
} |
|||
if q.listScopeMembersStmt, err = db.PrepareContext(ctx, listScopeMembers); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListScopeMembers: %w", err) |
|||
} |
|||
if q.listScopeMembersMultiStmt, err = db.PrepareContext(ctx, listScopeMembersMulti); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListScopeMembersMulti: %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.replaceItemStatProgressStmt, err = db.PrepareContext(ctx, replaceItemStatProgress); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ReplaceItemStatProgress: %w", err) |
|||
} |
|||
if q.replaceProjectRequirementStatStmt, err = db.PrepareContext(ctx, replaceProjectRequirementStat); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ReplaceProjectRequirementStat: %w", err) |
|||
} |
|||
if q.replaceScopeMemberStmt, err = db.PrepareContext(ctx, replaceScopeMember); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ReplaceScopeMember: %w", err) |
|||
} |
|||
if q.updateItemStmt, err = db.PrepareContext(ctx, updateItem); err != nil { |
|||
return nil, fmt.Errorf("error preparing query UpdateItem: %w", err) |
|||
} |
|||
if q.updateProjectStmt, err = db.PrepareContext(ctx, updateProject); err != nil { |
|||
return nil, fmt.Errorf("error preparing query UpdateProject: %w", err) |
|||
} |
|||
if q.updateProjectRequirementStmt, err = db.PrepareContext(ctx, updateProjectRequirement); err != nil { |
|||
return nil, fmt.Errorf("error preparing query UpdateProjectRequirement: %w", err) |
|||
} |
|||
if q.updateScopeStmt, err = db.PrepareContext(ctx, updateScope); err != nil { |
|||
return nil, fmt.Errorf("error preparing query UpdateScope: %w", err) |
|||
} |
|||
if q.updateStatStmt, err = db.PrepareContext(ctx, updateStat); err != nil { |
|||
return nil, fmt.Errorf("error preparing query UpdateStat: %w", err) |
|||
} |
|||
return &q, nil |
|||
} |
|||
|
|||
func (q *Queries) Close() error { |
|||
var err error |
|||
if q.clearItemProjectRequirementStmt != nil { |
|||
if cerr := q.clearItemProjectRequirementStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing clearItemProjectRequirementStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.clearItemStatProgressStmt != nil { |
|||
if cerr := q.clearItemStatProgressStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing clearItemStatProgressStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteAllItemStatProgressByStatIdStmt != nil { |
|||
if cerr := q.deleteAllItemStatProgressByStatIdStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteAllItemStatProgressByStatIdStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteAllProjectRequirementStatByStatIdStmt != nil { |
|||
if cerr := q.deleteAllProjectRequirementStatByStatIdStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteAllProjectRequirementStatByStatIdStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteAllProjectRequirementStatsStmt != nil { |
|||
if cerr := q.deleteAllProjectRequirementStatsStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteAllProjectRequirementStatsStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteAllProjectRequirementsStmt != nil { |
|||
if cerr := q.deleteAllProjectRequirementsStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteAllProjectRequirementsStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteAllScopeMembersStmt != nil { |
|||
if cerr := q.deleteAllScopeMembersStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteAllScopeMembersStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteItemStmt != nil { |
|||
if cerr := q.deleteItemStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteItemStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteItemForRequirementStmt != nil { |
|||
if cerr := q.deleteItemForRequirementStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteItemForRequirementStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteItemStatProgressStmt != nil { |
|||
if cerr := q.deleteItemStatProgressStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteItemStatProgressStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteProjectStmt != nil { |
|||
if cerr := q.deleteProjectStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteProjectStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteProjectRequirementStmt != nil { |
|||
if cerr := q.deleteProjectRequirementStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteProjectRequirementStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteProjectRequirementStatStmt != nil { |
|||
if cerr := q.deleteProjectRequirementStatStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteProjectRequirementStatStmt: %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.deleteStatStmt != nil { |
|||
if cerr := q.deleteStatStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteStatStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.getItemStmt != nil { |
|||
if cerr := q.getItemStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing getItemStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.getItemStatProgressBetweenStmt != nil { |
|||
if cerr := q.getItemStatProgressBetweenStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing getItemStatProgressBetweenStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.getProjectStmt != nil { |
|||
if cerr := q.getProjectStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing getProjectStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.getScopeStmt != nil { |
|||
if cerr := q.getScopeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing getScopeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.getStatStmt != nil { |
|||
if cerr := q.getStatStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing getStatStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.insertItemStmt != nil { |
|||
if cerr := q.insertItemStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing insertItemStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.insertProjectStmt != nil { |
|||
if cerr := q.insertProjectStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing insertProjectStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.insertProjectRequirementStmt != nil { |
|||
if cerr := q.insertProjectRequirementStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing insertProjectRequirementStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.insertScopeStmt != nil { |
|||
if cerr := q.insertScopeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing insertScopeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.insertStatStmt != nil { |
|||
if cerr := q.insertStatStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing insertStatStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemStatProgressStmt != nil { |
|||
if cerr := q.listItemStatProgressStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemStatProgressStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemStatProgressMultiStmt != nil { |
|||
if cerr := q.listItemStatProgressMultiStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemStatProgressMultiStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsAcquiredBetweenStmt != nil { |
|||
if cerr := q.listItemsAcquiredBetweenStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsAcquiredBetweenStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsByProjectStmt != nil { |
|||
if cerr := q.listItemsByProjectStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsByProjectStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsCreatedBetweenStmt != nil { |
|||
if cerr := q.listItemsCreatedBetweenStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsCreatedBetweenStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsCreatedBetweenNoScopeStmt != nil { |
|||
if cerr := q.listItemsCreatedBetweenNoScopeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsCreatedBetweenNoScopeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsLooseBetweenStmt != nil { |
|||
if cerr := q.listItemsLooseBetweenStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsLooseBetweenStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsLooseBetweenNoScopeStmt != nil { |
|||
if cerr := q.listItemsLooseBetweenNoScopeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsLooseBetweenNoScopeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsScheduledBetweenStmt != nil { |
|||
if cerr := q.listItemsScheduledBetweenStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsScheduledBetweenStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listItemsScheduledBetweenNoScopeStmt != nil { |
|||
if cerr := q.listItemsScheduledBetweenNoScopeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listItemsScheduledBetweenNoScopeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listProjectRequirementsStmt != nil { |
|||
if cerr := q.listProjectRequirementsStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listProjectRequirementsStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listProjectRequirementsStatsStmt != nil { |
|||
if cerr := q.listProjectRequirementsStatsStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listProjectRequirementsStatsStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listProjectsStmt != nil { |
|||
if cerr := q.listProjectsStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listProjectsStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listScopeMembersStmt != nil { |
|||
if cerr := q.listScopeMembersStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listScopeMembersStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listScopeMembersMultiStmt != nil { |
|||
if cerr := q.listScopeMembersMultiStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listScopeMembersMultiStmt: %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.replaceItemStatProgressStmt != nil { |
|||
if cerr := q.replaceItemStatProgressStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing replaceItemStatProgressStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.replaceProjectRequirementStatStmt != nil { |
|||
if cerr := q.replaceProjectRequirementStatStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing replaceProjectRequirementStatStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.replaceScopeMemberStmt != nil { |
|||
if cerr := q.replaceScopeMemberStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing replaceScopeMemberStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.updateItemStmt != nil { |
|||
if cerr := q.updateItemStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing updateItemStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.updateProjectStmt != nil { |
|||
if cerr := q.updateProjectStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing updateProjectStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.updateProjectRequirementStmt != nil { |
|||
if cerr := q.updateProjectRequirementStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing updateProjectRequirementStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.updateScopeStmt != nil { |
|||
if cerr := q.updateScopeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing updateScopeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.updateStatStmt != nil { |
|||
if cerr := q.updateStatStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing updateStatStmt: %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 |
|||
clearItemProjectRequirementStmt *sql.Stmt |
|||
clearItemStatProgressStmt *sql.Stmt |
|||
deleteAllItemStatProgressByStatIdStmt *sql.Stmt |
|||
deleteAllProjectRequirementStatByStatIdStmt *sql.Stmt |
|||
deleteAllProjectRequirementStatsStmt *sql.Stmt |
|||
deleteAllProjectRequirementsStmt *sql.Stmt |
|||
deleteAllScopeMembersStmt *sql.Stmt |
|||
deleteItemStmt *sql.Stmt |
|||
deleteItemForRequirementStmt *sql.Stmt |
|||
deleteItemStatProgressStmt *sql.Stmt |
|||
deleteProjectStmt *sql.Stmt |
|||
deleteProjectRequirementStmt *sql.Stmt |
|||
deleteProjectRequirementStatStmt *sql.Stmt |
|||
deleteScopeStmt *sql.Stmt |
|||
deleteScopeMemberStmt *sql.Stmt |
|||
deleteStatStmt *sql.Stmt |
|||
getItemStmt *sql.Stmt |
|||
getItemStatProgressBetweenStmt *sql.Stmt |
|||
getProjectStmt *sql.Stmt |
|||
getScopeStmt *sql.Stmt |
|||
getStatStmt *sql.Stmt |
|||
insertItemStmt *sql.Stmt |
|||
insertProjectStmt *sql.Stmt |
|||
insertProjectRequirementStmt *sql.Stmt |
|||
insertScopeStmt *sql.Stmt |
|||
insertStatStmt *sql.Stmt |
|||
listItemStatProgressStmt *sql.Stmt |
|||
listItemStatProgressMultiStmt *sql.Stmt |
|||
listItemsAcquiredBetweenStmt *sql.Stmt |
|||
listItemsByProjectStmt *sql.Stmt |
|||
listItemsCreatedBetweenStmt *sql.Stmt |
|||
listItemsCreatedBetweenNoScopeStmt *sql.Stmt |
|||
listItemsLooseBetweenStmt *sql.Stmt |
|||
listItemsLooseBetweenNoScopeStmt *sql.Stmt |
|||
listItemsScheduledBetweenStmt *sql.Stmt |
|||
listItemsScheduledBetweenNoScopeStmt *sql.Stmt |
|||
listProjectRequirementsStmt *sql.Stmt |
|||
listProjectRequirementsStatsStmt *sql.Stmt |
|||
listProjectsStmt *sql.Stmt |
|||
listScopeMembersStmt *sql.Stmt |
|||
listScopeMembersMultiStmt *sql.Stmt |
|||
listScopesStmt *sql.Stmt |
|||
listScopesByUserStmt *sql.Stmt |
|||
listStatsStmt *sql.Stmt |
|||
replaceItemStatProgressStmt *sql.Stmt |
|||
replaceProjectRequirementStatStmt *sql.Stmt |
|||
replaceScopeMemberStmt *sql.Stmt |
|||
updateItemStmt *sql.Stmt |
|||
updateProjectStmt *sql.Stmt |
|||
updateProjectRequirementStmt *sql.Stmt |
|||
updateScopeStmt *sql.Stmt |
|||
updateStatStmt *sql.Stmt |
|||
} |
|||
|
|||
func (q *Queries) WithTx(tx *sql.Tx) *Queries { |
|||
return &Queries{ |
|||
db: tx, |
|||
tx: tx, |
|||
clearItemProjectRequirementStmt: q.clearItemProjectRequirementStmt, |
|||
clearItemStatProgressStmt: q.clearItemStatProgressStmt, |
|||
deleteAllItemStatProgressByStatIdStmt: q.deleteAllItemStatProgressByStatIdStmt, |
|||
deleteAllProjectRequirementStatByStatIdStmt: q.deleteAllProjectRequirementStatByStatIdStmt, |
|||
deleteAllProjectRequirementStatsStmt: q.deleteAllProjectRequirementStatsStmt, |
|||
deleteAllProjectRequirementsStmt: q.deleteAllProjectRequirementsStmt, |
|||
deleteAllScopeMembersStmt: q.deleteAllScopeMembersStmt, |
|||
deleteItemStmt: q.deleteItemStmt, |
|||
deleteItemForRequirementStmt: q.deleteItemForRequirementStmt, |
|||
deleteItemStatProgressStmt: q.deleteItemStatProgressStmt, |
|||
deleteProjectStmt: q.deleteProjectStmt, |
|||
deleteProjectRequirementStmt: q.deleteProjectRequirementStmt, |
|||
deleteProjectRequirementStatStmt: q.deleteProjectRequirementStatStmt, |
|||
deleteScopeStmt: q.deleteScopeStmt, |
|||
deleteScopeMemberStmt: q.deleteScopeMemberStmt, |
|||
deleteStatStmt: q.deleteStatStmt, |
|||
getItemStmt: q.getItemStmt, |
|||
getItemStatProgressBetweenStmt: q.getItemStatProgressBetweenStmt, |
|||
getProjectStmt: q.getProjectStmt, |
|||
getScopeStmt: q.getScopeStmt, |
|||
getStatStmt: q.getStatStmt, |
|||
insertItemStmt: q.insertItemStmt, |
|||
insertProjectStmt: q.insertProjectStmt, |
|||
insertProjectRequirementStmt: q.insertProjectRequirementStmt, |
|||
insertScopeStmt: q.insertScopeStmt, |
|||
insertStatStmt: q.insertStatStmt, |
|||
listItemStatProgressStmt: q.listItemStatProgressStmt, |
|||
listItemStatProgressMultiStmt: q.listItemStatProgressMultiStmt, |
|||
listItemsAcquiredBetweenStmt: q.listItemsAcquiredBetweenStmt, |
|||
listItemsByProjectStmt: q.listItemsByProjectStmt, |
|||
listItemsCreatedBetweenStmt: q.listItemsCreatedBetweenStmt, |
|||
listItemsCreatedBetweenNoScopeStmt: q.listItemsCreatedBetweenNoScopeStmt, |
|||
listItemsLooseBetweenStmt: q.listItemsLooseBetweenStmt, |
|||
listItemsLooseBetweenNoScopeStmt: q.listItemsLooseBetweenNoScopeStmt, |
|||
listItemsScheduledBetweenStmt: q.listItemsScheduledBetweenStmt, |
|||
listItemsScheduledBetweenNoScopeStmt: q.listItemsScheduledBetweenNoScopeStmt, |
|||
listProjectRequirementsStmt: q.listProjectRequirementsStmt, |
|||
listProjectRequirementsStatsStmt: q.listProjectRequirementsStatsStmt, |
|||
listProjectsStmt: q.listProjectsStmt, |
|||
listScopeMembersStmt: q.listScopeMembersStmt, |
|||
listScopeMembersMultiStmt: q.listScopeMembersMultiStmt, |
|||
listScopesStmt: q.listScopesStmt, |
|||
listScopesByUserStmt: q.listScopesByUserStmt, |
|||
listStatsStmt: q.listStatsStmt, |
|||
replaceItemStatProgressStmt: q.replaceItemStatProgressStmt, |
|||
replaceProjectRequirementStatStmt: q.replaceProjectRequirementStatStmt, |
|||
replaceScopeMemberStmt: q.replaceScopeMemberStmt, |
|||
updateItemStmt: q.updateItemStmt, |
|||
updateProjectStmt: q.updateProjectStmt, |
|||
updateProjectRequirementStmt: q.updateProjectRequirementStmt, |
|||
updateScopeStmt: q.updateScopeStmt, |
|||
updateStatStmt: q.updateStatStmt, |
|||
} |
|||
} |
@ -0,0 +1,805 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
// source: items.sql
|
|||
|
|||
package mysqlcore |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"time" |
|||
|
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/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.exec(ctx, q.clearItemStatProgressStmt, 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.exec(ctx, q.deleteItemStmt, deleteItem, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteItemForRequirement = `-- name: DeleteItemForRequirement :exec |
|||
DELETE FROM item WHERE project_requirement_id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteItemForRequirement(ctx context.Context, projectRequirementID sql.NullInt32) error { |
|||
_, err := q.exec(ctx, q.deleteItemForRequirementStmt, deleteItemForRequirement, projectRequirementID) |
|||
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.exec(ctx, q.deleteItemStatProgressStmt, deleteItemStatProgress, arg.ItemID, arg.StatID) |
|||
return err |
|||
} |
|||
|
|||
const getItem = `-- name: GetItem :one |
|||
SELECT i.id, i.scope_id, i.project_requirement_id, i.owner_id, i.name, i.description, i.created_time, 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 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) GetItem(ctx context.Context, id int) (GetItemRow, error) { |
|||
row := q.queryRow(ctx, q.getItemStmt, getItem, id) |
|||
var i GetItemRow |
|||
err := row.Scan( |
|||
&i.ID, |
|||
&i.ScopeID, |
|||
&i.ProjectRequirementID, |
|||
&i.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.queryRow(ctx, q.getItemStatProgressBetweenStmt, 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, owner_id, acquired_time, scheduled_date) |
|||
VALUES (?, ?, ?, ?, ?, ?, ?, ?) |
|||
` |
|||
|
|||
type InsertItemParams struct { |
|||
ScopeID int |
|||
ProjectRequirementID sql.NullInt32 |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
OwnerID string |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
} |
|||
|
|||
func (q *Queries) InsertItem(ctx context.Context, arg InsertItemParams) (sql.Result, error) { |
|||
return q.exec(ctx, q.insertItemStmt, insertItem, |
|||
arg.ScopeID, |
|||
arg.ProjectRequirementID, |
|||
arg.Name, |
|||
arg.Description, |
|||
arg.CreatedTime, |
|||
arg.OwnerID, |
|||
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.query(ctx, q.listItemStatProgressStmt, 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.query(ctx, q.listItemStatProgressMultiStmt, 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.owner_id, i.name, i.description, i.created_time, 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 = ? |
|||
ORDER BY acquired_time DESC, created_time DESC |
|||
` |
|||
|
|||
type ListItemsAcquiredBetweenParams struct { |
|||
AcquiredTime sql.NullTime |
|||
AcquiredTime_2 sql.NullTime |
|||
ScopeID int |
|||
} |
|||
|
|||
type ListItemsAcquiredBetweenRow struct { |
|||
ID int |
|||
ScopeID int |
|||
ProjectRequirementID sql.NullInt32 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsAcquiredBetween(ctx context.Context, arg ListItemsAcquiredBetweenParams) ([]ListItemsAcquiredBetweenRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsAcquiredBetweenStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsByProject(ctx context.Context, projectID int) ([]ListItemsByProjectRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsByProjectStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 = ? |
|||
ORDER BY created_time DESC |
|||
` |
|||
|
|||
type ListItemsCreatedBetweenParams struct { |
|||
CreatedTime time.Time |
|||
CreatedTime_2 time.Time |
|||
ScopeID int |
|||
} |
|||
|
|||
type ListItemsCreatedBetweenRow struct { |
|||
ID int |
|||
ScopeID int |
|||
ProjectRequirementID sql.NullInt32 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsCreatedBetween(ctx context.Context, arg ListItemsCreatedBetweenParams) ([]ListItemsCreatedBetweenRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsCreatedBetweenStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsCreatedBetweenNoScope(ctx context.Context, arg ListItemsCreatedBetweenNoScopeParams) ([]ListItemsCreatedBetweenNoScopeRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsCreatedBetweenNoScopeStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 |
|||
AND i.project_requirement_id IS NULL |
|||
ORDER BY created_time DESC |
|||
` |
|||
|
|||
type ListItemsLooseBetweenParams struct { |
|||
CreatedTime time.Time |
|||
CreatedTime_2 time.Time |
|||
ScopeID int |
|||
} |
|||
|
|||
type ListItemsLooseBetweenRow struct { |
|||
ID int |
|||
ScopeID int |
|||
ProjectRequirementID sql.NullInt32 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsLooseBetween(ctx context.Context, arg ListItemsLooseBetweenParams) ([]ListItemsLooseBetweenRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsLooseBetweenStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsLooseBetweenNoScope(ctx context.Context, arg ListItemsLooseBetweenNoScopeParams) ([]ListItemsLooseBetweenNoScopeRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsLooseBetweenNoScopeStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 = ? |
|||
ORDER BY scheduled_date, created_time |
|||
` |
|||
|
|||
type ListItemsScheduledBetweenParams struct { |
|||
ScheduledDate sqltypes.NullDate |
|||
ScheduledDate_2 sqltypes.NullDate |
|||
ScopeID int |
|||
} |
|||
|
|||
type ListItemsScheduledBetweenRow struct { |
|||
ID int |
|||
ScopeID int |
|||
ProjectRequirementID sql.NullInt32 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsScheduledBetween(ctx context.Context, arg ListItemsScheduledBetweenParams) ([]ListItemsScheduledBetweenRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsScheduledBetweenStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.owner_id, i.name, i.description, i.created_time, 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 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
ProjectID sql.NullInt32 |
|||
} |
|||
|
|||
func (q *Queries) ListItemsScheduledBetweenNoScope(ctx context.Context, arg ListItemsScheduledBetweenNoScopeParams) ([]ListItemsScheduledBetweenNoScopeRow, error) { |
|||
rows, err := q.query(ctx, q.listItemsScheduledBetweenNoScopeStmt, 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.OwnerID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
&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.exec(ctx, q.replaceItemStatProgressStmt, 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 = ?, |
|||
owner_id = ? |
|||
WHERE id = ? |
|||
` |
|||
|
|||
type UpdateItemParams struct { |
|||
ProjectRequirementID sql.NullInt32 |
|||
Name string |
|||
Description string |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
OwnerID string |
|||
ID int |
|||
} |
|||
|
|||
func (q *Queries) UpdateItem(ctx context.Context, arg UpdateItemParams) error { |
|||
_, err := q.exec(ctx, q.updateItemStmt, updateItem, |
|||
arg.ProjectRequirementID, |
|||
arg.Name, |
|||
arg.Description, |
|||
arg.AcquiredTime, |
|||
arg.ScheduledDate, |
|||
arg.OwnerID, |
|||
arg.ID, |
|||
) |
|||
return err |
|||
} |
@ -0,0 +1,100 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
|
|||
package mysqlcore |
|||
|
|||
import ( |
|||
"database/sql" |
|||
"time" |
|||
|
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/sqltypes" |
|||
) |
|||
|
|||
type Item struct { |
|||
ID int |
|||
ScopeID int |
|||
ProjectRequirementID sql.NullInt32 |
|||
OwnerID string |
|||
Name string |
|||
Description string |
|||
CreatedTime time.Time |
|||
AcquiredTime sql.NullTime |
|||
ScheduledDate sqltypes.NullDate |
|||
} |
|||
|
|||
type ItemStatProgress struct { |
|||
ItemID int |
|||
StatID int |
|||
Acquired int |
|||
Required int |
|||
} |
|||
|
|||
type Project struct { |
|||
ID int |
|||
ScopeID int |
|||
OwnerID string |
|||
Name string |
|||
Status int |
|||
Description string |
|||
CreatedTime time.Time |
|||
} |
|||
|
|||
type ProjectRequirement struct { |
|||
ID int |
|||
ScopeID int |
|||
ProjectID int |
|||
Name string |
|||
Status int |
|||
Description string |
|||
} |
|||
|
|||
type ProjectRequirementStat struct { |
|||
ProjectRequirementID int |
|||
StatID int |
|||
Required int |
|||
} |
|||
|
|||
type Scope struct { |
|||
ID int |
|||
Name string |
|||
Abbreviation string |
|||
CustomLabels sqltypes.NullRawMessage |
|||
} |
|||
|
|||
type ScopeMember struct { |
|||
ScopeID int |
|||
UserID string |
|||
Name string |
|||
Owner bool |
|||
} |
|||
|
|||
type Sprint struct { |
|||
ID int |
|||
ScopeID int |
|||
Name string |
|||
Description string |
|||
FromTime time.Time |
|||
ToTime time.Time |
|||
IsTimed bool |
|||
IsCoarse bool |
|||
IsUnweighted bool |
|||
Kind int |
|||
AggregateName string |
|||
AggregateRequired int |
|||
} |
|||
|
|||
type SprintPart struct { |
|||
SprintID int |
|||
ObjectID int |
|||
Required int |
|||
} |
|||
|
|||
type Stat struct { |
|||
ID int |
|||
ScopeID int |
|||
Name string |
|||
Description string |
|||
Weight float64 |
|||
AllowedAmounts sqltypes.NullRawMessage |
|||
} |
@ -0,0 +1,323 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
// source: projects.sql
|
|||
|
|||
package mysqlcore |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
) |
|||
|
|||
const clearItemProjectRequirement = `-- name: ClearItemProjectRequirement :exec |
|||
UPDATE item |
|||
SET project_requirement_id = NULL |
|||
WHERE project_requirement_id = ? |
|||
` |
|||
|
|||
func (q *Queries) ClearItemProjectRequirement(ctx context.Context, projectRequirementID sql.NullInt32) error { |
|||
_, err := q.exec(ctx, q.clearItemProjectRequirementStmt, clearItemProjectRequirement, projectRequirementID) |
|||
return err |
|||
} |
|||
|
|||
const deleteAllProjectRequirementStats = `-- name: DeleteAllProjectRequirementStats :exec |
|||
DELETE FROM project_requirement_stat WHERE project_requirement_id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteAllProjectRequirementStats(ctx context.Context, projectRequirementID int) error { |
|||
_, err := q.exec(ctx, q.deleteAllProjectRequirementStatsStmt, deleteAllProjectRequirementStats, projectRequirementID) |
|||
return err |
|||
} |
|||
|
|||
const deleteAllProjectRequirements = `-- name: DeleteAllProjectRequirements :exec |
|||
DELETE FROM project_requirement WHERE project_id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteAllProjectRequirements(ctx context.Context, projectID int) error { |
|||
_, err := q.exec(ctx, q.deleteAllProjectRequirementsStmt, deleteAllProjectRequirements, projectID) |
|||
return err |
|||
} |
|||
|
|||
const deleteProject = `-- name: DeleteProject :exec |
|||
DELETE FROM project WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type DeleteProjectParams struct { |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) DeleteProject(ctx context.Context, arg DeleteProjectParams) error { |
|||
_, err := q.exec(ctx, q.deleteProjectStmt, deleteProject, arg.ID, arg.ScopeID) |
|||
return err |
|||
} |
|||
|
|||
const deleteProjectRequirement = `-- name: DeleteProjectRequirement :exec |
|||
DELETE FROM project_requirement WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type DeleteProjectRequirementParams struct { |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) DeleteProjectRequirement(ctx context.Context, arg DeleteProjectRequirementParams) error { |
|||
_, err := q.exec(ctx, q.deleteProjectRequirementStmt, deleteProjectRequirement, arg.ID, arg.ScopeID) |
|||
return err |
|||
} |
|||
|
|||
const deleteProjectRequirementStat = `-- name: DeleteProjectRequirementStat :exec |
|||
DELETE FROM project_requirement_stat WHERE project_requirement_id = ? AND stat_id = ? |
|||
` |
|||
|
|||
type DeleteProjectRequirementStatParams struct { |
|||
ProjectRequirementID int |
|||
StatID int |
|||
} |
|||
|
|||
func (q *Queries) DeleteProjectRequirementStat(ctx context.Context, arg DeleteProjectRequirementStatParams) error { |
|||
_, err := q.exec(ctx, q.deleteProjectRequirementStatStmt, deleteProjectRequirementStat, arg.ProjectRequirementID, arg.StatID) |
|||
return err |
|||
} |
|||
|
|||
const getProject = `-- name: GetProject :one |
|||
SELECT id, scope_id, owner_id, name, status, description, created_time FROM project WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type GetProjectParams struct { |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) GetProject(ctx context.Context, arg GetProjectParams) (Project, error) { |
|||
row := q.queryRow(ctx, q.getProjectStmt, getProject, arg.ID, arg.ScopeID) |
|||
var i Project |
|||
err := row.Scan( |
|||
&i.ID, |
|||
&i.ScopeID, |
|||
&i.OwnerID, |
|||
&i.Name, |
|||
&i.Status, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
) |
|||
return i, err |
|||
} |
|||
|
|||
const insertProject = `-- name: InsertProject :execresult |
|||
INSERT INTO project (scope_id, owner_id, name, status, description) |
|||
VALUES (?, ?, ?, ?, ?) |
|||
` |
|||
|
|||
type InsertProjectParams struct { |
|||
ScopeID int |
|||
OwnerID string |
|||
Name string |
|||
Status int |
|||
Description string |
|||
} |
|||
|
|||
func (q *Queries) InsertProject(ctx context.Context, arg InsertProjectParams) (sql.Result, error) { |
|||
return q.exec(ctx, q.insertProjectStmt, insertProject, |
|||
arg.ScopeID, |
|||
arg.OwnerID, |
|||
arg.Name, |
|||
arg.Status, |
|||
arg.Description, |
|||
) |
|||
} |
|||
|
|||
const insertProjectRequirement = `-- name: InsertProjectRequirement :execresult |
|||
INSERT INTO project_requirement (scope_id, project_id, name, status, description) |
|||
VALUES (?, ?, ?, ?, ?) |
|||
` |
|||
|
|||
type InsertProjectRequirementParams struct { |
|||
ScopeID int |
|||
ProjectID int |
|||
Name string |
|||
Status int |
|||
Description string |
|||
} |
|||
|
|||
func (q *Queries) InsertProjectRequirement(ctx context.Context, arg InsertProjectRequirementParams) (sql.Result, error) { |
|||
return q.exec(ctx, q.insertProjectRequirementStmt, insertProjectRequirement, |
|||
arg.ScopeID, |
|||
arg.ProjectID, |
|||
arg.Name, |
|||
arg.Status, |
|||
arg.Description, |
|||
) |
|||
} |
|||
|
|||
const listProjectRequirements = `-- name: ListProjectRequirements :many |
|||
SELECT id, scope_id, project_id, name, status, description FROM project_requirement WHERE project_id = ? |
|||
` |
|||
|
|||
func (q *Queries) ListProjectRequirements(ctx context.Context, projectID int) ([]ProjectRequirement, error) { |
|||
rows, err := q.query(ctx, q.listProjectRequirementsStmt, listProjectRequirements, 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 |
|||
} |
|||
|
|||
const listProjectRequirementsStats = `-- name: ListProjectRequirementsStats :many |
|||
SELECT prs.project_requirement_id, prs.stat_id, prs.required FROM project_requirement pr |
|||
RIGHT JOIN project_requirement_stat prs ON pr.id = prs.project_requirement_id |
|||
WHERE pr.project_id = ? |
|||
` |
|||
|
|||
func (q *Queries) ListProjectRequirementsStats(ctx context.Context, projectID int) ([]ProjectRequirementStat, error) { |
|||
rows, err := q.query(ctx, q.listProjectRequirementsStatsStmt, listProjectRequirementsStats, projectID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []ProjectRequirementStat{} |
|||
for rows.Next() { |
|||
var i ProjectRequirementStat |
|||
if err := rows.Scan(&i.ProjectRequirementID, &i.StatID, &i.Required); 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 listProjects = `-- name: ListProjects :many |
|||
SELECT id, scope_id, owner_id, name, status, description, created_time FROM project WHERE scope_id = ? ORDER BY status, name |
|||
` |
|||
|
|||
func (q *Queries) ListProjects(ctx context.Context, scopeID int) ([]Project, error) { |
|||
rows, err := q.query(ctx, q.listProjectsStmt, listProjects, scopeID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []Project{} |
|||
for rows.Next() { |
|||
var i Project |
|||
if err := rows.Scan( |
|||
&i.ID, |
|||
&i.ScopeID, |
|||
&i.OwnerID, |
|||
&i.Name, |
|||
&i.Status, |
|||
&i.Description, |
|||
&i.CreatedTime, |
|||
); 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 replaceProjectRequirementStat = `-- name: ReplaceProjectRequirementStat :exec |
|||
REPLACE INTO project_requirement_stat (project_requirement_id, stat_id, required) |
|||
VALUES (?, ?, ?) |
|||
` |
|||
|
|||
type ReplaceProjectRequirementStatParams struct { |
|||
ProjectRequirementID int |
|||
StatID int |
|||
Required int |
|||
} |
|||
|
|||
func (q *Queries) ReplaceProjectRequirementStat(ctx context.Context, arg ReplaceProjectRequirementStatParams) error { |
|||
_, err := q.exec(ctx, q.replaceProjectRequirementStatStmt, replaceProjectRequirementStat, arg.ProjectRequirementID, arg.StatID, arg.Required) |
|||
return err |
|||
} |
|||
|
|||
const updateProject = `-- name: UpdateProject :exec |
|||
UPDATE project |
|||
SET owner_id = ?, |
|||
name = ?, |
|||
status = ?, |
|||
description = ? |
|||
WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type UpdateProjectParams struct { |
|||
OwnerID string |
|||
Name string |
|||
Status int |
|||
Description string |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) UpdateProject(ctx context.Context, arg UpdateProjectParams) error { |
|||
_, err := q.exec(ctx, q.updateProjectStmt, updateProject, |
|||
arg.OwnerID, |
|||
arg.Name, |
|||
arg.Status, |
|||
arg.Description, |
|||
arg.ID, |
|||
arg.ScopeID, |
|||
) |
|||
return err |
|||
} |
|||
|
|||
const updateProjectRequirement = `-- name: UpdateProjectRequirement :exec |
|||
UPDATE project_requirement |
|||
SET name = ?, |
|||
status = ?, |
|||
description = ? |
|||
WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type UpdateProjectRequirementParams struct { |
|||
Name string |
|||
Status int |
|||
Description string |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) UpdateProjectRequirement(ctx context.Context, arg UpdateProjectRequirementParams) error { |
|||
_, err := q.exec(ctx, q.updateProjectRequirementStmt, updateProjectRequirement, |
|||
arg.Name, |
|||
arg.Status, |
|||
arg.Description, |
|||
arg.ID, |
|||
arg.ScopeID, |
|||
) |
|||
return err |
|||
} |
@ -0,0 +1,278 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
// source: scopes.sql
|
|||
|
|||
package mysqlcore |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
|
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/sqltypes" |
|||
) |
|||
|
|||
const deleteAllScopeMembers = `-- name: DeleteAllScopeMembers :exec |
|||
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) |
|||
return err |
|||
} |
|||
|
|||
const deleteScope = `-- name: DeleteScope :exec |
|||
DELETE FROM scope WHERE id=? |
|||
` |
|||
|
|||
func (q *Queries) DeleteScope(ctx context.Context, id int) error { |
|||
_, err := q.exec(ctx, q.deleteScopeStmt, deleteScope, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteScopeMember = `-- name: DeleteScopeMember :exec |
|||
DELETE FROM scope_member WHERE scope_id=? AND user_id=? |
|||
` |
|||
|
|||
type DeleteScopeMemberParams struct { |
|||
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) |
|||
return err |
|||
} |
|||
|
|||
const getScope = `-- name: GetScope :one |
|||
SELECT id, name, abbreviation, custom_labels FROM scope |
|||
WHERE id = ? |
|||
` |
|||
|
|||
func (q *Queries) GetScope(ctx context.Context, id int) (Scope, error) { |
|||
row := q.queryRow(ctx, q.getScopeStmt, getScope, id) |
|||
var i Scope |
|||
err := row.Scan( |
|||
&i.ID, |
|||
&i.Name, |
|||
&i.Abbreviation, |
|||
&i.CustomLabels, |
|||
) |
|||
return i, err |
|||
} |
|||
|
|||
const insertScope = `-- name: InsertScope :execresult |
|||
INSERT INTO scope (id, name, abbreviation, custom_labels) |
|||
VALUES (?, ?, ?, ?) |
|||
` |
|||
|
|||
type InsertScopeParams struct { |
|||
ID int |
|||
Name string |
|||
Abbreviation string |
|||
CustomLabels sqltypes.NullRawMessage |
|||
} |
|||
|
|||
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, |
|||
arg.CustomLabels, |
|||
) |
|||
} |
|||
|
|||
const listScopeMembers = `-- name: ListScopeMembers :many |
|||
SELECT scope_id, user_id, name, owner FROM scope_member |
|||
WHERE scope_id = ? |
|||
ORDER BY name |
|||
` |
|||
|
|||
func (q *Queries) ListScopeMembers(ctx context.Context, scopeID int) ([]ScopeMember, error) { |
|||
rows, err := q.query(ctx, q.listScopeMembersStmt, listScopeMembers, scopeID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []ScopeMember{} |
|||
for rows.Next() { |
|||
var i ScopeMember |
|||
if err := rows.Scan( |
|||
&i.ScopeID, |
|||
&i.UserID, |
|||
&i.Name, |
|||
&i.Owner, |
|||
); 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 listScopeMembersMulti = `-- name: ListScopeMembersMulti :many |
|||
SELECT scope_id, user_id, name, owner FROM scope_member |
|||
WHERE scope_id IN (?, ?, ?, ?, ?, ?) |
|||
ORDER BY name |
|||
` |
|||
|
|||
type ListScopeMembersMultiParams struct { |
|||
ScopeID int |
|||
ScopeID_2 int |
|||
ScopeID_3 int |
|||
ScopeID_4 int |
|||
ScopeID_5 int |
|||
ScopeID_6 int |
|||
} |
|||
|
|||
func (q *Queries) ListScopeMembersMulti(ctx context.Context, arg ListScopeMembersMultiParams) ([]ScopeMember, error) { |
|||
rows, err := q.query(ctx, q.listScopeMembersMultiStmt, listScopeMembersMulti, |
|||
arg.ScopeID, |
|||
arg.ScopeID_2, |
|||
arg.ScopeID_3, |
|||
arg.ScopeID_4, |
|||
arg.ScopeID_5, |
|||
arg.ScopeID_6, |
|||
) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []ScopeMember{} |
|||
for rows.Next() { |
|||
var i ScopeMember |
|||
if err := rows.Scan( |
|||
&i.ScopeID, |
|||
&i.UserID, |
|||
&i.Name, |
|||
&i.Owner, |
|||
); 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 listScopes = `-- name: ListScopes :many |
|||
SELECT id, name, abbreviation, custom_labels FROM scope |
|||
ORDER BY name |
|||
` |
|||
|
|||
func (q *Queries) ListScopes(ctx context.Context) ([]Scope, error) { |
|||
rows, err := q.query(ctx, q.listScopesStmt, listScopes) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []Scope{} |
|||
for rows.Next() { |
|||
var i Scope |
|||
if err := rows.Scan( |
|||
&i.ID, |
|||
&i.Name, |
|||
&i.Abbreviation, |
|||
&i.CustomLabels, |
|||
); 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 listScopesByUser = `-- name: ListScopesByUser :many |
|||
SELECT s.id, s.name, s.abbreviation, s.custom_labels FROM scope_member sm |
|||
RIGHT JOIN scope s on s.id = sm.scope_id |
|||
WHERE sm.user_id = ? |
|||
ORDER BY s.name |
|||
` |
|||
|
|||
func (q *Queries) ListScopesByUser(ctx context.Context, userID string) ([]Scope, error) { |
|||
rows, err := q.query(ctx, q.listScopesByUserStmt, listScopesByUser, userID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []Scope{} |
|||
for rows.Next() { |
|||
var i Scope |
|||
if err := rows.Scan( |
|||
&i.ID, |
|||
&i.Name, |
|||
&i.Abbreviation, |
|||
&i.CustomLabels, |
|||
); 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 replaceScopeMember = `-- name: ReplaceScopeMember :exec |
|||
REPLACE INTO scope_member (scope_id, user_id, name, owner) |
|||
VALUES (?, ?, ?, ?) |
|||
` |
|||
|
|||
type ReplaceScopeMemberParams struct { |
|||
ScopeID int |
|||
UserID string |
|||
Name string |
|||
Owner bool |
|||
} |
|||
|
|||
func (q *Queries) ReplaceScopeMember(ctx context.Context, arg ReplaceScopeMemberParams) error { |
|||
_, err := q.exec(ctx, q.replaceScopeMemberStmt, replaceScopeMember, |
|||
arg.ScopeID, |
|||
arg.UserID, |
|||
arg.Name, |
|||
arg.Owner, |
|||
) |
|||
return err |
|||
} |
|||
|
|||
const updateScope = `-- name: UpdateScope :exec |
|||
UPDATE scope SET name = ?, abbreviation = ?, custom_labels = ? WHERE id = ? |
|||
` |
|||
|
|||
type UpdateScopeParams struct { |
|||
Name string |
|||
Abbreviation string |
|||
CustomLabels sqltypes.NullRawMessage |
|||
ID int |
|||
} |
|||
|
|||
func (q *Queries) UpdateScope(ctx context.Context, arg UpdateScopeParams) error { |
|||
_, err := q.exec(ctx, q.updateScopeStmt, updateScope, |
|||
arg.Name, |
|||
arg.Abbreviation, |
|||
arg.CustomLabels, |
|||
arg.ID, |
|||
) |
|||
return err |
|||
} |
@ -0,0 +1,155 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
// source: stats.sql
|
|||
|
|||
package mysqlcore |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
|
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/sqltypes" |
|||
) |
|||
|
|||
const deleteAllItemStatProgressByStatId = `-- name: DeleteAllItemStatProgressByStatId :exec |
|||
DELETE FROM item_stat_progress WHERE stat_id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteAllItemStatProgressByStatId(ctx context.Context, statID int) error { |
|||
_, err := q.exec(ctx, q.deleteAllItemStatProgressByStatIdStmt, deleteAllItemStatProgressByStatId, statID) |
|||
return err |
|||
} |
|||
|
|||
const deleteAllProjectRequirementStatByStatId = `-- name: DeleteAllProjectRequirementStatByStatId :exec |
|||
DELETE FROM project_requirement_stat WHERE stat_id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteAllProjectRequirementStatByStatId(ctx context.Context, statID int) error { |
|||
_, err := q.exec(ctx, q.deleteAllProjectRequirementStatByStatIdStmt, deleteAllProjectRequirementStatByStatId, statID) |
|||
return err |
|||
} |
|||
|
|||
const deleteStat = `-- name: DeleteStat :exec |
|||
DELETE FROM stat WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type DeleteStatParams struct { |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) DeleteStat(ctx context.Context, arg DeleteStatParams) error { |
|||
_, err := q.exec(ctx, q.deleteStatStmt, deleteStat, arg.ID, arg.ScopeID) |
|||
return err |
|||
} |
|||
|
|||
const getStat = `-- name: GetStat :one |
|||
SELECT id, scope_id, name, description, weight, allowed_amounts FROM stat WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type GetStatParams struct { |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) GetStat(ctx context.Context, arg GetStatParams) (Stat, error) { |
|||
row := q.queryRow(ctx, q.getStatStmt, getStat, arg.ID, arg.ScopeID) |
|||
var i Stat |
|||
err := row.Scan( |
|||
&i.ID, |
|||
&i.ScopeID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.Weight, |
|||
&i.AllowedAmounts, |
|||
) |
|||
return i, err |
|||
} |
|||
|
|||
const insertStat = `-- name: InsertStat :execresult |
|||
INSERT INTO stat (scope_id, name, description, weight, allowed_amounts) |
|||
VALUES (?, ?, ?, ?, ?) |
|||
` |
|||
|
|||
type InsertStatParams struct { |
|||
ScopeID int |
|||
Name string |
|||
Description string |
|||
Weight float64 |
|||
AllowedAmounts sqltypes.NullRawMessage |
|||
} |
|||
|
|||
func (q *Queries) InsertStat(ctx context.Context, arg InsertStatParams) (sql.Result, error) { |
|||
return q.exec(ctx, q.insertStatStmt, insertStat, |
|||
arg.ScopeID, |
|||
arg.Name, |
|||
arg.Description, |
|||
arg.Weight, |
|||
arg.AllowedAmounts, |
|||
) |
|||
} |
|||
|
|||
const listStats = `-- name: ListStats :many |
|||
SELECT id, scope_id, name, description, weight, allowed_amounts FROM stat WHERE scope_id = ? ORDER BY name |
|||
` |
|||
|
|||
func (q *Queries) ListStats(ctx context.Context, scopeID int) ([]Stat, error) { |
|||
rows, err := q.query(ctx, q.listStatsStmt, listStats, scopeID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []Stat{} |
|||
for rows.Next() { |
|||
var i Stat |
|||
if err := rows.Scan( |
|||
&i.ID, |
|||
&i.ScopeID, |
|||
&i.Name, |
|||
&i.Description, |
|||
&i.Weight, |
|||
&i.AllowedAmounts, |
|||
); 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 updateStat = `-- name: UpdateStat :exec |
|||
UPDATE stat |
|||
SET name = ?, |
|||
description = ?, |
|||
weight = ?, |
|||
allowed_amounts = ? |
|||
WHERE id = ? AND scope_id = ? |
|||
` |
|||
|
|||
type UpdateStatParams struct { |
|||
Name string |
|||
Description string |
|||
Weight float64 |
|||
AllowedAmounts sqltypes.NullRawMessage |
|||
ID int |
|||
ScopeID int |
|||
} |
|||
|
|||
func (q *Queries) UpdateStat(ctx context.Context, arg UpdateStatParams) error { |
|||
_, err := q.exec(ctx, q.updateStatStmt, updateStat, |
|||
arg.Name, |
|||
arg.Description, |
|||
arg.Weight, |
|||
arg.AllowedAmounts, |
|||
arg.ID, |
|||
arg.ScopeID, |
|||
) |
|||
return err |
|||
} |
@ -0,0 +1,246 @@ |
|||
package mysql |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore" |
|||
) |
|||
|
|||
type projectRepository struct { |
|||
db *sql.DB |
|||
q *mysqlcore.Queries |
|||
} |
|||
|
|||
func (r *projectRepository) Find(ctx context.Context, scopeID, projectID int) (*entities.Project, error) { |
|||
row, err := r.q.GetProject(ctx, mysqlcore.GetProjectParams{ID: projectID, ScopeID: scopeID}) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return nil, models.NotFoundError("Project") |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
return &entities.Project{ |
|||
ID: row.ID, |
|||
ScopeID: row.ScopeID, |
|||
OwnerID: row.OwnerID, |
|||
CreatedTime: row.CreatedTime, |
|||
Name: row.Name, |
|||
Description: row.Description, |
|||
Status: models.Status(row.Status), |
|||
}, nil |
|||
} |
|||
|
|||
func (r *projectRepository) List(ctx context.Context, scopeID int) ([]entities.Project, error) { |
|||
rows, err := r.q.ListProjects(ctx, scopeID) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return []entities.Project{}, nil |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
res := make([]entities.Project, 0, len(rows)) |
|||
for _, row := range rows { |
|||
res = append(res, entities.Project{ |
|||
ID: row.ID, |
|||
ScopeID: row.ScopeID, |
|||
OwnerID: row.OwnerID, |
|||
CreatedTime: row.CreatedTime, |
|||
Name: row.Name, |
|||
Description: row.Description, |
|||
Status: models.Status(row.Status), |
|||
}) |
|||
} |
|||
|
|||
return res, nil |
|||
} |
|||
|
|||
func (r *projectRepository) Create(ctx context.Context, project entities.Project) (*entities.Project, error) { |
|||
res, err := r.q.InsertProject(ctx, mysqlcore.InsertProjectParams{ |
|||
ScopeID: project.ScopeID, |
|||
OwnerID: project.OwnerID, |
|||
Name: project.Name, |
|||
Status: int(project.Status), |
|||
Description: project.Description, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
id, err := res.LastInsertId() |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
project.ID = int(id) |
|||
return &project, nil |
|||
} |
|||
|
|||
func (r *projectRepository) Update(ctx context.Context, project entities.Project, update models.ProjectUpdate) error { |
|||
project.Update(update) |
|||
|
|||
return r.q.UpdateProject(ctx, mysqlcore.UpdateProjectParams{ |
|||
OwnerID: project.OwnerID, |
|||
Name: project.Name, |
|||
Status: int(project.Status), |
|||
Description: project.Description, |
|||
|
|||
ID: project.ID, |
|||
ScopeID: project.ScopeID, |
|||
}) |
|||
} |
|||
|
|||
func (r *projectRepository) Delete(ctx context.Context, project entities.Project) error { |
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer tx.Rollback() |
|||
q := r.q.WithTx(tx) |
|||
|
|||
reqs, err := q.ListProjectRequirements(ctx, project.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
for _, req := range reqs { |
|||
err = q.ClearItemProjectRequirement(ctx, sql.NullInt32{Valid: true, Int32: int32(req.ID)}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.DeleteAllProjectRequirementStats(ctx, req.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
} |
|||
|
|||
err = q.DeleteAllProjectRequirements(ctx, project.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.DeleteProject(ctx, mysqlcore.DeleteProjectParams{ID: project.ID, ScopeID: project.ScopeID}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
return tx.Commit() |
|||
} |
|||
|
|||
func (r *projectRepository) ListRequirements(ctx context.Context, projectID int) ([]entities.Requirement, []entities.RequirementStat, error) { |
|||
reqRows, err := r.q.ListProjectRequirements(ctx, projectID) |
|||
if err != nil && err != sql.ErrNoRows { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
statsRows, err := r.q.ListProjectRequirementsStats(ctx, projectID) |
|||
if err != nil && err != sql.ErrNoRows { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
requirements := make([]entities.Requirement, 0, len(reqRows)) |
|||
for _, row := range reqRows { |
|||
requirements = append(requirements, entities.Requirement{ |
|||
ID: row.ID, |
|||
ScopeID: row.ScopeID, |
|||
ProjectID: row.ProjectID, |
|||
Name: row.Name, |
|||
Description: row.Description, |
|||
Status: models.Status(row.Status), |
|||
}) |
|||
} |
|||
|
|||
stats := make([]entities.RequirementStat, 0, len(statsRows)) |
|||
for _, row := range statsRows { |
|||
stats = append(stats, entities.RequirementStat{ |
|||
RequirementID: row.ProjectRequirementID, |
|||
StatID: row.StatID, |
|||
Required: row.Required, |
|||
}) |
|||
} |
|||
|
|||
return requirements, stats, nil |
|||
} |
|||
|
|||
func (r *projectRepository) CreateRequirement(ctx context.Context, requirement entities.Requirement) (*entities.Requirement, error) { |
|||
res, err := r.q.InsertProjectRequirement(ctx, mysqlcore.InsertProjectRequirementParams{ |
|||
ScopeID: requirement.ScopeID, |
|||
ProjectID: requirement.ProjectID, |
|||
Name: requirement.Name, |
|||
Status: int(requirement.Status), |
|||
Description: requirement.Description, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
id, err := res.LastInsertId() |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
requirement.ID = int(id) |
|||
return &requirement, nil |
|||
} |
|||
|
|||
func (r *projectRepository) UpdateRequirement(ctx context.Context, requirement entities.Requirement, update models.RequirementUpdate) error { |
|||
requirement.Update(update) |
|||
|
|||
return r.q.UpdateProjectRequirement(ctx, mysqlcore.UpdateProjectRequirementParams{ |
|||
Name: requirement.Name, |
|||
Status: int(requirement.Status), |
|||
Description: requirement.Description, |
|||
ID: requirement.ID, |
|||
ScopeID: requirement.ScopeID, |
|||
}) |
|||
} |
|||
|
|||
func (r *projectRepository) DeleteRequirement(ctx context.Context, requirement entities.Requirement) error { |
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer tx.Rollback() |
|||
q := r.q.WithTx(tx) |
|||
|
|||
err = q.ClearItemProjectRequirement(ctx, sql.NullInt32{Valid: true, Int32: int32(requirement.ID)}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.DeleteAllProjectRequirementStats(ctx, requirement.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.DeleteProjectRequirement(ctx, mysqlcore.DeleteProjectRequirementParams{ |
|||
ScopeID: requirement.ScopeID, |
|||
ID: requirement.ID, |
|||
}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
return tx.Commit() |
|||
} |
|||
|
|||
func (r *projectRepository) UpsertRequirementStat(ctx context.Context, stat entities.RequirementStat) error { |
|||
return r.q.ReplaceProjectRequirementStat(ctx, mysqlcore.ReplaceProjectRequirementStatParams{ |
|||
ProjectRequirementID: stat.RequirementID, |
|||
StatID: stat.StatID, |
|||
Required: stat.Required, |
|||
}) |
|||
} |
|||
|
|||
func (r *projectRepository) DeleteRequirementStat(ctx context.Context, stat entities.RequirementStat) error { |
|||
return r.q.DeleteProjectRequirementStat(ctx, mysqlcore.DeleteProjectRequirementStatParams{ |
|||
ProjectRequirementID: stat.RequirementID, |
|||
StatID: stat.StatID, |
|||
}) |
|||
} |
@ -0,0 +1,114 @@ |
|||
-- 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 = ? |
|||
ORDER BY acquired_time DESC, created_time DESC; |
|||
|
|||
-- 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 = ? |
|||
ORDER BY scheduled_date, created_time; |
|||
|
|||
-- 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 = ? |
|||
ORDER BY created_time DESC; |
|||
|
|||
-- 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 |
|||
AND i.project_requirement_id IS NULL |
|||
ORDER BY created_time DESC; |
|||
|
|||
-- 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, owner_id, acquired_time, scheduled_date) |
|||
VALUES (?, ?, ?, ?, ?, ?, ?, ?); |
|||
|
|||
-- name: UpdateItem :exec |
|||
UPDATE item |
|||
SET project_requirement_id = ?, |
|||
name = ?, |
|||
description = ?, |
|||
acquired_time = ?, |
|||
scheduled_date = ?, |
|||
owner_id = ? |
|||
WHERE id = ?; |
|||
|
|||
-- name: DeleteItem :exec |
|||
DELETE FROM item WHERE id = ?; |
|||
|
|||
-- name: DeleteItemForRequirement :exec |
|||
DELETE FROM item WHERE project_requirement_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,60 @@ |
|||
-- name: ListProjects :many |
|||
SELECT * FROM project WHERE scope_id = ? ORDER BY status, name; |
|||
|
|||
-- name: GetProject :one |
|||
SELECT * FROM project WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: InsertProject :execresult |
|||
INSERT INTO project (scope_id, owner_id, name, status, description) |
|||
VALUES (?, ?, ?, ?, ?); |
|||
|
|||
-- name: UpdateProject :exec |
|||
UPDATE project |
|||
SET owner_id = ?, |
|||
name = ?, |
|||
status = ?, |
|||
description = ? |
|||
WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: DeleteProject :exec |
|||
DELETE FROM project WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: ListProjectRequirements :many |
|||
SELECT * FROM project_requirement WHERE project_id = ?; |
|||
|
|||
-- name: InsertProjectRequirement :execresult |
|||
INSERT INTO project_requirement (scope_id, project_id, name, status, description) |
|||
VALUES (?, ?, ?, ?, ?); |
|||
|
|||
-- name: UpdateProjectRequirement :exec |
|||
UPDATE project_requirement |
|||
SET name = ?, |
|||
status = ?, |
|||
description = ? |
|||
WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: DeleteProjectRequirement :exec |
|||
DELETE FROM project_requirement WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: DeleteAllProjectRequirements :exec |
|||
DELETE FROM project_requirement WHERE project_id = ?; |
|||
|
|||
-- name: ClearItemProjectRequirement :exec |
|||
UPDATE item |
|||
SET project_requirement_id = NULL |
|||
WHERE project_requirement_id = ?; |
|||
|
|||
-- name: ListProjectRequirementsStats :many |
|||
SELECT prs.* FROM project_requirement pr |
|||
RIGHT JOIN project_requirement_stat prs ON pr.id = prs.project_requirement_id |
|||
WHERE pr.project_id = ?; |
|||
|
|||
-- name: ReplaceProjectRequirementStat :exec |
|||
REPLACE INTO project_requirement_stat (project_requirement_id, stat_id, required) |
|||
VALUES (?, ?, ?); |
|||
|
|||
-- name: DeleteProjectRequirementStat :exec |
|||
DELETE FROM project_requirement_stat WHERE project_requirement_id = ? AND stat_id = ?; |
|||
|
|||
-- name: DeleteAllProjectRequirementStats :exec |
|||
DELETE FROM project_requirement_stat WHERE project_requirement_id = ?; |
@ -0,0 +1,43 @@ |
|||
-- name: GetScope :one |
|||
SELECT * FROM scope |
|||
WHERE id = ?; |
|||
|
|||
-- name: ListScopes :many |
|||
SELECT * FROM scope |
|||
ORDER BY name; |
|||
|
|||
-- name: ListScopesByUser :many |
|||
SELECT s.* FROM scope_member sm |
|||
RIGHT JOIN scope s on s.id = sm.scope_id |
|||
WHERE sm.user_id = ? |
|||
ORDER BY s.name; |
|||
|
|||
-- name: ListScopeMembers :many |
|||
SELECT * FROM scope_member |
|||
WHERE scope_id = ? |
|||
ORDER BY name; |
|||
|
|||
-- name: ListScopeMembersMulti :many |
|||
SELECT * FROM scope_member |
|||
WHERE scope_id IN (?, ?, ?, ?, ?, ?) |
|||
ORDER BY name; |
|||
|
|||
-- name: InsertScope :execresult |
|||
INSERT INTO scope (id, name, abbreviation, custom_labels) |
|||
VALUES (?, ?, ?, ?); |
|||
|
|||
-- name: UpdateScope :exec |
|||
UPDATE scope SET name = ?, abbreviation = ?, custom_labels = ? WHERE id = ?; |
|||
|
|||
-- name: ReplaceScopeMember :exec |
|||
REPLACE INTO scope_member (scope_id, user_id, name, owner) |
|||
VALUES (?, ?, ?, ?); |
|||
|
|||
-- name: DeleteScopeMember :exec |
|||
DELETE FROM scope_member WHERE scope_id=? AND user_id=?; |
|||
|
|||
-- name: DeleteAllScopeMembers :exec |
|||
DELETE FROM scope_member WHERE scope_id=?; |
|||
|
|||
-- name: DeleteScope :exec |
|||
DELETE FROM scope WHERE id=?; |
@ -0,0 +1,26 @@ |
|||
-- name: GetStat :one |
|||
SELECT * FROM stat WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: ListStats :many |
|||
SELECT * FROM stat WHERE scope_id = ? ORDER BY name; |
|||
|
|||
-- name: InsertStat :execresult |
|||
INSERT INTO stat (scope_id, name, description, weight, allowed_amounts) |
|||
VALUES (?, ?, ?, ?, ?); |
|||
|
|||
-- name: UpdateStat :exec |
|||
UPDATE stat |
|||
SET name = ?, |
|||
description = ?, |
|||
weight = ?, |
|||
allowed_amounts = ? |
|||
WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: DeleteStat :exec |
|||
DELETE FROM stat WHERE id = ? AND scope_id = ?; |
|||
|
|||
-- name: DeleteAllItemStatProgressByStatId :exec |
|||
DELETE FROM item_stat_progress WHERE stat_id = ?; |
|||
|
|||
-- name: DeleteAllProjectRequirementStatByStatId :exec |
|||
DELETE FROM project_requirement_stat WHERE stat_id = ?; |
@ -0,0 +1,197 @@ |
|||
package mysql |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"encoding/json" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore" |
|||
) |
|||
|
|||
type scopeRepository struct { |
|||
db *sql.DB |
|||
q *mysqlcore.Queries |
|||
} |
|||
|
|||
func (r *scopeRepository) Find(ctx context.Context, id int) (*entities.Scope, error) { |
|||
row, err := r.q.GetScope(ctx, id) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return nil, models.NotFoundError("Scope") |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
customLabels := make(map[string]string, 0) |
|||
if row.CustomLabels.Valid { |
|||
_ = json.Unmarshal(row.CustomLabels.RawMessage, &customLabels) |
|||
} |
|||
|
|||
return &entities.Scope{ |
|||
ID: row.ID, |
|||
Name: row.Name, |
|||
Abbreviation: row.Abbreviation, |
|||
CustomLabels: customLabels, |
|||
}, nil |
|||
} |
|||
|
|||
func (r *scopeRepository) List(ctx context.Context) ([]entities.Scope, error) { |
|||
rows, err := r.q.ListScopes(ctx) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return []entities.Scope{}, nil |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
res := make([]entities.Scope, 0, len(rows)) |
|||
for _, row := range rows { |
|||
customLabels := make(map[string]string, 0) |
|||
if row.CustomLabels.Valid { |
|||
_ = json.Unmarshal(row.CustomLabels.RawMessage, &customLabels) |
|||
} |
|||
|
|||
res = append(res, entities.Scope{ |
|||
ID: row.ID, |
|||
Name: row.Name, |
|||
Abbreviation: row.Abbreviation, |
|||
CustomLabels: customLabels, |
|||
}) |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
func (r *scopeRepository) ListUser(ctx context.Context, userID string) ([]entities.Scope, error) { |
|||
rows, err := r.q.ListScopesByUser(ctx, userID) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return []entities.Scope{}, nil |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
res := make([]entities.Scope, 0, len(rows)) |
|||
for _, row := range rows { |
|||
customLabels := make(map[string]string, 0) |
|||
if row.CustomLabels.Valid { |
|||
_ = json.Unmarshal(row.CustomLabels.RawMessage, &customLabels) |
|||
} |
|||
|
|||
res = append(res, entities.Scope{ |
|||
ID: row.ID, |
|||
Name: row.Name, |
|||
Abbreviation: row.Abbreviation, |
|||
CustomLabels: customLabels, |
|||
}) |
|||
} |
|||
|
|||
return res, nil |
|||
} |
|||
|
|||
func (r *scopeRepository) Create(ctx context.Context, scope entities.Scope, ownerID string) (*entities.Scope, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *scopeRepository) Update(ctx context.Context, scope entities.Scope, update models.ScopeUpdate) error { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *scopeRepository) Delete(ctx context.Context, scope entities.Scope) error { |
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer tx.Rollback() |
|||
q := r.q.WithTx(tx) |
|||
|
|||
err = q.DeleteAllScopeMembers(ctx, scope.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
err = q.DeleteScope(ctx, scope.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
// TODO: Wipe everything
|
|||
|
|||
return tx.Commit() |
|||
} |
|||
|
|||
func (r *scopeRepository) ListMembers(ctx context.Context, scopeIDs ...int) ([]entities.ScopeMember, error) { |
|||
res := make([]entities.ScopeMember, 0, 8) |
|||
if len(scopeIDs) == 1 { |
|||
rows, err := r.q.ListScopeMembers(ctx, scopeIDs[0]) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return []entities.ScopeMember{}, nil |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
for _, row := range rows { |
|||
res = append(res, entities.ScopeMember{ |
|||
ScopeID: row.ScopeID, |
|||
UserID: row.UserID, |
|||
Name: row.Name, |
|||
Owner: row.Owner, |
|||
}) |
|||
} |
|||
} else { |
|||
for i := 0; i < len(scopeIDs); i += 6 { |
|||
ids := []int{-1, -2, -3, -4, -5, -6} |
|||
copy(ids, scopeIDs[i:]) |
|||
|
|||
rows, err := r.q.ListScopeMembersMulti(ctx, mysqlcore.ListScopeMembersMultiParams{ |
|||
ScopeID: ids[0], |
|||
ScopeID_2: ids[1], |
|||
ScopeID_3: ids[2], |
|||
ScopeID_4: ids[3], |
|||
ScopeID_5: ids[4], |
|||
ScopeID_6: ids[5], |
|||
}) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return []entities.ScopeMember{}, nil |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
for _, row := range rows { |
|||
res = append(res, entities.ScopeMember{ |
|||
ScopeID: row.ScopeID, |
|||
UserID: row.UserID, |
|||
Name: row.Name, |
|||
Owner: row.Owner, |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
return res, nil |
|||
} |
|||
|
|||
func (r *scopeRepository) SaveMember(ctx context.Context, member entities.ScopeMember) error { |
|||
return r.q.ReplaceScopeMember(ctx, mysqlcore.ReplaceScopeMemberParams{ |
|||
ScopeID: member.ScopeID, |
|||
UserID: member.UserID, |
|||
Name: member.Name, |
|||
Owner: member.Owner, |
|||
}) |
|||
} |
|||
|
|||
func (r *scopeRepository) DeleteMember(ctx context.Context, member entities.ScopeMember) error { |
|||
return r.q.DeleteScopeMember(ctx, mysqlcore.DeleteScopeMemberParams{ |
|||
ScopeID: member.ScopeID, |
|||
UserID: member.UserID, |
|||
}) |
|||
} |
@ -0,0 +1,55 @@ |
|||
package sqltypes |
|||
|
|||
import ( |
|||
"database/sql/driver" |
|||
"errors" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"time" |
|||
) |
|||
|
|||
type NullDate struct { |
|||
Date models.Date |
|||
Valid bool |
|||
} |
|||
|
|||
func (n *NullDate) AsPtr() *models.Date { |
|||
if n.Valid { |
|||
dateCopy := n.Date |
|||
return &dateCopy |
|||
} else { |
|||
return nil |
|||
} |
|||
} |
|||
|
|||
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 |
|||
} |
@ -0,0 +1,36 @@ |
|||
package sqltypes |
|||
|
|||
import ( |
|||
"database/sql/driver" |
|||
"encoding/json" |
|||
"errors" |
|||
) |
|||
|
|||
type NullRawMessage struct { |
|||
RawMessage json.RawMessage |
|||
Valid bool |
|||
} |
|||
|
|||
func (n *NullRawMessage) Scan(value interface{}) error { |
|||
if value == nil { |
|||
n.RawMessage, n.Valid = json.RawMessage{}, false |
|||
return nil |
|||
} |
|||
buf, ok := value.([]byte) |
|||
|
|||
if !ok { |
|||
return errors.New("cannot parse to bytes") |
|||
} |
|||
|
|||
n.RawMessage, n.Valid = buf, true |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (n NullRawMessage) Value() (driver.Value, error) { |
|||
if !n.Valid { |
|||
return nil, nil |
|||
} |
|||
|
|||
return []byte(n.RawMessage), nil |
|||
} |
@ -0,0 +1,91 @@ |
|||
package mysql |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"encoding/json" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore" |
|||
) |
|||
|
|||
type statsRepository struct { |
|||
db *sql.DB |
|||
q *mysqlcore.Queries |
|||
} |
|||
|
|||
func (r *statsRepository) Find(ctx context.Context, scopeID, statID int) (*entities.Stat, error) { |
|||
row, err := r.q.GetStat(ctx, mysqlcore.GetStatParams{ScopeID: scopeID, ID: statID}) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return nil, models.NotFoundError("Stat") |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
var allowedAmounts []models.StatAllowedAmount |
|||
if row.AllowedAmounts.Valid { |
|||
allowedAmounts = make([]models.StatAllowedAmount, 0, 8) |
|||
_ = json.Unmarshal(row.AllowedAmounts.RawMessage, &allowedAmounts) |
|||
if len(allowedAmounts) == 0 { |
|||
allowedAmounts = nil |
|||
} |
|||
} |
|||
|
|||
return &entities.Stat{ |
|||
ID: row.ID, |
|||
Name: row.Name, |
|||
Weight: row.Weight, |
|||
Description: row.Description, |
|||
AllowedAmounts: allowedAmounts, |
|||
}, nil |
|||
} |
|||
|
|||
func (r *statsRepository) List(ctx context.Context, scopeID int) ([]entities.Stat, error) { |
|||
rows, err := r.q.ListStats(ctx, scopeID) |
|||
if err != nil { |
|||
if err == sql.ErrNoRows { |
|||
return nil, models.NotFoundError("Stat") |
|||
} |
|||
|
|||
return nil, err |
|||
} |
|||
|
|||
res := make([]entities.Stat, 0, len(rows)) |
|||
for _, row := range rows { |
|||
var allowedAmounts []models.StatAllowedAmount |
|||
if row.AllowedAmounts.Valid { |
|||
allowedAmounts = make([]models.StatAllowedAmount, 0, 8) |
|||
_ = json.Unmarshal(row.AllowedAmounts.RawMessage, &allowedAmounts) |
|||
if len(allowedAmounts) == 0 { |
|||
allowedAmounts = nil |
|||
} |
|||
} |
|||
|
|||
res = append(res, entities.Stat{ |
|||
ID: row.ID, |
|||
Name: row.Name, |
|||
Weight: row.Weight, |
|||
Description: row.Description, |
|||
AllowedAmounts: allowedAmounts, |
|||
}) |
|||
} |
|||
|
|||
return res, nil |
|||
} |
|||
|
|||
func (r *statsRepository) Insert(ctx context.Context, stat entities.Stat) (*entities.Stat, error) { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *statsRepository) Update(ctx context.Context, stat entities.Stat, update models.StatUpdate) error { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
|||
|
|||
func (r *statsRepository) Delete(ctx context.Context, stat entities.Stat) error { |
|||
//TODO implement me
|
|||
panic("implement me") |
|||
} |
@ -0,0 +1,14 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE scope ( |
|||
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, |
|||
`name` VARCHAR(255) NOT NULL, |
|||
`abbreviation` CHAR(8) NOT NULL, |
|||
`custom_labels` JSON |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS scope; |
|||
-- +goose StatementEnd |
@ -0,0 +1,17 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE scope_member ( |
|||
`scope_id` INT NOT NULL, |
|||
`user_id` CHAR(36) NOT NULL, |
|||
`name` VARCHAR(63) NOT NULL, |
|||
`owner` BOOLEAN NOT NULL, |
|||
|
|||
PRIMARY KEY (`scope_id`, `user_id`), |
|||
UNIQUE (`scope_id`, `name`) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS scope_member; |
|||
-- +goose StatementEnd |
@ -0,0 +1,18 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE stat ( |
|||
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, |
|||
`scope_id` INT NOT NULL, |
|||
`name` VARCHAR(255) NOT NULL, |
|||
`description` TEXT NOT NULL, |
|||
`weight` FLOAT NOT NULL, |
|||
`allowed_amounts` JSON, |
|||
|
|||
UNIQUE (`scope_id`, `name`) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS stat; |
|||
-- +goose StatementEnd |
@ -0,0 +1,18 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE project ( |
|||
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, |
|||
`scope_id` INT NOT NULL, |
|||
`owner_id` CHAR(36) NOT NULL, |
|||
`name` VARCHAR(255) NOT NULL, |
|||
`status` INT NOT NULL, |
|||
`description` TEXT NOT NULL, |
|||
|
|||
UNIQUE (`scope_id`, `name`) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS project; |
|||
-- +goose StatementEnd |
@ -0,0 +1,16 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE project_requirement ( |
|||
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, |
|||
`scope_id` INT NOT NULL, |
|||
`project_id` INT NOT NULL, |
|||
`name` VARCHAR(255) NOT NULL, |
|||
`status` INT NOT NULL, |
|||
`description` TEXT NOT NULL |
|||
) |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS project_requirement; |
|||
-- +goose StatementEnd |
@ -0,0 +1,19 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE item ( |
|||
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, |
|||
`scope_id` INT NOT NULL, |
|||
`project_requirement_id` INT, |
|||
`owner_id` CHAR(36) NOT NULL, |
|||
`name` VARCHAR(255) NOT NULL, |
|||
`description` TEXT NOT NULL, |
|||
`created_time` DATETIME NOT NULL, |
|||
`acquired_time` DATETIME, |
|||
`scheduled_date` DATE |
|||
) |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS item; |
|||
-- +goose StatementEnd |
@ -0,0 +1,17 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE item_stat_progress ( |
|||
`item_id` INT NOT NULL, |
|||
`stat_id` INT NOT NULL, |
|||
`acquired` INT NOT NULL, |
|||
`required` INT NOT NULL, |
|||
|
|||
PRIMARY KEY (`item_id`, `stat_id`), |
|||
UNIQUE (`stat_id`, `item_id`) |
|||
) |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS item_stat_progress; |
|||
-- +goose StatementEnd |
@ -0,0 +1,15 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE project_requirement_stat ( |
|||
`project_requirement_id` INT NOT NULL, |
|||
`stat_id` INT NOT NULL, |
|||
`required` INT NOT NULL, |
|||
|
|||
PRIMARY KEY (`project_requirement_id`, `stat_id`) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS project_requirement_stat; |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
ALTER TABLE project ADD COLUMN created_time TIMESTAMP NOT NULL DEFAULT NOW(); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
ALTER TABLE project DROP COLUMN IF EXISTS created_time; |
|||
-- +goose StatementEnd |
@ -0,0 +1,22 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE sprint ( |
|||
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, |
|||
`scope_id` INT NOT NULL, |
|||
`name` VARCHAR(255) NOT NULL, |
|||
`description` TEXT NOT NULL, |
|||
`from_time` DATETIME NOT NULL, |
|||
`to_time` DATETIME NOT NULL, |
|||
`is_timed` BOOLEAN NOT NULL, |
|||
`is_coarse` BOOLEAN NOT NULL, |
|||
`is_unweighted` BOOLEAN NOT NULL, |
|||
`kind` INT NOT NULL, |
|||
`aggregate_name` VARCHAR(255) NOT NULL, |
|||
`aggregate_required` INT NOT NULL |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS sprint; |
|||
-- +goose StatementEnd |
@ -0,0 +1,16 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE sprint_part ( |
|||
`sprint_id` INT NOT NULL, |
|||
`object_id` INT NOT NULL, |
|||
`required` INT NOT NULL, |
|||
|
|||
PRIMARY KEY (sprint_id, object_id), |
|||
UNIQUE (object_id, sprint_id) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE IF EXISTS sprint_part; |
|||
-- +goose StatementEnd |
@ -0,0 +1,30 @@ |
|||
version: "1" |
|||
packages: |
|||
- name: "mysqlcore" |
|||
path: "./ports/mysql/mysqlcore" |
|||
queries: "./ports/mysql/queries" |
|||
schema: "./scripts/goose-mysql" |
|||
engine: "mysql" |
|||
emit_prepared_queries: true |
|||
emit_interface: false |
|||
emit_exact_table_names: false |
|||
emit_empty_slices: true |
|||
emit_json_tags: false |
|||
overrides: |
|||
- go_type: "git.aiterp.net/stufflog3/stufflog3/ports/mysql/sqltypes.NullRawMessage" |
|||
db_type: "json" |
|||
nullable: true |
|||
- go_type: "git.aiterp.net/stufflog3/stufflog3/ports/mysql/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" |
|||
- column: "isp.total_acquired" |
|||
go_type: "int" |
|||
- column: "isp.total_required" |
|||
go_type: "int" |
@ -0,0 +1,22 @@ |
|||
package auth |
|||
|
|||
import ( |
|||
"context" |
|||
) |
|||
|
|||
type Service struct { |
|||
key struct{ Stuff uint64 } |
|||
} |
|||
|
|||
func (s *Service) ContextWithUser(ctx context.Context, id string) context.Context { |
|||
return context.WithValue(ctx, &s.key, id) |
|||
} |
|||
|
|||
func (s *Service) GetUser(ctx context.Context) string { |
|||
v := ctx.Value(&s.key) |
|||
if v == nil { |
|||
return "" |
|||
} |
|||
|
|||
return v.(string) |
|||
} |
@ -0,0 +1,22 @@ |
|||
package items |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"time" |
|||
) |
|||
|
|||
type Repository interface { |
|||
Find(ctx context.Context, scopeID, itemID int) (*entities.Item, error) |
|||
ListCreated(ctx context.Context, scopeID int, from, to time.Time) ([]entities.Item, error) |
|||
ListAcquired(ctx context.Context, scopeID int, from, to time.Time) ([]entities.Item, error) |
|||
ListScheduled(ctx context.Context, scopeID int, from, to models.Date) ([]entities.Item, error) |
|||
ListRequirement(ctx context.Context, requirementID int) ([]entities.Item, error) |
|||
ListProject(ctx context.Context, projectID int) ([]entities.Item, error) |
|||
Insert(ctx context.Context, item entities.Item) (*entities.Item, error) |
|||
Update(ctx context.Context, item entities.Item, update models.ItemUpdate) error |
|||
Delete(ctx context.Context, item entities.Item) error |
|||
ListProgress(ctx context.Context, items ...entities.Item) ([]entities.ItemProgress, error) |
|||
UpdateProgress(ctx context.Context, progress entities.ItemProgress) error |
|||
} |
@ -0,0 +1,28 @@ |
|||
package items |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/stats" |
|||
) |
|||
|
|||
type Service struct { |
|||
Scopes *scopes.Service |
|||
Stats *stats.Service |
|||
Repository Repository |
|||
} |
|||
|
|||
func (s *Service) ListProject(ctx context.Context, requirementID int) ([]entities.Item, []entities.ItemProgress, error) { |
|||
items, err := s.Repository.ListProject(ctx, requirementID) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
itemProgresses, err := s.Repository.ListProgress(ctx, items...) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
return items, itemProgresses, nil |
|||
} |
@ -0,0 +1,21 @@ |
|||
package projects |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
) |
|||
|
|||
type Repository interface { |
|||
Find(ctx context.Context, scopeID, projectID int) (*entities.Project, error) |
|||
List(ctx context.Context, scopeID int) ([]entities.Project, error) |
|||
Create(ctx context.Context, project entities.Project) (*entities.Project, error) |
|||
Update(ctx context.Context, project entities.Project, update models.ProjectUpdate) error |
|||
Delete(ctx context.Context, project entities.Project) error |
|||
ListRequirements(ctx context.Context, projectID int) ([]entities.Requirement, []entities.RequirementStat, error) |
|||
CreateRequirement(ctx context.Context, requirement entities.Requirement) (*entities.Requirement, error) |
|||
UpdateRequirement(ctx context.Context, requirement entities.Requirement, update models.RequirementUpdate) error |
|||
DeleteRequirement(ctx context.Context, requirement entities.Requirement) error |
|||
UpsertRequirementStat(ctx context.Context, stat entities.RequirementStat) error |
|||
DeleteRequirementStat(ctx context.Context, stat entities.RequirementStat) error |
|||
} |
@ -0,0 +1,143 @@ |
|||
package projects |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"time" |
|||
) |
|||
|
|||
type Entry struct { |
|||
ID int `json:"id"` |
|||
OwnerID string `json:"ownerId"` |
|||
CreatedTime time.Time `json:"createdTime"` |
|||
Name string `json:"name"` |
|||
Status models.Status `json:"status"` |
|||
} |
|||
|
|||
func generateEntry(project entities.Project) Entry { |
|||
return Entry{ |
|||
ID: project.ID, |
|||
OwnerID: project.OwnerID, |
|||
CreatedTime: project.CreatedTime, |
|||
Name: project.Name, |
|||
Status: project.Status, |
|||
} |
|||
} |
|||
|
|||
type Result struct { |
|||
entities.Project |
|||
Requirements []ResultRequirement `json:"requirements"` |
|||
} |
|||
|
|||
func GenerateResult( |
|||
project entities.Project, |
|||
requirement []entities.Requirement, |
|||
requirementStats []entities.RequirementStat, |
|||
items []entities.Item, |
|||
itemProgresses []entities.ItemProgress, |
|||
stats []entities.Stat, |
|||
) Result { |
|||
res := Result{ |
|||
Project: project, |
|||
Requirements: make([]ResultRequirement, 0, 8), |
|||
} |
|||
|
|||
for _, req := range requirement { |
|||
if req.ProjectID != project.ID { |
|||
continue |
|||
} |
|||
|
|||
resReq := ResultRequirement{ |
|||
ID: req.ID, |
|||
Name: req.Name, |
|||
Description: req.Description, |
|||
Status: req.Status, |
|||
Stats: make([]ResultRequirementStat, 0, 8), |
|||
Items: make([]ResultRequirementItem, 0, 8), |
|||
} |
|||
statIndices := make(map[int]int) |
|||
for _, reqStat := range requirementStats { |
|||
if reqStat.RequirementID != req.ID { |
|||
continue |
|||
} |
|||
|
|||
resStat := ResultRequirementStat{ |
|||
ID: reqStat.StatID, |
|||
Required: reqStat.Required, |
|||
} |
|||
for _, stat := range stats { |
|||
if stat.ID == resStat.ID { |
|||
resStat.Name = stat.Name |
|||
resStat.Weight = stat.Weight |
|||
break |
|||
} |
|||
} |
|||
|
|||
resReq.Stats = append(resReq.Stats, resStat) |
|||
statIndices[reqStat.StatID] = len(resReq.Stats) - 1 |
|||
} |
|||
|
|||
for _, item := range items { |
|||
if item.ProjectRequirementID == nil || *item.ProjectRequirementID != req.ID { |
|||
continue |
|||
} |
|||
|
|||
resItem := ResultRequirementItem{ |
|||
Item: item, |
|||
Stats: make([]ResultRequirementStat, 0, 8), |
|||
} |
|||
for _, itemProgress := range itemProgresses { |
|||
if itemProgress.ItemID != item.ID { |
|||
continue |
|||
} |
|||
|
|||
resStat := ResultRequirementStat{ |
|||
ID: itemProgress.StatID, |
|||
Acquired: itemProgress.Acquired, |
|||
Required: itemProgress.Required, |
|||
} |
|||
for _, stat := range stats { |
|||
if stat.ID == resStat.ID { |
|||
resStat.Name = stat.Name |
|||
resStat.Weight = stat.Weight |
|||
break |
|||
} |
|||
} |
|||
if si, ok := statIndices[resStat.ID]; ok { |
|||
resReq.Stats[si].Acquired += itemProgress.Acquired |
|||
} |
|||
|
|||
resItem.Stats = append(resItem.Stats, resStat) |
|||
} |
|||
|
|||
resReq.Items = append(resReq.Items, resItem) |
|||
} |
|||
|
|||
res.Requirements = append(res.Requirements, resReq) |
|||
} |
|||
|
|||
return res |
|||
} |
|||
|
|||
type ResultRequirement struct { |
|||
ID int `json:"id"` |
|||
Name string `json:"name"` |
|||
Description string `json:"description"` |
|||
Status models.Status `json:"status"` |
|||
Stats []ResultRequirementStat `json:"stats"` |
|||
Items []ResultRequirementItem `json:"items"` |
|||
} |
|||
|
|||
type ResultRequirementStat struct { |
|||
ID int `json:"id"` |
|||
Name string `json:"name"` |
|||
Weight float64 `json:"weight"` |
|||
Acquired int `json:"acquired"` |
|||
Required int `json:"required"` |
|||
} |
|||
|
|||
type ResultRequirementItem struct { |
|||
entities.Item |
|||
|
|||
Stats []ResultRequirementStat `json:"stats"` |
|||
} |
@ -0,0 +1,65 @@ |
|||
package projects |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/items" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/stats" |
|||
) |
|||
|
|||
type Service struct { |
|||
Scopes *scopes.Service |
|||
Stats *stats.Service |
|||
Items *items.Service |
|||
|
|||
Repository Repository |
|||
} |
|||
|
|||
func (s *Service) Find(ctx context.Context, id int) (*Result, error) { |
|||
scopeID := s.Scopes.ScopeFromContext(ctx).ID |
|||
|
|||
project, err := s.Repository.Find(ctx, scopeID, id) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
requirements, requirementStats, err := s.Repository.ListRequirements(ctx, id) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
items, itemProgresses, err := s.Items.ListProject(ctx, id) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
stats, err := s.Stats.List(ctx) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
result := GenerateResult( |
|||
*project, |
|||
requirements, |
|||
requirementStats, |
|||
items, |
|||
itemProgresses, |
|||
stats, |
|||
) |
|||
|
|||
return &result, nil |
|||
} |
|||
|
|||
func (s *Service) List(ctx context.Context) ([]Entry, error) { |
|||
projects, err := s.Repository.List(ctx, s.Scopes.ScopeFromContext(ctx).ID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
entries := make([]Entry, 0, len(projects)) |
|||
for _, project := range projects { |
|||
entries = append(entries, generateEntry(project)) |
|||
} |
|||
|
|||
return entries, nil |
|||
} |
@ -0,0 +1,20 @@ |
|||
package scopes |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
) |
|||
|
|||
type Repository interface { |
|||
Find(ctx context.Context, id int) (*entities.Scope, error) |
|||
List(ctx context.Context) ([]entities.Scope, error) |
|||
ListUser(ctx context.Context, userID string) ([]entities.Scope, error) |
|||
Create(ctx context.Context, scope entities.Scope, ownerID string) (*entities.Scope, error) |
|||
Update(ctx context.Context, scope entities.Scope, update models.ScopeUpdate) error |
|||
Delete(ctx context.Context, scope entities.Scope) error |
|||
|
|||
ListMembers(ctx context.Context, scopeIDs ...int) ([]entities.ScopeMember, error) |
|||
SaveMember(ctx context.Context, member entities.ScopeMember) error |
|||
DeleteMember(ctx context.Context, member entities.ScopeMember) error |
|||
} |
@ -0,0 +1,73 @@ |
|||
package scopes |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/auth" |
|||
) |
|||
|
|||
type Service struct { |
|||
Auth *auth.Service |
|||
Repository Repository |
|||
|
|||
contextKey struct{} |
|||
} |
|||
|
|||
func (s *Service) ContextWithScope(ctx context.Context, scope entities.Scope) context.Context { |
|||
return context.WithValue(ctx, &s.contextKey, &scope) |
|||
} |
|||
|
|||
func (s *Service) ScopeFromContext(ctx context.Context) *entities.Scope { |
|||
v := ctx.Value(&s.contextKey) |
|||
if v == nil { |
|||
return nil |
|||
} |
|||
|
|||
return v.(*entities.Scope) |
|||
} |
|||
|
|||
// Find finds a scope and its members, and returns it if the logged-in user is part of this list.
|
|||
func (s *Service) Find(ctx context.Context, id int) (*entities.Scope, []entities.ScopeMember, error) { |
|||
scope, err := s.Repository.Find(ctx, id) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
members, err := s.Repository.ListMembers(ctx, scope.ID) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
userID := s.Auth.GetUser(ctx) |
|||
found := false |
|||
for _, member := range members { |
|||
if member.UserID == userID { |
|||
found = true |
|||
break |
|||
} |
|||
} |
|||
if !found { |
|||
return nil, nil, models.NotFoundError("Scope") |
|||
} |
|||
|
|||
return scope, members, nil |
|||
} |
|||
|
|||
// List lists a scope and their members, and returns it if the logged-in user is part of this list.
|
|||
func (s *Service) List(ctx context.Context) ([]entities.Scope, []entities.ScopeMember, error) { |
|||
scopes, err := s.Repository.ListUser(ctx, s.Auth.GetUser(ctx)) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
ids := make([]int, 0, len(scopes)) |
|||
for _, scope := range scopes { |
|||
ids = append(ids, scope.ID) |
|||
} |
|||
members, err := s.Repository.ListMembers(ctx, ids...) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
|
|||
return scopes, members, nil |
|||
} |
@ -0,0 +1,15 @@ |
|||
package stats |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
) |
|||
|
|||
type Repository interface { |
|||
Find(ctx context.Context, scopeID, statID int) (*entities.Stat, error) |
|||
List(ctx context.Context, scopeID int) ([]entities.Stat, error) |
|||
Insert(ctx context.Context, stat entities.Stat) (*entities.Stat, error) |
|||
Update(ctx context.Context, stat entities.Stat, update models.StatUpdate) error |
|||
Delete(ctx context.Context, stat entities.Stat) error |
|||
} |
@ -0,0 +1,17 @@ |
|||
package stats |
|||
|
|||
import ( |
|||
"context" |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes" |
|||
) |
|||
|
|||
type Service struct { |
|||
Scopes *scopes.Service |
|||
|
|||
Repository Repository |
|||
} |
|||
|
|||
func (s *Service) List(ctx context.Context) ([]entities.Stat, error) { |
|||
return s.Repository.List(ctx, s.Scopes.ScopeFromContext(ctx).ID) |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue