Nexus/pkg/nex/cruda/command.go

131 lines
3.2 KiB
Go
Raw Normal View History

2024-10-20 11:55:52 +00:00
package cruda
import (
2024-10-20 13:22:53 +00:00
"errors"
2024-10-20 11:55:52 +00:00
"git.solsynth.dev/hypernet/nexus/pkg/nex"
2024-10-20 13:22:53 +00:00
"github.com/go-playground/validator/v10"
"gorm.io/gorm"
2024-10-20 11:55:52 +00:00
"net/http"
)
type CrudAction func(v *CrudConn) nex.CommandHandler
func AddModel[T any](v *CrudConn, model T, id, prefix string, tags []string) error {
2024-10-20 12:20:01 +00:00
funcList := []CrudAction{cmdList[T], cmdGet[T], cmdCreate[T], cmdUpdate[T], cmdDelete[T]}
2024-10-20 13:22:53 +00:00
funcCmds := []string{".list", "", "", "", ""}
2024-10-20 12:20:01 +00:00
funcMethods := []string{"get", "get", "put", "patch", "delete"}
2024-10-20 11:55:52 +00:00
for idx, fn := range funcList {
2024-10-20 12:20:01 +00:00
if err := v.Conn.AddCommand(prefix+id+funcCmds[idx], funcMethods[idx], tags, fn(v)); err != nil {
2024-10-20 11:55:52 +00:00
return err
}
}
return nil
}
2024-10-20 13:22:53 +00:00
var validate = validator.New(validator.WithRequiredStructEnabled())
2024-10-20 11:55:52 +00:00
func cmdList[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
2024-10-20 13:22:53 +00:00
take := int(nex.CtxValueShouldBe[int64](ctx, "query.take", 10))
skip := int(nex.CtxValueShouldBe[int64](ctx, "query.skip", 0))
2024-10-20 12:20:01 +00:00
var str T
var count int64
if err := c.db.Model(str).Count(&count).Error; err != nil {
return err
2024-10-20 11:55:52 +00:00
}
var out []T
if err := c.db.Offset(skip).Limit(take).Find(&out).Error; err != nil {
return err
}
2024-10-20 12:20:01 +00:00
return ctx.JSON(map[string]any{
"count": count,
"data": out,
}, http.StatusOK)
}
}
func cmdGet[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
2024-10-20 13:22:53 +00:00
id, err := nex.CtxValueMustBe[int64](ctx, "query.id")
if err != nil {
return err
}
2024-10-20 12:20:01 +00:00
var out T
if err := c.db.First(&out, "id = ?", id).Error; err != nil {
2024-10-20 13:22:53 +00:00
if errors.Is(err, gorm.ErrRecordNotFound) {
return ctx.Write([]byte(err.Error()), "text/plain", http.StatusNotFound)
}
2024-10-20 12:20:01 +00:00
return err
}
return ctx.JSON(out, http.StatusOK)
}
}
func cmdCreate[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
2024-10-20 13:22:53 +00:00
var payload T
if err := ctx.ReadJSON(&payload); err != nil {
2024-10-20 12:20:01 +00:00
return err
2024-10-20 13:22:53 +00:00
} else if err := validate.Struct(payload); err != nil {
return ctx.Write([]byte(err.Error()), "text/plain+error", http.StatusBadRequest)
2024-10-20 12:20:01 +00:00
}
2024-10-20 13:22:53 +00:00
if err := c.db.Create(&payload).Error; err != nil {
2024-10-20 12:20:01 +00:00
return err
}
2024-10-20 13:22:53 +00:00
return ctx.JSON(payload, http.StatusOK)
2024-10-20 12:20:01 +00:00
}
}
func cmdUpdate[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
2024-10-20 13:22:53 +00:00
id, err := nex.CtxValueMustBe[int64](ctx, "query.id")
if err != nil {
return err
}
2024-10-20 12:20:01 +00:00
var payload T
if err := ctx.ReadJSON(&payload); err != nil {
return err
2024-10-20 13:22:53 +00:00
} else if err := validate.Struct(payload); err != nil {
return ctx.Write([]byte(err.Error()), "text/plain+error", http.StatusBadRequest)
2024-10-20 12:20:01 +00:00
}
var out T
if err := c.db.Model(out).Where("id = ?", id).Updates(&payload).Error; err != nil {
return err
}
if err := c.db.First(&out, "id = ?", id).Error; err != nil {
return err
}
return ctx.JSON(out, http.StatusOK)
}
}
func cmdDelete[T any](c *CrudConn) nex.CommandHandler {
return func(ctx *nex.CommandCtx) error {
2024-10-20 13:22:53 +00:00
id, err := nex.CtxValueMustBe[int64](ctx, "query.id")
if err != nil {
return err
}
2024-10-20 12:20:01 +00:00
var out T
if err := c.db.Delete(&out, "id = ?", id).Error; err != nil {
2024-10-20 13:22:53 +00:00
if errors.Is(err, gorm.ErrRecordNotFound) {
return ctx.Write([]byte(err.Error()), "text/plain", http.StatusNotFound)
}
2024-10-20 12:20:01 +00:00
return err
}
2024-10-20 13:22:53 +00:00
return ctx.Write(nil, "text/plain", http.StatusOK)
2024-10-20 11:55:52 +00:00
}
}