Gisle Aune
2 years ago
24 changed files with 520 additions and 92 deletions
-
2cmd/stufflog3-local/main.go
-
9entities/scope.go
-
23internal/genutils/json.go
-
33internal/genutils/set.go
-
10models/errors.go
-
8models/status.go
-
61ports/httpapi/projects.go
-
18ports/httpapi/scopes.go
-
36ports/httpapi/stats.go
-
2ports/mysql/projects.go
-
12ports/mysql/scopes.go
-
85ports/mysql/stats.go
-
19usecases/items/result.go
-
14usecases/items/service.go
-
2usecases/projects/repository.go
-
20usecases/projects/result.go
-
64usecases/projects/service.go
-
9usecases/scopes/context.go
-
4usecases/scopes/repository.go
-
40usecases/scopes/result.go
-
69usecases/scopes/service.go
-
7usecases/sprints/service.go
-
2usecases/stats/repository.go
-
63usecases/stats/service.go
@ -0,0 +1,23 @@ |
|||
package genutils |
|||
|
|||
import ( |
|||
"bytes" |
|||
"encoding/json" |
|||
) |
|||
|
|||
func ParseJSON[T any](b []byte) (T, error) { |
|||
var res T |
|||
err := json.Unmarshal(b, &res) |
|||
|
|||
return res, err |
|||
} |
|||
|
|||
func ParseJSONArray[T any](b []byte) []T { |
|||
res := make([]T, 0, 16) |
|||
|
|||
if b != nil && !bytes.Equal(b, []byte{'n', 'u', 'l', 'l'}) { |
|||
_ = json.Unmarshal(b, &res) |
|||
} |
|||
|
|||
return res |
|||
} |
@ -0,0 +1,33 @@ |
|||
package genutils |
|||
|
|||
type Set[T comparable] struct { |
|||
m map[T]bool |
|||
a []T |
|||
} |
|||
|
|||
func (set *Set[T]) Add(values ...T) { |
|||
if set.m == nil { |
|||
set.m = make(map[T]bool, len(values)*4) |
|||
} |
|||
|
|||
for _, value := range values { |
|||
if set.m[value] { |
|||
continue |
|||
} |
|||
|
|||
set.m[value] = true |
|||
set.a = append(set.a, value) |
|||
} |
|||
} |
|||
|
|||
func (set *Set[T]) Has(v T) bool { |
|||
return set.m[v] |
|||
} |
|||
|
|||
func (set *Set[T]) Len() int { |
|||
return len(set.a) |
|||
} |
|||
|
|||
func (set *Set[T]) Values() []T { |
|||
return set.a[:len(set.a):len(set.a)] |
|||
} |
@ -0,0 +1,36 @@ |
|||
package httpapi |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/entities" |
|||
"git.aiterp.net/stufflog3/stufflog3/models" |
|||
"git.aiterp.net/stufflog3/stufflog3/usecases/stats" |
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
func Stats(g *gin.RouterGroup, stats *stats.Service) { |
|||
g.GET("", handler("stats", func(c *gin.Context) (interface{}, error) { |
|||
return stats.ListScoped(c.Request.Context()) |
|||
})) |
|||
|
|||
g.GET("/:stat_id", handler("stat", func(c *gin.Context) (interface{}, error) { |
|||
id, err := reqInt(c, "stat_id") |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return stats.Find(c.Request.Context(), id) |
|||
})) |
|||
|
|||
g.POST("", handler("stat", func(c *gin.Context) (interface{}, error) { |
|||
input := entities.Stat{} |
|||
err := c.BindJSON(&input) |
|||
if err != nil { |
|||
return nil, models.BadInputError{ |
|||
Object: "Scope", |
|||
Problem: "Invalid JSON: " + err.Error(), |
|||
} |
|||
} |
|||
|
|||
return stats.Create(c.Request.Context(), input) |
|||
})) |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue