Move to string to GID

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-01-23 17:29:16 +01:00
parent e6035cd701
commit f6e1e80202
11 changed files with 110 additions and 44 deletions

View File

@@ -19,6 +19,9 @@ omit_panic_handler: true
call_argument_directives_with_null: true
models:
ID:
model:
- "github.com/getprobo/probo/pkg/api/console/v1/types.GIDScalar"
Datetime:
model:
- "github.com/99designs/gqlgen/graphql.Time"

View File

@@ -15,6 +15,7 @@ import (
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection"
"github.com/getprobo/probo/pkg/api/console/v1/types"
"github.com/getprobo/probo/pkg/probo/coredata/gid"
"github.com/getprobo/probo/pkg/probo/coredata/page"
gqlparser "github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
@@ -104,7 +105,7 @@ type ComplexityRoot struct {
}
Query struct {
Node func(childComplexity int, id string) int
Node func(childComplexity int, id gid.GID) int
}
Task struct {
@@ -135,7 +136,7 @@ type OrganizationResolver interface {
Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.FrameworkConnection, error)
}
type QueryResolver interface {
Node(ctx context.Context, id string) (types.Node, error)
Node(ctx context.Context, id gid.GID) (types.Node, error)
}
type executableSchema struct {
@@ -385,7 +386,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false
}
return e.complexity.Query.Node(childComplexity, args["id"].(string)), true
return e.complexity.Query.Node(childComplexity, args["id"].(gid.GID)), true
case "Task.createdAt":
if e.complexity.Task.CreatedAt == nil {
@@ -915,13 +916,13 @@ func (ec *executionContext) field_Query_node_args(ctx context.Context, rawArgs m
func (ec *executionContext) field_Query_node_argsID(
ctx context.Context,
rawArgs map[string]any,
) (string, error) {
) (gid.GID, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id"))
if tmp, ok := rawArgs["id"]; ok {
return ec.unmarshalNID2string(ctx, tmp)
return ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx, tmp)
}
var zeroVal string
var zeroVal gid.GID
return zeroVal, nil
}
@@ -999,9 +1000,9 @@ func (ec *executionContext) _Control_id(ctx context.Context, field graphql.Colle
}
return graphql.Null
}
res := resTmp.(string)
res := resTmp.(gid.GID)
fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res)
return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Control_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -1420,9 +1421,9 @@ func (ec *executionContext) _Framework_id(ctx context.Context, field graphql.Col
}
return graphql.Null
}
res := resTmp.(string)
res := resTmp.(gid.GID)
fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res)
return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Framework_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -1841,9 +1842,9 @@ func (ec *executionContext) _Organization_id(ctx context.Context, field graphql.
}
return graphql.Null
}
res := resTmp.(string)
res := resTmp.(gid.GID)
fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res)
return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Organization_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -2176,7 +2177,7 @@ func (ec *executionContext) _Query_node(ctx context.Context, field graphql.Colle
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Node(rctx, fc.Args["id"].(string))
return ec.resolvers.Query().Node(rctx, fc.Args["id"].(gid.GID))
})
if err != nil {
ec.Error(ctx, err)
@@ -2342,9 +2343,9 @@ func (ec *executionContext) _Task_id(ctx context.Context, field graphql.Collecte
}
return graphql.Null
}
res := resTmp.(string)
res := resTmp.(gid.GID)
fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res)
return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Task_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -5461,13 +5462,13 @@ func (ec *executionContext) marshalNFrameworkEdge2ᚖgithubᚗcomᚋgetproboᚋp
return ec._FrameworkEdge(ctx, sel, v)
}
func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) {
res, err := graphql.UnmarshalID(v)
func (ec *executionContext) unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx context.Context, v any) (gid.GID, error) {
res, err := types.UnmarshalGIDScalar(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
res := graphql.MarshalID(v)
func (ec *executionContext) marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋproboᚋcoredataᚋgidᚐGID(ctx context.Context, sel ast.SelectionSet, v gid.GID) graphql.Marshaler {
res := types.MarshalGIDScalar(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")

View File

@@ -0,0 +1,44 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package types
import (
"errors"
"io"
"strconv"
"github.com/99designs/gqlgen/graphql"
"github.com/getprobo/probo/pkg/probo/coredata/gid"
)
func MarshalGIDScalar(id gid.GID) graphql.Marshaler {
return graphql.WriterFunc(func(w io.Writer) {
w.Write([]byte(strconv.Quote(id.String())))
})
}
func UnmarshalGIDScalar(v interface{}) (gid.GID, error) {
s, ok := v.(string)
if !ok {
return gid.Nil, errors.New("must be a string")
}
id, err := gid.ParseGID(s)
if err != nil {
return gid.Nil, err
}
return id, nil
}

View File

@@ -5,16 +5,17 @@ package types
import (
"time"
"github.com/getprobo/probo/pkg/probo/coredata/gid"
"github.com/getprobo/probo/pkg/probo/coredata/page"
)
type Node interface {
IsNode()
GetID() string
GetID() gid.GID
}
type Control struct {
ID string `json:"id"`
ID gid.GID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Tasks *TaskConnection `json:"tasks"`
@@ -22,8 +23,8 @@ type Control struct {
UpdatedAt time.Time `json:"updatedAt"`
}
func (Control) IsNode() {}
func (this Control) GetID() string { return this.ID }
func (Control) IsNode() {}
func (this Control) GetID() gid.GID { return this.ID }
type ControlConnection struct {
Edges []*ControlEdge `json:"edges"`
@@ -36,7 +37,7 @@ type ControlEdge struct {
}
type Framework struct {
ID string `json:"id"`
ID gid.GID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Controls *ControlConnection `json:"controls"`
@@ -44,8 +45,8 @@ type Framework struct {
UpdatedAt time.Time `json:"updatedAt"`
}
func (Framework) IsNode() {}
func (this Framework) GetID() string { return this.ID }
func (Framework) IsNode() {}
func (this Framework) GetID() gid.GID { return this.ID }
type FrameworkConnection struct {
Edges []*FrameworkEdge `json:"edges"`
@@ -58,15 +59,15 @@ type FrameworkEdge struct {
}
type Organization struct {
ID string `json:"id"`
ID gid.GID `json:"id"`
Name string `json:"name"`
Frameworks *FrameworkConnection `json:"frameworks"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Organization) IsNode() {}
func (this Organization) GetID() string { return this.ID }
func (Organization) IsNode() {}
func (this Organization) GetID() gid.GID { return this.ID }
type PageInfo struct {
HasNextPage bool `json:"hasNextPage"`
@@ -79,14 +80,14 @@ type Query struct {
}
type Task struct {
ID string `json:"id"`
ID gid.GID `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Task) IsNode() {}
func (this Task) GetID() string { return this.ID }
func (Task) IsNode() {}
func (this Task) GetID() gid.GID { return this.ID }
type TaskConnection struct {
Edges []*TaskEdge `json:"edges"`

View File

@@ -10,6 +10,7 @@ import (
"github.com/getprobo/probo/pkg/api/console/v1/schema"
"github.com/getprobo/probo/pkg/api/console/v1/types"
"github.com/getprobo/probo/pkg/probo/coredata/gid"
"github.com/getprobo/probo/pkg/probo/coredata/page"
)
@@ -50,7 +51,7 @@ func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organi
}
// Node is the resolver for the node field.
func (r *queryResolver) Node(ctx context.Context, id string) (types.Node, error) {
func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) {
panic(fmt.Errorf("not implemented: Node - node"))
}

View File

@@ -62,7 +62,7 @@ func (c *Controls) LoadByFrameworkID(
ctx context.Context,
conn pg.Conn,
scope *Scope,
frameworkID string,
frameworkID gid.GID,
cursor *page.Cursor,
) error {
q := `

View File

@@ -60,7 +60,7 @@ func (f *Frameworks) LoadByOrganizationID(
ctx context.Context,
conn pg.Conn,
scope *Scope,
organizationID string,
organizationID gid.GID,
cursor *page.Cursor,
) error {
q := `
@@ -115,7 +115,7 @@ func (f *Framework) LoadByID(
ctx context.Context,
conn pg.Conn,
scope *Scope,
frameworkID string,
frameworkID gid.GID,
) error {
q := `
SELECT

View File

@@ -27,15 +27,30 @@ type (
GID uuid.UUID
)
var (
Nil = GID(uuid.Nil)
)
func ParseGID(encoded string) (GID, error) {
gid := GID{}
err := gid.UnmarshalText([]byte(encoded))
if err != nil {
return Nil, err
}
return gid, nil
}
func NewGID(et uint32) (GID, error) {
id, err := uuid.NewV7()
if err != nil {
return GID(uuid.Nil), err
return Nil, err
}
binary.BigEndian.PutUint32(id[10:14], et)
return GID(id), nil
return Nil, nil
}
func (gid GID) Value() (driver.Value, error) {

View File

@@ -47,7 +47,7 @@ func (o *Organization) LoadByID(
ctx context.Context,
conn pg.Conn,
scope *Scope,
organizationID string,
organizationID gid.GID,
) error {
q := `
SELECT

View File

@@ -58,7 +58,7 @@ func (t *Tasks) LoadByControlID(
ctx context.Context,
conn pg.Conn,
scope *Scope,
controlID string,
controlID gid.GID,
cursor *page.Cursor,
) error {
q := `

View File

@@ -18,6 +18,7 @@ import (
"context"
"github.com/getprobo/probo/pkg/probo/coredata"
"github.com/getprobo/probo/pkg/probo/coredata/gid"
"github.com/getprobo/probo/pkg/probo/coredata/page"
"go.gearno.de/kit/pg"
)
@@ -38,7 +39,7 @@ func NewService(ctx context.Context, pgClient *pg.Client) *Service {
func (s *Service) GetOrganization(
ctx context.Context,
organizationID string,
organizationID gid.GID,
) (*coredata.Organization, error) {
organization := &coredata.Organization{}
@@ -63,7 +64,7 @@ func (s *Service) GetOrganization(
func (s *Service) ListOrganizationFrameworks(
ctx context.Context,
organizationID string,
organizationID gid.GID,
cursor *page.Cursor,
) (*page.Page[*coredata.Framework], error) {
var frameworks coredata.Frameworks
@@ -90,7 +91,7 @@ func (s *Service) ListOrganizationFrameworks(
func (s *Service) ListFrameworkControls(
ctx context.Context,
frameworkID string,
frameworkID gid.GID,
cursor *page.Cursor,
) (*page.Page[*coredata.Control], error) {
var controls coredata.Controls
@@ -117,7 +118,7 @@ func (s *Service) ListFrameworkControls(
func (s *Service) ListControlTasks(
ctx context.Context,
controlID string,
controlID gid.GID,
cursor *page.Cursor,
) (*page.Page[*coredata.Task], error) {
var tasks coredata.Tasks