From e784cfd25972c0f8ffc2066e41984f4f043a7bf2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 26 Nov 2020 13:30:11 -0500 Subject: [PATCH] API: Implement updateRepository easy path Renaming repositories requires a little bit more work --- api/gqlgen.yml | 3 ++ api/graph/api/generated.go | 61 +++++++---------------------------- api/graph/model/models_gen.go | 6 ---- api/graph/schema.graphqls | 2 +- api/graph/schema.resolvers.go | 33 +++++++++++++++++-- 5 files changed, 47 insertions(+), 58 deletions(-) diff --git a/api/gqlgen.yml b/api/gqlgen.yml index c696039..3d27946 100644 --- a/api/gqlgen.yml +++ b/api/gqlgen.yml @@ -54,6 +54,9 @@ models: - github.com/99designs/gqlgen/graphql.Int - github.com/99designs/gqlgen/graphql.Int64 - github.com/99designs/gqlgen/graphql.Int32 + RepoInput: + model: + - "map[string]interface{}" Cursor: model: - git.sr.ht/~sircmpwn/core-go/model.Cursor diff --git a/api/graph/api/generated.go b/api/graph/api/generated.go index b2fb9ef..3f4f92c 100644 --- a/api/graph/api/generated.go +++ b/api/graph/api/generated.go @@ -114,7 +114,7 @@ type ComplexityRoot struct { DeleteArtifact func(childComplexity int, id int) int DeleteRepository func(childComplexity int, id int) int UpdateACL func(childComplexity int, repoID int, mode model.AccessMode, entity string) int - UpdateRepository func(childComplexity int, id int, params model.RepoInput) int + UpdateRepository func(childComplexity int, id int, input map[string]interface{}) int UploadArtifact func(childComplexity int, repoID int, revspec string, file graphql.Upload) int } @@ -242,7 +242,7 @@ type CommitResolver interface { } type MutationResolver interface { CreateRepository(ctx context.Context, name string, visibility model.Visibility, description *string) (*model.Repository, error) - UpdateRepository(ctx context.Context, id int, params model.RepoInput) (*model.Repository, error) + UpdateRepository(ctx context.Context, id int, input map[string]interface{}) (*model.Repository, error) DeleteRepository(ctx context.Context, id int) (*model.Repository, error) UpdateACL(ctx context.Context, repoID int, mode model.AccessMode, entity string) (*model.ACL, error) DeleteACL(ctx context.Context, repoID int, entity string) (*model.ACL, error) @@ -588,7 +588,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.UpdateRepository(childComplexity, args["id"].(int), args["params"].(model.RepoInput)), true + return e.complexity.Mutation.UpdateRepository(childComplexity, args["id"].(int), args["input"].(map[string]interface{})), true case "Mutation.uploadArtifact": if e.complexity.Mutation.UploadArtifact == nil { @@ -1590,7 +1590,7 @@ type Mutation { createRepository(name: String!, visibility: Visibility!, description: String): Repository! @access(scope: REPOSITORIES, kind: RW) # Updates the metadata for a git repository - updateRepository(id: Int!, params: RepoInput!): Repository! @access(scope: REPOSITORIES, kind: RW) + updateRepository(id: Int!, input: RepoInput!): Repository! @access(scope: REPOSITORIES, kind: RW) # Deletes a git repository deleteRepository(id: Int!): Repository! @access(scope: REPOSITORIES, kind: RW) @@ -1787,15 +1787,15 @@ func (ec *executionContext) field_Mutation_updateRepository_args(ctx context.Con } } args["id"] = arg0 - var arg1 model.RepoInput - if tmp, ok := rawArgs["params"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) - arg1, err = ec.unmarshalNRepoInput2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐRepoInput(ctx, tmp) + var arg1 map[string]interface{} + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg1, err = ec.unmarshalNRepoInput2map(ctx, tmp) if err != nil { return nil, err } } - args["params"] = arg1 + args["input"] = arg1 return args, nil } @@ -3387,7 +3387,7 @@ func (ec *executionContext) _Mutation_updateRepository(ctx context.Context, fiel resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { directive0 := func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().UpdateRepository(rctx, args["id"].(int), args["params"].(model.RepoInput)) + return ec.resolvers.Mutation().UpdateRepository(rctx, args["id"].(int), args["input"].(map[string]interface{})) } directive1 := func(ctx context.Context) (interface{}, error) { scope, err := ec.unmarshalNAccessScope2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐAccessScope(ctx, "REPOSITORIES") @@ -7956,42 +7956,6 @@ func (ec *executionContext) unmarshalInputFilter(ctx context.Context, obj interf return it, nil } -func (ec *executionContext) unmarshalInputRepoInput(ctx context.Context, obj interface{}) (model.RepoInput, error) { - var it model.RepoInput - var asMap = obj.(map[string]interface{}) - - for k, v := range asMap { - switch k { - case "name": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - it.Name, err = ec.unmarshalOString2ᚖstring(ctx, v) - if err != nil { - return it, err - } - case "description": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("description")) - it.Description, err = ec.unmarshalOString2ᚖstring(ctx, v) - if err != nil { - return it, err - } - case "visibility": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("visibility")) - it.Visibility, err = ec.unmarshalOVisibility2ᚖgitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐVisibility(ctx, v) - if err != nil { - return it, err - } - } - } - - return it, nil -} - // endregion **************************** input.gotpl ***************************** // region ************************** interface.gotpl *************************** @@ -9895,9 +9859,8 @@ func (ec *executionContext) marshalNReferenceCursor2ᚖgitᚗsrᚗhtᚋאsircmpw return ec._ReferenceCursor(ctx, sel, v) } -func (ec *executionContext) unmarshalNRepoInput2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐRepoInput(ctx context.Context, v interface{}) (model.RepoInput, error) { - res, err := ec.unmarshalInputRepoInput(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) +func (ec *executionContext) unmarshalNRepoInput2map(ctx context.Context, v interface{}) (map[string]interface{}, error) { + return v.(map[string]interface{}), nil } func (ec *executionContext) marshalNRepository2gitᚗsrᚗhtᚋאsircmpwnᚋgitᚗsrᚗhtᚋapiᚋgraphᚋmodelᚐRepository(ctx context.Context, sel ast.SelectionSet, v model.Repository) graphql.Marshaler { diff --git a/api/graph/model/models_gen.go b/api/graph/model/models_gen.go index 8bc5757..54a9a53 100644 --- a/api/graph/model/models_gen.go +++ b/api/graph/model/models_gen.go @@ -39,12 +39,6 @@ type ReferenceCursor struct { Cursor *model.Cursor `json:"cursor"` } -type RepoInput struct { - Name *string `json:"name"` - Description *string `json:"description"` - Visibility *Visibility `json:"visibility"` -} - type RepositoryCursor struct { Results []*Repository `json:"results"` Cursor *model.Cursor `json:"cursor"` diff --git a/api/graph/schema.graphqls b/api/graph/schema.graphqls index a12a717..58f0fd6 100644 --- a/api/graph/schema.graphqls +++ b/api/graph/schema.graphqls @@ -343,7 +343,7 @@ type Mutation { createRepository(name: String!, visibility: Visibility!, description: String): Repository! @access(scope: REPOSITORIES, kind: RW) # Updates the metadata for a git repository - updateRepository(id: Int!, params: RepoInput!): Repository! @access(scope: REPOSITORIES, kind: RW) + updateRepository(id: Int!, input: RepoInput!): Repository! @access(scope: REPOSITORIES, kind: RW) # Deletes a git repository deleteRepository(id: Int!): Repository! @access(scope: REPOSITORIES, kind: RW) diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go index d621bf6..fbf5dad 100644 --- a/api/graph/schema.resolvers.go +++ b/api/graph/schema.resolvers.go @@ -21,6 +21,7 @@ import ( "git.sr.ht/~sircmpwn/git.sr.ht/api/graph/model" "git.sr.ht/~sircmpwn/git.sr.ht/api/loaders" "github.com/99designs/gqlgen/graphql" + sq "github.com/Masterminds/squirrel" git "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" @@ -155,8 +156,36 @@ func (r *mutationResolver) CreateRepository(ctx context.Context, name string, vi return &repo, nil } -func (r *mutationResolver) UpdateRepository(ctx context.Context, id int, params model.RepoInput) (*model.Repository, error) { - panic(fmt.Errorf("updateRepository: not implemented")) +func (r *mutationResolver) UpdateRepository(ctx context.Context, id int, input map[string]interface{}) (*model.Repository, error) { + if _, ok := input["name"]; ok { + panic(fmt.Errorf("updateRepository: rename not implemented")) // TODO + } + + var repo model.Repository + if err := database.WithTx(ctx, nil, func(tx *sql.Tx) error { + row := database.Apply(&repo, input). + Where(`id = ?`, id). + Where(`owner_id = ?`, auth.ForContext(ctx).UserID). + Set(`updated`, sq.Expr(`now() at time zone 'utc'`)). + Suffix(`RETURNING + id, created, updated, name, description, visibility, + upstream_uri, path, owner_id`). + RunWith(tx). + QueryRowContext(ctx) + if err := row.Scan(&repo.ID, &repo.Created, &repo.Updated, + &repo.Name, &repo.Description, &repo.Visibility, + &repo.UpstreamURL, &repo.Path, &repo.OwnerID); err != nil { + if err == sql.ErrNoRows { + return fmt.Errorf("No repository by ID %d found for this user", id) + } + return err + } + return nil + }); err != nil { + return nil, err + } + + return &repo, nil } func (r *mutationResolver) DeleteRepository(ctx context.Context, id int) (*model.Repository, error) { -- 2.38.4