diff --git a/apps/db-adapter/internal/api/person.go b/apps/db-adapter/internal/api/person.go index cdcb17c..e5ee1c9 100644 --- a/apps/db-adapter/internal/api/person.go +++ b/apps/db-adapter/internal/api/person.go @@ -67,8 +67,81 @@ func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByI c.JSON(http.StatusOK, res) } -func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDeletePersonParams) {} +func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDeletePersonParams) { + ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer cancel() + session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) -func (srv *server) UpdatePerson(c *gin.Context, id int, params api.UpdatePersonParams) {} + actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer acancel() + if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) -func (srv *server) HardDeletePerson(c *gin.Context, id int, params api.HardDeletePersonParams) {} + return + } + + qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer qCancel() + res, err := session.ExecuteWrite(qctx, memgraph.SoftDeletePerson(qctx, id)) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + + return + } + + c.JSON(http.StatusOK, res) +} + +func (srv *server) UpdatePerson(c *gin.Context, id int, params api.UpdatePersonParams) { + var person *api.PersonProperties + if err := c.ShouldBindJSON(&person); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) + + return + } + + actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer acancel() + session := srv.db.NewSession(actx, neo4j.SessionConfig{}) + if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) + + return + } + + qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer qCancel() + res, err := session.ExecuteWrite(qctx, memgraph.UpdatePerson(qctx, id, person)) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + + return + } + + c.JSON(http.StatusOK, res) +} + +func (srv *server) HardDeletePerson(c *gin.Context, id int, params api.HardDeletePersonParams) { + ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer cancel() + session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + + actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer acancel() + if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) + + return + } + + qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + defer qCancel() + res, err := session.ExecuteWrite(qctx, memgraph.HardDeletePerson(qctx, id)) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + + return + } + + c.JSON(http.StatusOK, res) +} diff --git a/apps/db-adapter/internal/memgraph/person.go b/apps/db-adapter/internal/memgraph/person.go index c3c0f54..1889ea5 100644 --- a/apps/db-adapter/internal/memgraph/person.go +++ b/apps/db-adapter/internal/memgraph/person.go @@ -2,6 +2,7 @@ package memgraph import ( "context" + "fmt" "github.com/neo4j/neo4j-go-driver/v5/neo4j" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" @@ -42,3 +43,57 @@ func GetPersonById(ctx context.Context, id int) neo4j.ManagedTransactionWork { return record.AsMap(), nil } } + +func UpdatePerson(ctx context.Context, id int, person *api.PersonProperties) neo4j.ManagedTransactionWork { + return func(tx neo4j.ManagedTransaction) (any, error) { + result, err := tx.Run(ctx, UpdatePersonCypherQuery, map[string]any{ + "id": id, + "props": *person, + }) + if err != nil { + return nil, err + } + + record, err := result.Single(ctx) + if err != nil { + return nil, err + } + + return record.AsMap(), nil + } +} + +func SoftDeletePerson(ctx context.Context, id int) neo4j.ManagedTransactionWork { + return func(tx neo4j.ManagedTransaction) (any, error) { + result, err := tx.Run(ctx, SoftDeletePersonCypherQuery, map[string]any{ + "id": id, + }) + if err != nil { + return nil, err + } + + record, err := result.Single(ctx) + if err != nil { + return nil, err + } + + return record.AsMap(), nil + } +} + +func HardDeletePerson(ctx context.Context, id int) neo4j.ManagedTransactionWork { + return func(tx neo4j.ManagedTransaction) (any, error) { + result, err := tx.Run(ctx, HardDeletePersonCypherQuery, map[string]any{ + "id": id, + }) + if err != nil { + return nil, err + } + + if result.Peek(ctx) { + return nil, fmt.Errorf("record was returned when it wasn't supposed to happen") + } + + return nil, nil + } +} diff --git a/apps/db-adapter/internal/memgraph/relationship.go b/apps/db-adapter/internal/memgraph/relationship.go new file mode 100644 index 0000000..59e5136 --- /dev/null +++ b/apps/db-adapter/internal/memgraph/relationship.go @@ -0,0 +1,45 @@ +package memgraph + +import ( + "context" + + "github.com/neo4j/neo4j-go-driver/v5/neo4j" +) + +func GetRelationship(ctx context.Context, id1, id2 int) neo4j.ManagedTransactionWork { + return func(tx neo4j.ManagedTransaction) (any, error) { + result, err := tx.Run(ctx, GetRelationshipCypherQuery, map[string]any{ + "id1": id1, + "id2": id2, + }) + if err != nil { + return nil, err + } + + records, err := result.Collect(ctx) + if err != nil { + return nil, err + } + + return records, nil + } +} + +func CreateChildParentRelationship(ctx context.Context, childId, parentId int) neo4j.ManagedTransactionWork { + return func(tx neo4j.ManagedTransaction) (any, error) { + result, err := tx.Run(ctx, CreateChildParentRelationshipCypherQuery, map[string]any{ + "childId": childId, + "parentId": parentId, + }) + if err != nil { + return nil, err + } + + record, err := result.Single(ctx) + if err != nil { + return nil, err + } + + return record.AsMap(), nil + } +}